2 * Validator for Closure-based JSDoc.
5 package org.chromium.devtools.jsdoc;
7 import java.util.ArrayList;
8 import java.util.Collections;
9 import java.util.HashMap;
10 import java.util.List;
12 import java.util.SortedSet;
13 import java.util.concurrent.ExecutionException;
14 import java.util.concurrent.ExecutorService;
15 import java.util.concurrent.Executors;
16 import java.util.concurrent.Future;
18 public class JsDocValidator {
20 private void run(String[] args) {
21 int threadCount = Math.min(args.length, Runtime.getRuntime().availableProcessors());
22 ExecutorService executor = Executors.newFixedThreadPool(threadCount);
24 runWithExecutor(args, executor);
30 private void runWithExecutor(String[] args, ExecutorService executor) {
31 List<Future<ValidatorContext>> futures = new ArrayList<>(args.length);
32 Map<Future<ValidatorContext>, String> fileNamesByFuture = new HashMap<>();
33 for (String fileName : args) {
34 Future<ValidatorContext> future = executor.submit(new FileCheckerCallable(fileName));
35 fileNamesByFuture.put(future, fileName);
39 List<ValidatorContext> contexts = new ArrayList<>(args.length);
40 for (Future<ValidatorContext> future : futures) {
42 ValidatorContext context = future.get();
43 if (context != null) {
44 contexts.add(context);
46 } catch (InterruptedException | ExecutionException e) {
47 System.err.println(fileNamesByFuture.get(future) + ": ERROR - " + e.getMessage());
52 for (ValidatorContext context : contexts) {
53 entryCount += context.getValidationResult().size();
55 List<LogEntry> entries = new ArrayList<>(entryCount);
56 for (ValidatorContext context : contexts) {
57 SortedSet<ValidatorContext.MessageRecord> records = context.getValidationResult();
58 for (ValidatorContext.MessageRecord record : records) {
59 entries.add(new LogEntry(context.scriptFileName, record));
62 Collections.sort(entries);
63 for (LogEntry entry : entries) {
64 System.err.println(entry.record.text);
66 if (!entries.isEmpty())
67 System.err.println("Total errors: " + entries.size());
70 public static void main(String[] args) {
71 new JsDocValidator().run(args);
74 private static class LogEntry implements Comparable<LogEntry> {
75 private final String fileName;
76 private final ValidatorContext.MessageRecord record;
78 LogEntry(String fileName, ValidatorContext.MessageRecord record) {
79 this.fileName = fileName;
84 public int compareTo(LogEntry other) {
85 int result = fileName.compareTo(other.fileName);
89 return Integer.compare(record.position, other.record.position);
93 public int hashCode() {
94 return 17 + fileName.hashCode() * 3 + this.record.hashCode() * 5;
98 public boolean equals(Object obj) {
105 if (getClass() != obj.getClass()) {
108 LogEntry other = (LogEntry) obj;
109 if (fileName != other.fileName
110 && (fileName != null && !fileName.equals(other.fileName))) {
114 if (record == other.record) {
117 if (record != null) {
118 if (other.record == null) {
121 return record.position == other.record.position;