Index: pkg/compiler/lib/src/parser/class_element_parser.dart |
diff --git a/pkg/compiler/lib/src/parser/class_element_parser.dart b/pkg/compiler/lib/src/parser/class_element_parser.dart |
index 6a72ad0f3f3538f0615aaf2e261595566b897e7c..745665d07b404ea753de06d4553348c8ebea23df 100644 |
--- a/pkg/compiler/lib/src/parser/class_element_parser.dart |
+++ b/pkg/compiler/lib/src/parser/class_element_parser.dart |
@@ -4,45 +4,11 @@ |
library dart2js.parser.classes; |
-import '../compiler.dart' show |
- Compiler; |
-import '../diagnostics/diagnostic_listener.dart' show |
- DiagnosticListener; |
-import '../diagnostics/messages.dart' show |
- MessageKind; |
-import '../diagnostics/invariant.dart' show |
- invariant; |
-import '../elements/elements.dart' show |
- CompilationUnitElement, |
- Element, |
- ElementKind, |
- Elements, |
- MetadataAnnotation, |
- STATE_NOT_STARTED, |
- STATE_DONE; |
-import '../elements/modelx.dart' show |
- ClassElementX, |
- ElementX, |
- FieldElementX, |
- VariableList; |
-import '../elements/visitor.dart' show |
- ElementVisitor; |
import '../tokens/token.dart' show |
Token; |
-import '../tree/tree.dart'; |
-import '../util/util.dart' show |
- Link; |
import 'listener.dart' show |
- Listener, |
- NodeListener, |
- ParserError, |
- PartialConstructorElement, |
- PartialElement, |
- PartialFunctionElement, |
- PartialMetadataAnnotation; |
-import 'parser.dart' show |
- Parser; |
+ Listener; |
import 'partial_parser.dart' show |
PartialParser; |
@@ -51,236 +17,3 @@ class ClassElementParser extends PartialParser { |
Token parseClassBody(Token token) => fullParseClassBody(token); |
} |
- |
-class PartialClassElement extends ClassElementX with PartialElement { |
Johnni Winther
2015/09/02 13:14:41
Moved to partial_elements.dart
|
- ClassNode cachedNode; |
- |
- PartialClassElement(String name, |
- Token beginToken, |
- Token endToken, |
- Element enclosing, |
- int id) |
- : super(name, enclosing, id, STATE_NOT_STARTED) { |
- this.beginToken = beginToken; |
- this.endToken = endToken; |
- } |
- |
- void set supertypeLoadState(int state) { |
- assert(state == STATE_NOT_STARTED || state == supertypeLoadState + 1); |
- assert(state <= STATE_DONE); |
- super.supertypeLoadState = state; |
- } |
- |
- void set resolutionState(int state) { |
- assert(state == STATE_NOT_STARTED || state == resolutionState + 1); |
- assert(state <= STATE_DONE); |
- super.resolutionState = state; |
- } |
- |
- bool get hasNode => cachedNode != null; |
- |
- ClassNode get node { |
- assert(invariant(this, cachedNode != null, |
- message: "Node has not been computed for $this.")); |
- return cachedNode; |
- } |
- |
- ClassNode parseNode(Compiler compiler) { |
- if (cachedNode != null) return cachedNode; |
- compiler.withCurrentElement(this, () { |
- compiler.parser.measure(() { |
- MemberListener listener = new MemberListener(compiler, this); |
- Parser parser = new ClassElementParser(listener); |
- try { |
- Token token = parser.parseTopLevelDeclaration(beginToken); |
- assert(identical(token, endToken.next)); |
- cachedNode = listener.popNode(); |
- assert( |
- invariant( |
- beginToken, listener.nodes.isEmpty, |
- message: "Non-empty listener stack: ${listener.nodes}")); |
- } on ParserError { |
- // TODO(ahe): Often, a ParserError is thrown while parsing the class |
- // body. This means that the stack actually contains most of the |
- // information synthesized below. Consider rewriting the parser so |
- // endClassDeclaration is called before parsing the class body. |
- Identifier name = new Identifier(findMyName(beginToken)); |
- NodeList typeParameters = null; |
- Node supertype = null; |
- NodeList interfaces = listener.makeNodeList(0, null, null, ","); |
- Token extendsKeyword = null; |
- NodeList body = listener.makeNodeList(0, beginToken, endToken, null); |
- cachedNode = new ClassNode( |
- Modifiers.EMPTY, name, typeParameters, supertype, interfaces, |
- beginToken, extendsKeyword, body, endToken); |
- hasParseError = true; |
- } |
- }); |
- compiler.patchParser.measure(() { |
- if (isPatched) { |
- // TODO(lrn): Perhaps extract functionality so it doesn't |
- // need compiler. |
- compiler.patchParser.parsePatchClassNode(patch); |
- } |
- }); |
- }); |
- return cachedNode; |
- } |
- |
- Token get position => beginToken; |
- |
- // TODO(johnniwinther): Ensure that modifiers are always available. |
- Modifiers get modifiers => |
- cachedNode != null ? cachedNode.modifiers : Modifiers.EMPTY; |
- |
- accept(ElementVisitor visitor, arg) { |
- return visitor.visitClassElement(this, arg); |
- } |
- |
- PartialClassElement copyWithEnclosing(CompilationUnitElement enclosing) { |
- return new PartialClassElement(name, beginToken, endToken, enclosing, id); |
- } |
-} |
- |
-class MemberListener extends NodeListener { |
- final ClassElementX enclosingClass; |
- |
- MemberListener(DiagnosticListener listener, |
- ClassElementX enclosingElement) |
- : this.enclosingClass = enclosingElement, |
- super(listener, enclosingElement.compilationUnit); |
- |
- bool isConstructorName(Node nameNode) { |
- if (enclosingClass == null || |
- enclosingClass.kind != ElementKind.CLASS) { |
- return false; |
- } |
- String name; |
- if (nameNode.asIdentifier() != null) { |
- name = nameNode.asIdentifier().source; |
- } else { |
- Send send = nameNode.asSend(); |
- name = send.receiver.asIdentifier().source; |
- } |
- return enclosingClass.name == name; |
- } |
- |
- // TODO(johnniwinther): Remove this method. |
- String getMethodNameHack(Node methodName) { |
- Send send = methodName.asSend(); |
- if (send == null) { |
- if (isConstructorName(methodName)) return ''; |
- return methodName.asIdentifier().source; |
- } |
- Identifier receiver = send.receiver.asIdentifier(); |
- Identifier selector = send.selector.asIdentifier(); |
- Operator operator = selector.asOperator(); |
- if (operator != null) { |
- assert(identical(receiver.source, 'operator')); |
- // TODO(ahe): It is a hack to compare to ')', but it beats |
- // parsing the node. |
- bool isUnary = identical(operator.token.next.next.stringValue, ')'); |
- return Elements.constructOperatorName(operator.source, isUnary); |
- } else { |
- if (receiver == null || receiver.source != enclosingClass.name) { |
- listener.reportError(send.receiver, |
- MessageKind.INVALID_CONSTRUCTOR_NAME, |
- {'name': enclosingClass.name}); |
- } |
- return selector.source; |
- } |
- } |
- |
- void endMethod(Token getOrSet, Token beginToken, Token endToken) { |
- super.endMethod(getOrSet, beginToken, endToken); |
- FunctionExpression method = popNode(); |
- pushNode(null); |
- bool isConstructor = isConstructorName(method.name); |
- String name = getMethodNameHack(method.name); |
- Element memberElement; |
- if (isConstructor) { |
- if (getOrSet != null) { |
- recoverableError(getOrSet, 'illegal modifier'); |
- } |
- memberElement = new PartialConstructorElement( |
- name, beginToken, endToken, |
- ElementKind.GENERATIVE_CONSTRUCTOR, |
- method.modifiers, |
- enclosingClass); |
- } else { |
- memberElement = new PartialFunctionElement( |
- name, beginToken, getOrSet, endToken, |
- method.modifiers, enclosingClass, hasBody: method.hasBody()); |
- } |
- addMember(memberElement); |
- } |
- |
- void endFactoryMethod(Token beginToken, Token endToken) { |
- super.endFactoryMethod(beginToken, endToken); |
- FunctionExpression method = popNode(); |
- pushNode(null); |
- String name = getMethodNameHack(method.name); |
- Identifier singleIdentifierName = method.name.asIdentifier(); |
- if (singleIdentifierName != null && singleIdentifierName.source == name) { |
- if (name != enclosingClass.name) { |
- listener.reportError(singleIdentifierName, |
- MessageKind.INVALID_UNNAMED_CONSTRUCTOR_NAME, |
- {'name': enclosingClass.name}); |
- } |
- } |
- Element memberElement = new PartialConstructorElement( |
- name, beginToken, endToken, |
- ElementKind.FUNCTION, |
- method.modifiers, |
- enclosingClass); |
- addMember(memberElement); |
- } |
- |
- void endFields(int count, Token beginToken, Token endToken) { |
- bool hasParseError = memberErrors.head; |
- super.endFields(count, beginToken, endToken); |
- VariableDefinitions variableDefinitions = popNode(); |
- Modifiers modifiers = variableDefinitions.modifiers; |
- pushNode(null); |
- void buildFieldElement(Identifier name, VariableList fields) { |
- Element element = |
- new FieldElementX(name, enclosingClass, fields); |
- addMember(element); |
- } |
- buildFieldElements(modifiers, variableDefinitions.definitions, |
- enclosingClass, |
- buildFieldElement, beginToken, endToken, |
- hasParseError); |
- } |
- |
- void endInitializer(Token assignmentOperator) { |
- pushNode(null); // Super expects an expression, but |
- // ClassElementParser just skips expressions. |
- super.endInitializer(assignmentOperator); |
- } |
- |
- void endInitializers(int count, Token beginToken, Token endToken) { |
- pushNode(null); |
- } |
- |
- void addMetadata(ElementX memberElement) { |
- for (Link link = metadata; !link.isEmpty; link = link.tail) { |
- memberElement.addMetadata(link.head); |
- } |
- metadata = const Link<MetadataAnnotation>(); |
- } |
- |
- void addMember(ElementX memberElement) { |
- addMetadata(memberElement); |
- enclosingClass.addMember(memberElement, listener); |
- } |
- |
- void endMetadata(Token beginToken, Token periodBeforeName, Token endToken) { |
- popNode(); // Discard arguments. |
- if (periodBeforeName != null) { |
- popNode(); // Discard name. |
- } |
- popNode(); // Discard node (Send or Identifier). |
- pushMetadata(new PartialMetadataAnnotation(beginToken, endToken)); |
- } |
-} |