1 package org.chromium.devtools.jsdoc;
3 import com.google.javascript.rhino.head.CompilerEnvirons;
4 import com.google.javascript.rhino.head.IRFactory;
5 import com.google.javascript.rhino.head.ast.AstNode;
6 import com.google.javascript.rhino.head.ast.AstRoot;
8 import org.chromium.devtools.jsdoc.checks.ContextTrackingValidationCheck;
10 import java.io.FileNotFoundException;
11 import java.io.IOException;
12 import java.io.StringReader;
13 import java.nio.ByteBuffer;
14 import java.nio.charset.StandardCharsets;
15 import java.nio.file.FileSystems;
16 import java.nio.file.Files;
17 import java.util.ArrayList;
18 import java.util.List;
19 import java.util.concurrent.Callable;
21 public class FileCheckerCallable implements Callable<ValidatorContext> {
23 private final String fileName;
25 public FileCheckerCallable(String fileName) {
26 this.fileName = fileName;
30 public ValidatorContext call() {
32 ValidatorContext context = new ValidatorContext(readScriptText(), fileName);
33 AstRoot node = parseScript(context);
34 ValidationCheckDispatcher dispatcher = new ValidationCheckDispatcher(context);
35 dispatcher.registerCheck(new ContextTrackingValidationCheck());
36 node.visit(dispatcher);
39 } catch (FileNotFoundException e) {
40 logError("File not found: " + fileName);
41 } catch (IOException e) {
42 logError("Failed to read file " + fileName);
47 private ScriptText readScriptText() throws IOException {
48 byte[] encoded = Files.readAllBytes(FileSystems.getDefault().getPath(fileName));
49 String text = StandardCharsets.UTF_8.decode(ByteBuffer.wrap(encoded)).toString();
50 return new ScriptText(text);
53 private static AstRoot parseScript(ValidatorContext context) throws IOException {
54 CompilerEnvirons env = new CompilerEnvirons();
55 env.setRecoverFromErrors(true);
56 env.setGenerateDebugInfo(true);
57 env.setRecordingLocalJsDocComments(true);
58 env.setAllowSharpComments(true);
59 env.setRecordingComments(true);
60 IRFactory factory = new IRFactory(env);
61 return factory.parse(new StringReader(context.scriptText.text), context.scriptFileName, 1);
64 private static void logError(String message) {
65 System.err.println("ERROR: " + message);
68 private static class ValidationCheckDispatcher extends DoDidVisitorAdapter {
69 private final List<ValidationCheck> checks = new ArrayList<>(2);
70 private final ValidatorContext context;
72 public ValidationCheckDispatcher(ValidatorContext context) {
73 this.context = context;
76 public void registerCheck(ValidationCheck check) {
77 check.setContext(context);
82 public void doVisit(AstNode node) {
83 for (DoDidNodeVisitor visitor : checks) {
84 visitor.doVisit(node);
89 public void didVisit(AstNode node) {
90 for (ValidationCheck check : checks) {