| 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 |