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

Side by Side Diff: pkg/compiler/lib/src/patch_parser.dart

Issue 1971193002: Patches to support Dart VM patch files in dart2js. (Closed) Base URL: sso://user/ahe/dart-sdk@master
Patch Set: Created 4 years, 6 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
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2012, 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 * This library contains the infrastructure to parse and integrate patch files. 6 * This library contains the infrastructure to parse and integrate patch files.
7 * 7 *
8 * Three types of elements can be patched: [LibraryElement], [ClassElement], 8 * Three types of elements can be patched: [LibraryElement], [ClassElement],
9 * [FunctionElement]. Patches are introduced in patch libraries which are loaded 9 * [FunctionElement]. Patches are introduced in patch libraries which are loaded
10 * together with the corresponding origin library. Which libraries that are 10 * together with the corresponding origin library. Which libraries that are
(...skipping 124 matching lines...) Expand 10 before | Expand all | Expand 10 after
135 import 'library_loader.dart' show LibraryLoader; 135 import 'library_loader.dart' show LibraryLoader;
136 import 'options.dart' show ParserOptions; 136 import 'options.dart' show ParserOptions;
137 import 'parser/listener.dart' show Listener, ParserError; 137 import 'parser/listener.dart' show Listener, ParserError;
138 import 'parser/element_listener.dart' show ElementListener; 138 import 'parser/element_listener.dart' show ElementListener;
139 import 'parser/member_listener.dart' show MemberListener; 139 import 'parser/member_listener.dart' show MemberListener;
140 import 'parser/partial_elements.dart' show PartialClassElement; 140 import 'parser/partial_elements.dart' show PartialClassElement;
141 import 'parser/partial_parser.dart' show PartialParser; 141 import 'parser/partial_parser.dart' show PartialParser;
142 import 'parser/parser.dart' show Parser; 142 import 'parser/parser.dart' show Parser;
143 import 'scanner/scanner.dart' show Scanner; 143 import 'scanner/scanner.dart' show Scanner;
144 import 'script.dart'; 144 import 'script.dart';
145 import 'tokens/token.dart' show StringToken, Token; 145 import 'tokens/token.dart' show SymbolToken, StringToken, Token;
146
147 import 'tokens/token_constants.dart' show EOF_TOKEN;
148
149 import 'tokens/precedence_constants.dart' show AT_INFO;
150
151 class PartialPatchParser extends PartialParser {
152 PartialPatchParser(Listener listener, ParserOptions options)
153 : super(listener, options);
154
155 Token parseMetadataStar(Token token, {bool forParameter: false}) {
156 listener.beginMetadataStar(token);
157 int count = 0;
158 while (token.kind != EOF_TOKEN) {
159 if (optional('@', token)) {
160 token = parseMetadata(token);
161 count++;
162 } else if (optional('patch', token)) {
163 token = parsePatchKeyword(token);
164 } else {
165 break;
166 }
167 }
168 listener.endMetadataStar(count, forParameter);
169 return token;
170 }
171
172 Token parsePatchKeyword(Token token) {
173 listener.beginMetadata(token);
174 Token start = new SymbolToken(AT_INFO, token.charOffset)..next = token;
175 assert(optional('patch', token));
176 token = parseIdentifier(token);
177 token = parseQualifiedRestOpt(token);
178 token = parseTypeArgumentsOpt(token);
179 Token period = null;
180 if (optional('.', token)) {
181 period = token;
182 token = parseIdentifier(token.next);
183 }
184 token = parseArgumentsOpt(token);
185 listener.endMetadata(start, period, token);
186 return token;
187 }
188 }
146 189
147 class PatchParserTask extends CompilerTask { 190 class PatchParserTask extends CompilerTask {
148 final String name = "Patching Parser"; 191 final String name = "Patching Parser";
149 final ParserOptions parserOptions; 192 final ParserOptions parserOptions;
150 193
151 PatchParserTask(Compiler compiler, this.parserOptions) : super(compiler); 194 PatchParserTask(Compiler compiler, this.parserOptions) : super(compiler);
152 195
153 /** 196 /**
154 * Scans a library patch file, applies the method patches and 197 * Scans a library patch file, applies the method patches and
155 * injections to the library, and returns a list of class 198 * injections to the library, and returns a list of class
156 * patches. 199 * patches.
157 */ 200 */
158 Future patchLibrary( 201 Future patchLibrary(
159 LibraryLoader loader, Uri patchUri, LibraryElement originLibrary) { 202 LibraryLoader loader, Uri patchUri, LibraryElement originLibrary) {
160 return compiler.readScript(patchUri, originLibrary).then((Script script) { 203 return compiler.readScript(patchUri, originLibrary).then((Script script) {
161 var patchLibrary = new LibraryElementX(script, null, originLibrary); 204 var patchLibrary = new LibraryElementX(script, null, originLibrary);
162 return reporter.withCurrentElement(patchLibrary, () { 205 return reporter.withCurrentElement(patchLibrary, () {
163 loader.registerNewLibrary(patchLibrary); 206 loader.registerNewLibrary(patchLibrary);
164 reporter.withCurrentElement(patchLibrary.entryCompilationUnit, () { 207 reporter.withCurrentElement(patchLibrary.entryCompilationUnit, () {
165 // This patches the elements of the patch library into [library]. 208 // This patches the elements of the patch library into [library].
166 // Injected elements are added directly under the compilation unit. 209 // Injected elements are added directly under the compilation unit.
167 // Patch elements are stored on the patched functions or classes. 210 // Patch elements are stored on the patched functions or classes.
168 scanLibraryElements(patchLibrary.entryCompilationUnit); 211 scanLibraryElements(patchLibrary.entryCompilationUnit);
169 }); 212 });
170 return loader.processLibraryTags(patchLibrary); 213 return loader.processLibraryTags(patchLibrary, isPatchLibrary: true);
171 }); 214 });
172 }); 215 });
173 } 216 }
174 217
175 void scanLibraryElements(CompilationUnitElement compilationUnit) { 218 void scanLibraryElements(CompilationUnitElement compilationUnit) {
176 measure(() { 219 measure(() {
177 // TODO(johnniwinther): Test that parts and exports are handled correctly. 220 // TODO(johnniwinther): Test that parts and exports are handled correctly.
178 Script script = compilationUnit.script; 221 Script script = compilationUnit.script;
179 Token tokens = new Scanner(script.file).tokenize(); 222 Token tokens = new Scanner(script.file).tokenize();
180 Listener patchListener = 223 Listener patchListener =
181 new PatchElementListener(compiler, compilationUnit, compiler); 224 new PatchElementListener(compiler, compilationUnit, compiler);
182 try { 225 try {
183 new PartialParser(patchListener, parserOptions).parseUnit(tokens); 226 new PartialPatchParser(patchListener, parserOptions).parseUnit(tokens);
184 } on ParserError catch (e) { 227 } on ParserError catch (e) {
185 // No need to recover from a parser error in platform libraries, user 228 // No need to recover from a parser error in platform libraries, user
186 // will never see this if the libraries are tested correctly. 229 // will never see this if the libraries are tested correctly.
187 reporter.internalError( 230 reporter.internalError(
188 compilationUnit, "Parser error in patch file: $e"); 231 compilationUnit, "Parser error in patch file: $e");
189 } 232 }
190 }); 233 });
191 } 234 }
192 235
193 void parsePatchClassNode(PartialClassElement cls) { 236 void parsePatchClassNode(PartialClassElement cls) {
194 // Parse [PartialClassElement] using a "patch"-aware parser instead 237 // Parse [PartialClassElement] using a "patch"-aware parser instead
195 // of calling its [parseNode] method. 238 // of calling its [parseNode] method.
196 if (cls.cachedNode != null) return; 239 if (cls.cachedNode != null) return;
197 240
198 measure(() => reporter.withCurrentElement(cls, () { 241 measure(() => reporter.withCurrentElement(cls, () {
199 MemberListener listener = new PatchMemberListener(compiler, cls); 242 MemberListener listener = new PatchMemberListener(compiler, cls);
200 Parser parser = new PatchClassElementParser(listener, parserOptions); 243 Parser parser = new PatchClassElementParser(listener, parserOptions);
201 try { 244 try {
202 Token token = parser.parseTopLevelDeclaration(cls.beginToken); 245 Token token = parser.parseTopLevelDeclaration(cls.beginToken);
203 assert(identical(token, cls.endToken.next)); 246 assert(identical(token, cls.endToken.next));
204 } on ParserError catch (e) { 247 } on ParserError catch (e) {
205 // No need to recover from a parser error in platform libraries, use r 248 // No need to recover from a parser error in platform libraries, use r
206 // will never see this if the libraries are tested correctly. 249 // will never see this if the libraries are tested correctly.
207 reporter.internalError(cls, "Parser error in patch file: $e"); 250 reporter.internalError(cls, "Parser error in patch file: $e");
208 } 251 }
209 cls.cachedNode = listener.popNode(); 252 cls.cachedNode = listener.popNode();
210 assert(listener.nodes.isEmpty); 253 assert(listener.nodes.isEmpty);
211 })); 254 }));
212 } 255 }
256
257 void scanUnit(CompilationUnitElement unit, {bool isPart: true}) {
258 // TODO(ahe): Implement this.
259 throw "not implemented";
260 }
213 } 261 }
214 262
215 class PatchMemberListener extends MemberListener { 263 class PatchMemberListener extends MemberListener {
216 final Compiler compiler; 264 final Compiler compiler;
217 265
218 PatchMemberListener(Compiler compiler, ClassElement enclosingClass) 266 PatchMemberListener(Compiler compiler, ClassElement enclosingClass)
219 : this.compiler = compiler, 267 : this.compiler = compiler,
220 super(compiler.parsing.getScannerOptionsFor(enclosingClass), 268 super(compiler.parsing.getScannerOptionsFor(enclosingClass),
221 compiler.reporter, enclosingClass); 269 compiler.reporter, enclosingClass);
222 270
223 @override 271 @override
224 void addMember(Element patch) { 272 void addMember(Element patch) {
225 addMetadata(patch); 273 addMetadata(patch);
226 274
227 PatchVersion patchVersion = getPatchVersion(compiler, patch); 275 PatchVersion patchVersion = getPatchVersion(compiler, patch);
228 if (patchVersion != null) { 276 if (patchVersion != null) {
229 if (patchVersion.isActive(compiler.patchVersion)) { 277 if (patchVersion.isActive(compiler.patchVersion)) {
230 Element origin = enclosingClass.origin.localLookup(patch.name); 278 Element origin = enclosingClass.origin.localLookup(patch.name);
231 patchElement(compiler, reporter, origin, patch); 279 patchElement(compiler, reporter, origin, patch);
232 enclosingClass.addMember(patch, reporter); 280 enclosingClass.addMember(patch, reporter);
233 } else { 281 } else {
234 // Skip this element. 282 // Skip this element.
235 } 283 }
236 } else { 284 } else {
237 if (Name.isPublicName(patch.name)) { 285 Element origin = enclosingClass.origin.localLookup(patch.name);
286 if (origin != null) {
287 patchElement(compiler, reporter, origin, patch);
288 } else if (Name.isPublicName(patch.name)) {
238 reporter.reportErrorMessage(patch, MessageKind.INJECTED_PUBLIC_MEMBER); 289 reporter.reportErrorMessage(patch, MessageKind.INJECTED_PUBLIC_MEMBER);
239 } 290 }
240 enclosingClass.addMember(patch, reporter); 291 enclosingClass.addMember(patch, reporter);
241 } 292 }
242 } 293 }
243 } 294 }
244 295
245 /** 296 /**
246 * Partial parser for patch files that also handles the members of class 297 * Partial parser for patch files that also handles the members of class
247 * declarations. 298 * declarations.
(...skipping 26 matching lines...) Expand all
274 if (patchVersion.isActive(compiler.patchVersion)) { 325 if (patchVersion.isActive(compiler.patchVersion)) {
275 LibraryElement originLibrary = compilationUnitElement.library; 326 LibraryElement originLibrary = compilationUnitElement.library;
276 assert(originLibrary.isPatched); 327 assert(originLibrary.isPatched);
277 Element origin = originLibrary.localLookup(patch.name); 328 Element origin = originLibrary.localLookup(patch.name);
278 patchElement(compiler, reporter, origin, patch); 329 patchElement(compiler, reporter, origin, patch);
279 compilationUnitElement.addMember(patch, reporter); 330 compilationUnitElement.addMember(patch, reporter);
280 } else { 331 } else {
281 // Skip this element. 332 // Skip this element.
282 } 333 }
283 } else { 334 } else {
284 if (Name.isPublicName(patch.name)) { 335 LibraryElement originLibrary = compilationUnitElement.library;
336 Element origin = originLibrary.localLookup(patch.name);
337 if (origin != null) {
338 patchElement(compiler, reporter, origin, patch);
339 } else if (Name.isPublicName(patch.name)) {
285 reporter.reportErrorMessage(patch, MessageKind.INJECTED_PUBLIC_MEMBER); 340 reporter.reportErrorMessage(patch, MessageKind.INJECTED_PUBLIC_MEMBER);
286 } 341 }
287 compilationUnitElement.addMember(patch, reporter); 342 compilationUnitElement.addMember(patch, reporter);
288 } 343 }
289 } 344 }
290 } 345 }
291 346
292 void patchElement(Compiler compiler, DiagnosticReporter reporter, 347 void patchElement(Compiler compiler, DiagnosticReporter reporter,
293 Element origin, Element patch) { 348 Element origin, Element patch) {
294 if (origin == null) { 349 if (origin == null) {
(...skipping 317 matching lines...) Expand 10 before | Expand all | Expand 10 after
612 667
613 class PatchVersion { 668 class PatchVersion {
614 final String tag; 669 final String tag;
615 670
616 const PatchVersion(this.tag); 671 const PatchVersion(this.tag);
617 672
618 bool isActive(String patchTag) => tag == null || tag == patchTag; 673 bool isActive(String patchTag) => tag == null || tag == patchTag;
619 674
620 String toString() => 'PatchVersion($tag)'; 675 String toString() => 'PatchVersion($tag)';
621 } 676 }
OLDNEW
« no previous file with comments | « pkg/compiler/lib/src/parser/parser.dart ('k') | pkg/compiler/lib/src/resolution/class_hierarchy.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698