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 |