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.resolution.class_hierarchy; | 5 library dart2js.resolution.class_hierarchy; |
6 | 6 |
7 import '../compiler.dart' show | 7 import '../compiler.dart' show |
8 Compiler; | 8 Compiler; |
9 import '../dart_types.dart'; | 9 import '../dart_types.dart'; |
10 import '../diagnostics/invariant.dart' show | 10 import '../diagnostics/invariant.dart' show |
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
61 // Resolve the bounds of type variables. | 61 // Resolve the bounds of type variables. |
62 Iterator<DartType> types = element.typeVariables.iterator; | 62 Iterator<DartType> types = element.typeVariables.iterator; |
63 Link<Node> nodeLink = node.nodes; | 63 Link<Node> nodeLink = node.nodes; |
64 while (!nodeLink.isEmpty) { | 64 while (!nodeLink.isEmpty) { |
65 types.moveNext(); | 65 types.moveNext(); |
66 TypeVariableType typeVariable = types.current; | 66 TypeVariableType typeVariable = types.current; |
67 String typeName = typeVariable.name; | 67 String typeName = typeVariable.name; |
68 TypeVariable typeNode = nodeLink.head; | 68 TypeVariable typeNode = nodeLink.head; |
69 registry.useType(typeNode, typeVariable); | 69 registry.useType(typeNode, typeVariable); |
70 if (nameSet.contains(typeName)) { | 70 if (nameSet.contains(typeName)) { |
71 error(typeNode, MessageKind.DUPLICATE_TYPE_VARIABLE_NAME, | 71 compiler.reportErrorMessage( |
72 {'typeVariableName': typeName}); | 72 typeNode, |
| 73 MessageKind.DUPLICATE_TYPE_VARIABLE_NAME, |
| 74 {'typeVariableName': typeName}); |
73 } | 75 } |
74 nameSet.add(typeName); | 76 nameSet.add(typeName); |
75 | 77 |
76 TypeVariableElementX variableElement = typeVariable.element; | 78 TypeVariableElementX variableElement = typeVariable.element; |
77 if (typeNode.bound != null) { | 79 if (typeNode.bound != null) { |
78 DartType boundType = typeResolver.resolveTypeAnnotation( | 80 DartType boundType = typeResolver.resolveTypeAnnotation( |
79 this, typeNode.bound); | 81 this, typeNode.bound); |
80 variableElement.boundCache = boundType; | 82 variableElement.boundCache = boundType; |
81 | 83 |
82 void checkTypeVariableBound() { | 84 void checkTypeVariableBound() { |
83 Link<TypeVariableElement> seenTypeVariables = | 85 Link<TypeVariableElement> seenTypeVariables = |
84 const Link<TypeVariableElement>(); | 86 const Link<TypeVariableElement>(); |
85 seenTypeVariables = seenTypeVariables.prepend(variableElement); | 87 seenTypeVariables = seenTypeVariables.prepend(variableElement); |
86 DartType bound = boundType; | 88 DartType bound = boundType; |
87 while (bound.isTypeVariable) { | 89 while (bound.isTypeVariable) { |
88 TypeVariableElement element = bound.element; | 90 TypeVariableElement element = bound.element; |
89 if (seenTypeVariables.contains(element)) { | 91 if (seenTypeVariables.contains(element)) { |
90 if (identical(element, variableElement)) { | 92 if (identical(element, variableElement)) { |
91 // Only report an error on the checked type variable to avoid | 93 // Only report an error on the checked type variable to avoid |
92 // generating multiple errors for the same cyclicity. | 94 // generating multiple errors for the same cyclicity. |
93 warning(typeNode.name, MessageKind.CYCLIC_TYPE_VARIABLE, | 95 compiler.reportWarningMessage( |
| 96 typeNode.name, |
| 97 MessageKind.CYCLIC_TYPE_VARIABLE, |
94 {'typeVariableName': variableElement.name}); | 98 {'typeVariableName': variableElement.name}); |
95 } | 99 } |
96 break; | 100 break; |
97 } | 101 } |
98 seenTypeVariables = seenTypeVariables.prepend(element); | 102 seenTypeVariables = seenTypeVariables.prepend(element); |
99 bound = element.bound; | 103 bound = element.bound; |
100 } | 104 } |
101 } | 105 } |
102 addDeferredAction(element, checkTypeVariableBound); | 106 addDeferredAction(element, checkTypeVariableBound); |
103 } else { | 107 } else { |
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
187 } | 191 } |
188 calculateAllSupertypes(element); | 192 calculateAllSupertypes(element); |
189 | 193 |
190 if (!element.hasConstructor) { | 194 if (!element.hasConstructor) { |
191 Element superMember = element.superclass.localLookup(''); | 195 Element superMember = element.superclass.localLookup(''); |
192 if (superMember == null || !superMember.isGenerativeConstructor) { | 196 if (superMember == null || !superMember.isGenerativeConstructor) { |
193 MessageKind kind = MessageKind.CANNOT_FIND_CONSTRUCTOR; | 197 MessageKind kind = MessageKind.CANNOT_FIND_CONSTRUCTOR; |
194 Map arguments = {'constructorName': ''}; | 198 Map arguments = {'constructorName': ''}; |
195 // TODO(ahe): Why is this a compile-time error? Or if it is an error, | 199 // TODO(ahe): Why is this a compile-time error? Or if it is an error, |
196 // why do we bother to registerThrowNoSuchMethod below? | 200 // why do we bother to registerThrowNoSuchMethod below? |
197 compiler.reportError(node, kind, arguments); | 201 compiler.reportErrorMessage(node, kind, arguments); |
198 superMember = new ErroneousElementX( | 202 superMember = new ErroneousElementX( |
199 kind, arguments, '', element); | 203 kind, arguments, '', element); |
200 registry.registerThrowNoSuchMethod(); | 204 registry.registerThrowNoSuchMethod(); |
201 } else { | 205 } else { |
202 ConstructorElement superConstructor = superMember; | 206 ConstructorElement superConstructor = superMember; |
203 superConstructor.computeType(compiler); | 207 superConstructor.computeType(compiler); |
204 if (!CallStructure.NO_ARGS.signatureApplies( | 208 if (!CallStructure.NO_ARGS.signatureApplies( |
205 superConstructor.functionSignature)) { | 209 superConstructor.functionSignature)) { |
206 MessageKind kind = MessageKind.NO_MATCHING_CONSTRUCTOR_FOR_IMPLICIT; | 210 MessageKind kind = MessageKind.NO_MATCHING_CONSTRUCTOR_FOR_IMPLICIT; |
207 compiler.reportError(node, kind); | 211 compiler.reportErrorMessage(node, kind); |
208 superMember = new ErroneousElementX(kind, {}, '', element); | 212 superMember = new ErroneousElementX(kind, {}, '', element); |
209 } | 213 } |
210 } | 214 } |
211 FunctionElement constructor = | 215 FunctionElement constructor = |
212 new SynthesizedConstructorElementX.forDefault(superMember, element); | 216 new SynthesizedConstructorElementX.forDefault(superMember, element); |
213 if (superMember.isErroneous) { | 217 if (superMember.isErroneous) { |
214 compiler.elementsWithCompileTimeErrors.add(constructor); | 218 compiler.elementsWithCompileTimeErrors.add(constructor); |
215 } | 219 } |
216 element.setDefaultConstructor(constructor, compiler); | 220 element.setDefaultConstructor(constructor, compiler); |
217 } | 221 } |
218 return element.computeType(compiler); | 222 return element.computeType(compiler); |
219 } | 223 } |
220 | 224 |
221 @override | 225 @override |
222 DartType visitEnum(Enum node) { | 226 DartType visitEnum(Enum node) { |
223 if (element == null) { | 227 if (element == null) { |
224 throw compiler.internalError(node, 'element is null'); | 228 throw compiler.internalError(node, 'element is null'); |
225 } | 229 } |
226 if (element.resolutionState != STATE_STARTED) { | 230 if (element.resolutionState != STATE_STARTED) { |
227 throw compiler.internalError(element, | 231 throw compiler.internalError(element, |
228 'cyclic resolution of class $element'); | 232 'cyclic resolution of class $element'); |
229 } | 233 } |
230 | 234 |
231 InterfaceType enumType = element.computeType(compiler); | 235 InterfaceType enumType = element.computeType(compiler); |
232 element.supertype = compiler.objectClass.computeType(compiler); | 236 element.supertype = compiler.objectClass.computeType(compiler); |
233 element.interfaces = const Link<DartType>(); | 237 element.interfaces = const Link<DartType>(); |
234 calculateAllSupertypes(element); | 238 calculateAllSupertypes(element); |
235 | 239 |
236 if (node.names.nodes.isEmpty) { | 240 if (node.names.nodes.isEmpty) { |
237 compiler.reportError(node, | 241 compiler.reportErrorMessage( |
238 MessageKind.EMPTY_ENUM_DECLARATION, | 242 node, |
239 {'enumName': element.name}); | 243 MessageKind.EMPTY_ENUM_DECLARATION, |
| 244 {'enumName': element.name}); |
240 } | 245 } |
241 | 246 |
242 EnumCreator creator = new EnumCreator(compiler, element); | 247 EnumCreator creator = new EnumCreator(compiler, element); |
243 creator.createMembers(); | 248 creator.createMembers(); |
244 return enumType; | 249 return enumType; |
245 } | 250 } |
246 | 251 |
247 /// Resolves the mixed type for [mixinNode] and checks that the the mixin type | 252 /// Resolves the mixed type for [mixinNode] and checks that the the mixin type |
248 /// is a valid, non-blacklisted interface type. The mixin type is returned. | 253 /// is a valid, non-blacklisted interface type. The mixin type is returned. |
249 DartType checkMixinType(TypeAnnotation mixinNode) { | 254 DartType checkMixinType(TypeAnnotation mixinNode) { |
250 DartType mixinType = resolveType(mixinNode); | 255 DartType mixinType = resolveType(mixinNode); |
251 if (isBlackListed(mixinType)) { | 256 if (isBlackListed(mixinType)) { |
252 compiler.reportError(mixinNode, | 257 compiler.reportErrorMessage( |
253 MessageKind.CANNOT_MIXIN, {'type': mixinType}); | 258 mixinNode, |
| 259 MessageKind.CANNOT_MIXIN, |
| 260 {'type': mixinType}); |
254 } else if (mixinType.isTypeVariable) { | 261 } else if (mixinType.isTypeVariable) { |
255 compiler.reportError(mixinNode, MessageKind.CLASS_NAME_EXPECTED); | 262 compiler.reportErrorMessage( |
| 263 mixinNode, |
| 264 MessageKind.CLASS_NAME_EXPECTED); |
256 } else if (mixinType.isMalformed) { | 265 } else if (mixinType.isMalformed) { |
257 compiler.reportError(mixinNode, MessageKind.CANNOT_MIXIN_MALFORMED, | 266 compiler.reportErrorMessage( |
| 267 mixinNode, |
| 268 MessageKind.CANNOT_MIXIN_MALFORMED, |
258 {'className': element.name, 'malformedType': mixinType}); | 269 {'className': element.name, 'malformedType': mixinType}); |
259 } else if (mixinType.isEnumType) { | 270 } else if (mixinType.isEnumType) { |
260 compiler.reportError(mixinNode, MessageKind.CANNOT_MIXIN_ENUM, | 271 compiler.reportErrorMessage( |
| 272 mixinNode, |
| 273 MessageKind.CANNOT_MIXIN_ENUM, |
261 {'className': element.name, 'enumType': mixinType}); | 274 {'className': element.name, 'enumType': mixinType}); |
262 } | 275 } |
263 return mixinType; | 276 return mixinType; |
264 } | 277 } |
265 | 278 |
266 DartType visitNamedMixinApplication(NamedMixinApplication node) { | 279 DartType visitNamedMixinApplication(NamedMixinApplication node) { |
267 if (element == null) { | 280 if (element == null) { |
268 throw compiler.internalError(node, 'element is null'); | 281 throw compiler.internalError(node, 'element is null'); |
269 } | 282 } |
270 if (element.resolutionState != STATE_STARTED) { | 283 if (element.resolutionState != STATE_STARTED) { |
271 throw compiler.internalError(element, | 284 throw compiler.internalError(element, |
272 'cyclic resolution of class $element'); | 285 'cyclic resolution of class $element'); |
273 } | 286 } |
274 | 287 |
275 if (identical(node.classKeyword.stringValue, 'typedef')) { | 288 if (identical(node.classKeyword.stringValue, 'typedef')) { |
276 // TODO(aprelev@gmail.com): Remove this deprecation diagnostic | 289 // TODO(aprelev@gmail.com): Remove this deprecation diagnostic |
277 // together with corresponding TODO in parser.dart. | 290 // together with corresponding TODO in parser.dart. |
278 compiler.reportWarning(node.classKeyword, | 291 compiler.reportWarningMessage( |
| 292 node.classKeyword, |
279 MessageKind.DEPRECATED_TYPEDEF_MIXIN_SYNTAX); | 293 MessageKind.DEPRECATED_TYPEDEF_MIXIN_SYNTAX); |
280 } | 294 } |
281 | 295 |
282 element.computeType(compiler); | 296 element.computeType(compiler); |
283 scope = new TypeDeclarationScope(scope, element); | 297 scope = new TypeDeclarationScope(scope, element); |
284 resolveTypeVariableBounds(node.typeParameters); | 298 resolveTypeVariableBounds(node.typeParameters); |
285 | 299 |
286 // Generate anonymous mixin application elements for the | 300 // Generate anonymous mixin application elements for the |
287 // intermediate mixin applications (excluding the last). | 301 // intermediate mixin applications (excluding the last). |
288 DartType supertype = resolveSupertype(element, node.superclass); | 302 DartType supertype = resolveSupertype(element, node.superclass); |
(...skipping 133 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
422 DartType mixinType) { | 436 DartType mixinType) { |
423 ClassElement mixin = mixinType.element; | 437 ClassElement mixin = mixinType.element; |
424 mixin.ensureResolved(compiler); | 438 mixin.ensureResolved(compiler); |
425 | 439 |
426 // Check for cycles in the mixin chain. | 440 // Check for cycles in the mixin chain. |
427 ClassElement previous = mixinApplication; // For better error messages. | 441 ClassElement previous = mixinApplication; // For better error messages. |
428 ClassElement current = mixin; | 442 ClassElement current = mixin; |
429 while (current != null && current.isMixinApplication) { | 443 while (current != null && current.isMixinApplication) { |
430 MixinApplicationElement currentMixinApplication = current; | 444 MixinApplicationElement currentMixinApplication = current; |
431 if (currentMixinApplication == mixinApplication) { | 445 if (currentMixinApplication == mixinApplication) { |
432 compiler.reportError( | 446 compiler.reportErrorMessage( |
433 mixinApplication, MessageKind.ILLEGAL_MIXIN_CYCLE, | 447 mixinApplication, |
| 448 MessageKind.ILLEGAL_MIXIN_CYCLE, |
434 {'mixinName1': current.name, 'mixinName2': previous.name}); | 449 {'mixinName1': current.name, 'mixinName2': previous.name}); |
435 // We have found a cycle in the mixin chain. Return null as | 450 // We have found a cycle in the mixin chain. Return null as |
436 // the mixin for this application to avoid getting into | 451 // the mixin for this application to avoid getting into |
437 // infinite recursion when traversing members. | 452 // infinite recursion when traversing members. |
438 return null; | 453 return null; |
439 } | 454 } |
440 previous = current; | 455 previous = current; |
441 current = currentMixinApplication.mixin; | 456 current = currentMixinApplication.mixin; |
442 } | 457 } |
443 registry.registerMixinUse(mixinApplication, mixin); | 458 registry.registerMixinUse(mixinApplication, mixin); |
444 return mixinType; | 459 return mixinType; |
445 } | 460 } |
446 | 461 |
447 DartType resolveType(TypeAnnotation node) { | 462 DartType resolveType(TypeAnnotation node) { |
448 return typeResolver.resolveTypeAnnotation(this, node); | 463 return typeResolver.resolveTypeAnnotation(this, node); |
449 } | 464 } |
450 | 465 |
451 DartType resolveSupertype(ClassElement cls, TypeAnnotation superclass) { | 466 DartType resolveSupertype(ClassElement cls, TypeAnnotation superclass) { |
452 DartType supertype = resolveType(superclass); | 467 DartType supertype = resolveType(superclass); |
453 if (supertype != null) { | 468 if (supertype != null) { |
454 if (supertype.isMalformed) { | 469 if (supertype.isMalformed) { |
455 compiler.reportError(superclass, MessageKind.CANNOT_EXTEND_MALFORMED, | 470 compiler.reportErrorMessage( |
| 471 superclass, |
| 472 MessageKind.CANNOT_EXTEND_MALFORMED, |
456 {'className': element.name, 'malformedType': supertype}); | 473 {'className': element.name, 'malformedType': supertype}); |
457 return objectType; | 474 return objectType; |
458 } else if (supertype.isEnumType) { | 475 } else if (supertype.isEnumType) { |
459 compiler.reportError(superclass, MessageKind.CANNOT_EXTEND_ENUM, | 476 compiler.reportErrorMessage( |
| 477 superclass, |
| 478 MessageKind.CANNOT_EXTEND_ENUM, |
460 {'className': element.name, 'enumType': supertype}); | 479 {'className': element.name, 'enumType': supertype}); |
461 return objectType; | 480 return objectType; |
462 } else if (!supertype.isInterfaceType) { | 481 } else if (!supertype.isInterfaceType) { |
463 compiler.reportError(superclass.typeName, | 482 compiler.reportErrorMessage( |
| 483 superclass.typeName, |
464 MessageKind.CLASS_NAME_EXPECTED); | 484 MessageKind.CLASS_NAME_EXPECTED); |
465 return objectType; | 485 return objectType; |
466 } else if (isBlackListed(supertype)) { | 486 } else if (isBlackListed(supertype)) { |
467 compiler.reportError(superclass, MessageKind.CANNOT_EXTEND, | 487 compiler.reportErrorMessage( |
| 488 superclass, |
| 489 MessageKind.CANNOT_EXTEND, |
468 {'type': supertype}); | 490 {'type': supertype}); |
469 return objectType; | 491 return objectType; |
470 } | 492 } |
471 } | 493 } |
472 return supertype; | 494 return supertype; |
473 } | 495 } |
474 | 496 |
475 Link<DartType> resolveInterfaces(NodeList interfaces, Node superclass) { | 497 Link<DartType> resolveInterfaces(NodeList interfaces, Node superclass) { |
476 Link<DartType> result = const Link<DartType>(); | 498 Link<DartType> result = const Link<DartType>(); |
477 if (interfaces == null) return result; | 499 if (interfaces == null) return result; |
478 for (Link<Node> link = interfaces.nodes; !link.isEmpty; link = link.tail) { | 500 for (Link<Node> link = interfaces.nodes; !link.isEmpty; link = link.tail) { |
479 DartType interfaceType = resolveType(link.head); | 501 DartType interfaceType = resolveType(link.head); |
480 if (interfaceType != null) { | 502 if (interfaceType != null) { |
481 if (interfaceType.isMalformed) { | 503 if (interfaceType.isMalformed) { |
482 compiler.reportError(superclass, | 504 compiler.reportErrorMessage( |
| 505 superclass, |
483 MessageKind.CANNOT_IMPLEMENT_MALFORMED, | 506 MessageKind.CANNOT_IMPLEMENT_MALFORMED, |
484 {'className': element.name, 'malformedType': interfaceType}); | 507 {'className': element.name, 'malformedType': interfaceType}); |
485 } else if (interfaceType.isEnumType) { | 508 } else if (interfaceType.isEnumType) { |
486 compiler.reportError(superclass, | 509 compiler.reportErrorMessage( |
| 510 superclass, |
487 MessageKind.CANNOT_IMPLEMENT_ENUM, | 511 MessageKind.CANNOT_IMPLEMENT_ENUM, |
488 {'className': element.name, 'enumType': interfaceType}); | 512 {'className': element.name, 'enumType': interfaceType}); |
489 } else if (!interfaceType.isInterfaceType) { | 513 } else if (!interfaceType.isInterfaceType) { |
490 // TODO(johnniwinther): Handle dynamic. | 514 // TODO(johnniwinther): Handle dynamic. |
491 TypeAnnotation typeAnnotation = link.head; | 515 TypeAnnotation typeAnnotation = link.head; |
492 error(typeAnnotation.typeName, MessageKind.CLASS_NAME_EXPECTED); | 516 compiler.reportErrorMessage( |
| 517 typeAnnotation.typeName, MessageKind.CLASS_NAME_EXPECTED); |
493 } else { | 518 } else { |
494 if (interfaceType == element.supertype) { | 519 if (interfaceType == element.supertype) { |
495 compiler.reportError( | 520 compiler.reportErrorMessage( |
496 superclass, | 521 superclass, |
497 MessageKind.DUPLICATE_EXTENDS_IMPLEMENTS, | 522 MessageKind.DUPLICATE_EXTENDS_IMPLEMENTS, |
498 {'type': interfaceType}); | 523 {'type': interfaceType}); |
499 compiler.reportError( | 524 compiler.reportErrorMessage( |
500 link.head, | 525 link.head, |
501 MessageKind.DUPLICATE_EXTENDS_IMPLEMENTS, | 526 MessageKind.DUPLICATE_EXTENDS_IMPLEMENTS, |
502 {'type': interfaceType}); | 527 {'type': interfaceType}); |
503 } | 528 } |
504 if (result.contains(interfaceType)) { | 529 if (result.contains(interfaceType)) { |
505 compiler.reportError( | 530 compiler.reportErrorMessage( |
506 link.head, | 531 link.head, |
507 MessageKind.DUPLICATE_IMPLEMENTS, | 532 MessageKind.DUPLICATE_IMPLEMENTS, |
508 {'type': interfaceType}); | 533 {'type': interfaceType}); |
509 } | 534 } |
510 result = result.prepend(interfaceType); | 535 result = result.prepend(interfaceType); |
511 if (isBlackListed(interfaceType)) { | 536 if (isBlackListed(interfaceType)) { |
512 error(link.head, MessageKind.CANNOT_IMPLEMENT, | 537 compiler.reportErrorMessage( |
513 {'type': interfaceType}); | 538 link.head, |
| 539 MessageKind.CANNOT_IMPLEMENT, |
| 540 {'type': interfaceType}); |
514 } | 541 } |
515 } | 542 } |
516 } | 543 } |
517 } | 544 } |
518 return result; | 545 return result; |
519 } | 546 } |
520 | 547 |
521 /** | 548 /** |
522 * Compute the list of all supertypes. | 549 * Compute the list of all supertypes. |
523 * | 550 * |
(...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
653 void visitIdentifier(Identifier node) { | 680 void visitIdentifier(Identifier node) { |
654 Element element = lookupInScope(compiler, node, context, node.source); | 681 Element element = lookupInScope(compiler, node, context, node.source); |
655 if (element != null && element.isClass) { | 682 if (element != null && element.isClass) { |
656 loadSupertype(element, node); | 683 loadSupertype(element, node); |
657 } | 684 } |
658 } | 685 } |
659 | 686 |
660 void visitSend(Send node) { | 687 void visitSend(Send node) { |
661 Identifier prefix = node.receiver.asIdentifier(); | 688 Identifier prefix = node.receiver.asIdentifier(); |
662 if (prefix == null) { | 689 if (prefix == null) { |
663 error(node.receiver, MessageKind.NOT_A_PREFIX, {'node': node.receiver}); | 690 compiler.reportErrorMessage( |
| 691 node.receiver, MessageKind.NOT_A_PREFIX, {'node': node.receiver}); |
664 return; | 692 return; |
665 } | 693 } |
666 Element element = lookupInScope(compiler, prefix, context, prefix.source); | 694 Element element = lookupInScope(compiler, prefix, context, prefix.source); |
667 if (element == null || !identical(element.kind, ElementKind.PREFIX)) { | 695 if (element == null || !identical(element.kind, ElementKind.PREFIX)) { |
668 error(node.receiver, MessageKind.NOT_A_PREFIX, {'node': node.receiver}); | 696 compiler.reportErrorMessage( |
| 697 node.receiver, MessageKind.NOT_A_PREFIX, {'node': node.receiver}); |
669 return; | 698 return; |
670 } | 699 } |
671 PrefixElement prefixElement = element; | 700 PrefixElement prefixElement = element; |
672 Identifier selector = node.selector.asIdentifier(); | 701 Identifier selector = node.selector.asIdentifier(); |
673 var e = prefixElement.lookupLocalMember(selector.source); | 702 var e = prefixElement.lookupLocalMember(selector.source); |
674 if (e == null || !e.impliesType) { | 703 if (e == null || !e.impliesType) { |
675 error(node.selector, MessageKind.CANNOT_RESOLVE_TYPE, | 704 compiler.reportErrorMessage( |
676 {'typeName': node.selector}); | 705 node.selector, |
| 706 MessageKind.CANNOT_RESOLVE_TYPE, |
| 707 {'typeName': node.selector}); |
677 return; | 708 return; |
678 } | 709 } |
679 loadSupertype(e, node); | 710 loadSupertype(e, node); |
680 } | 711 } |
681 } | 712 } |
OLD | NEW |