| OLD | NEW |
| (Empty) |
| 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 | |
| 3 // BSD-style license that can be found in the LICENSE file. | |
| 4 | |
| 5 /** | |
| 6 * Parser for Dart code based on the experimental analyzer. | |
| 7 */ | |
| 8 library dart_parser; | |
| 9 | |
| 10 import 'package:analyzer_experimental/src/generated/ast.dart'; | |
| 11 import 'package:analyzer_experimental/src/generated/error.dart'; | |
| 12 import 'package:analyzer_experimental/src/generated/parser.dart'; | |
| 13 import 'package:analyzer_experimental/src/generated/scanner.dart'; | |
| 14 import 'package:source_maps/span.dart' show SourceFile, SourceFileSegment, Locat
ion; | |
| 15 import 'utils.dart' show escapeDartString; | |
| 16 | |
| 17 /** Information extracted from a source Dart file. */ | |
| 18 class DartCodeInfo { | |
| 19 | |
| 20 /** Library qualified identifier, if any. */ | |
| 21 final String libraryName; | |
| 22 | |
| 23 /** Library which the code is part-of, if any. */ | |
| 24 final String partOf; | |
| 25 | |
| 26 /** Declared imports, exports, and parts. */ | |
| 27 final List<Directive> directives; | |
| 28 | |
| 29 /** Source file representation used to compute source map information. */ | |
| 30 final SourceFile sourceFile; | |
| 31 | |
| 32 /** The parsed code. */ | |
| 33 final CompilationUnit compilationUnit; | |
| 34 | |
| 35 /** The full source code. */ | |
| 36 final String code; | |
| 37 | |
| 38 DartCodeInfo(this.libraryName, this.partOf, this.directives, code, | |
| 39 this.sourceFile, [compilationUnit]) | |
| 40 : this.code = code, | |
| 41 this.compilationUnit = compilationUnit == null | |
| 42 ? _parseCompilationUnit(code) : compilationUnit; | |
| 43 | |
| 44 bool get isPart => | |
| 45 compilationUnit.directives.any((d) => d is PartOfDirective); | |
| 46 | |
| 47 int get directivesEnd { | |
| 48 if (compilationUnit.directives.length == 0) return 0; | |
| 49 return compilationUnit.directives.last.end; | |
| 50 } | |
| 51 | |
| 52 /** | |
| 53 * The position of the first "part" directive. If none is found, | |
| 54 * this behaves like [directivesEnd]. | |
| 55 */ | |
| 56 int get firstPartOffset { | |
| 57 for (var directive in compilationUnit.directives) { | |
| 58 if (directive is PartDirective) return directive.offset; | |
| 59 } | |
| 60 // No part directives, just return directives end. | |
| 61 return directivesEnd; | |
| 62 } | |
| 63 | |
| 64 /** Gets the code after the [directives]. */ | |
| 65 String codeAfterDirectives() => code.substring(directivesEnd); | |
| 66 | |
| 67 ClassDeclaration findClass(String name) { | |
| 68 for (var decl in compilationUnit.declarations) { | |
| 69 if (decl is ClassDeclaration) { | |
| 70 if (decl.name.name == name) return decl; | |
| 71 } | |
| 72 } | |
| 73 return null; | |
| 74 } | |
| 75 } | |
| 76 | |
| 77 SimpleStringLiteral createStringLiteral(String contents) { | |
| 78 var lexeme = "'${escapeDartString(contents)}'"; | |
| 79 var token = new StringToken(TokenType.STRING, lexeme, null); | |
| 80 return new SimpleStringLiteral.full(token, contents); | |
| 81 } | |
| 82 | |
| 83 | |
| 84 /** | |
| 85 * Parse and extract top-level directives from [code]. | |
| 86 * | |
| 87 */ | |
| 88 // TODO(sigmund): log emitted error/warning messages | |
| 89 DartCodeInfo parseDartCode(String path, String code, [Location offset]) { | |
| 90 var unit = _parseCompilationUnit(code); | |
| 91 | |
| 92 // Extract some information from the compilation unit. | |
| 93 String libraryName, partName; | |
| 94 var directives = []; | |
| 95 int directiveEnd = 0; | |
| 96 for (var directive in unit.directives) { | |
| 97 if (directive is LibraryDirective) { | |
| 98 libraryName = directive.name.name; | |
| 99 } else if (directive is PartOfDirective) { | |
| 100 partName = directive.libraryName.name; | |
| 101 } else { | |
| 102 assert(directive is UriBasedDirective); | |
| 103 // Normalize the library URI. | |
| 104 var uriNode = directive.uri; | |
| 105 if (uriNode is! SimpleStringLiteral) { | |
| 106 String uri = uriNode.accept(new ConstantEvaluator()); | |
| 107 directive.uri = createStringLiteral(uri); | |
| 108 } | |
| 109 directives.add(directive); | |
| 110 } | |
| 111 } | |
| 112 | |
| 113 var sourceFile = offset == null | |
| 114 ? new SourceFile.text(path, code) | |
| 115 : new SourceFileSegment(path, code, offset); | |
| 116 | |
| 117 return new DartCodeInfo(libraryName, partName, directives, code, | |
| 118 sourceFile, unit); | |
| 119 } | |
| 120 | |
| 121 CompilationUnit _parseCompilationUnit(String code) { | |
| 122 var errorListener = new _ErrorCollector(); | |
| 123 var scanner = new StringScanner(null, code, errorListener); | |
| 124 var token = scanner.tokenize(); | |
| 125 var parser = new Parser(null, errorListener); | |
| 126 return parser.parseCompilationUnit(token); | |
| 127 } | |
| 128 | |
| 129 class _ErrorCollector extends AnalysisErrorListener { | |
| 130 final errors = new List<AnalysisError>(); | |
| 131 onError(error) => errors.add(error); | |
| 132 } | |
| OLD | NEW |