/* * Copyright (c) 2013, the Dart project authors. * * Licensed under the Eclipse Public License v1.0 (the "License"); you may not use this file except * in compliance with the License. You may obtain a copy of the License at * * http://www.eclipse.org/legal/epl-v10.html * * Unless required by applicable law or agreed to in writing, software distributed under the License * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express * or implied. See the License for the specific language governing permissions and limitations under * the License. */ package com.google.dart.engine.internal.hint; import com.google.dart.engine.ast.CompilationUnit; import com.google.dart.engine.context.AnalysisContext; import com.google.dart.engine.context.AnalysisException; import com.google.dart.engine.element.CompilationUnitElement; import com.google.dart.engine.element.LibraryElement; import com.google.dart.engine.error.AnalysisErrorListener; import com.google.dart.engine.error.HintCode; import com.google.dart.engine.internal.context.PerformanceStatistics; import com.google.dart.engine.internal.error.ErrorReporter; import com.google.dart.engine.internal.resolver.InheritanceManager; import com.google.dart.engine.source.Source; import com.google.dart.engine.utilities.general.TimeCounter.TimeCounterHandle; /** * Instances of the class {@code HintGenerator} traverse a library's worth of dart code at a time to * generate hints over the set of sources. * * @see HintCode * @coverage dart.engine.resolver */ public class HintGenerator { private final CompilationUnit[] compilationUnits; @SuppressWarnings("unused") private final AnalysisContext context; AnalysisErrorListener errorListener; private ImportsVerifier importsVerifier; private final boolean enableDart2JSHints; /** * The inheritance manager used to find overridden methods. */ private InheritanceManager manager; public HintGenerator(CompilationUnit[] compilationUnits, AnalysisContext context, AnalysisErrorListener errorListener) { this.compilationUnits = compilationUnits; this.context = context; this.errorListener = errorListener; LibraryElement library = compilationUnits[0].getElement().getLibrary(); importsVerifier = new ImportsVerifier(library); enableDart2JSHints = context.getAnalysisOptions().getDart2jsHint(); manager = new InheritanceManager(compilationUnits[0].getElement().getLibrary()); } public void generateForLibrary() throws AnalysisException { TimeCounterHandle timeCounter = PerformanceStatistics.hints.start(); try { for (int i = 0; i < compilationUnits.length; i++) { CompilationUnitElement element = compilationUnits[i].getElement(); if (element != null) { if (i == 0) { importsVerifier.setInDefiningCompilationUnit(true); generateForCompilationUnit(compilationUnits[i], element.getSource()); importsVerifier.setInDefiningCompilationUnit(false); } else { generateForCompilationUnit(compilationUnits[i], element.getSource()); } } } ErrorReporter definingCompilationUnitErrorReporter = new ErrorReporter( errorListener, compilationUnits[0].getElement().getSource()); importsVerifier.generateDuplicateImportHints(definingCompilationUnitErrorReporter); importsVerifier.generateUnusedImportHints(definingCompilationUnitErrorReporter); } finally { timeCounter.stop(); } } private void generateForCompilationUnit(CompilationUnit unit, Source source) { ErrorReporter errorReporter = new ErrorReporter(errorListener, source); unit.accept(importsVerifier); // dead code analysis unit.accept(new DeadCodeVerifier(errorReporter)); // dart2js analysis if (enableDart2JSHints) { unit.accept(new Dart2JSVerifier(errorReporter)); } // Dart best practices unit.accept(new BestPracticesVerifier(errorReporter)); unit.accept(new OverrideVerifier(manager, errorReporter)); // Find to-do comments new ToDoFinder(errorReporter).findIn(unit); // pub analysis // TODO(danrubel/jwren) Commented out until bugs in the pub verifier are fixed // unit.accept(new PubVerifier(context, errorReporter)); } }