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

Side by Side Diff: sdk/lib/_internal/compiler/implementation/scanner/class_element_parser.dart

Issue 694353007: Move dart2js from sdk/lib/_internal/compiler to pkg/compiler (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 6 years, 1 month 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
OLDNEW
(Empty)
1 // Copyright (c) 2011, 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 part of scanner;
6
7 class ClassElementParser extends PartialParser {
8 ClassElementParser(Listener listener) : super(listener);
9
10 Token parseClassBody(Token token) => fullParseClassBody(token);
11 }
12
13 class PartialClassElement extends ClassElementX with PartialElement {
14 ClassNode cachedNode;
15
16 PartialClassElement(String name,
17 Token beginToken,
18 Token endToken,
19 Element enclosing,
20 int id)
21 : super(name, enclosing, id, STATE_NOT_STARTED) {
22 this.beginToken = beginToken;
23 this.endToken = endToken;
24 }
25
26 void set supertypeLoadState(int state) {
27 assert(state == supertypeLoadState + 1);
28 assert(state <= STATE_DONE);
29 super.supertypeLoadState = state;
30 }
31
32 void set resolutionState(int state) {
33 assert(state == resolutionState + 1);
34 assert(state <= STATE_DONE);
35 super.resolutionState = state;
36 }
37
38 bool get hasNode => cachedNode != null;
39
40 ClassNode get node {
41 assert(invariant(this, cachedNode != null,
42 message: "Node has not been computed for $this."));
43 return cachedNode;
44 }
45
46 ClassNode parseNode(Compiler compiler) {
47 if (cachedNode != null) return cachedNode;
48 compiler.withCurrentElement(this, () {
49 compiler.parser.measure(() {
50 MemberListener listener = new MemberListener(compiler, this);
51 Parser parser = new ClassElementParser(listener);
52 Token token = parser.parseTopLevelDeclaration(beginToken);
53 assert(identical(token, endToken.next));
54 cachedNode = listener.popNode();
55 assert(invariant(beginToken, listener.nodes.isEmpty,
56 message: "Non-empty listener stack: ${listener.nodes}"));
57 });
58 compiler.patchParser.measure(() {
59 if (isPatched) {
60 // TODO(lrn): Perhaps extract functionality so it doesn't
61 // need compiler.
62 compiler.patchParser.parsePatchClassNode(patch);
63 }
64 });
65 });
66 return cachedNode;
67 }
68
69 Token get position => beginToken;
70
71 // TODO(johnniwinther): Ensure that modifiers are always available.
72 Modifiers get modifiers =>
73 cachedNode != null ? cachedNode.modifiers : Modifiers.EMPTY;
74
75 accept(ElementVisitor visitor) => visitor.visitClassElement(this);
76 }
77
78 class MemberListener extends NodeListener {
79 final ClassElement enclosingElement;
80
81 MemberListener(DiagnosticListener listener,
82 Element enclosingElement)
83 : this.enclosingElement = enclosingElement,
84 super(listener, enclosingElement.compilationUnit);
85
86 bool isConstructorName(Node nameNode) {
87 if (enclosingElement == null ||
88 enclosingElement.kind != ElementKind.CLASS) {
89 return false;
90 }
91 String name;
92 if (nameNode.asIdentifier() != null) {
93 name = nameNode.asIdentifier().source;
94 } else {
95 Send send = nameNode.asSend();
96 name = send.receiver.asIdentifier().source;
97 }
98 return enclosingElement.name == name;
99 }
100
101 // TODO(johnniwinther): Remove this method.
102 String getMethodNameHack(Node methodName) {
103 Send send = methodName.asSend();
104 if (send == null) {
105 if (isConstructorName(methodName)) return '';
106 return methodName.asIdentifier().source;
107 }
108 Identifier receiver = send.receiver.asIdentifier();
109 Identifier selector = send.selector.asIdentifier();
110 Operator operator = selector.asOperator();
111 if (operator != null) {
112 assert(identical(receiver.source, 'operator'));
113 // TODO(ahe): It is a hack to compare to ')', but it beats
114 // parsing the node.
115 bool isUnary = identical(operator.token.next.next.stringValue, ')');
116 return Elements.constructOperatorName(operator.source, isUnary);
117 } else {
118 if (receiver == null || receiver.source != enclosingElement.name) {
119 listener.reportError(send.receiver,
120 MessageKind.INVALID_CONSTRUCTOR_NAME,
121 {'name': enclosingElement.name});
122 }
123 return selector.source;
124 }
125 }
126
127 void endMethod(Token getOrSet, Token beginToken, Token endToken) {
128 super.endMethod(getOrSet, beginToken, endToken);
129 FunctionExpression method = popNode();
130 pushNode(null);
131 bool isConstructor = isConstructorName(method.name);
132 String name = getMethodNameHack(method.name);
133 Element memberElement;
134 if (isConstructor) {
135 if (getOrSet != null) {
136 recoverableError(getOrSet, 'illegal modifier');
137 }
138 memberElement = new PartialConstructorElement(
139 name, beginToken, endToken,
140 ElementKind.GENERATIVE_CONSTRUCTOR,
141 method.modifiers,
142 enclosingElement);
143 } else {
144 ElementKind kind = ElementKind.FUNCTION;
145 if (getOrSet != null) {
146 kind = (identical(getOrSet.stringValue, 'get'))
147 ? ElementKind.GETTER : ElementKind.SETTER;
148 }
149 memberElement =
150 new PartialFunctionElement(name, beginToken, getOrSet, endToken,
151 kind, method.modifiers, enclosingElement,
152 !method.hasBody());
153 }
154 addMember(memberElement);
155 }
156
157 void endFactoryMethod(Token beginToken, Token endToken) {
158 super.endFactoryMethod(beginToken, endToken);
159 FunctionExpression method = popNode();
160 pushNode(null);
161 String name = getMethodNameHack(method.name);
162 Identifier singleIdentifierName = method.name.asIdentifier();
163 if (singleIdentifierName != null && singleIdentifierName.source == name) {
164 if (name != enclosingElement.name) {
165 listener.reportError(singleIdentifierName,
166 MessageKind.INVALID_UNNAMED_CONSTRUCTOR_NAME,
167 {'name': enclosingElement.name});
168 }
169 }
170 ElementKind kind = ElementKind.FUNCTION;
171 Element memberElement = new PartialConstructorElement(
172 name, beginToken, endToken,
173 ElementKind.FUNCTION,
174 method.modifiers,
175 enclosingElement);
176 addMember(memberElement);
177 }
178
179 void endFields(int count, Token beginToken, Token endToken) {
180 bool hasParseError = memberErrors.head;
181 super.endFields(count, beginToken, endToken);
182 VariableDefinitions variableDefinitions = popNode();
183 Modifiers modifiers = variableDefinitions.modifiers;
184 pushNode(null);
185 void buildFieldElement(Identifier name, VariableList fields) {
186 Element element =
187 new FieldElementX(name, enclosingElement, fields);
188 addMember(element);
189 }
190 buildFieldElements(modifiers, variableDefinitions.definitions,
191 enclosingElement,
192 buildFieldElement, beginToken, endToken,
193 hasParseError);
194 }
195
196 void endInitializer(Token assignmentOperator) {
197 pushNode(null); // Super expects an expression, but
198 // ClassElementParser just skips expressions.
199 super.endInitializer(assignmentOperator);
200 }
201
202 void endInitializers(int count, Token beginToken, Token endToken) {
203 pushNode(null);
204 }
205
206 void addMember(Element memberElement) {
207 for (Link link = metadata; !link.isEmpty; link = link.tail) {
208 memberElement.addMetadata(link.head);
209 }
210 metadata = const Link<MetadataAnnotation>();
211 enclosingElement.addMember(memberElement, listener);
212 }
213
214 void endMetadata(Token beginToken, Token periodBeforeName, Token endToken) {
215 popNode(); // Discard arguments.
216 if (periodBeforeName != null) {
217 popNode(); // Discard name.
218 }
219 popNode(); // Discard node (Send or Identifier).
220 pushMetadata(new PartialMetadataAnnotation(beginToken, endToken));
221 }
222 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698