| OLD | NEW |
| 1 // Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2015, 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 library dart2js.parser.partial_elements; | 5 library dart2js.parser.partial_elements; |
| 6 | 6 |
| 7 import '../common.dart'; | 7 import '../common.dart'; |
| 8 import '../common/resolution.dart' show | 8 import '../common/resolution.dart' show Parsing, Resolution; |
| 9 Parsing, | |
| 10 Resolution; | |
| 11 import '../dart_types.dart' show DynamicType; | 9 import '../dart_types.dart' show DynamicType; |
| 12 import '../elements/elements.dart' show | 10 import '../elements/elements.dart' |
| 13 CompilationUnitElement, | 11 show |
| 14 ConstructorElement, | 12 CompilationUnitElement, |
| 15 Element, | 13 ConstructorElement, |
| 16 ElementKind, | 14 Element, |
| 17 GetterElement, | 15 ElementKind, |
| 18 LibraryElement, | 16 GetterElement, |
| 19 MetadataAnnotation, | 17 LibraryElement, |
| 20 MethodElement, | 18 MetadataAnnotation, |
| 21 SetterElement, | 19 MethodElement, |
| 22 STATE_NOT_STARTED, | 20 SetterElement, |
| 23 STATE_DONE; | 21 STATE_NOT_STARTED, |
| 24 import '../elements/modelx.dart' show | 22 STATE_DONE; |
| 25 BaseFunctionElementX, | 23 import '../elements/modelx.dart' |
| 26 ClassElementX, | 24 show |
| 27 ConstructorElementX, | 25 BaseFunctionElementX, |
| 28 DeclarationSite, | 26 ClassElementX, |
| 29 ElementX, | 27 ConstructorElementX, |
| 30 FieldElementX, | 28 DeclarationSite, |
| 31 GetterElementX, | 29 ElementX, |
| 32 MetadataAnnotationX, | 30 FieldElementX, |
| 33 MethodElementX, | 31 GetterElementX, |
| 34 SetterElementX, | 32 MetadataAnnotationX, |
| 35 TypedefElementX, | 33 MethodElementX, |
| 36 VariableList; | 34 SetterElementX, |
| 37 import '../elements/visitor.dart' show | 35 TypedefElementX, |
| 38 ElementVisitor; | 36 VariableList; |
| 39 import '../tokens/token.dart' show | 37 import '../elements/visitor.dart' show ElementVisitor; |
| 40 BadInputToken, | 38 import '../tokens/token.dart' |
| 41 BeginGroupToken, | 39 show |
| 42 ErrorToken, | 40 BadInputToken, |
| 43 KeywordToken, | 41 BeginGroupToken, |
| 44 StringToken, | 42 ErrorToken, |
| 45 Token, | 43 KeywordToken, |
| 46 UnmatchedToken, | 44 StringToken, |
| 47 UnterminatedToken; | 45 Token, |
| 48 import '../tokens/token_constants.dart' as Tokens show | 46 UnmatchedToken, |
| 49 EOF_TOKEN; | 47 UnterminatedToken; |
| 48 import '../tokens/token_constants.dart' as Tokens show EOF_TOKEN; |
| 50 import '../tree/tree.dart'; | 49 import '../tree/tree.dart'; |
| 51 | 50 |
| 52 import 'class_element_parser.dart' show | 51 import 'class_element_parser.dart' show ClassElementParser; |
| 53 ClassElementParser; | 52 import 'parser.dart' show Parser; |
| 54 import 'parser.dart' show | 53 import 'listener.dart' show ParserError; |
| 55 Parser; | 54 import 'member_listener.dart' show MemberListener; |
| 56 import 'listener.dart' show | 55 import 'node_listener.dart' show NodeListener; |
| 57 ParserError; | |
| 58 import 'member_listener.dart' show | |
| 59 MemberListener; | |
| 60 import 'node_listener.dart' show | |
| 61 NodeListener; | |
| 62 | 56 |
| 63 abstract class PartialElement implements DeclarationSite { | 57 abstract class PartialElement implements DeclarationSite { |
| 64 Token beginToken; | 58 Token beginToken; |
| 65 Token endToken; | 59 Token endToken; |
| 66 | 60 |
| 67 bool hasParseError = false; | 61 bool hasParseError = false; |
| 68 | 62 |
| 69 bool get isMalformed => hasParseError; | 63 bool get isMalformed => hasParseError; |
| 70 | 64 |
| 71 DeclarationSite get declarationSite => this; | 65 DeclarationSite get declarationSite => this; |
| (...skipping 12 matching lines...) Expand all Loading... |
| 84 */ | 78 */ |
| 85 Token _position; | 79 Token _position; |
| 86 | 80 |
| 87 void init(Token beginToken, Token getOrSet, Token endToken) { | 81 void init(Token beginToken, Token getOrSet, Token endToken) { |
| 88 this.beginToken = beginToken; | 82 this.beginToken = beginToken; |
| 89 this.getOrSet = getOrSet; | 83 this.getOrSet = getOrSet; |
| 90 this.endToken = endToken; | 84 this.endToken = endToken; |
| 91 _position = ElementX.findNameToken( | 85 _position = ElementX.findNameToken( |
| 92 beginToken, | 86 beginToken, |
| 93 modifiers.isFactory || isGenerativeConstructor, | 87 modifiers.isFactory || isGenerativeConstructor, |
| 94 name, enclosingElement.name); | 88 name, |
| 89 enclosingElement.name); |
| 95 } | 90 } |
| 96 | 91 |
| 97 bool get hasNode => cachedNode != null; | 92 bool get hasNode => cachedNode != null; |
| 98 | 93 |
| 99 FunctionExpression get node { | 94 FunctionExpression get node { |
| 100 assert(invariant(this, cachedNode != null, | 95 assert(invariant(this, cachedNode != null, |
| 101 message: "Node has not been computed for $this.")); | 96 message: "Node has not been computed for $this.")); |
| 102 return cachedNode; | 97 return cachedNode; |
| 103 } | 98 } |
| 104 | 99 |
| (...skipping 14 matching lines...) Expand all Loading... |
| 119 | 114 |
| 120 void reusePartialFunctionMixin() { | 115 void reusePartialFunctionMixin() { |
| 121 cachedNode = null; | 116 cachedNode = null; |
| 122 } | 117 } |
| 123 | 118 |
| 124 DeclarationSite get declarationSite; | 119 DeclarationSite get declarationSite; |
| 125 } | 120 } |
| 126 | 121 |
| 127 abstract class PartialFunctionElement | 122 abstract class PartialFunctionElement |
| 128 implements PartialElement, PartialFunctionMixin { | 123 implements PartialElement, PartialFunctionMixin { |
| 129 | 124 factory PartialFunctionElement(String name, Token beginToken, Token getOrSet, |
| 130 factory PartialFunctionElement( | 125 Token endToken, Modifiers modifiers, Element enclosingElement, |
| 131 String name, | |
| 132 Token beginToken, | |
| 133 Token getOrSet, | |
| 134 Token endToken, | |
| 135 Modifiers modifiers, | |
| 136 Element enclosingElement, | |
| 137 {bool hasBody: true}) { | 126 {bool hasBody: true}) { |
| 138 if (getOrSet == null) { | 127 if (getOrSet == null) { |
| 139 return new PartialMethodElement( | 128 return new PartialMethodElement( |
| 140 name, beginToken, endToken, modifiers, | 129 name, beginToken, endToken, modifiers, enclosingElement, |
| 141 enclosingElement, hasBody: hasBody); | 130 hasBody: hasBody); |
| 142 } else if (identical(getOrSet.stringValue, 'get')) { | 131 } else if (identical(getOrSet.stringValue, 'get')) { |
| 143 return new PartialGetterElement( | 132 return new PartialGetterElement( |
| 144 name, beginToken, getOrSet, endToken, modifiers, | 133 name, beginToken, getOrSet, endToken, modifiers, enclosingElement, |
| 145 enclosingElement, hasBody: hasBody); | 134 hasBody: hasBody); |
| 146 } else { | 135 } else { |
| 147 assert(identical(getOrSet.stringValue, 'set')); | 136 assert(identical(getOrSet.stringValue, 'set')); |
| 148 return new PartialSetterElement( | 137 return new PartialSetterElement( |
| 149 name, beginToken, getOrSet, endToken, modifiers, | 138 name, beginToken, getOrSet, endToken, modifiers, enclosingElement, |
| 150 enclosingElement, hasBody: hasBody); | 139 hasBody: hasBody); |
| 151 } | 140 } |
| 152 } | 141 } |
| 153 | 142 |
| 154 PartialFunctionElement copyWithEnclosing(Element enclosing); | 143 PartialFunctionElement copyWithEnclosing(Element enclosing); |
| 155 } | 144 } |
| 156 | 145 |
| 157 | |
| 158 class PartialMethodElement extends MethodElementX | 146 class PartialMethodElement extends MethodElementX |
| 159 with PartialElement, PartialFunctionMixin | 147 with PartialElement, PartialFunctionMixin |
| 160 implements PartialFunctionElement { | 148 implements PartialFunctionElement { |
| 161 PartialMethodElement(String name, | 149 PartialMethodElement(String name, Token beginToken, Token endToken, |
| 162 Token beginToken, | 150 Modifiers modifiers, Element enclosing, |
| 163 Token endToken, | 151 {bool hasBody: true}) |
| 164 Modifiers modifiers, | |
| 165 Element enclosing, | |
| 166 {bool hasBody: true}) | |
| 167 : super(name, ElementKind.FUNCTION, modifiers, enclosing, hasBody) { | 152 : super(name, ElementKind.FUNCTION, modifiers, enclosing, hasBody) { |
| 168 init(beginToken, null, endToken); | 153 init(beginToken, null, endToken); |
| 169 } | 154 } |
| 170 | 155 |
| 171 void reuseElement() { | 156 void reuseElement() { |
| 172 super.reuseElement(); | 157 super.reuseElement(); |
| 173 reusePartialFunctionMixin(); | 158 reusePartialFunctionMixin(); |
| 174 } | 159 } |
| 175 | 160 |
| 176 PartialMethodElement copyWithEnclosing(Element enclosing) { | 161 PartialMethodElement copyWithEnclosing(Element enclosing) { |
| 177 return new PartialMethodElement( | 162 return new PartialMethodElement( |
| 178 name, beginToken, endToken, modifiers, enclosing, hasBody: hasBody); | 163 name, beginToken, endToken, modifiers, enclosing, |
| 164 hasBody: hasBody); |
| 179 } | 165 } |
| 180 } | 166 } |
| 181 | 167 |
| 182 class PartialGetterElement extends GetterElementX | 168 class PartialGetterElement extends GetterElementX |
| 183 with PartialElement, PartialFunctionMixin | 169 with PartialElement, PartialFunctionMixin |
| 184 implements GetterElement, PartialFunctionElement { | 170 implements GetterElement, PartialFunctionElement { |
| 185 PartialGetterElement(String name, | 171 PartialGetterElement(String name, Token beginToken, Token getToken, |
| 186 Token beginToken, | 172 Token endToken, Modifiers modifiers, Element enclosing, |
| 187 Token getToken, | 173 {bool hasBody: true}) |
| 188 Token endToken, | |
| 189 Modifiers modifiers, | |
| 190 Element enclosing, | |
| 191 {bool hasBody: true}) | |
| 192 : super(name, modifiers, enclosing, hasBody) { | 174 : super(name, modifiers, enclosing, hasBody) { |
| 193 init(beginToken, getToken, endToken); | 175 init(beginToken, getToken, endToken); |
| 194 } | 176 } |
| 195 | 177 |
| 196 @override | 178 @override |
| 197 SetterElement get setter => abstractField.setter; | 179 SetterElement get setter => abstractField.setter; |
| 198 | 180 |
| 199 void reuseElement() { | 181 void reuseElement() { |
| 200 super.reuseElement(); | 182 super.reuseElement(); |
| 201 reusePartialFunctionMixin(); | 183 reusePartialFunctionMixin(); |
| 202 } | 184 } |
| 203 | 185 |
| 204 PartialGetterElement copyWithEnclosing(Element enclosing) { | 186 PartialGetterElement copyWithEnclosing(Element enclosing) { |
| 205 return new PartialGetterElement( | 187 return new PartialGetterElement( |
| 206 name, beginToken, getOrSet, endToken, modifiers, enclosing, | 188 name, beginToken, getOrSet, endToken, modifiers, enclosing, |
| 207 hasBody: hasBody); | 189 hasBody: hasBody); |
| 208 } | 190 } |
| 209 } | 191 } |
| 210 | 192 |
| 211 class PartialSetterElement extends SetterElementX | 193 class PartialSetterElement extends SetterElementX |
| 212 with PartialElement, PartialFunctionMixin | 194 with PartialElement, PartialFunctionMixin |
| 213 implements SetterElement, PartialFunctionElement { | 195 implements SetterElement, PartialFunctionElement { |
| 214 PartialSetterElement(String name, | 196 PartialSetterElement(String name, Token beginToken, Token setToken, |
| 215 Token beginToken, | 197 Token endToken, Modifiers modifiers, Element enclosing, |
| 216 Token setToken, | 198 {bool hasBody: true}) |
| 217 Token endToken, | |
| 218 Modifiers modifiers, | |
| 219 Element enclosing, | |
| 220 {bool hasBody: true}) | |
| 221 : super(name, modifiers, enclosing, hasBody) { | 199 : super(name, modifiers, enclosing, hasBody) { |
| 222 init(beginToken, setToken, endToken); | 200 init(beginToken, setToken, endToken); |
| 223 } | 201 } |
| 224 | 202 |
| 225 @override | 203 @override |
| 226 GetterElement get getter => abstractField.getter; | 204 GetterElement get getter => abstractField.getter; |
| 227 | 205 |
| 228 void reuseElement() { | 206 void reuseElement() { |
| 229 super.reuseElement(); | 207 super.reuseElement(); |
| 230 reusePartialFunctionMixin(); | 208 reusePartialFunctionMixin(); |
| 231 } | 209 } |
| 232 | 210 |
| 233 PartialSetterElement copyWithEnclosing(Element enclosing) { | 211 PartialSetterElement copyWithEnclosing(Element enclosing) { |
| 234 return new PartialSetterElement( | 212 return new PartialSetterElement( |
| 235 name, beginToken, getOrSet, endToken, modifiers, enclosing, | 213 name, beginToken, getOrSet, endToken, modifiers, enclosing, |
| 236 hasBody: hasBody); | 214 hasBody: hasBody); |
| 237 } | 215 } |
| 238 } | 216 } |
| 239 | 217 |
| 240 // TODO(johnniwinther): Create [PartialGenerativeConstructor] and | 218 // TODO(johnniwinther): Create [PartialGenerativeConstructor] and |
| 241 // [PartialFactoryConstructor] subclasses and make this abstract. | 219 // [PartialFactoryConstructor] subclasses and make this abstract. |
| 242 class PartialConstructorElement extends ConstructorElementX | 220 class PartialConstructorElement extends ConstructorElementX |
| 243 with PartialElement, PartialFunctionMixin { | 221 with PartialElement, PartialFunctionMixin { |
| 244 PartialConstructorElement(String name, | 222 PartialConstructorElement(String name, Token beginToken, Token endToken, |
| 245 Token beginToken, | 223 ElementKind kind, Modifiers modifiers, Element enclosing) |
| 246 Token endToken, | |
| 247 ElementKind kind, | |
| 248 Modifiers modifiers, | |
| 249 Element enclosing) | |
| 250 : super(name, kind, modifiers, enclosing) { | 224 : super(name, kind, modifiers, enclosing) { |
| 251 init(beginToken, null, endToken); | 225 init(beginToken, null, endToken); |
| 252 } | 226 } |
| 253 | 227 |
| 254 void reuseElement() { | 228 void reuseElement() { |
| 255 super.reuseElement(); | 229 super.reuseElement(); |
| 256 reusePartialFunctionMixin(); | 230 reusePartialFunctionMixin(); |
| 257 } | 231 } |
| 258 } | 232 } |
| 259 | 233 |
| 260 class PartialFieldList extends VariableList with PartialElement { | 234 class PartialFieldList extends VariableList with PartialElement { |
| 261 PartialFieldList(Token beginToken, | 235 PartialFieldList( |
| 262 Token endToken, | 236 Token beginToken, Token endToken, Modifiers modifiers, bool hasParseError) |
| 263 Modifiers modifiers, | |
| 264 bool hasParseError) | |
| 265 : super(modifiers) { | 237 : super(modifiers) { |
| 266 super.beginToken = beginToken; | 238 super.beginToken = beginToken; |
| 267 super.endToken = endToken; | 239 super.endToken = endToken; |
| 268 super.hasParseError = hasParseError; | 240 super.hasParseError = hasParseError; |
| 269 } | 241 } |
| 270 | 242 |
| 271 VariableDefinitions parseNode(Element element, Parsing parsing) { | 243 VariableDefinitions parseNode(Element element, Parsing parsing) { |
| 272 if (definitions != null) return definitions; | 244 if (definitions != null) return definitions; |
| 273 DiagnosticReporter reporter = parsing.reporter; | 245 DiagnosticReporter reporter = parsing.reporter; |
| 274 reporter.withCurrentElement(element, () { | 246 reporter.withCurrentElement(element, () { |
| 275 definitions = parse( | 247 definitions = parse(parsing, element, declarationSite, |
| 276 parsing, element, declarationSite, | |
| 277 (Parser parser) => parser.parseMember(beginToken)); | 248 (Parser parser) => parser.parseMember(beginToken)); |
| 278 | 249 |
| 279 if (!hasParseError && | 250 if (!hasParseError && |
| 280 !definitions.modifiers.isVar && | 251 !definitions.modifiers.isVar && |
| 281 !definitions.modifiers.isFinal && | 252 !definitions.modifiers.isFinal && |
| 282 !definitions.modifiers.isConst && | 253 !definitions.modifiers.isConst && |
| 283 definitions.type == null && | 254 definitions.type == null && |
| 284 !definitions.isErroneous) { | 255 !definitions.isErroneous) { |
| 285 reporter.reportErrorMessage( | 256 reporter.reportErrorMessage(definitions, MessageKind.GENERIC, { |
| 286 definitions, | 257 'text': 'A field declaration must start with var, final, ' |
| 287 MessageKind.GENERIC, | 258 'const, or a type annotation.' |
| 288 { 'text': 'A field declaration must start with var, final, ' | 259 }); |
| 289 'const, or a type annotation.' }); | |
| 290 } | 260 } |
| 291 }); | 261 }); |
| 292 return definitions; | 262 return definitions; |
| 293 } | 263 } |
| 294 | 264 |
| 295 computeType(Element element, Resolution resolution) { | 265 computeType(Element element, Resolution resolution) { |
| 296 if (type != null) return type; | 266 if (type != null) return type; |
| 297 // TODO(johnniwinther): Compute this in the resolver. | 267 // TODO(johnniwinther): Compute this in the resolver. |
| 298 VariableDefinitions node = parseNode(element, resolution.parsing); | 268 VariableDefinitions node = parseNode(element, resolution.parsing); |
| 299 if (node.type != null) { | 269 if (node.type != null) { |
| 300 type = resolution.reporter.withCurrentElement(element, () { | 270 type = resolution.reporter.withCurrentElement(element, () { |
| 301 return resolution.resolveTypeAnnotation(element, node.type); | 271 return resolution.resolveTypeAnnotation(element, node.type); |
| 302 }); | 272 }); |
| 303 } else { | 273 } else { |
| 304 type = const DynamicType(); | 274 type = const DynamicType(); |
| 305 } | 275 } |
| 306 assert(type != null); | 276 assert(type != null); |
| 307 return type; | 277 return type; |
| 308 } | 278 } |
| 309 } | 279 } |
| 310 | 280 |
| 311 class PartialTypedefElement extends TypedefElementX with PartialElement { | 281 class PartialTypedefElement extends TypedefElementX with PartialElement { |
| 312 | |
| 313 PartialTypedefElement( | 282 PartialTypedefElement( |
| 314 String name, | 283 String name, Element enclosing, Token beginToken, Token endToken) |
| 315 Element enclosing, | |
| 316 Token beginToken, | |
| 317 Token endToken) | |
| 318 : super(name, enclosing) { | 284 : super(name, enclosing) { |
| 319 this.beginToken = beginToken; | 285 this.beginToken = beginToken; |
| 320 this.endToken = endToken; | 286 this.endToken = endToken; |
| 321 } | 287 } |
| 322 | 288 |
| 323 Token get token => beginToken; | 289 Token get token => beginToken; |
| 324 | 290 |
| 325 Node parseNode(Parsing parsing) { | 291 Node parseNode(Parsing parsing) { |
| 326 if (cachedNode != null) return cachedNode; | 292 if (cachedNode != null) return cachedNode; |
| 327 cachedNode = parse( | 293 cachedNode = parse(parsing, this, declarationSite, |
| 328 parsing, this, declarationSite, | |
| 329 (p) => p.parseTopLevelDeclaration(token)); | 294 (p) => p.parseTopLevelDeclaration(token)); |
| 330 return cachedNode; | 295 return cachedNode; |
| 331 } | 296 } |
| 332 | 297 |
| 333 Token get position => findMyName(token); | 298 Token get position => findMyName(token); |
| 334 } | 299 } |
| 335 | 300 |
| 336 /// A [MetadataAnnotation] which is constructed on demand. | 301 /// A [MetadataAnnotation] which is constructed on demand. |
| 337 class PartialMetadataAnnotation extends MetadataAnnotationX | 302 class PartialMetadataAnnotation extends MetadataAnnotationX |
| 338 implements PartialElement { | 303 implements PartialElement { |
| (...skipping 20 matching lines...) Expand all Loading... |
| 359 assert(token != null); | 324 assert(token != null); |
| 360 return token; | 325 return token; |
| 361 } | 326 } |
| 362 | 327 |
| 363 void set endToken(_) { | 328 void set endToken(_) { |
| 364 throw new UnsupportedError("endToken="); | 329 throw new UnsupportedError("endToken="); |
| 365 } | 330 } |
| 366 | 331 |
| 367 Node parseNode(Parsing parsing) { | 332 Node parseNode(Parsing parsing) { |
| 368 if (cachedNode != null) return cachedNode; | 333 if (cachedNode != null) return cachedNode; |
| 369 var metadata = parse(parsing, | 334 var metadata = parse(parsing, annotatedElement, declarationSite, |
| 370 annotatedElement, | 335 (p) => p.parseMetadata(beginToken)); |
| 371 declarationSite, | |
| 372 (p) => p.parseMetadata(beginToken)); | |
| 373 if (metadata is Metadata) { | 336 if (metadata is Metadata) { |
| 374 cachedNode = metadata.expression; | 337 cachedNode = metadata.expression; |
| 375 return cachedNode; | 338 return cachedNode; |
| 376 } else { | 339 } else { |
| 377 assert (metadata is ErrorNode); | 340 assert(metadata is ErrorNode); |
| 378 return metadata; | 341 return metadata; |
| 379 } | 342 } |
| 380 } | 343 } |
| 381 | 344 |
| 382 bool get hasNode => cachedNode != null; | 345 bool get hasNode => cachedNode != null; |
| 383 | 346 |
| 384 Node get node { | 347 Node get node { |
| 385 assert(invariant(this, hasNode)); | 348 assert(invariant(this, hasNode)); |
| 386 return cachedNode; | 349 return cachedNode; |
| 387 } | 350 } |
| 388 } | 351 } |
| 389 | 352 |
| 390 class PartialClassElement extends ClassElementX with PartialElement { | 353 class PartialClassElement extends ClassElementX with PartialElement { |
| 391 ClassNode cachedNode; | 354 ClassNode cachedNode; |
| 392 | 355 |
| 393 PartialClassElement(String name, | 356 PartialClassElement( |
| 394 Token beginToken, | 357 String name, Token beginToken, Token endToken, Element enclosing, int id) |
| 395 Token endToken, | |
| 396 Element enclosing, | |
| 397 int id) | |
| 398 : super(name, enclosing, id, STATE_NOT_STARTED) { | 358 : super(name, enclosing, id, STATE_NOT_STARTED) { |
| 399 this.beginToken = beginToken; | 359 this.beginToken = beginToken; |
| 400 this.endToken = endToken; | 360 this.endToken = endToken; |
| 401 } | 361 } |
| 402 | 362 |
| 403 void set supertypeLoadState(int state) { | 363 void set supertypeLoadState(int state) { |
| 404 assert(state == STATE_NOT_STARTED || state == supertypeLoadState + 1); | 364 assert(state == STATE_NOT_STARTED || state == supertypeLoadState + 1); |
| 405 assert(state <= STATE_DONE); | 365 assert(state <= STATE_DONE); |
| 406 super.supertypeLoadState = state; | 366 super.supertypeLoadState = state; |
| 407 } | 367 } |
| (...skipping 17 matching lines...) Expand all Loading... |
| 425 DiagnosticReporter reporter = parsing.reporter; | 385 DiagnosticReporter reporter = parsing.reporter; |
| 426 reporter.withCurrentElement(this, () { | 386 reporter.withCurrentElement(this, () { |
| 427 parsing.measure(() { | 387 parsing.measure(() { |
| 428 MemberListener listener = new MemberListener( | 388 MemberListener listener = new MemberListener( |
| 429 parsing.getScannerOptionsFor(this), reporter, this); | 389 parsing.getScannerOptionsFor(this), reporter, this); |
| 430 Parser parser = new ClassElementParser(listener, parsing.parserOptions); | 390 Parser parser = new ClassElementParser(listener, parsing.parserOptions); |
| 431 try { | 391 try { |
| 432 Token token = parser.parseTopLevelDeclaration(beginToken); | 392 Token token = parser.parseTopLevelDeclaration(beginToken); |
| 433 assert(identical(token, endToken.next)); | 393 assert(identical(token, endToken.next)); |
| 434 cachedNode = listener.popNode(); | 394 cachedNode = listener.popNode(); |
| 435 assert( | 395 assert(invariant(beginToken, listener.nodes.isEmpty, |
| 436 invariant( | 396 message: "Non-empty listener stack: ${listener.nodes}")); |
| 437 beginToken, listener.nodes.isEmpty, | |
| 438 message: "Non-empty listener stack: ${listener.nodes}")); | |
| 439 } on ParserError { | 397 } on ParserError { |
| 440 // TODO(ahe): Often, a ParserError is thrown while parsing the class | 398 // TODO(ahe): Often, a ParserError is thrown while parsing the class |
| 441 // body. This means that the stack actually contains most of the | 399 // body. This means that the stack actually contains most of the |
| 442 // information synthesized below. Consider rewriting the parser so | 400 // information synthesized below. Consider rewriting the parser so |
| 443 // endClassDeclaration is called before parsing the class body. | 401 // endClassDeclaration is called before parsing the class body. |
| 444 Identifier name = new Identifier(findMyName(beginToken)); | 402 Identifier name = new Identifier(findMyName(beginToken)); |
| 445 NodeList typeParameters = null; | 403 NodeList typeParameters = null; |
| 446 Node supertype = null; | 404 Node supertype = null; |
| 447 NodeList interfaces = listener.makeNodeList(0, null, null, ","); | 405 NodeList interfaces = listener.makeNodeList(0, null, null, ","); |
| 448 Token extendsKeyword = null; | 406 Token extendsKeyword = null; |
| 449 NodeList body = listener.makeNodeList(0, beginToken, endToken, null); | 407 NodeList body = listener.makeNodeList(0, beginToken, endToken, null); |
| 450 cachedNode = new ClassNode( | 408 cachedNode = new ClassNode( |
| 451 Modifiers.EMPTY, name, typeParameters, supertype, interfaces, | 409 Modifiers.EMPTY, |
| 452 beginToken, extendsKeyword, body, endToken); | 410 name, |
| 411 typeParameters, |
| 412 supertype, |
| 413 interfaces, |
| 414 beginToken, |
| 415 extendsKeyword, |
| 416 body, |
| 417 endToken); |
| 453 hasParseError = true; | 418 hasParseError = true; |
| 454 } | 419 } |
| 455 }); | 420 }); |
| 456 if (isPatched) { | 421 if (isPatched) { |
| 457 parsing.parsePatchClass(patch); | 422 parsing.parsePatchClass(patch); |
| 458 } | 423 } |
| 459 }); | 424 }); |
| 460 return cachedNode; | 425 return cachedNode; |
| 461 } | 426 } |
| 462 | 427 |
| 463 Token get position => beginToken; | 428 Token get position => beginToken; |
| 464 | 429 |
| 465 // TODO(johnniwinther): Ensure that modifiers are always available. | 430 // TODO(johnniwinther): Ensure that modifiers are always available. |
| 466 Modifiers get modifiers => | 431 Modifiers get modifiers => |
| 467 cachedNode != null ? cachedNode.modifiers : Modifiers.EMPTY; | 432 cachedNode != null ? cachedNode.modifiers : Modifiers.EMPTY; |
| 468 | 433 |
| 469 accept(ElementVisitor visitor, arg) { | 434 accept(ElementVisitor visitor, arg) { |
| 470 return visitor.visitClassElement(this, arg); | 435 return visitor.visitClassElement(this, arg); |
| 471 } | 436 } |
| 472 | 437 |
| 473 PartialClassElement copyWithEnclosing(CompilationUnitElement enclosing) { | 438 PartialClassElement copyWithEnclosing(CompilationUnitElement enclosing) { |
| 474 return new PartialClassElement(name, beginToken, endToken, enclosing, id); | 439 return new PartialClassElement(name, beginToken, endToken, enclosing, id); |
| 475 } | 440 } |
| 476 } | 441 } |
| 477 | 442 |
| 478 Node parse( | 443 Node parse(Parsing parsing, ElementX element, PartialElement partial, |
| 479 Parsing parsing, | |
| 480 ElementX element, | |
| 481 PartialElement partial, | |
| 482 doParse(Parser parser)) { | 444 doParse(Parser parser)) { |
| 483 DiagnosticReporter reporter = parsing.reporter; | 445 DiagnosticReporter reporter = parsing.reporter; |
| 484 return parsing.measure(() { | 446 return parsing.measure(() { |
| 485 return reporter.withCurrentElement(element, () { | 447 return reporter.withCurrentElement(element, () { |
| 486 CompilationUnitElement unit = element.compilationUnit; | 448 CompilationUnitElement unit = element.compilationUnit; |
| 487 NodeListener listener = new NodeListener( | 449 NodeListener listener = new NodeListener( |
| 488 parsing.getScannerOptionsFor(element), reporter, unit); | 450 parsing.getScannerOptionsFor(element), reporter, unit); |
| 489 listener.memberErrors = listener.memberErrors.prepend(false); | 451 listener.memberErrors = listener.memberErrors.prepend(false); |
| 490 try { | 452 try { |
| 491 if (partial.hasParseError) { | 453 if (partial.hasParseError) { |
| 492 listener.suppressParseErrors = true; | 454 listener.suppressParseErrors = true; |
| 493 } | 455 } |
| 494 doParse(new Parser(listener, parsing.parserOptions)); | 456 doParse(new Parser(listener, parsing.parserOptions)); |
| 495 } on ParserError catch (e) { | 457 } on ParserError catch (e) { |
| 496 partial.hasParseError = true; | 458 partial.hasParseError = true; |
| 497 return new ErrorNode(element.position, e.reason); | 459 return new ErrorNode(element.position, e.reason); |
| 498 } | 460 } |
| 499 Node node = listener.popNode(); | 461 Node node = listener.popNode(); |
| 500 assert(listener.nodes.isEmpty); | 462 assert(listener.nodes.isEmpty); |
| 501 return node; | 463 return node; |
| 502 }); | 464 }); |
| 503 }); | 465 }); |
| 504 } | 466 } |
| OLD | NEW |