Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(260)

Unified Diff: pkg/analyzer_cli/lib/src/analyzer_impl.dart

Issue 1459683003: `analyzer_cli` move to SDK. (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: master merge Created 5 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « pkg/analyzer_cli/bin/analyzer.dart ('k') | pkg/analyzer_cli/lib/src/bootloader.dart » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: pkg/analyzer_cli/lib/src/analyzer_impl.dart
diff --git a/pkg/analyzer_cli/lib/src/analyzer_impl.dart b/pkg/analyzer_cli/lib/src/analyzer_impl.dart
new file mode 100644
index 0000000000000000000000000000000000000000..32d5f3792c89ce7552ff5b565028e5f09037a305
--- /dev/null
+++ b/pkg/analyzer_cli/lib/src/analyzer_impl.dart
@@ -0,0 +1,303 @@
+// Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library analyzer_cli.src.analyzer_impl;
+
+import 'dart:collection';
+import 'dart:io';
+
+import 'package:analyzer/src/generated/element.dart';
+import 'package:analyzer/src/generated/engine.dart';
+import 'package:analyzer/src/generated/error.dart';
+import 'package:analyzer/src/generated/java_engine.dart';
+import 'package:analyzer/src/generated/java_io.dart';
+import 'package:analyzer/src/generated/sdk_io.dart';
+import 'package:analyzer/src/generated/source.dart';
+import 'package:analyzer/src/generated/source_io.dart';
+import 'package:analyzer/src/generated/utilities_general.dart';
+import 'package:analyzer_cli/src/driver.dart';
+import 'package:analyzer_cli/src/error_formatter.dart';
+import 'package:analyzer_cli/src/options.dart';
+
+DirectoryBasedDartSdk sdk;
+
+/// The maximum number of sources for which AST structures should be kept in the cache.
+const int _maxCacheSize = 512;
+
+int currentTimeMillis() => new DateTime.now().millisecondsSinceEpoch;
+
+/// Analyzes single library [File].
+class AnalyzerImpl {
+ final CommandLineOptions options;
+ final int startTime;
+
+ final AnalysisContext context;
+ final Source librarySource;
+
+ /// All [Source]s references by the analyzed library.
+ final Set<Source> sources = new Set<Source>();
+
+ /// All [AnalysisErrorInfo]s in the analyzed library.
+ final List<AnalysisErrorInfo> errorInfos = new List<AnalysisErrorInfo>();
+
+ /// [HashMap] between sources and analysis error infos.
+ final HashMap<Source, AnalysisErrorInfo> sourceErrorsMap =
+ new HashMap<Source, AnalysisErrorInfo>();
+
+ /// If the file specified on the command line is part of a package, the name
+ /// of that package. Otherwise `null`. This allows us to analyze the file
+ /// specified on the command line as though it is reached via a "package:"
+ /// URI, but avoid suppressing its output in the event that the user has not
+ /// specified the "--package-warnings" option.
+ String _selfPackageName;
+
+ AnalyzerImpl(this.context, this.librarySource, this.options, this.startTime);
+
+ /// Returns the maximal [ErrorSeverity] of the recorded errors.
+ ErrorSeverity get maxErrorSeverity {
+ var status = ErrorSeverity.NONE;
+ for (AnalysisErrorInfo errorInfo in errorInfos) {
+ for (AnalysisError error in errorInfo.errors) {
+ if (!_isDesiredError(error)) {
+ continue;
+ }
+ var severity = computeSeverity(error, options);
+ status = status.max(severity);
+ }
+ }
+ return status;
+ }
+
+ void addCompilationUnitSource(CompilationUnitElement unit,
+ Set<LibraryElement> libraries, Set<CompilationUnitElement> units) {
+ if (unit == null || units.contains(unit)) {
+ return;
+ }
+ units.add(unit);
+ sources.add(unit.source);
+ }
+
+ void addLibrarySources(LibraryElement library, Set<LibraryElement> libraries,
+ Set<CompilationUnitElement> units) {
+ if (library == null || !libraries.add(library)) {
+ return;
+ }
+ // Maybe skip library.
+ {
+ UriKind uriKind = library.source.uriKind;
+ // Optionally skip package: libraries.
+ if (!options.showPackageWarnings && _isOtherPackage(library.source.uri)) {
+ return;
+ }
+ // Optionally skip SDK libraries.
+ if (!options.showSdkWarnings && uriKind == UriKind.DART_URI) {
+ return;
+ }
+ }
+ // Add compilation units.
+ addCompilationUnitSource(library.definingCompilationUnit, libraries, units);
+ for (CompilationUnitElement child in library.parts) {
+ addCompilationUnitSource(child, libraries, units);
+ }
+ // Add referenced libraries.
+ for (LibraryElement child in library.importedLibraries) {
+ addLibrarySources(child, libraries, units);
+ }
+ for (LibraryElement child in library.exportedLibraries) {
+ addLibrarySources(child, libraries, units);
+ }
+ }
+
+ /// Treats the [sourcePath] as the top level library and analyzes it using a
+ /// synchronous algorithm over the analysis engine. If [printMode] is `0`,
+ /// then no error or performance information is printed. If [printMode] is `1`,
+ /// then both will be printed. If [printMode] is `2`, then only performance
+ /// information will be printed, and it will be marked as being for a cold VM.
+ ErrorSeverity analyzeSync({int printMode: 1}) {
+ setupForAnalysis();
+ return _analyzeSync(printMode);
+ }
+
+ /// Fills [errorInfos] using [sources].
+ void prepareErrors() {
+ for (Source source in sources) {
+ context.computeErrors(source);
+
+ errorInfos.add(context.getErrors(source));
+ }
+ }
+
+ /// Fills [sources].
+ void prepareSources(LibraryElement library) {
+ var units = new Set<CompilationUnitElement>();
+ var libraries = new Set<LibraryElement>();
+ addLibrarySources(library, libraries, units);
+ }
+
+ /// Setup local fields such as the analysis context for analysis.
+ void setupForAnalysis() {
+ sources.clear();
+ errorInfos.clear();
+ Uri libraryUri = librarySource.uri;
+ if (libraryUri.scheme == 'package' && libraryUri.pathSegments.length > 0) {
+ _selfPackageName = libraryUri.pathSegments[0];
+ }
+ }
+
+ /// The sync version of analysis.
+ ErrorSeverity _analyzeSync(int printMode) {
+ // Don't try to analyze parts.
+ if (context.computeKindOf(librarySource) == SourceKind.PART) {
+ stderr.writeln("Only libraries can be analyzed.");
+ stderr.writeln(
+ "${librarySource.fullName} is a part and can not be analyzed.");
+ return ErrorSeverity.ERROR;
+ }
+ // Resolve library.
+ var libraryElement = context.computeLibraryElement(librarySource);
+ // Prepare source and errors.
+ prepareSources(libraryElement);
+ prepareErrors();
+
+ // Print errors and performance numbers.
+ if (printMode == 1) {
+ _printErrorsAndPerf();
+ } else if (printMode == 2) {
+ _printColdPerf();
+ }
+
+ // Compute max severity and set exitCode.
+ ErrorSeverity status = maxErrorSeverity;
+ if (status == ErrorSeverity.WARNING && options.warningsAreFatal) {
+ status = ErrorSeverity.ERROR;
+ }
+ return status;
+ }
+
+ bool _isDesiredError(AnalysisError error) {
+ if (error.errorCode.type == ErrorType.TODO) {
+ return false;
+ }
+ if (computeSeverity(error, options) == ErrorSeverity.INFO &&
+ options.disableHints) {
+ return false;
+ }
+ return true;
+ }
+
+ /// Determine whether the given URI refers to a package other than the package
+ /// being analyzed.
+ bool _isOtherPackage(Uri uri) {
+ if (uri.scheme != 'package') {
+ return false;
+ }
+ if (_selfPackageName != null &&
+ uri.pathSegments.length > 0 &&
+ uri.pathSegments[0] == _selfPackageName) {
+ return false;
+ }
+ return true;
+ }
+
+ _printColdPerf() {
+ // Print cold VM performance numbers.
+ int totalTime = currentTimeMillis() - startTime;
+ int otherTime = totalTime;
+ for (PerformanceTag tag in PerformanceTag.all) {
+ if (tag != PerformanceTag.UNKNOWN) {
+ int tagTime = tag.elapsedMs;
+ outSink.writeln('${tag.label}-cold:$tagTime');
+ otherTime -= tagTime;
+ }
+ }
+ outSink.writeln('other-cold:$otherTime');
+ outSink.writeln("total-cold:$totalTime");
+ }
+
+ _printErrorsAndPerf() {
+ // The following is a hack. We currently print out to stderr to ensure that
+ // when in batch mode we print to stderr, this is because the prints from
+ // batch are made to stderr. The reason that options.shouldBatch isn't used
+ // is because when the argument flags are constructed in BatchRunner and
+ // passed in from batch mode which removes the batch flag to prevent the
+ // "cannot have the batch flag and source file" error message.
+ StringSink sink = options.machineFormat ? errorSink : outSink;
+
+ // Print errors.
+ ErrorFormatter formatter =
+ new ErrorFormatter(sink, options, _isDesiredError);
+ formatter.formatErrors(errorInfos);
+ }
+
+ /// Compute the severity of the error; however:
+ /// * if [options.enableTypeChecks] is false, then de-escalate checked-mode
+ /// compile time errors to a severity of [ErrorSeverity.INFO].
+ /// * if [options.hintsAreFatal] is true, escalate hints to errors.
+ static ErrorSeverity computeSeverity(
+ AnalysisError error, CommandLineOptions options) {
+ if (!options.enableTypeChecks &&
+ error.errorCode.type == ErrorType.CHECKED_MODE_COMPILE_TIME_ERROR) {
+ return ErrorSeverity.INFO;
+ }
+ if (options.hintsAreFatal && error.errorCode is HintCode) {
+ return ErrorSeverity.ERROR;
+ }
+ return error.errorCode.errorSeverity;
+ }
+
+ /// Return the corresponding package directory or `null` if none is found.
+ static JavaFile getPackageDirectoryFor(JavaFile sourceFile) {
+ // We are going to ask parent file, so get absolute path.
+ sourceFile = sourceFile.getAbsoluteFile();
+ // Look in the containing directories.
+ JavaFile dir = sourceFile.getParentFile();
+ while (dir != null) {
+ JavaFile packagesDir = new JavaFile.relative(dir, "packages");
+ if (packagesDir.exists()) {
+ return packagesDir;
+ }
+ dir = dir.getParentFile();
+ }
+ // Not found.
+ return null;
+ }
+}
+
+/// This [Logger] prints out information comments to [outSink] and error messages
+/// to [errorSink].
+class StdLogger extends Logger {
+ StdLogger();
+
+ @override
+ void logError(String message, [CaughtException exception]) {
+ errorSink.writeln(message);
+ if (exception != null) {
+ errorSink.writeln(exception);
+ }
+ }
+
+ @override
+ void logError2(String message, Object exception) {
+ errorSink.writeln(message);
+ if (exception != null) {
+ errorSink.writeln(exception.toString());
+ }
+ }
+
+ @override
+ void logInformation(String message, [CaughtException exception]) {
+ outSink.writeln(message);
+ if (exception != null) {
+ outSink.writeln(exception);
+ }
+ }
+
+ @override
+ void logInformation2(String message, Object exception) {
+ outSink.writeln(message);
+ if (exception != null) {
+ outSink.writeln(exception.toString());
+ }
+ }
+}
« no previous file with comments | « pkg/analyzer_cli/bin/analyzer.dart ('k') | pkg/analyzer_cli/lib/src/bootloader.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698