| OLD | NEW |
| 1 // Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file | 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 | 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 part of scanner; | 5 part of scanner; |
| 6 | 6 |
| 7 class ClassElementParser extends PartialParser { | 7 class ClassElementParser extends PartialParser { |
| 8 ClassElementParser(Listener listener) : super(listener); | 8 ClassElementParser(Listener listener) : super(listener); |
| 9 | 9 |
| 10 Token parseClassBody(Token token) => fullParseClassBody(token); | 10 Token parseClassBody(Token token) => fullParseClassBody(token); |
| (...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 92 cachedNode != null ? cachedNode.modifiers : Modifiers.EMPTY; | 92 cachedNode != null ? cachedNode.modifiers : Modifiers.EMPTY; |
| 93 | 93 |
| 94 accept(ElementVisitor visitor) => visitor.visitClassElement(this); | 94 accept(ElementVisitor visitor) => visitor.visitClassElement(this); |
| 95 | 95 |
| 96 PartialClassElement copyWithEnclosing(CompilationUnitElement enclosing) { | 96 PartialClassElement copyWithEnclosing(CompilationUnitElement enclosing) { |
| 97 return new PartialClassElement(name, beginToken, endToken, enclosing, id); | 97 return new PartialClassElement(name, beginToken, endToken, enclosing, id); |
| 98 } | 98 } |
| 99 } | 99 } |
| 100 | 100 |
| 101 class MemberListener extends NodeListener { | 101 class MemberListener extends NodeListener { |
| 102 final ClassElement enclosingElement; | 102 final ClassElement enclosingClass; |
| 103 | 103 |
| 104 MemberListener(DiagnosticListener listener, | 104 MemberListener(DiagnosticListener listener, |
| 105 Element enclosingElement) | 105 ClassElement enclosingElement) |
| 106 : this.enclosingElement = enclosingElement, | 106 : this.enclosingClass = enclosingElement, |
| 107 super(listener, enclosingElement.compilationUnit); | 107 super(listener, enclosingElement.compilationUnit); |
| 108 | 108 |
| 109 bool isConstructorName(Node nameNode) { | 109 bool isConstructorName(Node nameNode) { |
| 110 if (enclosingElement == null || | 110 if (enclosingClass == null || |
| 111 enclosingElement.kind != ElementKind.CLASS) { | 111 enclosingClass.kind != ElementKind.CLASS) { |
| 112 return false; | 112 return false; |
| 113 } | 113 } |
| 114 String name; | 114 String name; |
| 115 if (nameNode.asIdentifier() != null) { | 115 if (nameNode.asIdentifier() != null) { |
| 116 name = nameNode.asIdentifier().source; | 116 name = nameNode.asIdentifier().source; |
| 117 } else { | 117 } else { |
| 118 Send send = nameNode.asSend(); | 118 Send send = nameNode.asSend(); |
| 119 name = send.receiver.asIdentifier().source; | 119 name = send.receiver.asIdentifier().source; |
| 120 } | 120 } |
| 121 return enclosingElement.name == name; | 121 return enclosingClass.name == name; |
| 122 } | 122 } |
| 123 | 123 |
| 124 // TODO(johnniwinther): Remove this method. | 124 // TODO(johnniwinther): Remove this method. |
| 125 String getMethodNameHack(Node methodName) { | 125 String getMethodNameHack(Node methodName) { |
| 126 Send send = methodName.asSend(); | 126 Send send = methodName.asSend(); |
| 127 if (send == null) { | 127 if (send == null) { |
| 128 if (isConstructorName(methodName)) return ''; | 128 if (isConstructorName(methodName)) return ''; |
| 129 return methodName.asIdentifier().source; | 129 return methodName.asIdentifier().source; |
| 130 } | 130 } |
| 131 Identifier receiver = send.receiver.asIdentifier(); | 131 Identifier receiver = send.receiver.asIdentifier(); |
| 132 Identifier selector = send.selector.asIdentifier(); | 132 Identifier selector = send.selector.asIdentifier(); |
| 133 Operator operator = selector.asOperator(); | 133 Operator operator = selector.asOperator(); |
| 134 if (operator != null) { | 134 if (operator != null) { |
| 135 assert(identical(receiver.source, 'operator')); | 135 assert(identical(receiver.source, 'operator')); |
| 136 // TODO(ahe): It is a hack to compare to ')', but it beats | 136 // TODO(ahe): It is a hack to compare to ')', but it beats |
| 137 // parsing the node. | 137 // parsing the node. |
| 138 bool isUnary = identical(operator.token.next.next.stringValue, ')'); | 138 bool isUnary = identical(operator.token.next.next.stringValue, ')'); |
| 139 return Elements.constructOperatorName(operator.source, isUnary); | 139 return Elements.constructOperatorName(operator.source, isUnary); |
| 140 } else { | 140 } else { |
| 141 if (receiver == null || receiver.source != enclosingElement.name) { | 141 if (receiver == null || receiver.source != enclosingClass.name) { |
| 142 listener.reportError(send.receiver, | 142 listener.reportError(send.receiver, |
| 143 MessageKind.INVALID_CONSTRUCTOR_NAME, | 143 MessageKind.INVALID_CONSTRUCTOR_NAME, |
| 144 {'name': enclosingElement.name}); | 144 {'name': enclosingClass.name}); |
| 145 } | 145 } |
| 146 return selector.source; | 146 return selector.source; |
| 147 } | 147 } |
| 148 } | 148 } |
| 149 | 149 |
| 150 void endMethod(Token getOrSet, Token beginToken, Token endToken) { | 150 void endMethod(Token getOrSet, Token beginToken, Token endToken) { |
| 151 super.endMethod(getOrSet, beginToken, endToken); | 151 super.endMethod(getOrSet, beginToken, endToken); |
| 152 FunctionExpression method = popNode(); | 152 FunctionExpression method = popNode(); |
| 153 pushNode(null); | 153 pushNode(null); |
| 154 bool isConstructor = isConstructorName(method.name); | 154 bool isConstructor = isConstructorName(method.name); |
| 155 String name = getMethodNameHack(method.name); | 155 String name = getMethodNameHack(method.name); |
| 156 Element memberElement; | 156 Element memberElement; |
| 157 if (isConstructor) { | 157 if (isConstructor) { |
| 158 if (getOrSet != null) { | 158 if (getOrSet != null) { |
| 159 recoverableError(getOrSet, 'illegal modifier'); | 159 recoverableError(getOrSet, 'illegal modifier'); |
| 160 } | 160 } |
| 161 memberElement = new PartialConstructorElement( | 161 memberElement = new PartialConstructorElement( |
| 162 name, beginToken, endToken, | 162 name, beginToken, endToken, |
| 163 ElementKind.GENERATIVE_CONSTRUCTOR, | 163 ElementKind.GENERATIVE_CONSTRUCTOR, |
| 164 method.modifiers, | 164 method.modifiers, |
| 165 enclosingElement); | 165 enclosingClass); |
| 166 } else { | 166 } else { |
| 167 ElementKind kind = ElementKind.FUNCTION; | 167 ElementKind kind = ElementKind.FUNCTION; |
| 168 if (getOrSet != null) { | 168 if (getOrSet != null) { |
| 169 kind = (identical(getOrSet.stringValue, 'get')) | 169 kind = (identical(getOrSet.stringValue, 'get')) |
| 170 ? ElementKind.GETTER : ElementKind.SETTER; | 170 ? ElementKind.GETTER : ElementKind.SETTER; |
| 171 } | 171 } |
| 172 memberElement = | 172 memberElement = |
| 173 new PartialFunctionElement(name, beginToken, getOrSet, endToken, | 173 new PartialFunctionElement(name, beginToken, getOrSet, endToken, |
| 174 kind, method.modifiers, enclosingElement, | 174 kind, method.modifiers, enclosingClass, |
| 175 !method.hasBody()); | 175 !method.hasBody()); |
| 176 } | 176 } |
| 177 addMember(memberElement); | 177 addMember(memberElement); |
| 178 } | 178 } |
| 179 | 179 |
| 180 void endFactoryMethod(Token beginToken, Token endToken) { | 180 void endFactoryMethod(Token beginToken, Token endToken) { |
| 181 super.endFactoryMethod(beginToken, endToken); | 181 super.endFactoryMethod(beginToken, endToken); |
| 182 FunctionExpression method = popNode(); | 182 FunctionExpression method = popNode(); |
| 183 pushNode(null); | 183 pushNode(null); |
| 184 String name = getMethodNameHack(method.name); | 184 String name = getMethodNameHack(method.name); |
| 185 Identifier singleIdentifierName = method.name.asIdentifier(); | 185 Identifier singleIdentifierName = method.name.asIdentifier(); |
| 186 if (singleIdentifierName != null && singleIdentifierName.source == name) { | 186 if (singleIdentifierName != null && singleIdentifierName.source == name) { |
| 187 if (name != enclosingElement.name) { | 187 if (name != enclosingClass.name) { |
| 188 listener.reportError(singleIdentifierName, | 188 listener.reportError(singleIdentifierName, |
| 189 MessageKind.INVALID_UNNAMED_CONSTRUCTOR_NAME, | 189 MessageKind.INVALID_UNNAMED_CONSTRUCTOR_NAME, |
| 190 {'name': enclosingElement.name}); | 190 {'name': enclosingClass.name}); |
| 191 } | 191 } |
| 192 } | 192 } |
| 193 ElementKind kind = ElementKind.FUNCTION; | 193 ElementKind kind = ElementKind.FUNCTION; |
| 194 Element memberElement = new PartialConstructorElement( | 194 Element memberElement = new PartialConstructorElement( |
| 195 name, beginToken, endToken, | 195 name, beginToken, endToken, |
| 196 ElementKind.FUNCTION, | 196 ElementKind.FUNCTION, |
| 197 method.modifiers, | 197 method.modifiers, |
| 198 enclosingElement); | 198 enclosingClass); |
| 199 addMember(memberElement); | 199 addMember(memberElement); |
| 200 } | 200 } |
| 201 | 201 |
| 202 void endFields(int count, Token beginToken, Token endToken) { | 202 void endFields(int count, Token beginToken, Token endToken) { |
| 203 bool hasParseError = memberErrors.head; | 203 bool hasParseError = memberErrors.head; |
| 204 super.endFields(count, beginToken, endToken); | 204 super.endFields(count, beginToken, endToken); |
| 205 VariableDefinitions variableDefinitions = popNode(); | 205 VariableDefinitions variableDefinitions = popNode(); |
| 206 Modifiers modifiers = variableDefinitions.modifiers; | 206 Modifiers modifiers = variableDefinitions.modifiers; |
| 207 pushNode(null); | 207 pushNode(null); |
| 208 void buildFieldElement(Identifier name, VariableList fields) { | 208 void buildFieldElement(Identifier name, VariableList fields) { |
| 209 Element element = | 209 Element element = |
| 210 new FieldElementX(name, enclosingElement, fields); | 210 new FieldElementX(name, enclosingClass, fields); |
| 211 addMember(element); | 211 addMember(element); |
| 212 } | 212 } |
| 213 buildFieldElements(modifiers, variableDefinitions.definitions, | 213 buildFieldElements(modifiers, variableDefinitions.definitions, |
| 214 enclosingElement, | 214 enclosingClass, |
| 215 buildFieldElement, beginToken, endToken, | 215 buildFieldElement, beginToken, endToken, |
| 216 hasParseError); | 216 hasParseError); |
| 217 } | 217 } |
| 218 | 218 |
| 219 void endInitializer(Token assignmentOperator) { | 219 void endInitializer(Token assignmentOperator) { |
| 220 pushNode(null); // Super expects an expression, but | 220 pushNode(null); // Super expects an expression, but |
| 221 // ClassElementParser just skips expressions. | 221 // ClassElementParser just skips expressions. |
| 222 super.endInitializer(assignmentOperator); | 222 super.endInitializer(assignmentOperator); |
| 223 } | 223 } |
| 224 | 224 |
| 225 void endInitializers(int count, Token beginToken, Token endToken) { | 225 void endInitializers(int count, Token beginToken, Token endToken) { |
| 226 pushNode(null); | 226 pushNode(null); |
| 227 } | 227 } |
| 228 | 228 |
| 229 void addMember(Element memberElement) { | 229 void addMetadata(Element memberElement) { |
| 230 for (Link link = metadata; !link.isEmpty; link = link.tail) { | 230 for (Link link = metadata; !link.isEmpty; link = link.tail) { |
| 231 memberElement.addMetadata(link.head); | 231 memberElement.addMetadata(link.head); |
| 232 } | 232 } |
| 233 metadata = const Link<MetadataAnnotation>(); | 233 metadata = const Link<MetadataAnnotation>(); |
| 234 enclosingElement.addMember(memberElement, listener); | 234 } |
| 235 |
| 236 void addMember(Element memberElement) { |
| 237 addMetadata(memberElement); |
| 238 enclosingClass.addMember(memberElement, listener); |
| 235 } | 239 } |
| 236 | 240 |
| 237 void endMetadata(Token beginToken, Token periodBeforeName, Token endToken) { | 241 void endMetadata(Token beginToken, Token periodBeforeName, Token endToken) { |
| 238 popNode(); // Discard arguments. | 242 popNode(); // Discard arguments. |
| 239 if (periodBeforeName != null) { | 243 if (periodBeforeName != null) { |
| 240 popNode(); // Discard name. | 244 popNode(); // Discard name. |
| 241 } | 245 } |
| 242 popNode(); // Discard node (Send or Identifier). | 246 popNode(); // Discard node (Send or Identifier). |
| 243 pushMetadata(new PartialMetadataAnnotation(beginToken, endToken)); | 247 pushMetadata(new PartialMetadataAnnotation(beginToken, endToken)); |
| 244 } | 248 } |
| 245 } | 249 } |
| OLD | NEW |