Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(64)

Side by Side Diff: lib/src/dart_parser.dart

Issue 12225039: Support for observable models, fixes #259 (Closed) Base URL: https://github.com/dart-lang/web-ui.git@master
Patch Set: small formatting fixes Created 7 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(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 'dart:utf';
11 import 'dart:math' as math;
12 import 'package:analyzer_experimental/src/generated/ast.dart';
13 import 'package:analyzer_experimental/src/generated/error.dart';
14 import 'package:analyzer_experimental/src/generated/java_core.dart';
15 import 'package:analyzer_experimental/src/generated/parser.dart';
16 import 'package:analyzer_experimental/src/generated/scanner.dart';
17 import 'package:source_maps/span.dart' show File, FileSpan;
18 import 'file_system/path.dart';
19 import 'info.dart';
20 import 'messages.dart';
21 import 'refactor.dart' show $CR, $LF;
22 import 'utils.dart';
23
24 /** Information extracted from a source Dart file. */
25 class DartCodeInfo {
26 // TODO(jmesserly): VM hashCode performance workaround ...
27 static int _nextHash = 0;
28 final int hashCode = ++_nextHash;
29
30 /** Library qualified identifier, if any. */
31 final String libraryName;
32
33 /** Library which the code is part-of, if any. */
34 final String partOf;
35
36 /** Declared imports, exports, and parts. */
37 final List<Directive> directives;
38
39 /** The parsed code. */
40 CompilationUnit _compilationUnit;
41
42 /** The full source code. */
43 String _code;
44
45 DartCodeInfo(this.libraryName, this.partOf, this.directives, code,
46 [compilationUnit]) : _code = code, _compilationUnit = compilationUnit;
47
48 String get code => _code;
49
50 set code(String value) {
51 // TODO(jmesserly): invalidate libraryName, partOf, and directives as well?
52 // In general we should move this to querying from the CompilationUnit.
53 _code = value;
54 _compilationUnit = null;
55 }
56
57 CompilationUnit get compilationUnit {
58 // If this has been invalidated, reparse the code
59 if (_compilationUnit == null) _compilationUnit = parseCompilationUnit(code);
60 return _compilationUnit;
61 }
62
63 int get directivesEnd {
64 if (compilationUnit.directives.length == 0) return 0;
65 return compilationUnit.directives.map((d) => d.end).max();
66 }
67
68 /** Gets the code after the [directives]. */
69 String codeAfterDirectives() => code.substring(directivesEnd);
Siggi Cherem (dart-lang) 2013/02/13 01:43:24 nit: make it a property?
Jennifer Messerly 2013/02/13 05:43:15 It could be repeated O(N)'s if used that way. Tryi
Siggi Cherem (dart-lang) 2013/02/13 19:28:54 Shouldn't good inlining take care of that in this
Jennifer Messerly 2013/02/13 20:21:20 No. I think you mean inlining plus common subexpre
70
71 ClassDeclaration findClass(String name) {
72 for (var decl in compilationUnit.declarations) {
73 if (decl is ClassDeclaration) {
74 if (decl.name.name == name) return decl;
75 }
76 }
77 return null;
78 }
79 }
80
81 // TODO(jmesserly): I think Part and Import will have a common base class soon,
82 // which will make this easier.
83 StringLiteral getDirectiveUri(Directive directive) {
84 if (directive is NamespaceDirective) {
85 return (directive as NamespaceDirective).libraryUri;
Siggi Cherem (dart-lang) 2013/02/13 01:43:24 if you haven't, it might be nice to give them feed
Jennifer Messerly 2013/02/13 05:43:15 Already done. I think it's already fixed, but not
86 } else {
87 return (directive as PartDirective).partUri;
88 }
89 }
90
91 void setDirectiveUri(Directive directive, StringLiteral uri) {
92 if (directive is NamespaceDirective) {
93 (directive as NamespaceDirective).libraryUri2 = uri;
Siggi Cherem (dart-lang) 2013/02/13 01:43:24 ohh weird - bad code generation =)...
Jennifer Messerly 2013/02/13 05:43:15 hehe, yeah. I think Konstantin is looking into it
94 } else {
95 (directive as PartDirective).partUri2 = uri;
96 }
97 }
98
99 SimpleStringLiteral createStringLiteral(String contents) {
100 var lexeme = "'${escapeDartString(contents)}'";
101 var token = new StringToken(TokenType.STRING, lexeme, null);
102 return new SimpleStringLiteral(token, contents);
103 }
104
105
106 /**
107 * Parse and extract top-level directives from [code].
108 *
109 * Adds emitted error/warning messages to [messages], if [messages] is
110 * supplied.
111 */
112 DartCodeInfo parseDartCode(Path path, String code, Messages messages) {
113 var unit = parseCompilationUnit(code, path: path, messages: messages);
114
115 // Extract some information from the compilation unit.
116 String libraryName, partName;
117 var directives = [];
118 int directiveEnd = 0;
119 for (var directive in unit.directives) {
120 if (directive is LibraryDirective) {
121 libraryName = directive.name.name;
122 } else if (directive is PartOfDirective) {
123 partName = directive.libraryName.name;
124 } else {
125 // Normalize the library URI.
126 var uriNode = getDirectiveUri(directive);
127 if (uriNode is! SimpleStringLiteral) {
128 String uri = uriNode.accept(new ConstantEvaluator());
129 setDirectiveUri(directive, createStringLiteral(uri));
130 }
131 directives.add(directive);
132 }
133 }
134
135 return new DartCodeInfo(libraryName, partName, directives, code, unit);
136 }
137
138 CompilationUnit parseCompilationUnit(String code, {Path path,
139 Messages messages}) {
140
141 var errorListener = new _ErrorCollector();
142 var scanner = new StringScanner(null, code, errorListener);
143 var token = scanner.tokenize();
144 var parser = new Parser(null, errorListener);
145 var unit = parser.parseCompilationUnit(token);
146
147 if (path == null || messages == null) return unit;
148
149 // TODO(jmesserly): removed this for now because the analyzer doesn't format
150 // messages properly, so you end up with things like "Unexpected token '%s'".
151 // This used to convert parser messages into our messages. Enable this
152 // once analyzer is fixed.
153 if (false) {
154 var file = new File.text(path.toString(), code);
155 for (var e in errorListener.errors) {
156 var span = new FileSpan(file, e.offset, e.offset + e.length);
157
158 var severity = e.errorCode.errorSeverity;
159 if (severity == ErrorSeverity.ERROR) {
160 messages.error(e.message, span, file: path);
161 } else {
162 assert(severity == ErrorSeverity.WARNING);
163 messages.warning(e.message, span, file: path);
164 }
165 }
166 }
167
168 return unit;
169 }
170
171 class _ErrorCollector extends AnalysisErrorListener {
172 final errors = new List<AnalysisError>();
173 onError(error) => errors.add(error);
174 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698