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

Unified Diff: lib/compiler/implementation/patch_parser.dart

Issue 10697084: Recognize "patch" identifier in .dartp files. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Addressed review comments Created 8 years, 5 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « lib/compiler/implementation/lib/math.dartp ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: lib/compiler/implementation/patch_parser.dart
diff --git a/lib/compiler/implementation/patch_parser.dart b/lib/compiler/implementation/patch_parser.dart
new file mode 100644
index 0000000000000000000000000000000000000000..13ac6bff0e94175952c6f0921f3142067e93b7b1
--- /dev/null
+++ b/lib/compiler/implementation/patch_parser.dart
@@ -0,0 +1,166 @@
+// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+#library("patchparser");
+#import("dart:uri");
+
+#import("tree/tree.dart", prefix: "tree");
+#import("leg.dart", prefix: 'leg'); // CompilerTask, Compiler.
+#import("apiimpl.dart");
+#import("scanner/scannerlib.dart"); // Scanner, Parsers, Listeners
+#import("elements/elements.dart");
+#import('native_handler.dart', prefix: 'native');
+
+class PatchParserTask extends leg.CompilerTask {
+ PatchParserTask(leg.Compiler compiler): super(compiler);
+ final String name = "Patching Parser";
+
+ LibraryElement loadPatchLibrary(Uri uri) {
+ bool newLibrary = false;
+ PatchLibraryElement library =
+ compiler.libraries.putIfAbsent(uri.toString(), () {
+ newLibrary = true;
+ leg.Script script = compiler.readScript(uri, null);
+ LibraryElement element =
+ new LibraryElement(script);
+ native.maybeEnableNative(compiler, element, uri);
+ return element;
+ });
+ if (newLibrary) {
+ compiler.withCurrentElement(library, () {
+ scanLibraryElements(library);
+ compiler.onLibraryLoaded(library, uri);
+ });
+ }
+ return library;
+ }
+
+ void scanLibraryElements(LibraryElement library) {
+ measure(() {
+ // TODO(lrn): Possibly recursively handle #source directives in patch.
+ leg.Script script = library.script;
+ Token tokens = new StringScanner(script.text).tokenize();
+ Function idGenerator = compiler.getNextFreeClassId;
+ PatchListener patchListener =
+ new PatchElementListener(compiler, library, idGenerator);
+ new PatchParser(patchListener).parseUnit(tokens);
+ });
+ }
+}
+
+/**
+ * Extension of the [Listener] interface to handle the extra "patch" pseudo-
+ * keyword in patch files.
+ * Patch files shouldn't have a type named "patch".
+ */
+interface PatchListener extends Listener {
+ void beginPatch(Token patch);
+ void endPatch(Token patch);
+}
+
+/**
+ * Partial parser that extends the top-level and class grammars to allow the
+ * word "patch" in front of some declarations.
+ */
+class PatchParser extends PartialParser {
+ PatchParser(PatchListener listener) : super(listener);
+
+ PatchListener get patchListener() => listener;
+
+ bool isPatch(Token token) {
+ return token.stringValue === null &&
+ token.slowToString() == "patch";
+ }
+
+ /**
+ * Parse top-level declarations, and allow "patch" in front of functions
+ * and classes.
+ */
+ Token parseTopLevelDeclaration(Token token) {
+ if (!isPatch(token)) {
+ return super.parseTopLevelDeclaration(token);
+ }
+ Token patch = token;
+ token = token.next;
+ String value = token.stringValue;
+ if (value === 'interface'
+ || value === 'typedef'
+ || value === '#'
+ || value === 'abstract') {
+ // At the top level, you can only patch functions and classes.
+ // Patch classes and functions can't be marked abstract.
+ return listener.unexpected(patch);
+ }
+ patchListener.beginPatch(patch);
+ token = super.parseTopLevelDeclaration(token.next);
+ patchListener.endPatch(patch);
+ return token;
+ }
+
+ /**
+ * Parse a class member.
+ * If the member starts with "patch", it's a member override.
+ * Only methods can be overridden, including constructors, getters and
+ * setters, but not fields. If "patch" occurs in front of a field, the error
+ * is caught elsewhere.
+ */
+ Token parseMember(Token token) {
+ if (!isPatch(token)) {
+ return super.parseMember(token);
+ }
+ Token patch = token;
+ patchListener.beginPatch(patch);
+ token = super.parseMember(token.next);
+ patchListener.endPatch(patch);
+ return token;
+ }
+}
+
+
+/**
+ * Partial parser for patch files that also handles the members of class
+ * declarations.
+ */
+class PatchClassElementParser extends PatchParser {
+ PatchClassElementParser(PatchListener listener) : super(listener);
+
+ Token parseClassBody(Token token) => fullParseClassBody(token);
+}
+
+
+/**
+ * Extension of [ElementListener] for parsing patch files.
+ */
+class PatchElementListener extends ElementListener implements PatchListener {
+ bool isMemberPatch = false;
+ bool isClassPatch = false;
+ PatchElementListener(DiagnosticListener listener,
+ CompilationUnitElement patchElement,
+ int idGenerator())
+ : super(listener, patchElement, idGenerator);
+
+ void beginPatch(Token token) {
+ if (token.next.stringValue === "class") {
+ isClassPatch = true;
+ } else {
+ isMemberPatch = true;
+ }
+ handleIdentifier(token);
+ }
+
+ void endPatch(Token token) {
+ if (token.next.stringValue === "class") {
+ isClassPatch = false;
+ } else {
+ isMemberPatch = false;
+ }
+ }
+
+ void pushElement(Element element) {
+ if (isMemberPatch || (isClassPatch && element is ClassElement)) {
+ element.addMetadata(popNode());
+ }
+ super.pushElement(element);
+ }
+}
« no previous file with comments | « lib/compiler/implementation/lib/math.dartp ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698