2 * Validator for Closure-based JSDoc.
5 package org.chromium.devtools.jsdoc;
7 import java.util.ArrayList;
8 import java.util.Collections;
10 import java.util.SortedSet;
11 import java.util.concurrent.ExecutionException;
12 import java.util.concurrent.ExecutorService;
13 import java.util.concurrent.Executors;
14 import java.util.concurrent.Future;
16 public class JsDocValidator {
18 private void run(String[] args) {
19 int threadCount = Math.min(args.length, Runtime.getRuntime().availableProcessors());
20 ExecutorService executor = Executors.newFixedThreadPool(threadCount);
22 runWithExecutor(args, executor);
28 private void runWithExecutor(String[] args, ExecutorService executor) {
29 List<Future<ValidatorContext>> futures = new ArrayList<>(args.length);
30 for (String fileName : args) {
31 futures.add(executor.submit(new FileCheckerCallable(fileName)));
34 List<ValidatorContext> contexts = new ArrayList<>(args.length);
35 for (Future<ValidatorContext> future : futures) {
37 ValidatorContext context = future.get();
38 if (context != null) {
39 contexts.add(context);
41 } catch (InterruptedException | ExecutionException e) {
42 System.err.println("ERROR - " + e.getMessage());
47 for (ValidatorContext context : contexts) {
48 entryCount += context.getValidationResult().size();
50 List<LogEntry> entries = new ArrayList<>(entryCount);
51 for (ValidatorContext context : contexts) {
52 SortedSet<ValidatorContext.MessageRecord> records = context.getValidationResult();
53 for (ValidatorContext.MessageRecord record : records) {
54 entries.add(new LogEntry(context.scriptFileName, record));
57 Collections.sort(entries);
58 for (LogEntry entry : entries) {
59 System.err.println(entry.record.text);
61 if (!entries.isEmpty())
62 System.err.println("Total errors: " + entries.size());
65 public static void main(String[] args) {
66 new JsDocValidator().run(args);
69 private static class LogEntry implements Comparable<LogEntry> {
70 private final String fileName;
71 private final ValidatorContext.MessageRecord record;
73 LogEntry(String fileName, ValidatorContext.MessageRecord record) {
74 this.fileName = fileName;
79 public int compareTo(LogEntry other) {
80 int result = fileName.compareTo(other.fileName);
84 return Integer.compare(record.position, other.record.position);
88 public int hashCode() {
89 return 17 + fileName.hashCode() * 3 + this.record.hashCode() * 5;
93 public boolean equals(Object obj) {
100 if (getClass() != obj.getClass()) {
103 LogEntry other = (LogEntry) obj;
104 if (fileName != other.fileName
105 && (fileName != null && !fileName.equals(other.fileName))) {
109 if (record == other.record) {
112 if (record != null) {
113 if (other.record == null) {
116 return record.position == other.record.position;