| Index: third_party/WebKit/Source/devtools/scripts/jsdoc-validator/src/org/chromium/devtools/jsdoc/JsDocValidator.java
|
| diff --git a/third_party/WebKit/Source/devtools/scripts/jsdoc-validator/src/org/chromium/devtools/jsdoc/JsDocValidator.java b/third_party/WebKit/Source/devtools/scripts/jsdoc-validator/src/org/chromium/devtools/jsdoc/JsDocValidator.java
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..fa4392c64ed60ae98c3fbbf8e5d4049e04110baf
|
| --- /dev/null
|
| +++ b/third_party/WebKit/Source/devtools/scripts/jsdoc-validator/src/org/chromium/devtools/jsdoc/JsDocValidator.java
|
| @@ -0,0 +1,159 @@
|
| +/**
|
| + * Validator for Closure-based JSDoc.
|
| + */
|
| +
|
| +package org.chromium.devtools.jsdoc;
|
| +
|
| +import java.io.IOException;
|
| +import java.nio.charset.Charset;
|
| +import java.nio.file.FileSystems;
|
| +import java.nio.file.Files;
|
| +import java.util.ArrayList;
|
| +import java.util.Collections;
|
| +import java.util.HashMap;
|
| +import java.util.List;
|
| +import java.util.Map;
|
| +import java.util.SortedSet;
|
| +import java.util.concurrent.ExecutionException;
|
| +import java.util.concurrent.ExecutorService;
|
| +import java.util.concurrent.Executors;
|
| +import java.util.concurrent.Future;
|
| +
|
| +public class JsDocValidator {
|
| +
|
| + private static final String FILES_LIST_NAME = "--files-list-name";
|
| +
|
| + private void run(String[] args) {
|
| + if (args.length == 0) {
|
| + System.err.println("At least 1 argument is expected");
|
| + System.exit(1);
|
| + }
|
| + String[] files;
|
| + if (FILES_LIST_NAME.equals(args[0])) {
|
| + files = readFileNames(args);
|
| + } else {
|
| + files = args;
|
| + }
|
| + int threadCount = Math.min(files.length, Runtime.getRuntime().availableProcessors());
|
| + ExecutorService executor = Executors.newFixedThreadPool(threadCount);
|
| + try {
|
| + runWithExecutor(files, executor);
|
| + } finally {
|
| + executor.shutdown();
|
| + }
|
| + }
|
| +
|
| + private String[] readFileNames(String[] args) {
|
| + if (args.length != 2) {
|
| + System.err.println("A single file name is expected to follow " + FILES_LIST_NAME);
|
| + System.exit(1);
|
| + }
|
| + try {
|
| + List<String> list = Files.readAllLines(
|
| + FileSystems.getDefault().getPath(args[1]), Charset.forName("UTF-8"));
|
| + return list.toArray(new String[list.size()]);
|
| + } catch (IOException e) {
|
| + System.err.println("Unable to read list file " + args[1]);
|
| + e.printStackTrace();
|
| + System.exit(1);
|
| + return new String[0];
|
| + }
|
| + }
|
| +
|
| + private void runWithExecutor(String[] args, ExecutorService executor) {
|
| + List<Future<ValidatorContext>> futures = new ArrayList<>(args.length);
|
| + Map<Future<ValidatorContext>, String> fileNamesByFuture = new HashMap<>();
|
| + for (String fileName : args) {
|
| + Future<ValidatorContext> future = executor.submit(new FileCheckerCallable(fileName));
|
| + fileNamesByFuture.put(future, fileName);
|
| + futures.add(future);
|
| + }
|
| +
|
| + List<ValidatorContext> contexts = new ArrayList<>(args.length);
|
| + for (Future<ValidatorContext> future : futures) {
|
| + try {
|
| + ValidatorContext context = future.get();
|
| + if (context != null) {
|
| + contexts.add(context);
|
| + }
|
| + } catch (InterruptedException | ExecutionException e) {
|
| + System.err.println(fileNamesByFuture.get(future) + ": ERROR - " + e.getMessage());
|
| + }
|
| + }
|
| +
|
| + int entryCount = 0;
|
| + for (ValidatorContext context : contexts) {
|
| + entryCount += context.getValidationResult().size();
|
| + }
|
| + List<LogEntry> entries = new ArrayList<>(entryCount);
|
| + for (ValidatorContext context : contexts) {
|
| + SortedSet<ValidatorContext.MessageRecord> records = context.getValidationResult();
|
| + for (ValidatorContext.MessageRecord record : records) {
|
| + entries.add(new LogEntry(context.scriptFileName, record));
|
| + }
|
| + }
|
| + Collections.sort(entries);
|
| + for (LogEntry entry : entries) {
|
| + System.err.println(entry.record.text);
|
| + }
|
| + if (!entries.isEmpty())
|
| + System.err.println("Total errors: " + entries.size());
|
| + }
|
| +
|
| + public static void main(String[] args) {
|
| + new JsDocValidator().run(args);
|
| + }
|
| +
|
| + private static class LogEntry implements Comparable<LogEntry> {
|
| + private final String fileName;
|
| + private final ValidatorContext.MessageRecord record;
|
| +
|
| + LogEntry(String fileName, ValidatorContext.MessageRecord record) {
|
| + this.fileName = fileName;
|
| + this.record = record;
|
| + }
|
| +
|
| + @Override
|
| + public int compareTo(LogEntry other) {
|
| + int result = fileName.compareTo(other.fileName);
|
| + if (result != 0) {
|
| + return result;
|
| + }
|
| + return Integer.compare(record.position, other.record.position);
|
| + }
|
| +
|
| + @Override
|
| + public int hashCode() {
|
| + return 17 + fileName.hashCode() * 3 + this.record.hashCode() * 5;
|
| + }
|
| +
|
| + @Override
|
| + public boolean equals(Object obj) {
|
| + if (this == obj) {
|
| + return true;
|
| + }
|
| + if (obj == null) {
|
| + return false;
|
| + }
|
| + if (getClass() != obj.getClass()) {
|
| + return false;
|
| + }
|
| + LogEntry other = (LogEntry) obj;
|
| + if (fileName != other.fileName
|
| + && (fileName != null && !fileName.equals(other.fileName))) {
|
| + return false;
|
| + }
|
| +
|
| + if (record == other.record) {
|
| + return true;
|
| + }
|
| + if (record != null) {
|
| + if (other.record == null) {
|
| + return false;
|
| + }
|
| + return record.position == other.record.position;
|
| + }
|
| + return false;
|
| + }
|
| + }
|
| +}
|
|
|