| OLD | NEW |
| 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
| 3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 | 4 |
| 5 library analyzer_impl; | 5 library analyzer_impl; |
| 6 | 6 |
| 7 import 'dart:async'; |
| 8 |
| 7 import 'dart:io'; | 9 import 'dart:io'; |
| 8 | 10 |
| 9 import 'package:path/path.dart' as pathos; | 11 import 'package:path/path.dart' as pathos; |
| 10 | 12 |
| 11 import 'generated/java_io.dart'; | 13 import 'generated/java_io.dart'; |
| 12 import 'generated/engine.dart'; | 14 import 'generated/engine.dart'; |
| 13 import 'generated/error.dart'; | 15 import 'generated/error.dart'; |
| 14 import 'generated/source_io.dart'; | 16 import 'generated/source_io.dart'; |
| 15 import 'generated/sdk.dart'; | 17 import 'generated/sdk.dart'; |
| 16 import 'generated/sdk_io.dart'; | 18 import 'generated/sdk_io.dart'; |
| 17 import 'generated/ast.dart'; | |
| 18 import 'generated/element.dart'; | 19 import 'generated/element.dart'; |
| 19 import '../options.dart'; | 20 import '../options.dart'; |
| 20 | 21 |
| 22 import 'package:analyzer/src/generated/java_core.dart' show JavaSystem; |
| 23 import 'package:analyzer/src/error_formatter.dart'; |
| 24 |
| 21 /** | 25 /** |
| 22 * The maximum number of sources for which AST structures should be kept in the
cache. | 26 * The maximum number of sources for which AST structures should be kept in the
cache. |
| 23 */ | 27 */ |
| 24 const int _MAX_CACHE_SIZE = 512; | 28 const int _MAX_CACHE_SIZE = 512; |
| 25 | 29 |
| 26 DartSdk sdk; | 30 DartSdk sdk; |
| 27 | 31 |
| 28 /// Analyzes single library [File]. | 32 /// Analyzes single library [File]. |
| 29 class AnalyzerImpl { | 33 class AnalyzerImpl { |
| 34 final String sourcePath; |
| 30 final CommandLineOptions options; | 35 final CommandLineOptions options; |
| 36 final int startTime; |
| 31 | 37 |
| 32 ContentCache contentCache = new ContentCache(); | 38 ContentCache contentCache = new ContentCache(); |
| 33 SourceFactory sourceFactory; | 39 SourceFactory sourceFactory; |
| 34 AnalysisContext context; | 40 AnalysisContext context; |
| 35 | 41 |
| 36 /// All [Source]s references by the analyzed library. | 42 /// All [Source]s references by the analyzed library. |
| 37 final Set<Source> sources = new Set<Source>(); | 43 final Set<Source> sources = new Set<Source>(); |
| 38 | 44 |
| 39 /// All [AnalysisErrorInfo]s in the analyzed library. | 45 /// All [AnalysisErrorInfo]s in the analyzed library. |
| 40 final List<AnalysisErrorInfo> errorInfos = new List<AnalysisErrorInfo>(); | 46 final List<AnalysisErrorInfo> errorInfos = new List<AnalysisErrorInfo>(); |
| 41 | 47 |
| 42 AnalyzerImpl(CommandLineOptions this.options) { | 48 AnalyzerImpl(this.sourcePath, this.options, this.startTime) { |
| 43 if (sdk == null) { | 49 if (sdk == null) { |
| 44 sdk = new DirectoryBasedDartSdk(new JavaFile(options.dartSdkPath)); | 50 sdk = new DirectoryBasedDartSdk(new JavaFile(options.dartSdkPath)); |
| 45 } | 51 } |
| 46 } | 52 } |
| 47 | 53 |
| 48 /** | 54 /** |
| 49 * Treats the [sourcePath] as the top level library and analyzes it. | 55 * Treats the [sourcePath] as the top level library and analyzes it. |
| 50 */ | 56 */ |
| 51 void analyze(String sourcePath) { | 57 void analyze() { |
| 52 sources.clear(); | 58 sources.clear(); |
| 53 errorInfos.clear(); | 59 errorInfos.clear(); |
| 54 if (sourcePath == null) { | 60 if (sourcePath == null) { |
| 55 throw new ArgumentError("sourcePath cannot be null"); | 61 throw new ArgumentError("sourcePath cannot be null"); |
| 56 } | 62 } |
| 57 var sourceFile = new JavaFile(sourcePath); | 63 JavaFile sourceFile = new JavaFile(sourcePath); |
| 58 var uriKind = getUriKind(sourceFile); | 64 UriKind uriKind = getUriKind(sourceFile); |
| 59 var librarySource = new FileBasedSource.con2(sourceFile, uriKind); | 65 Source librarySource = new FileBasedSource.con2(sourceFile, uriKind); |
| 66 |
| 60 // prepare context | 67 // prepare context |
| 61 prepareAnalysisContext(sourceFile); | 68 prepareAnalysisContext(sourceFile, librarySource); |
| 62 // don't try to analyzer parts | 69 |
| 63 var unit = context.parseCompilationUnit(librarySource); | 70 // async perform all tasks in context |
| 64 var hasLibraryDirective = false; | 71 _analyze(); |
| 65 var hasPartOfDirective = false; | 72 } |
| 66 for (var directive in unit.directives) { | 73 |
| 67 if (directive is LibraryDirective) hasLibraryDirective = true; | 74 void _analyze() { |
| 68 if (directive is PartOfDirective) hasPartOfDirective = true; | 75 new Future(context.performAnalysisTask).then((AnalysisResult result) { |
| 69 } | 76 List<ChangeNotice> notices = result.changeNotices; |
| 70 if (hasPartOfDirective && !hasLibraryDirective) { | 77 // TODO(jwren) change 'notices != null' to 'result.hasMoreWork()' after |
| 71 print("Only libraries can be analyzed."); | 78 // next dart translation is landed for the analyzer |
| 72 print("$sourceFile is a part and can not be analyzed."); | 79 if (notices != null) { |
| 73 return; | 80 // There is more work, record the set of sources, and then call self |
| 74 } | 81 // again to perform next task |
| 75 // resolve library | 82 for (ChangeNotice notice in notices) { |
| 76 var libraryElement = context.computeLibraryElement(librarySource); | 83 sources.add(notice.source); |
| 77 // prepare source and errors | 84 } |
| 78 prepareSources(libraryElement); | 85 return _analyze(); |
| 79 prepareErrors(); | 86 } |
| 87 // |
| 88 // There are not any more tasks, set error code and print performance |
| 89 // numbers. |
| 90 // |
| 91 // prepare errors |
| 92 prepareErrors(); |
| 93 |
| 94 // compute max severity and set exitCode |
| 95 ErrorSeverity status = maxErrorSeverity; |
| 96 if (status == ErrorSeverity.WARNING && options.warningsAreFatal) { |
| 97 status = ErrorSeverity.ERROR; |
| 98 } |
| 99 exitCode = status.ordinal; |
| 100 |
| 101 // print errors |
| 102 ErrorFormatter formatter = new ErrorFormatter(stdout, options); |
| 103 formatter.formatErrors(errorInfos); |
| 104 |
| 105 // print performance numbers |
| 106 if (options.perf) { |
| 107 int totalTime = JavaSystem.currentTimeMillis() - startTime; |
| 108 int ioTime = PerformanceStatistics.io.result; |
| 109 int scanTime = PerformanceStatistics.scan.result; |
| 110 int parseTime = PerformanceStatistics.parse.result; |
| 111 int resolveTime = PerformanceStatistics.resolve.result; |
| 112 int errorsTime = PerformanceStatistics.errors.result; |
| 113 int hintsTime = PerformanceStatistics.hints.result; |
| 114 int angularTime = PerformanceStatistics.angular.result; |
| 115 stdout.writeln("io:$ioTime"); |
| 116 stdout.writeln("scan:$scanTime"); |
| 117 stdout.writeln("parse:$parseTime"); |
| 118 stdout.writeln("resolve:$resolveTime"); |
| 119 stdout.writeln("errors:$errorsTime"); |
| 120 stdout.writeln("hints:$hintsTime"); |
| 121 stdout.writeln("angular:$angularTime"); |
| 122 stdout.writeln("other:${totalTime |
| 123 - (ioTime + scanTime + parseTime + resolveTime + errorsTime + hints
Time |
| 124 + angularTime)}"); |
| 125 stdout.writeln("total:$totalTime"); |
| 126 } |
| 127 }).catchError((exception, stackTrace) { |
| 128 AnalysisEngine.instance.logger.logError(exception); |
| 129 }); |
| 80 } | 130 } |
| 81 | 131 |
| 82 /// Returns the maximal [ErrorSeverity] of the recorded errors. | 132 /// Returns the maximal [ErrorSeverity] of the recorded errors. |
| 83 ErrorSeverity get maxErrorSeverity { | 133 ErrorSeverity get maxErrorSeverity { |
| 84 var status = ErrorSeverity.NONE; | 134 var status = ErrorSeverity.NONE; |
| 85 for (AnalysisErrorInfo errorInfo in errorInfos) { | 135 for (AnalysisErrorInfo errorInfo in errorInfos) { |
| 86 for (AnalysisError error in errorInfo.errors) { | 136 for (AnalysisError error in errorInfo.errors) { |
| 87 var severity = error.errorCode.errorSeverity; | 137 var severity = error.errorCode.errorSeverity; |
| 88 status = status.max(severity); | 138 status = status.max(severity); |
| 89 } | 139 } |
| 90 } | 140 } |
| 91 return status; | 141 return status; |
| 92 } | 142 } |
| 93 | 143 |
| 94 void prepareAnalysisContext(JavaFile sourceFile) { | 144 void prepareAnalysisContext(JavaFile sourceFile, Source source) { |
| 95 List<UriResolver> resolvers = [new DartUriResolver(sdk), new FileUriResolver
()]; | 145 List<UriResolver> resolvers = [new DartUriResolver(sdk), new FileUriResolver
()]; |
| 96 // may be add package resolver | 146 // may be add package resolver |
| 97 { | 147 { |
| 98 JavaFile packageDirectory; | 148 JavaFile packageDirectory; |
| 99 if (options.packageRootPath != null) { | 149 if (options.packageRootPath != null) { |
| 100 packageDirectory = new JavaFile(options.packageRootPath); | 150 packageDirectory = new JavaFile(options.packageRootPath); |
| 101 } else { | 151 } else { |
| 102 packageDirectory = getPackageDirectoryFor(sourceFile); | 152 packageDirectory = getPackageDirectoryFor(sourceFile); |
| 103 } | 153 } |
| 104 if (packageDirectory != null) { | 154 if (packageDirectory != null) { |
| 105 resolvers.add(new PackageUriResolver([packageDirectory])); | 155 resolvers.add(new PackageUriResolver([packageDirectory])); |
| 106 } | 156 } |
| 107 } | 157 } |
| 108 sourceFactory = new SourceFactory(resolvers); | 158 sourceFactory = new SourceFactory(resolvers); |
| 109 context = AnalysisEngine.instance.createAnalysisContext(); | 159 context = AnalysisEngine.instance.createAnalysisContext(); |
| 110 context.sourceFactory = sourceFactory; | 160 context.sourceFactory = sourceFactory; |
| 111 | 161 |
| 112 // set options for context | 162 // set options for context |
| 113 AnalysisOptionsImpl contextOptions = new AnalysisOptionsImpl(); | 163 AnalysisOptionsImpl contextOptions = new AnalysisOptionsImpl(); |
| 114 contextOptions.cacheSize = _MAX_CACHE_SIZE; | 164 contextOptions.cacheSize = _MAX_CACHE_SIZE; |
| 115 contextOptions.hint = !options.disableHints; | 165 contextOptions.hint = !options.disableHints; |
| 116 context.analysisOptions = contextOptions; | 166 context.analysisOptions = contextOptions; |
| 117 } | |
| 118 | 167 |
| 119 /// Fills [sources]. | 168 // Create and add a ChangeSet |
| 120 void prepareSources(LibraryElement library) { | 169 ChangeSet changeSet = new ChangeSet(); |
| 121 var units = new Set<CompilationUnitElement>(); | 170 changeSet.addedSource(source); |
| 122 var libraries = new Set<LibraryElement>(); | 171 context.applyChanges(changeSet); |
| 123 addLibrarySources(library, libraries, units); | |
| 124 } | 172 } |
| 125 | 173 |
| 126 void addCompilationUnitSource(CompilationUnitElement unit, Set<LibraryElement>
libraries, | 174 void addCompilationUnitSource(CompilationUnitElement unit, Set<LibraryElement>
libraries, |
| 127 Set<CompilationUnitElement> units) { | 175 Set<CompilationUnitElement> units) { |
| 128 if (unit == null || units.contains(unit)) { | 176 if (unit == null || units.contains(unit)) { |
| 129 return; | 177 return; |
| 130 } | 178 } |
| 131 units.add(unit); | 179 units.add(unit); |
| 132 sources.add(unit.source); | 180 sources.add(unit.source); |
| 133 } | 181 } |
| (...skipping 22 matching lines...) Expand all Loading... |
| 156 } | 204 } |
| 157 // add referenced libraries | 205 // add referenced libraries |
| 158 for (LibraryElement child in library.importedLibraries) { | 206 for (LibraryElement child in library.importedLibraries) { |
| 159 addLibrarySources(child, libraries, units); | 207 addLibrarySources(child, libraries, units); |
| 160 } | 208 } |
| 161 for (LibraryElement child in library.exportedLibraries) { | 209 for (LibraryElement child in library.exportedLibraries) { |
| 162 addLibrarySources(child, libraries, units); | 210 addLibrarySources(child, libraries, units); |
| 163 } | 211 } |
| 164 } | 212 } |
| 165 | 213 |
| 166 /// Fills [errorInfos]. | 214 /// Fills [errorInfos] using [sources]. |
| 167 void prepareErrors() { | 215 void prepareErrors() { |
| 168 for (Source source in sources) { | 216 for (Source source in sources) { |
| 169 context.computeErrors(source); | 217 context.computeErrors(source); |
| 170 var sourceErrors = context.getErrors(source); | 218 var sourceErrors = context.getErrors(source); |
| 171 errorInfos.add(sourceErrors); | 219 errorInfos.add(sourceErrors); |
| 172 } | 220 } |
| 173 } | 221 } |
| 174 | 222 |
| 175 static JavaFile getPackageDirectoryFor(JavaFile sourceFile) { | 223 static JavaFile getPackageDirectoryFor(JavaFile sourceFile) { |
| 176 // we are going to ask parent file, so get absolute path | 224 // we are going to ask parent file, so get absolute path |
| (...skipping 27 matching lines...) Expand all Loading... |
| 204 var internalPath = pathos.join(libraryDirectory, '_internal') + pathos.s
eparator; | 252 var internalPath = pathos.join(libraryDirectory, '_internal') + pathos.s
eparator; |
| 205 if (!filePath.startsWith(internalPath)) { | 253 if (!filePath.startsWith(internalPath)) { |
| 206 return UriKind.DART_URI; | 254 return UriKind.DART_URI; |
| 207 } | 255 } |
| 208 } | 256 } |
| 209 } | 257 } |
| 210 // some generic file | 258 // some generic file |
| 211 return UriKind.FILE_URI; | 259 return UriKind.FILE_URI; |
| 212 } | 260 } |
| 213 } | 261 } |
| OLD | NEW |