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 /** | 5 /** |
6 * Parser for Dart code based on the experimental analyzer. | 6 * Parser for Dart code based on the experimental analyzer. |
7 */ | 7 */ |
8 library dart_parser; | 8 library dart_parser; |
9 | 9 |
10 import 'dart:utf'; | |
11 import 'dart:math' as math; | |
12 import 'package:analyzer_experimental/src/generated/ast.dart'; | 10 import 'package:analyzer_experimental/src/generated/ast.dart'; |
13 import 'package:analyzer_experimental/src/generated/error.dart'; | 11 import 'package:analyzer_experimental/src/generated/error.dart'; |
14 import 'package:analyzer_experimental/src/generated/parser.dart'; | 12 import 'package:analyzer_experimental/src/generated/parser.dart'; |
15 import 'package:analyzer_experimental/src/generated/scanner.dart'; | 13 import 'package:analyzer_experimental/src/generated/scanner.dart'; |
16 import 'package:source_maps/span.dart' show SourceFile, SourceFileSegment, Locat
ion; | 14 import 'package:source_maps/span.dart' show SourceFile, SourceFileSegment, Locat
ion; |
17 import 'info.dart'; | |
18 import 'messages.dart'; | 15 import 'messages.dart'; |
19 import 'refactor.dart' show $CR, $LF; | 16 import 'utils.dart' show escapeDartString; |
20 import 'utils.dart'; | |
21 | 17 |
22 /** Information extracted from a source Dart file. */ | 18 /** Information extracted from a source Dart file. */ |
23 class DartCodeInfo extends Hashable { | 19 class DartCodeInfo { |
24 | 20 |
25 /** Library qualified identifier, if any. */ | 21 /** Library qualified identifier, if any. */ |
26 final String libraryName; | 22 final String libraryName; |
27 | 23 |
28 /** Library which the code is part-of, if any. */ | 24 /** Library which the code is part-of, if any. */ |
29 final String partOf; | 25 final String partOf; |
30 | 26 |
31 /** Declared imports, exports, and parts. */ | 27 /** Declared imports, exports, and parts. */ |
32 final List<Directive> directives; | 28 final List<Directive> directives; |
33 | 29 |
34 /** Source file representation used to compute source map information. */ | 30 /** Source file representation used to compute source map information. */ |
35 final SourceFile sourceFile; | 31 final SourceFile sourceFile; |
36 | 32 |
37 /** The parsed code. */ | 33 /** The parsed code. */ |
38 final CompilationUnit compilationUnit; | 34 final CompilationUnit compilationUnit; |
39 | 35 |
40 /** The full source code. */ | 36 /** The full source code. */ |
41 final String code; | 37 final String code; |
42 | 38 |
43 DartCodeInfo(this.libraryName, this.partOf, this.directives, code, | 39 DartCodeInfo(this.libraryName, this.partOf, this.directives, code, |
44 this.sourceFile, [compilationUnit]) | 40 this.sourceFile, [compilationUnit]) |
45 : this.code = code, | 41 : this.code = code, |
46 this.compilationUnit = compilationUnit == null | 42 this.compilationUnit = compilationUnit == null |
47 ? parseCompilationUnit(code) : compilationUnit; | 43 ? _parseCompilationUnit(code) : compilationUnit; |
48 | 44 |
49 bool get isPart => | 45 bool get isPart => |
50 compilationUnit.directives.any((d) => d is PartOfDirective); | 46 compilationUnit.directives.any((d) => d is PartOfDirective); |
51 | 47 |
52 int get directivesEnd { | 48 int get directivesEnd { |
53 if (compilationUnit.directives.length == 0) return 0; | 49 if (compilationUnit.directives.length == 0) return 0; |
54 return compilationUnit.directives.last.end; | 50 return compilationUnit.directives.last.end; |
55 } | 51 } |
56 | 52 |
57 /** | 53 /** |
(...skipping 24 matching lines...) Expand all Loading... |
82 SimpleStringLiteral createStringLiteral(String contents) { | 78 SimpleStringLiteral createStringLiteral(String contents) { |
83 var lexeme = "'${escapeDartString(contents)}'"; | 79 var lexeme = "'${escapeDartString(contents)}'"; |
84 var token = new StringToken(TokenType.STRING, lexeme, null); | 80 var token = new StringToken(TokenType.STRING, lexeme, null); |
85 return new SimpleStringLiteral.full(token, contents); | 81 return new SimpleStringLiteral.full(token, contents); |
86 } | 82 } |
87 | 83 |
88 | 84 |
89 /** | 85 /** |
90 * Parse and extract top-level directives from [code]. | 86 * Parse and extract top-level directives from [code]. |
91 * | 87 * |
92 * Adds emitted error/warning messages to [messages], if [messages] is | |
93 * supplied. | |
94 */ | 88 */ |
95 DartCodeInfo parseDartCode(String path, String code, Messages messages, | 89 // TODO(sigmund): log emitted error/warning messages |
96 [Location offset]) { | 90 DartCodeInfo parseDartCode(String path, String code, [Location offset]) { |
97 var unit = parseCompilationUnit(code, path: path, messages: messages); | 91 var unit = _parseCompilationUnit(code); |
98 | 92 |
99 // Extract some information from the compilation unit. | 93 // Extract some information from the compilation unit. |
100 String libraryName, partName; | 94 String libraryName, partName; |
101 var directives = []; | 95 var directives = []; |
102 int directiveEnd = 0; | 96 int directiveEnd = 0; |
103 for (var directive in unit.directives) { | 97 for (var directive in unit.directives) { |
104 if (directive is LibraryDirective) { | 98 if (directive is LibraryDirective) { |
105 libraryName = directive.name.name; | 99 libraryName = directive.name.name; |
106 } else if (directive is PartOfDirective) { | 100 } else if (directive is PartOfDirective) { |
107 partName = directive.libraryName.name; | 101 partName = directive.libraryName.name; |
(...skipping 10 matching lines...) Expand all Loading... |
118 } | 112 } |
119 | 113 |
120 var sourceFile = offset == null | 114 var sourceFile = offset == null |
121 ? new SourceFile.text(path, code) | 115 ? new SourceFile.text(path, code) |
122 : new SourceFileSegment(path, code, offset); | 116 : new SourceFileSegment(path, code, offset); |
123 | 117 |
124 return new DartCodeInfo(libraryName, partName, directives, code, | 118 return new DartCodeInfo(libraryName, partName, directives, code, |
125 sourceFile, unit); | 119 sourceFile, unit); |
126 } | 120 } |
127 | 121 |
128 CompilationUnit parseCompilationUnit(String code, {String path, | 122 CompilationUnit _parseCompilationUnit(String code) { |
129 Messages messages}) { | |
130 | |
131 var errorListener = new _ErrorCollector(); | 123 var errorListener = new _ErrorCollector(); |
132 var scanner = new StringScanner(null, code, errorListener); | 124 var scanner = new StringScanner(null, code, errorListener); |
133 var token = scanner.tokenize(); | 125 var token = scanner.tokenize(); |
134 var parser = new Parser(null, errorListener); | 126 var parser = new Parser(null, errorListener); |
135 var unit = parser.parseCompilationUnit(token); | 127 return parser.parseCompilationUnit(token); |
136 | |
137 if (path == null || messages == null) return unit; | |
138 | |
139 // TODO(jmesserly): removed this for now because the analyzer doesn't format | |
140 // messages properly, so you end up with things like "Unexpected token '%s'". | |
141 // This used to convert parser messages into our messages. Enable this | |
142 // once analyzer is fixed. | |
143 // TODO(sigmund): once we enable this, we need to fix compiler.dart to clear | |
144 // out the output of the compiler if we see compilation errors. | |
145 if (false) { | |
146 var file = new SourceFile.text(path, code); | |
147 for (var e in errorListener.errors) { | |
148 var span = file.span(e.offset, e.offset + e.length); | |
149 | |
150 var severity = e.errorCode.errorSeverity; | |
151 if (severity == ErrorSeverity.ERROR) { | |
152 messages.error(e.message, span); | |
153 } else { | |
154 assert(severity == ErrorSeverity.WARNING); | |
155 messages.warning(e.message, span); | |
156 } | |
157 } | |
158 } | |
159 | |
160 return unit; | |
161 } | 128 } |
162 | 129 |
163 class _ErrorCollector extends AnalysisErrorListener { | 130 class _ErrorCollector extends AnalysisErrorListener { |
164 final errors = new List<AnalysisError>(); | 131 final errors = new List<AnalysisError>(); |
165 onError(error) => errors.add(error); | 132 onError(error) => errors.add(error); |
166 } | 133 } |
OLD | NEW |