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

Unified Diff: observatory_pub_packages/analyzer/src/analyzer_impl.dart

Issue 816693004: Add observatory_pub_packages snapshot to third_party (Closed) Base URL: http://dart.googlecode.com/svn/third_party/
Patch Set: Created 6 years 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
Index: observatory_pub_packages/analyzer/src/analyzer_impl.dart
===================================================================
--- observatory_pub_packages/analyzer/src/analyzer_impl.dart (revision 0)
+++ observatory_pub_packages/analyzer/src/analyzer_impl.dart (working copy)
@@ -0,0 +1,400 @@
+// Copyright (c) 2013, 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_impl;
+
+import 'dart:async';
+
+import 'dart:io';
+
+import 'generated/constant.dart';
+import 'generated/engine.dart';
+import 'generated/element.dart';
+import 'generated/error.dart';
+import 'generated/java_io.dart';
+import 'generated/sdk.dart';
+import 'generated/sdk_io.dart';
+import 'generated/source_io.dart';
+import '../options.dart';
+
+import 'dart:collection';
+
+import 'package:analyzer/src/generated/java_core.dart' show JavaSystem;
+import 'package:analyzer/src/error_formatter.dart';
+
+/**
+ * The maximum number of sources for which AST structures should be kept in the cache.
+ */
+const int _MAX_CACHE_SIZE = 512;
+
+DartSdk sdk;
+
+/// Analyzes single library [File].
+class AnalyzerImpl {
+ final String sourcePath;
+ final CommandLineOptions options;
+ final int startTime;
+
+ ContentCache contentCache = new ContentCache();
+ SourceFactory sourceFactory;
+ AnalysisContext context;
+ 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>();
+
+ AnalyzerImpl(this.sourcePath, this.options, this.startTime) {
+ if (sdk == null) {
+ sdk = new DirectoryBasedDartSdk(new JavaFile(options.dartSdkPath));
+ }
+ }
+
+ /**
+ * 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);
+ }
+
+ /**
+ * Treats the [sourcePath] as the top level library and analyzes it using a
+ * asynchronous algorithm over the analysis engine.
+ */
+ void analyzeAsync() {
+ setupForAnalysis();
+ _analyzeAsync();
+ }
+
+ /**
+ * Setup local fields such as the analysis context for analysis.
+ */
+ void setupForAnalysis() {
+ sources.clear();
+ errorInfos.clear();
+ if (sourcePath == null) {
+ throw new ArgumentError("sourcePath cannot be null");
+ }
+ JavaFile sourceFile = new JavaFile(sourcePath);
+ Uri uri = getUri(sourceFile);
+ librarySource = new FileBasedSource.con2(uri, sourceFile);
+
+ // prepare context
+ prepareAnalysisContext(sourceFile, librarySource);
+ }
+
+ /// The sync version of analysis.
+ ErrorSeverity _analyzeSync(int printMode) {
+ // don't try to analyze parts
+ if (context.computeKindOf(librarySource) == SourceKind.PART) {
+ print("Only libraries can be analyzed.");
+ print("$sourcePath 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;
+ }
+
+ /// The async version of the analysis
+ void _analyzeAsync() {
+ new Future(context.performAnalysisTask).then((AnalysisResult result) {
+ List<ChangeNotice> notices = result.changeNotices;
+ if (result.hasMoreWork) {
+ // There is more work, record the set of sources, and then call self
+ // again to perform next task
+ for (ChangeNotice notice in notices) {
+ sources.add(notice.source);
+ sourceErrorsMap[notice.source] = notice;
+ }
+ return _analyzeAsync();
+ }
+ //
+ // There are not any more tasks, set error code and print performance
+ // numbers.
+ //
+ // prepare errors
+ sourceErrorsMap.forEach((k,v) {
+ errorInfos.add(sourceErrorsMap[k]);
+ });
+
+ // print errors and performance numbers
+ _printErrorsAndPerf();
+
+ // compute max severity and set exitCode
+ ErrorSeverity status = maxErrorSeverity;
+ if (status == ErrorSeverity.WARNING && options.warningsAreFatal) {
+ status = ErrorSeverity.ERROR;
+ }
+ exitCode = status.ordinal;
+ }).catchError((ex, st) {
+ AnalysisEngine.instance.logger.logError("${ex}\n${st}");
+ });
+ }
+
+ bool _excludeTodo(AnalysisError error) => error.errorCode.type != ErrorType.TODO;
+
+ _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.
+ IOSink sink = options.machineFormat ? stderr : stdout;
+
+ // print errors
+ ErrorFormatter formatter = new ErrorFormatter(sink, options, _excludeTodo);
+ formatter.formatErrors(errorInfos);
+
+ // print performance numbers
+ if (options.perf || options.warmPerf) {
+ int totalTime = JavaSystem.currentTimeMillis() - startTime;
+ int ioTime = PerformanceStatistics.io.result;
+ int scanTime = PerformanceStatistics.scan.result;
+ int parseTime = PerformanceStatistics.parse.result;
+ int resolveTime = PerformanceStatistics.resolve.result;
+ int errorsTime = PerformanceStatistics.errors.result;
+ int hintsTime = PerformanceStatistics.hints.result;
+ int angularTime = PerformanceStatistics.angular.result;
+ stdout.writeln("io:$ioTime");
+ stdout.writeln("scan:$scanTime");
+ stdout.writeln("parse:$parseTime");
+ stdout.writeln("resolve:$resolveTime");
+ stdout.writeln("errors:$errorsTime");
+ stdout.writeln("hints:$hintsTime");
+ stdout.writeln("angular:$angularTime");
+ stdout.writeln("other:${totalTime
+ - (ioTime + scanTime + parseTime + resolveTime + errorsTime + hintsTime
+ + angularTime)}");
+ stdout.writeln("total:$totalTime");
+ }
+ }
+
+ _printColdPerf() {
+ // print cold VM performance numbers
+ int totalTime = JavaSystem.currentTimeMillis() - startTime;
+ int ioTime = PerformanceStatistics.io.result;
+ int scanTime = PerformanceStatistics.scan.result;
+ int parseTime = PerformanceStatistics.parse.result;
+ int resolveTime = PerformanceStatistics.resolve.result;
+ int errorsTime = PerformanceStatistics.errors.result;
+ int hintsTime = PerformanceStatistics.hints.result;
+ int angularTime = PerformanceStatistics.angular.result;
+ stdout.writeln("io-cold:$ioTime");
+ stdout.writeln("scan-cold:$scanTime");
+ stdout.writeln("parse-cold:$parseTime");
+ stdout.writeln("resolve-cold:$resolveTime");
+ stdout.writeln("errors-cold:$errorsTime");
+ stdout.writeln("hints-cold:$hintsTime");
+ stdout.writeln("angular-cold:$angularTime");
+ stdout.writeln("other-cold:${totalTime
+ - (ioTime + scanTime + parseTime + resolveTime + errorsTime + hintsTime
+ + angularTime)}");
+ stdout.writeln("total-cold:$totalTime");
+ }
+
+ /// 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) {
+ var severity = error.errorCode.errorSeverity;
+ status = status.max(severity);
+ }
+ }
+ return status;
+ }
+
+ void prepareAnalysisContext(JavaFile sourceFile, Source source) {
+ List<UriResolver> resolvers = [new DartUriResolver(sdk), new FileUriResolver()];
+ // may be add package resolver
+ {
+ JavaFile packageDirectory;
+ if (options.packageRootPath != null) {
+ packageDirectory = new JavaFile(options.packageRootPath);
+ } else {
+ packageDirectory = getPackageDirectoryFor(sourceFile);
+ }
+ if (packageDirectory != null) {
+ resolvers.add(new PackageUriResolver([packageDirectory]));
+ }
+ }
+ sourceFactory = new SourceFactory(resolvers);
+ context = AnalysisEngine.instance.createAnalysisContext();
+ context.sourceFactory = sourceFactory;
+ Map<String, String> definedVariables = options.definedVariables;
+ if (!definedVariables.isEmpty) {
+ DeclaredVariables declaredVariables = context.declaredVariables;
+ definedVariables.forEach((String variableName, String value) {
+ declaredVariables.define(variableName, value);
+ });
+ }
+ // Uncomment the following to have errors reported on stdout and stderr
+ AnalysisEngine.instance.logger = new StdLogger(options.log);
+
+ // set options for context
+ AnalysisOptionsImpl contextOptions = new AnalysisOptionsImpl();
+ contextOptions.cacheSize = _MAX_CACHE_SIZE;
+ contextOptions.hint = !options.disableHints;
+ contextOptions.enableAsync = options.enableAsync;
+ contextOptions.enableEnum = options.enableEnum;
+ context.analysisOptions = contextOptions;
+
+ // Create and add a ChangeSet
+ ChangeSet changeSet = new ChangeSet();
+ changeSet.addedSource(source);
+ context.applyChanges(changeSet);
+ }
+
+ 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;
+ }
+ // may be skip library
+ {
+ UriKind uriKind = library.source.uriKind;
+ // Optionally skip package: libraries.
+ if (!options.showPackageWarnings && uriKind == UriKind.PACKAGE_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);
+ }
+ }
+
+ /// Fills [sources].
+ void prepareSources(LibraryElement library) {
+ var units = new Set<CompilationUnitElement>();
+ var libraries = new Set<LibraryElement>();
+ addLibrarySources(library, libraries, units);
+ }
+
+ /// Fills [errorInfos] using [sources].
+ void prepareErrors() {
+ for (Source source in sources) {
+ context.computeErrors(source);
+ var sourceErrors = context.getErrors(source);
+ errorInfos.add(sourceErrors);
+ }
+ }
+
+ 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;
+ }
+
+ /**
+ * Returns the [Uri] for the given input file.
+ *
+ * Usually it is a `file:` [Uri], but if [file] is located in the `lib`
+ * directory of the [sdk], then returns a `dart:` [Uri].
+ */
+ static Uri getUri(JavaFile file) {
+ // may be file in SDK
+ {
+ Source source = sdk.fromFileUri(file.toURI());
+ if (source != null) {
+ return source.uri;
+ }
+ }
+ // some generic file
+ return file.toURI();
+ }
+}
+
+/**
+ * This [Logger] prints out information comments to [stdout] and error messages
+ * to [stderr].
+ */
+class StdLogger extends Logger {
+ final bool log;
+
+ StdLogger(this.log);
+
+ @override
+ void logError(String message) {
+ stderr.writeln(message);
+ }
+
+ @override
+ void logError2(String message, Exception exception) {
+ stderr.writeln(message);
+ }
+
+ @override
+ void logInformation(String message) {
+ if (log) {
+ stdout.writeln(message);
+ }
+ }
+
+ @override
+ void logInformation2(String message, Exception exception) {
+ if (log) {
+ stdout.writeln(message);
+ }
+ }
+}
« no previous file with comments | « observatory_pub_packages/analyzer/source/package_map_resolver.dart ('k') | observatory_pub_packages/analyzer/src/error.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698