Chromium Code Reviews| 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 |
| 11 import 'package:analyzer/src/error_formatter.dart'; | |
| 12 import 'package:analyzer/src/generated/java_core.dart' show JavaSystem; | |
| 9 import 'package:path/path.dart' as pathos; | 13 import 'package:path/path.dart' as pathos; |
| 10 | 14 |
| 11 import 'generated/java_io.dart'; | 15 import 'generated/java_io.dart'; |
| 12 import 'generated/engine.dart'; | 16 import 'generated/engine.dart'; |
| 13 import 'generated/error.dart'; | 17 import 'generated/error.dart'; |
| 14 import 'generated/source_io.dart'; | 18 import 'generated/source_io.dart'; |
| 15 import 'generated/sdk.dart'; | 19 import 'generated/sdk.dart'; |
| 16 import 'generated/sdk_io.dart'; | 20 import 'generated/sdk_io.dart'; |
| 17 import 'generated/ast.dart'; | |
| 18 import 'generated/element.dart'; | 21 import 'generated/element.dart'; |
| 19 import '../options.dart'; | 22 import '../options.dart'; |
| 20 | 23 |
| 21 | |
| 22 DartSdk sdk; | 24 DartSdk sdk; |
| 23 | 25 |
| 24 /// Analyzes single library [File]. | 26 /// Analyzes single library [File]. |
| 25 class AnalyzerImpl { | 27 class AnalyzerImpl { |
| 28 final String sourcePath; | |
| 26 final CommandLineOptions options; | 29 final CommandLineOptions options; |
| 30 int startTime; | |
| 27 | 31 |
| 28 ContentCache contentCache = new ContentCache(); | 32 ContentCache contentCache = new ContentCache(); |
| 29 SourceFactory sourceFactory; | 33 SourceFactory sourceFactory; |
| 30 AnalysisContext context; | 34 AnalysisContext context; |
| 31 | 35 |
| 32 /// All [Source]s references by the analyzed library. | 36 /// All [Source]s references by the analyzed library. |
| 33 final Set<Source> sources = new Set<Source>(); | 37 final Set<Source> sources = new Set<Source>(); |
| 34 | 38 |
| 35 /// All [AnalysisErrorInfo]s in the analyzed library. | 39 /// All [AnalysisErrorInfo]s in the analyzed library. |
| 36 final List<AnalysisErrorInfo> errorInfos = new List<AnalysisErrorInfo>(); | 40 final List<AnalysisErrorInfo> errorInfos = new List<AnalysisErrorInfo>(); |
| 37 | 41 |
| 38 AnalyzerImpl(CommandLineOptions this.options) { | 42 AnalyzerImpl(String this.sourcePath, CommandLineOptions this.options, int this .startTime) { |
|
Brian Wilkerson
2014/03/11 18:36:53
Don't include type annotations for field initializ
jwren
2014/03/11 21:53:04
Done.
| |
| 39 if (sdk == null) { | 43 if (sdk == null) { |
| 40 sdk = new DirectoryBasedDartSdk(new JavaFile(options.dartSdkPath)); | 44 sdk = new DirectoryBasedDartSdk(new JavaFile(options.dartSdkPath)); |
| 41 } | 45 } |
| 42 } | 46 } |
| 43 | 47 |
| 44 /** | 48 /** |
| 45 * Treats the [sourcePath] as the top level library and analyzes it. | 49 * Treats the [sourcePath] as the top level library and analyzes it. |
| 46 */ | 50 */ |
| 47 void analyze(String sourcePath) { | 51 void analyze() { |
| 48 sources.clear(); | 52 sources.clear(); |
| 49 errorInfos.clear(); | 53 errorInfos.clear(); |
| 50 if (sourcePath == null) { | 54 if (sourcePath == null) { |
| 51 throw new ArgumentError("sourcePath cannot be null"); | 55 throw new ArgumentError("sourcePath cannot be null"); |
| 52 } | 56 } |
| 53 var sourceFile = new JavaFile(sourcePath); | 57 JavaFile sourceFile = new JavaFile(sourcePath); |
| 54 var uriKind = getUriKind(sourceFile); | 58 UriKind uriKind = getUriKind(sourceFile); |
| 55 var librarySource = new FileBasedSource.con2(sourceFile, uriKind); | 59 Source librarySource = new FileBasedSource.con2(sourceFile, uriKind); |
| 60 | |
| 56 // prepare context | 61 // prepare context |
| 57 prepareAnalysisContext(sourceFile); | 62 prepareAnalysisContext(sourceFile, librarySource); |
| 58 // don't try to analyzer parts | 63 |
| 59 var unit = context.parseCompilationUnit(librarySource); | 64 // async perform all tasks in context |
| 60 var hasLibraryDirective = false; | 65 _analyze(); |
| 61 var hasPartOfDirective = false; | 66 } |
| 62 for (var directive in unit.directives) { | 67 |
| 63 if (directive is LibraryDirective) hasLibraryDirective = true; | 68 void _analyze() { |
|
Bob Nystrom
2014/03/11 18:24:46
Drive-by code review!
It's considered good style
jwren
2014/03/11 21:53:04
Bob- Thanks for the feedback. For now we are goin
| |
| 64 if (directive is PartOfDirective) hasPartOfDirective = true; | 69 new Future(context.performAnalysisTask).then((AnalysisResult result) { |
| 65 } | 70 List<ChangeNotice> notices = result.changeNotices; |
|
Bob Nystrom
2014/03/11 18:24:46
Style nit: this function body should be indented +
jwren
2014/03/11 21:53:04
Done.
| |
| 66 if (hasPartOfDirective && !hasLibraryDirective) { | 71 // TODO(jwren) change notices != null to result.isMoreWork after new |
| 67 print("Only libraries can be analyzed."); | 72 // dart translation is landed |
| 68 print("$sourceFile is a part and can not be analyzed."); | 73 if(notices != null) { |
|
Bob Nystrom
2014/03/11 18:24:46
Space after "if".
Brian Wilkerson
2014/03/11 18:36:53
You're not making use of the utility method you de
jwren
2014/03/11 21:53:04
Done.
Correct.
| |
| 69 return; | 74 // There is more work, record the set of sources, and then call self |
| 70 } | 75 // again to perform next task |
| 71 // resolve library | 76 for(ChangeNotice notice in notices) { |
|
Brian Wilkerson
2014/03/11 18:36:53
nit: space after "for"
jwren
2014/03/11 21:53:04
Done.
| |
| 72 var libraryElement = context.computeLibraryElement(librarySource); | 77 sources.add(notice.source); |
| 73 // prepare source and errors | 78 } |
| 74 prepareSources(libraryElement); | 79 return _analyze(); |
| 75 prepareErrors(); | 80 } else { |
|
Bob Nystrom
2014/03/11 18:24:46
Friendly suggestion: Since the if case always retu
jwren
2014/03/11 21:53:04
Done.
| |
| 81 // | |
| 82 // There are not any more tasks, set error code and print performance | |
| 83 // numbers. | |
| 84 // | |
| 85 // prepare errors | |
| 86 prepareErrors(); | |
| 87 | |
| 88 // compute max severity and set exitCode | |
| 89 ErrorSeverity status = maxErrorSeverity; | |
| 90 if (status == ErrorSeverity.WARNING && options.warningsAreFatal) { | |
| 91 status = ErrorSeverity.ERROR; | |
| 92 } | |
| 93 exitCode = status.ordinal; | |
| 94 | |
| 95 // print errors | |
| 96 ErrorFormatter formatter = new ErrorFormatter(stdout, options); | |
| 97 formatter.formatErrors(errorInfos); | |
| 98 | |
| 99 // print performance numbers | |
| 100 if (options.perf) { | |
| 101 int totalTime = JavaSystem.currentTimeMillis() - startTime; | |
| 102 int ioTime = PerformanceStatistics.io.result; | |
| 103 int scanTime = PerformanceStatistics.scan.result; | |
| 104 int parseTime = PerformanceStatistics.parse.result; | |
| 105 int resolveTime = PerformanceStatistics.resolve.result; | |
| 106 int errorsTime = PerformanceStatistics.errors.result; | |
| 107 int hintsTime = PerformanceStatistics.hints.result; | |
| 108 int angularTime = PerformanceStatistics.angular.result; | |
| 109 stdout.writeln("io:$ioTime"); | |
| 110 stdout.writeln("scan:$scanTime"); | |
| 111 stdout.writeln("parse:$parseTime"); | |
| 112 stdout.writeln("resolve:$resolveTime"); | |
| 113 stdout.writeln("errors:$errorsTime"); | |
| 114 stdout.writeln("hints:$hintsTime"); | |
| 115 stdout.writeln("angular:$angularTime"); | |
| 116 stdout.writeln("other:${totalTime | |
| 117 - (ioTime + scanTime + parseTime + resolveTime + errorsTime + h intsTime | |
| 118 + angularTime)}"); | |
| 119 stdout.writeln("total:$totalTime"); | |
| 120 } | |
| 121 } | |
| 122 }).catchError((exception, stackTrace) { | |
| 123 AnalysisEngine.instance.logger.logError(exception); | |
|
Bob Nystrom
2014/03/11 18:24:46
This only needs to be indented +2.
jwren
2014/03/11 21:53:04
Done.
| |
| 124 }); | |
| 76 } | 125 } |
| 77 | 126 |
| 78 /// Returns the maximal [ErrorSeverity] of the recorded errors. | 127 /// Returns the maximal [ErrorSeverity] of the recorded errors. |
| 79 ErrorSeverity get maxErrorSeverity { | 128 ErrorSeverity get maxErrorSeverity { |
| 80 var status = ErrorSeverity.NONE; | 129 var status = ErrorSeverity.NONE; |
| 81 for (AnalysisErrorInfo errorInfo in errorInfos) { | 130 for (AnalysisErrorInfo errorInfo in errorInfos) { |
| 82 for (AnalysisError error in errorInfo.errors) { | 131 for (AnalysisError error in errorInfo.errors) { |
| 83 var severity = error.errorCode.errorSeverity; | 132 var severity = error.errorCode.errorSeverity; |
| 84 status = status.max(severity); | 133 status = status.max(severity); |
| 85 } | 134 } |
| 86 } | 135 } |
| 87 return status; | 136 return status; |
| 88 } | 137 } |
| 89 | 138 |
| 90 void prepareAnalysisContext(JavaFile sourceFile) { | 139 void prepareAnalysisContext(JavaFile sourceFile, Source source) { |
| 91 List<UriResolver> resolvers = [new DartUriResolver(sdk), new FileUriResolver ()]; | 140 List<UriResolver> resolvers = [new DartUriResolver(sdk), new FileUriResolver ()]; |
| 92 // may be add package resolver | 141 // may be add package resolver |
| 93 { | 142 { |
| 94 JavaFile packageDirectory; | 143 JavaFile packageDirectory; |
| 95 if (options.packageRootPath != null) { | 144 if (options.packageRootPath != null) { |
| 96 packageDirectory = new JavaFile(options.packageRootPath); | 145 packageDirectory = new JavaFile(options.packageRootPath); |
| 97 } else { | 146 } else { |
| 98 packageDirectory = getPackageDirectoryFor(sourceFile); | 147 packageDirectory = getPackageDirectoryFor(sourceFile); |
| 99 } | 148 } |
| 100 if (packageDirectory != null) { | 149 if (packageDirectory != null) { |
| 101 resolvers.add(new PackageUriResolver([packageDirectory])); | 150 resolvers.add(new PackageUriResolver([packageDirectory])); |
| 102 } | 151 } |
| 103 } | 152 } |
| 104 sourceFactory = new SourceFactory(resolvers); | 153 sourceFactory = new SourceFactory(resolvers); |
| 105 context = AnalysisEngine.instance.createAnalysisContext(); | 154 context = AnalysisEngine.instance.createAnalysisContext(); |
| 106 context.sourceFactory = sourceFactory; | 155 context.sourceFactory = sourceFactory; |
| 107 | 156 |
| 108 // set options for context | 157 // set options for context |
| 109 AnalysisOptionsImpl contextOptions = new AnalysisOptionsImpl(); | 158 AnalysisOptionsImpl contextOptions = new AnalysisOptionsImpl(); |
| 110 contextOptions.cacheSize = 256; | 159 contextOptions.cacheSize = 256; |
| 111 contextOptions.hint = !options.disableHints; | 160 contextOptions.hint = !options.disableHints; |
| 112 context.analysisOptions = contextOptions; | 161 context.analysisOptions = contextOptions; |
| 113 } | |
| 114 | 162 |
| 115 /// Fills [sources]. | 163 // Create and add a ChangeSet |
| 116 void prepareSources(LibraryElement library) { | 164 ChangeSet changeSet = new ChangeSet(); |
| 117 var units = new Set<CompilationUnitElement>(); | 165 changeSet.addedSource(source); |
| 118 var libraries = new Set<LibraryElement>(); | 166 context.applyChanges(changeSet); |
| 119 addLibrarySources(library, libraries, units); | |
| 120 } | 167 } |
| 121 | 168 |
| 122 void addCompilationUnitSource(CompilationUnitElement unit, Set<LibraryElement> libraries, | 169 void addCompilationUnitSource(CompilationUnitElement unit, Set<LibraryElement> libraries, |
| 123 Set<CompilationUnitElement> units) { | 170 Set<CompilationUnitElement> units) { |
| 124 if (unit == null || units.contains(unit)) { | 171 if (unit == null || units.contains(unit)) { |
| 125 return; | 172 return; |
| 126 } | 173 } |
| 127 units.add(unit); | 174 units.add(unit); |
| 128 sources.add(unit.source); | 175 sources.add(unit.source); |
| 129 } | 176 } |
| (...skipping 22 matching lines...) Expand all Loading... | |
| 152 } | 199 } |
| 153 // add referenced libraries | 200 // add referenced libraries |
| 154 for (LibraryElement child in library.importedLibraries) { | 201 for (LibraryElement child in library.importedLibraries) { |
| 155 addLibrarySources(child, libraries, units); | 202 addLibrarySources(child, libraries, units); |
| 156 } | 203 } |
| 157 for (LibraryElement child in library.exportedLibraries) { | 204 for (LibraryElement child in library.exportedLibraries) { |
| 158 addLibrarySources(child, libraries, units); | 205 addLibrarySources(child, libraries, units); |
| 159 } | 206 } |
| 160 } | 207 } |
| 161 | 208 |
| 162 /// Fills [errorInfos]. | 209 /// Fills [errorInfos] using [sources]. |
| 163 void prepareErrors() { | 210 void prepareErrors() { |
| 164 for (Source source in sources) { | 211 for (Source source in sources) { |
| 165 context.computeErrors(source); | 212 context.computeErrors(source); |
| 166 var sourceErrors = context.getErrors(source); | 213 var sourceErrors = context.getErrors(source); |
| 167 errorInfos.add(sourceErrors); | 214 errorInfos.add(sourceErrors); |
| 168 } | 215 } |
| 169 } | 216 } |
| 170 | 217 |
| 171 static JavaFile getPackageDirectoryFor(JavaFile sourceFile) { | 218 static JavaFile getPackageDirectoryFor(JavaFile sourceFile) { |
| 172 // we are going to ask parent file, so get absolute path | 219 // we are going to ask parent file, so get absolute path |
| (...skipping 27 matching lines...) Expand all Loading... | |
| 200 var internalPath = pathos.join(libraryDirectory, '_internal') + pathos.s eparator; | 247 var internalPath = pathos.join(libraryDirectory, '_internal') + pathos.s eparator; |
| 201 if (!filePath.startsWith(internalPath)) { | 248 if (!filePath.startsWith(internalPath)) { |
| 202 return UriKind.DART_URI; | 249 return UriKind.DART_URI; |
| 203 } | 250 } |
| 204 } | 251 } |
| 205 } | 252 } |
| 206 // some generic file | 253 // some generic file |
| 207 return UriKind.FILE_URI; | 254 return UriKind.FILE_URI; |
| 208 } | 255 } |
| 209 } | 256 } |
| OLD | NEW |