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

Side by Side 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 unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « lib/compiler/implementation/lib/math.dartp ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
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
3 // BSD-style license that can be found in the LICENSE file.
4
5 #library("patchparser");
6 #import("dart:uri");
7
8 #import("tree/tree.dart", prefix: "tree");
9 #import("leg.dart", prefix: 'leg'); // CompilerTask, Compiler.
10 #import("apiimpl.dart");
11 #import("scanner/scannerlib.dart"); // Scanner, Parsers, Listeners
12 #import("elements/elements.dart");
13 #import('native_handler.dart', prefix: 'native');
14
15 class PatchParserTask extends leg.CompilerTask {
16 PatchParserTask(leg.Compiler compiler): super(compiler);
17 final String name = "Patching Parser";
18
19 LibraryElement loadPatchLibrary(Uri uri) {
20 bool newLibrary = false;
21 PatchLibraryElement library =
22 compiler.libraries.putIfAbsent(uri.toString(), () {
23 newLibrary = true;
24 leg.Script script = compiler.readScript(uri, null);
25 LibraryElement element =
26 new LibraryElement(script);
27 native.maybeEnableNative(compiler, element, uri);
28 return element;
29 });
30 if (newLibrary) {
31 compiler.withCurrentElement(library, () {
32 scanLibraryElements(library);
33 compiler.onLibraryLoaded(library, uri);
34 });
35 }
36 return library;
37 }
38
39 void scanLibraryElements(LibraryElement library) {
40 measure(() {
41 // TODO(lrn): Possibly recursively handle #source directives in patch.
42 leg.Script script = library.script;
43 Token tokens = new StringScanner(script.text).tokenize();
44 Function idGenerator = compiler.getNextFreeClassId;
45 PatchListener patchListener =
46 new PatchElementListener(compiler, library, idGenerator);
47 new PatchParser(patchListener).parseUnit(tokens);
48 });
49 }
50 }
51
52 /**
53 * Extension of the [Listener] interface to handle the extra "patch" pseudo-
54 * keyword in patch files.
55 * Patch files shouldn't have a type named "patch".
56 */
57 interface PatchListener extends Listener {
58 void beginPatch(Token patch);
59 void endPatch(Token patch);
60 }
61
62 /**
63 * Partial parser that extends the top-level and class grammars to allow the
64 * word "patch" in front of some declarations.
65 */
66 class PatchParser extends PartialParser {
67 PatchParser(PatchListener listener) : super(listener);
68
69 PatchListener get patchListener() => listener;
70
71 bool isPatch(Token token) {
72 return token.stringValue === null &&
73 token.slowToString() == "patch";
74 }
75
76 /**
77 * Parse top-level declarations, and allow "patch" in front of functions
78 * and classes.
79 */
80 Token parseTopLevelDeclaration(Token token) {
81 if (!isPatch(token)) {
82 return super.parseTopLevelDeclaration(token);
83 }
84 Token patch = token;
85 token = token.next;
86 String value = token.stringValue;
87 if (value === 'interface'
88 || value === 'typedef'
89 || value === '#'
90 || value === 'abstract') {
91 // At the top level, you can only patch functions and classes.
92 // Patch classes and functions can't be marked abstract.
93 return listener.unexpected(patch);
94 }
95 patchListener.beginPatch(patch);
96 token = super.parseTopLevelDeclaration(token.next);
97 patchListener.endPatch(patch);
98 return token;
99 }
100
101 /**
102 * Parse a class member.
103 * If the member starts with "patch", it's a member override.
104 * Only methods can be overridden, including constructors, getters and
105 * setters, but not fields. If "patch" occurs in front of a field, the error
106 * is caught elsewhere.
107 */
108 Token parseMember(Token token) {
109 if (!isPatch(token)) {
110 return super.parseMember(token);
111 }
112 Token patch = token;
113 patchListener.beginPatch(patch);
114 token = super.parseMember(token.next);
115 patchListener.endPatch(patch);
116 return token;
117 }
118 }
119
120
121 /**
122 * Partial parser for patch files that also handles the members of class
123 * declarations.
124 */
125 class PatchClassElementParser extends PatchParser {
126 PatchClassElementParser(PatchListener listener) : super(listener);
127
128 Token parseClassBody(Token token) => fullParseClassBody(token);
129 }
130
131
132 /**
133 * Extension of [ElementListener] for parsing patch files.
134 */
135 class PatchElementListener extends ElementListener implements PatchListener {
136 bool isMemberPatch = false;
137 bool isClassPatch = false;
138 PatchElementListener(DiagnosticListener listener,
139 CompilationUnitElement patchElement,
140 int idGenerator())
141 : super(listener, patchElement, idGenerator);
142
143 void beginPatch(Token token) {
144 if (token.next.stringValue === "class") {
145 isClassPatch = true;
146 } else {
147 isMemberPatch = true;
148 }
149 handleIdentifier(token);
150 }
151
152 void endPatch(Token token) {
153 if (token.next.stringValue === "class") {
154 isClassPatch = false;
155 } else {
156 isMemberPatch = false;
157 }
158 }
159
160 void pushElement(Element element) {
161 if (isMemberPatch || (isClassPatch && element is ClassElement)) {
162 element.addMetadata(popNode());
163 }
164 super.pushElement(element);
165 }
166 }
OLDNEW
« 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