| 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 part of analyzer; | |
| 5 | 4 |
| 6 /// Analyzes single library [File]. | 5 library analyzer; |
| 7 class _AnalyzerImpl { | |
| 8 final CommandLineOptions options; | |
| 9 DartSdk sdk; | |
| 10 | 6 |
| 11 ContentCache contentCache = new ContentCache(); | 7 import 'dart:io'; |
| 12 SourceFactory sourceFactory; | |
| 13 AnalysisContext context; | |
| 14 | 8 |
| 15 /// All [Source]s references by the analyzed library. | 9 import 'src/error.dart'; |
| 16 final Set<Source> sources = new Set<Source>(); | 10 import 'src/generated/ast.dart'; |
| 11 import 'src/generated/error.dart'; |
| 12 import 'src/generated/java_io.dart'; |
| 13 import 'src/generated/parser.dart'; |
| 14 import 'src/generated/scanner.dart'; |
| 15 import 'src/generated/source_io.dart'; |
| 16 import 'src/utils.dart'; |
| 17 | 17 |
| 18 /// All [AnalysisErrorInfo]s in the analyzed library. | 18 export 'src/error.dart'; |
| 19 final List<AnalysisErrorInfo> errorInfos = new List<AnalysisErrorInfo>(); | 19 export 'src/generated/ast.dart'; |
| 20 export 'src/generated/error.dart'; |
| 20 | 21 |
| 21 _AnalyzerImpl(CommandLineOptions this.options) { | 22 /// Parses a Dart file into an AST. |
| 22 sdk = new DirectoryBasedDartSdk(new JavaFile(options.dartSdkPath)); | 23 CompilationUnit parseDartFile(String path) { |
| 23 } | 24 var contents = new File(path).readAsStringSync(); |
| 25 var errorCollector = new _ErrorCollector(); |
| 26 var sourceFactory = new SourceFactory.con2([new FileUriResolver()]); |
| 27 var source = sourceFactory.forUri(pathToFileUri(path).toString()); |
| 28 var scanner = new StringScanner(source, contents, errorCollector); |
| 29 var token = scanner.tokenize(); |
| 30 var parser = new Parser(source, errorCollector); |
| 31 var unit = parser.parseCompilationUnit(token); |
| 32 unit.lineInfo = new LineInfo(scanner.lineStarts); |
| 24 | 33 |
| 25 /** | 34 if (errorCollector.hasErrors) throw errorCollector.group; |
| 26 * Treats the [sourcePath] as the top level library and analyzes it. | |
| 27 */ | |
| 28 void analyze(String sourcePath) { | |
| 29 sources.clear(); | |
| 30 errorInfos.clear(); | |
| 31 if (sourcePath == null) { | |
| 32 throw new ArgumentError("sourcePath cannot be null"); | |
| 33 } | |
| 34 var sourceFile = new JavaFile(sourcePath); | |
| 35 var librarySource = new FileBasedSource.con1(contentCache, sourceFile); | |
| 36 // resolve library | |
| 37 prepareAnalysisContext(sourceFile); | |
| 38 var libraryElement = context.computeLibraryElement(librarySource); | |
| 39 // prepare source and errors | |
| 40 prepareSources(libraryElement); | |
| 41 prepareErrors(); | |
| 42 } | |
| 43 | 35 |
| 44 /// Returns the maximal [ErrorSeverity] of the recorded errors. | 36 return unit; |
| 45 ErrorSeverity get maxErrorSeverity { | 37 } |
| 46 var status = ErrorSeverity.NONE; | |
| 47 for (AnalysisErrorInfo errorInfo in errorInfos) { | |
| 48 for (AnalysisError error in errorInfo.errors) { | |
| 49 var severity = error.errorCode.errorSeverity; | |
| 50 status = status.max(severity); | |
| 51 } | |
| 52 } | |
| 53 return status; | |
| 54 } | |
| 55 | 38 |
| 56 void prepareAnalysisContext(JavaFile sourceFile) { | 39 /// Converts an AST node representing a string literal into a [String]. |
| 57 List<UriResolver> resolvers = [new DartUriResolver(sdk), new FileUriResolver
()]; | 40 String stringLiteralToString(StringLiteral literal) { |
| 58 // may be add package resolver | 41 if (literal is AdjacentStrings) { |
| 59 { | 42 return literal.strings.map(stringLiteralToString).join(); |
| 60 var packageDirectory = getPackageDirectoryFor(sourceFile); | 43 } else if (literal is SimpleStringLiteral) { |
| 61 if (packageDirectory != null) { | 44 return literal.value; |
| 62 resolvers.add(new PackageUriResolver([packageDirectory])); | 45 } else { |
| 63 } | 46 throw new ArgumentError("Can't convert $literal to a Dart string."); |
| 64 } | |
| 65 sourceFactory = new SourceFactory.con1(contentCache, resolvers); | |
| 66 context = AnalysisEngine.instance.createAnalysisContext(); | |
| 67 context.sourceFactory = sourceFactory; | |
| 68 } | |
| 69 | |
| 70 /// Fills [sources]. | |
| 71 void prepareSources(LibraryElement library) { | |
| 72 var units = new Set<CompilationUnitElement>(); | |
| 73 var libraries = new Set<LibraryElement>(); | |
| 74 addLibrarySources(library, libraries, units); | |
| 75 } | |
| 76 | |
| 77 void addCompilationUnitSource(CompilationUnitElement unit, Set<LibraryElement>
libraries, | |
| 78 Set<CompilationUnitElement> units) { | |
| 79 if (unit == null || units.contains(unit)) { | |
| 80 return; | |
| 81 } | |
| 82 units.add(unit); | |
| 83 sources.add(unit.source); | |
| 84 } | |
| 85 | |
| 86 void addLibrarySources(LibraryElement library, Set<LibraryElement> libraries, | |
| 87 Set<CompilationUnitElement> units) { | |
| 88 if (library == null || libraries.contains(library)) { | |
| 89 return; | |
| 90 } | |
| 91 libraries.add(library); | |
| 92 // may be skip library | |
| 93 { | |
| 94 UriKind uriKind = library.source.uriKind; | |
| 95 // Optionally skip package: libraries. | |
| 96 if (!options.showPackageWarnings && uriKind == UriKind.PACKAGE_URI) { | |
| 97 return; | |
| 98 } | |
| 99 // Optionally skip SDK libraries. | |
| 100 if (!options.showSdkWarnings && uriKind == UriKind.DART_URI) { | |
| 101 return; | |
| 102 } | |
| 103 } | |
| 104 // add compilation units | |
| 105 addCompilationUnitSource(library.definingCompilationUnit, libraries, units); | |
| 106 for (CompilationUnitElement child in library.parts) { | |
| 107 addCompilationUnitSource(child, libraries, units); | |
| 108 } | |
| 109 // add referenced libraries | |
| 110 for (LibraryElement child in library.importedLibraries) { | |
| 111 addLibrarySources(child, libraries, units); | |
| 112 } | |
| 113 for (LibraryElement child in library.exportedLibraries) { | |
| 114 addLibrarySources(child, libraries, units); | |
| 115 } | |
| 116 } | |
| 117 | |
| 118 /// Fills [errorInfos]. | |
| 119 void prepareErrors() { | |
| 120 for (Source source in sources) { | |
| 121 var sourceErrors = context.getErrors(source); | |
| 122 errorInfos.add(sourceErrors); | |
| 123 } | |
| 124 } | |
| 125 | |
| 126 static JavaFile getPackageDirectoryFor(JavaFile sourceFile) { | |
| 127 JavaFile sourceFolder = sourceFile.getParentFile(); | |
| 128 JavaFile packagesFolder = new JavaFile.relative(sourceFolder, "packages"); | |
| 129 if (packagesFolder.exists()) { | |
| 130 return packagesFolder; | |
| 131 } | |
| 132 return null; | |
| 133 } | 47 } |
| 134 } | 48 } |
| 49 |
| 50 /// A simple error listener that collects errors into an [AnalysisErrorGroup]. |
| 51 class _ErrorCollector extends AnalysisErrorListener { |
| 52 final _errors = <AnalysisError>[]; |
| 53 |
| 54 /// Whether any errors where collected. |
| 55 bool get hasErrors => !_errors.isEmpty; |
| 56 |
| 57 /// The group of errors collected. |
| 58 AnalyzerErrorGroup get group => |
| 59 new AnalyzerErrorGroup.fromAnalysisErrors(_errors); |
| 60 |
| 61 _ErrorCollector(); |
| 62 |
| 63 void onError(AnalysisError error) => _errors.add(error); |
| 64 } |
| OLD | NEW |