| OLD | NEW |
| 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, 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 resolution; | 5 part of resolution; |
| 6 | 6 |
| 7 abstract class TreeElements { | 7 abstract class TreeElements { |
| 8 Element get currentElement; | 8 Element get currentElement; |
| 9 Setlet<Node> get superUses; | 9 Setlet<Node> get superUses; |
| 10 | 10 |
| (...skipping 2559 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2570 } | 2570 } |
| 2571 } | 2571 } |
| 2572 | 2572 |
| 2573 bool resolvedArguments = false; | 2573 bool resolvedArguments = false; |
| 2574 if (node.isOperator) { | 2574 if (node.isOperator) { |
| 2575 String operatorString = node.selector.asOperator().source; | 2575 String operatorString = node.selector.asOperator().source; |
| 2576 if (identical(operatorString, 'is')) { | 2576 if (identical(operatorString, 'is')) { |
| 2577 // TODO(johnniwinther): Use seen type tests to avoid registration of | 2577 // TODO(johnniwinther): Use seen type tests to avoid registration of |
| 2578 // mutation/access to unpromoted variables. | 2578 // mutation/access to unpromoted variables. |
| 2579 DartType type = | 2579 DartType type = |
| 2580 resolveTypeExpression(node.typeAnnotationFromIsCheckOrCast); | 2580 resolveTypeAnnotation(node.typeAnnotationFromIsCheckOrCast); |
| 2581 if (type != null) { | 2581 if (type != null) { |
| 2582 compiler.enqueuer.resolution.registerIsCheck(type, mapping); | 2582 compiler.enqueuer.resolution.registerIsCheck(type, mapping); |
| 2583 } | 2583 } |
| 2584 resolvedArguments = true; | 2584 resolvedArguments = true; |
| 2585 } else if (identical(operatorString, 'as')) { | 2585 } else if (identical(operatorString, 'as')) { |
| 2586 DartType type = resolveTypeExpression(node.arguments.head); | 2586 DartType type = resolveTypeAnnotation(node.arguments.head); |
| 2587 if (type != null) { | 2587 if (type != null) { |
| 2588 compiler.enqueuer.resolution.registerAsCheck(type, mapping); | 2588 compiler.enqueuer.resolution.registerAsCheck(type, mapping); |
| 2589 } | 2589 } |
| 2590 resolvedArguments = true; | 2590 resolvedArguments = true; |
| 2591 } else if (identical(operatorString, '&&')) { | 2591 } else if (identical(operatorString, '&&')) { |
| 2592 doInPromotionScope(node.arguments.head, | 2592 doInPromotionScope(node.arguments.head, |
| 2593 () => resolveArguments(node.argumentsNode)); | 2593 () => resolveArguments(node.argumentsNode)); |
| 2594 resolvedArguments = true; | 2594 resolvedArguments = true; |
| 2595 } | 2595 } |
| 2596 } | 2596 } |
| (...skipping 248 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2845 } | 2845 } |
| 2846 | 2846 |
| 2847 void handleRedirectingFactoryBody(Return node) { | 2847 void handleRedirectingFactoryBody(Return node) { |
| 2848 final isSymbolConstructor = enclosingElement == compiler.symbolConstructor; | 2848 final isSymbolConstructor = enclosingElement == compiler.symbolConstructor; |
| 2849 if (!enclosingElement.isFactoryConstructor()) { | 2849 if (!enclosingElement.isFactoryConstructor()) { |
| 2850 compiler.reportError( | 2850 compiler.reportError( |
| 2851 node, MessageKind.FACTORY_REDIRECTION_IN_NON_FACTORY); | 2851 node, MessageKind.FACTORY_REDIRECTION_IN_NON_FACTORY); |
| 2852 compiler.reportHint( | 2852 compiler.reportHint( |
| 2853 enclosingElement, MessageKind.MISSING_FACTORY_KEYWORD); | 2853 enclosingElement, MessageKind.MISSING_FACTORY_KEYWORD); |
| 2854 } | 2854 } |
| 2855 FunctionElement redirectionTarget = resolveRedirectingFactory(node); | 2855 FunctionElement constructor = enclosingElement; |
| 2856 bool isConstConstructor = constructor.modifiers.isConst(); |
| 2857 FunctionElement redirectionTarget = resolveRedirectingFactory( |
| 2858 node, inConstContext: isConstConstructor); |
| 2859 constructor.defaultImplementation = redirectionTarget; |
| 2856 useElement(node.expression, redirectionTarget); | 2860 useElement(node.expression, redirectionTarget); |
| 2857 FunctionElement constructor = enclosingElement; | |
| 2858 if (constructor.modifiers.isConst() && | |
| 2859 !redirectionTarget.modifiers.isConst()) { | |
| 2860 error(node, MessageKind.CONSTRUCTOR_IS_NOT_CONST); | |
| 2861 } | |
| 2862 if (redirectionTarget == constructor) { | |
| 2863 compiler.reportError(node, MessageKind.CYCLIC_REDIRECTING_FACTORY); | |
| 2864 return; | |
| 2865 } | |
| 2866 constructor.defaultImplementation = redirectionTarget; | |
| 2867 if (Elements.isUnresolved(redirectionTarget)) { | 2861 if (Elements.isUnresolved(redirectionTarget)) { |
| 2868 compiler.backend.registerThrowNoSuchMethod(mapping); | 2862 compiler.backend.registerThrowNoSuchMethod(mapping); |
| 2869 return; | 2863 return; |
| 2864 } else { |
| 2865 if (isConstConstructor && |
| 2866 !redirectionTarget.modifiers.isConst()) { |
| 2867 compiler.reportError(node, MessageKind.CONSTRUCTOR_IS_NOT_CONST); |
| 2868 } |
| 2869 if (redirectionTarget == constructor) { |
| 2870 compiler.reportError(node, MessageKind.CYCLIC_REDIRECTING_FACTORY); |
| 2871 return; |
| 2872 } |
| 2870 } | 2873 } |
| 2871 | 2874 |
| 2872 // Check that the target constructor is type compatible with the | 2875 // Check that the target constructor is type compatible with the |
| 2873 // redirecting constructor. | 2876 // redirecting constructor. |
| 2874 ClassElement targetClass = redirectionTarget.getEnclosingClass(); | 2877 ClassElement targetClass = redirectionTarget.getEnclosingClass(); |
| 2875 InterfaceType type = mapping.getType(node.expression); | 2878 InterfaceType type = mapping.getType(node.expression); |
| 2876 FunctionType targetType = redirectionTarget.computeType(compiler) | 2879 FunctionType targetType = redirectionTarget.computeType(compiler) |
| 2877 .subst(type.typeArguments, targetClass.typeVariables); | 2880 .subst(type.typeArguments, targetClass.typeVariables); |
| 2878 FunctionType constructorType = constructor.computeType(compiler); | 2881 FunctionType constructorType = constructor.computeType(compiler); |
| 2879 bool isSubtype = compiler.types.isSubtype(targetType, constructorType); | 2882 bool isSubtype = compiler.types.isSubtype(targetType, constructorType); |
| (...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2984 compiler.backend.registerThrowNoSuchMethod(mapping); | 2987 compiler.backend.registerThrowNoSuchMethod(mapping); |
| 2985 } | 2988 } |
| 2986 | 2989 |
| 2987 // [constructor] might be the implementation element | 2990 // [constructor] might be the implementation element |
| 2988 // and only declaration elements may be registered. | 2991 // and only declaration elements may be registered. |
| 2989 world.registerStaticUse(constructor.declaration); | 2992 world.registerStaticUse(constructor.declaration); |
| 2990 ClassElement cls = constructor.getEnclosingClass(); | 2993 ClassElement cls = constructor.getEnclosingClass(); |
| 2991 InterfaceType type = mapping.getType(node); | 2994 InterfaceType type = mapping.getType(node); |
| 2992 if (node.isConst() && type.containsTypeVariables) { | 2995 if (node.isConst() && type.containsTypeVariables) { |
| 2993 compiler.reportError(node.send.selector, | 2996 compiler.reportError(node.send.selector, |
| 2994 MessageKind.TYPE_VARIABLE_IN_CONSTANT); | 2997 MessageKind.TYPE_VARIABLE_IN_CONSTANT); |
| 2995 } | 2998 } |
| 2996 world.registerInstantiatedType(type, mapping); | 2999 world.registerInstantiatedType(type, mapping); |
| 2997 if (constructor.isFactoryConstructor() && !type.typeArguments.isEmpty) { | 3000 if (constructor.isFactoryConstructor() && !type.typeArguments.isEmpty) { |
| 2998 world.registerFactoryWithTypeArguments(mapping); | 3001 world.registerFactoryWithTypeArguments(mapping); |
| 2999 } | 3002 } |
| 3000 if (constructor.isGenerativeConstructor() && cls.isAbstract(compiler)) { | 3003 if (constructor.isGenerativeConstructor() && cls.isAbstract(compiler)) { |
| 3001 warning(node, MessageKind.ABSTRACT_CLASS_INSTANTIATION); | 3004 warning(node, MessageKind.ABSTRACT_CLASS_INSTANTIATION); |
| 3002 compiler.backend.registerAbstractClassInstantiation(mapping); | 3005 compiler.backend.registerAbstractClassInstantiation(mapping); |
| 3003 } | 3006 } |
| 3004 | 3007 |
| (...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3065 | 3068 |
| 3066 /** | 3069 /** |
| 3067 * Try to resolve the constructor that is referred to by [node]. | 3070 * Try to resolve the constructor that is referred to by [node]. |
| 3068 * Note: this function may return an ErroneousFunctionElement instead of | 3071 * Note: this function may return an ErroneousFunctionElement instead of |
| 3069 * [null], if there is no corresponding constructor, class or library. | 3072 * [null], if there is no corresponding constructor, class or library. |
| 3070 */ | 3073 */ |
| 3071 FunctionElement resolveConstructor(NewExpression node) { | 3074 FunctionElement resolveConstructor(NewExpression node) { |
| 3072 return node.accept(new ConstructorResolver(compiler, this)); | 3075 return node.accept(new ConstructorResolver(compiler, this)); |
| 3073 } | 3076 } |
| 3074 | 3077 |
| 3075 FunctionElement resolveRedirectingFactory(Return node) { | 3078 FunctionElement resolveRedirectingFactory(Return node, |
| 3076 return node.accept(new ConstructorResolver(compiler, this)); | 3079 {bool inConstContext: false}) { |
| 3080 return node.accept(new ConstructorResolver(compiler, this, |
| 3081 inConstContext: inConstContext)); |
| 3077 } | 3082 } |
| 3078 | 3083 |
| 3079 DartType resolveTypeExpression(TypeAnnotation node) { | 3084 DartType resolveTypeAnnotation(TypeAnnotation node, |
| 3080 return resolveTypeAnnotation(node); | 3085 {bool malformedIsError: false}) { |
| 3081 } | 3086 DartType type = typeResolver.resolveTypeAnnotation( |
| 3082 | 3087 this, node, malformedIsError: malformedIsError); |
| 3083 DartType resolveTypeAnnotation(TypeAnnotation node) { | |
| 3084 DartType type = typeResolver.resolveTypeAnnotation(this, node); | |
| 3085 if (type == null) return null; | 3088 if (type == null) return null; |
| 3086 if (inCheckContext) { | 3089 if (inCheckContext) { |
| 3087 compiler.enqueuer.resolution.registerIsCheck(type, mapping); | 3090 compiler.enqueuer.resolution.registerIsCheck(type, mapping); |
| 3088 compiler.backend.registerRequiredType(type, enclosingElement); | 3091 compiler.backend.registerRequiredType(type, enclosingElement); |
| 3089 } | 3092 } |
| 3090 return type; | 3093 return type; |
| 3091 } | 3094 } |
| 3092 | 3095 |
| 3093 visitModifiers(Modifiers node) { | 3096 visitModifiers(Modifiers node) { |
| 3094 // TODO(ngeoffray): Implement this. | 3097 // TODO(ngeoffray): Implement this. |
| 3095 unimplemented(node, 'modifiers'); | 3098 unimplemented(node, 'modifiers'); |
| 3096 } | 3099 } |
| 3097 | 3100 |
| 3098 visitLiteralList(LiteralList node) { | 3101 visitLiteralList(LiteralList node) { |
| 3099 NodeList arguments = node.typeArguments; | 3102 NodeList arguments = node.typeArguments; |
| 3100 DartType typeArgument; | 3103 DartType typeArgument; |
| 3101 if (arguments != null) { | 3104 if (arguments != null) { |
| 3102 Link<Node> nodes = arguments.nodes; | 3105 Link<Node> nodes = arguments.nodes; |
| 3103 if (nodes.isEmpty) { | 3106 if (nodes.isEmpty) { |
| 3104 // The syntax [: <>[] :] is not allowed. | 3107 // The syntax [: <>[] :] is not allowed. |
| 3105 error(arguments, MessageKind.MISSING_TYPE_ARGUMENT.error); | 3108 error(arguments, MessageKind.MISSING_TYPE_ARGUMENT.error); |
| 3106 } else { | 3109 } else { |
| 3107 typeArgument = resolveTypeExpression(nodes.head); | 3110 typeArgument = resolveTypeAnnotation(nodes.head); |
| 3108 for (nodes = nodes.tail; !nodes.isEmpty; nodes = nodes.tail) { | 3111 for (nodes = nodes.tail; !nodes.isEmpty; nodes = nodes.tail) { |
| 3109 warning(nodes.head, MessageKind.ADDITIONAL_TYPE_ARGUMENT.warning); | 3112 warning(nodes.head, MessageKind.ADDITIONAL_TYPE_ARGUMENT.warning); |
| 3110 resolveTypeAnnotation(nodes.head); | 3113 resolveTypeAnnotation(nodes.head); |
| 3111 } | 3114 } |
| 3112 } | 3115 } |
| 3113 } | 3116 } |
| 3114 DartType listType; | 3117 DartType listType; |
| 3115 if (typeArgument != null) { | 3118 if (typeArgument != null) { |
| 3116 if (node.isConst() && typeArgument.containsTypeVariables) { | 3119 if (node.isConst() && typeArgument.containsTypeVariables) { |
| 3117 compiler.reportError(arguments.nodes.head, | 3120 compiler.reportError(arguments.nodes.head, |
| (...skipping 194 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3312 visitLiteralMap(LiteralMap node) { | 3315 visitLiteralMap(LiteralMap node) { |
| 3313 NodeList arguments = node.typeArguments; | 3316 NodeList arguments = node.typeArguments; |
| 3314 DartType keyTypeArgument; | 3317 DartType keyTypeArgument; |
| 3315 DartType valueTypeArgument; | 3318 DartType valueTypeArgument; |
| 3316 if (arguments != null) { | 3319 if (arguments != null) { |
| 3317 Link<Node> nodes = arguments.nodes; | 3320 Link<Node> nodes = arguments.nodes; |
| 3318 if (nodes.isEmpty) { | 3321 if (nodes.isEmpty) { |
| 3319 // The syntax [: <>{} :] is not allowed. | 3322 // The syntax [: <>{} :] is not allowed. |
| 3320 error(arguments, MessageKind.MISSING_TYPE_ARGUMENT.error); | 3323 error(arguments, MessageKind.MISSING_TYPE_ARGUMENT.error); |
| 3321 } else { | 3324 } else { |
| 3322 keyTypeArgument = resolveTypeExpression(nodes.head); | 3325 keyTypeArgument = resolveTypeAnnotation(nodes.head); |
| 3323 nodes = nodes.tail; | 3326 nodes = nodes.tail; |
| 3324 if (nodes.isEmpty) { | 3327 if (nodes.isEmpty) { |
| 3325 warning(arguments, MessageKind.MISSING_TYPE_ARGUMENT.warning); | 3328 warning(arguments, MessageKind.MISSING_TYPE_ARGUMENT.warning); |
| 3326 } else { | 3329 } else { |
| 3327 valueTypeArgument = resolveTypeExpression(nodes.head); | 3330 valueTypeArgument = resolveTypeAnnotation(nodes.head); |
| 3328 for (nodes = nodes.tail; !nodes.isEmpty; nodes = nodes.tail) { | 3331 for (nodes = nodes.tail; !nodes.isEmpty; nodes = nodes.tail) { |
| 3329 warning(nodes.head, MessageKind.ADDITIONAL_TYPE_ARGUMENT.warning); | 3332 warning(nodes.head, MessageKind.ADDITIONAL_TYPE_ARGUMENT.warning); |
| 3330 resolveTypeAnnotation(nodes.head); | 3333 resolveTypeAnnotation(nodes.head); |
| 3331 } | 3334 } |
| 3332 } | 3335 } |
| 3333 } | 3336 } |
| 3334 } | 3337 } |
| 3335 DartType mapType; | 3338 DartType mapType; |
| 3336 if (valueTypeArgument != null) { | 3339 if (valueTypeArgument != null) { |
| 3337 mapType = new InterfaceType(compiler.mapClass, | 3340 mapType = new InterfaceType(compiler.mapClass, |
| (...skipping 1160 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4498 | 4501 |
| 4499 // TODO(ahe): This is temporary. | 4502 // TODO(ahe): This is temporary. |
| 4500 ClassElement get currentClass { | 4503 ClassElement get currentClass { |
| 4501 return enclosingElement.isMember() | 4504 return enclosingElement.isMember() |
| 4502 ? enclosingElement.getEnclosingClass() : null; | 4505 ? enclosingElement.getEnclosingClass() : null; |
| 4503 } | 4506 } |
| 4504 } | 4507 } |
| 4505 | 4508 |
| 4506 class ConstructorResolver extends CommonResolverVisitor<Element> { | 4509 class ConstructorResolver extends CommonResolverVisitor<Element> { |
| 4507 final ResolverVisitor resolver; | 4510 final ResolverVisitor resolver; |
| 4508 bool inConstContext = false; | 4511 bool inConstContext; |
| 4509 DartType type; | 4512 DartType type; |
| 4510 | 4513 |
| 4511 ConstructorResolver(Compiler compiler, this.resolver) : super(compiler); | 4514 ConstructorResolver(Compiler compiler, this.resolver, |
| 4515 {bool this.inConstContext: false}) |
| 4516 : super(compiler); |
| 4512 | 4517 |
| 4513 visitNode(Node node) { | 4518 visitNode(Node node) { |
| 4514 throw 'not supported'; | 4519 throw 'not supported'; |
| 4515 } | 4520 } |
| 4516 | 4521 |
| 4517 failOrReturnErroneousElement(Element enclosing, Node diagnosticNode, | 4522 failOrReturnErroneousElement(Element enclosing, Node diagnosticNode, |
| 4518 String targetName, DualKind kind, | 4523 String targetName, DualKind kind, |
| 4519 Map arguments) { | 4524 Map arguments) { |
| 4520 if (kind == MessageKind.CANNOT_FIND_CONSTRUCTOR) { | 4525 if (kind == MessageKind.CANNOT_FIND_CONSTRUCTOR) { |
| 4521 compiler.backend.registerThrowNoSuchMethod(resolver.mapping); | 4526 compiler.backend.registerThrowNoSuchMethod(resolver.mapping); |
| 4522 } else { | 4527 } else { |
| 4523 compiler.backend.registerThrowRuntimeError(resolver.mapping); | 4528 compiler.backend.registerThrowRuntimeError(resolver.mapping); |
| 4524 } | 4529 } |
| 4525 if (inConstContext) { | 4530 if (inConstContext) { |
| 4526 compiler.reportError(diagnosticNode, kind.error, arguments); | 4531 compiler.reportError(diagnosticNode, kind.error, arguments); |
| 4527 } else { | 4532 } else { |
| 4528 ResolutionWarning warning = | 4533 ResolutionWarning warning = |
| 4529 new ResolutionWarning( | 4534 new ResolutionWarning( |
| 4530 kind.warning, arguments, compiler.terseDiagnostics); | 4535 kind.warning, arguments, compiler.terseDiagnostics); |
| 4531 compiler.reportWarning(diagnosticNode, warning); | 4536 compiler.reportWarning(diagnosticNode, warning); |
| 4532 return new ErroneousElementX( | |
| 4533 kind.error, arguments, targetName, enclosing); | |
| 4534 } | 4537 } |
| 4538 return new ErroneousElementX( |
| 4539 kind.error, arguments, targetName, enclosing); |
| 4535 } | 4540 } |
| 4536 | 4541 |
| 4537 Selector createConstructorSelector(String constructorName) { | 4542 Selector createConstructorSelector(String constructorName) { |
| 4538 return constructorName == '' | 4543 return constructorName == '' |
| 4539 ? new Selector.callDefaultConstructor( | 4544 ? new Selector.callDefaultConstructor( |
| 4540 resolver.enclosingElement.getLibrary()) | 4545 resolver.enclosingElement.getLibrary()) |
| 4541 : new Selector.callConstructor( | 4546 : new Selector.callConstructor( |
| 4542 constructorName, | 4547 constructorName, |
| 4543 resolver.enclosingElement.getLibrary()); | 4548 resolver.enclosingElement.getLibrary()); |
| 4544 } | 4549 } |
| (...skipping 15 matching lines...) Expand all Loading... |
| 4560 diagnosticNode, | 4565 diagnosticNode, |
| 4561 fullConstructorName, | 4566 fullConstructorName, |
| 4562 MessageKind.CANNOT_FIND_CONSTRUCTOR, | 4567 MessageKind.CANNOT_FIND_CONSTRUCTOR, |
| 4563 {'constructorName': fullConstructorName}); | 4568 {'constructorName': fullConstructorName}); |
| 4564 } else if (inConstContext && !result.modifiers.isConst()) { | 4569 } else if (inConstContext && !result.modifiers.isConst()) { |
| 4565 error(diagnosticNode, MessageKind.CONSTRUCTOR_IS_NOT_CONST); | 4570 error(diagnosticNode, MessageKind.CONSTRUCTOR_IS_NOT_CONST); |
| 4566 } | 4571 } |
| 4567 return result; | 4572 return result; |
| 4568 } | 4573 } |
| 4569 | 4574 |
| 4570 visitNewExpression(NewExpression node) { | 4575 Element visitNewExpression(NewExpression node) { |
| 4571 inConstContext = node.isConst(); | 4576 inConstContext = node.isConst(); |
| 4572 Node selector = node.send.selector; | 4577 Node selector = node.send.selector; |
| 4573 Element e = visit(selector); | 4578 Element element = visit(selector); |
| 4574 return finishConstructorReference(e, node.send.selector, node); | 4579 assert(invariant(selector, element != null, |
| 4580 message: 'No element return for $selector.')); |
| 4581 return finishConstructorReference(element, node.send.selector, node); |
| 4575 } | 4582 } |
| 4576 | 4583 |
| 4577 /// Finishes resolution of a constructor reference and records the | 4584 /// Finishes resolution of a constructor reference and records the |
| 4578 /// type of the constructed instance on [expression]. | 4585 /// type of the constructed instance on [expression]. |
| 4579 FunctionElement finishConstructorReference(Element e, | 4586 FunctionElement finishConstructorReference(Element element, |
| 4580 Node diagnosticNode, | 4587 Node diagnosticNode, |
| 4581 Node expression) { | 4588 Node expression) { |
| 4589 assert(invariant(diagnosticNode, element != null, |
| 4590 message: 'No element return for $diagnosticNode.')); |
| 4582 // Find the unnamed constructor if the reference resolved to a | 4591 // Find the unnamed constructor if the reference resolved to a |
| 4583 // class. | 4592 // class. |
| 4584 if (!Elements.isUnresolved(e) && !e.isConstructor()) { | 4593 if (!Elements.isUnresolved(element) && !element.isConstructor()) { |
| 4585 if (e.isClass()) { | 4594 if (element.isClass()) { |
| 4586 ClassElement cls = e; | 4595 ClassElement cls = element; |
| 4587 cls.ensureResolved(compiler); | 4596 cls.ensureResolved(compiler); |
| 4588 // The unnamed constructor may not exist, so [e] may become unresolved. | 4597 // The unnamed constructor may not exist, so [e] may become unresolved. |
| 4589 e = lookupConstructor(cls, diagnosticNode, ''); | 4598 element = lookupConstructor(cls, diagnosticNode, ''); |
| 4590 } else { | 4599 } else { |
| 4591 e = failOrReturnErroneousElement( | 4600 element = failOrReturnErroneousElement( |
| 4592 e, diagnosticNode, e.name, MessageKind.NOT_A_TYPE, | 4601 element, diagnosticNode, element.name, MessageKind.NOT_A_TYPE, |
| 4593 {'node': diagnosticNode}); | 4602 {'node': diagnosticNode}); |
| 4594 } | 4603 } |
| 4595 } | 4604 } |
| 4596 if (type == null) { | 4605 if (type == null) { |
| 4597 if (Elements.isUnresolved(e)) { | 4606 if (Elements.isUnresolved(element)) { |
| 4598 type = compiler.types.dynamicType; | 4607 type = compiler.types.dynamicType; |
| 4599 } else { | 4608 } else { |
| 4600 type = e.getEnclosingClass().computeType(compiler).asRaw(); | 4609 type = element.getEnclosingClass().computeType(compiler).asRaw(); |
| 4601 } | 4610 } |
| 4602 } | 4611 } |
| 4603 resolver.mapping.setType(expression, type); | 4612 resolver.mapping.setType(expression, type); |
| 4604 return e; | 4613 return element; |
| 4605 } | 4614 } |
| 4606 | 4615 |
| 4607 visitTypeAnnotation(TypeAnnotation node) { | 4616 Element visitTypeAnnotation(TypeAnnotation node) { |
| 4608 assert(invariant(node, type == null)); | 4617 assert(invariant(node, type == null)); |
| 4609 type = resolver.resolveTypeExpression(node); | 4618 type = resolver.resolveTypeAnnotation(node, |
| 4619 malformedIsError: inConstContext); |
| 4610 compiler.backend.registerRequiredType(type, resolver.enclosingElement); | 4620 compiler.backend.registerRequiredType(type, resolver.enclosingElement); |
| 4611 return resolver.mapping[node]; | 4621 return type.element; |
| 4612 } | 4622 } |
| 4613 | 4623 |
| 4614 visitSend(Send node) { | 4624 Element visitSend(Send node) { |
| 4615 Element e = visit(node.receiver); | 4625 Element element = visit(node.receiver); |
| 4616 if (Elements.isUnresolved(e)) return e; | 4626 assert(invariant(node.receiver, element != null, |
| 4627 message: 'No element return for $node.receiver.')); |
| 4628 if (Elements.isUnresolved(element)) return element; |
| 4617 Identifier name = node.selector.asIdentifier(); | 4629 Identifier name = node.selector.asIdentifier(); |
| 4618 if (name == null) internalError(node.selector, 'unexpected node'); | 4630 if (name == null) internalError(node.selector, 'unexpected node'); |
| 4619 | 4631 |
| 4620 if (identical(e.kind, ElementKind.CLASS)) { | 4632 if (element.isClass()) { |
| 4621 ClassElement cls = e; | 4633 ClassElement cls = element; |
| 4622 cls.ensureResolved(compiler); | 4634 cls.ensureResolved(compiler); |
| 4623 return lookupConstructor(cls, name, name.source); | 4635 return lookupConstructor(cls, name, name.source); |
| 4624 } else if (identical(e.kind, ElementKind.PREFIX)) { | 4636 } else if (element.isPrefix()) { |
| 4625 PrefixElement prefix = e; | 4637 PrefixElement prefix = element; |
| 4626 e = prefix.lookupLocalMember(name.source); | 4638 element = prefix.lookupLocalMember(name.source); |
| 4627 e = Elements.unwrap(e, compiler, node); | 4639 element = Elements.unwrap(element, compiler, node); |
| 4628 if (e == null) { | 4640 if (element == null) { |
| 4629 return failOrReturnErroneousElement( | 4641 return failOrReturnErroneousElement( |
| 4630 resolver.enclosingElement, name, | 4642 resolver.enclosingElement, name, |
| 4631 name.source, | 4643 name.source, |
| 4632 MessageKind.CANNOT_RESOLVE, | 4644 MessageKind.CANNOT_RESOLVE, |
| 4633 {'name': name}); | 4645 {'name': name}); |
| 4634 } else if (!identical(e.kind, ElementKind.CLASS)) { | 4646 } else if (!element.isClass()) { |
| 4635 error(node, MessageKind.NOT_A_TYPE.error, {'node': name}); | 4647 error(node, MessageKind.NOT_A_TYPE.error, {'node': name}); |
| 4636 } | 4648 } |
| 4637 } else { | 4649 } else { |
| 4638 internalError(node.receiver, 'unexpected element $e'); | 4650 internalError(node.receiver, 'unexpected element $element'); |
| 4639 } | 4651 } |
| 4640 return e; | 4652 return element; |
| 4641 } | 4653 } |
| 4642 | 4654 |
| 4643 Element visitIdentifier(Identifier node) { | 4655 Element visitIdentifier(Identifier node) { |
| 4644 String name = node.source; | 4656 String name = node.source; |
| 4645 Element e = resolver.reportLookupErrorIfAny( | 4657 Element element = resolver.reportLookupErrorIfAny( |
| 4646 lookupInScope(compiler, node, resolver.scope, name), node, name); | 4658 lookupInScope(compiler, node, resolver.scope, name), node, name); |
| 4647 // TODO(johnniwinther): Change errors to warnings, cf. 11.11.1. | 4659 // TODO(johnniwinther): Change errors to warnings, cf. 11.11.1. |
| 4648 if (e == null) { | 4660 if (element == null) { |
| 4649 return failOrReturnErroneousElement(resolver.enclosingElement, node, name, | 4661 return failOrReturnErroneousElement(resolver.enclosingElement, node, name, |
| 4650 MessageKind.CANNOT_RESOLVE, | 4662 MessageKind.CANNOT_RESOLVE, |
| 4651 {'name': name}); | 4663 {'name': name}); |
| 4652 } else if (e.isErroneous()) { | 4664 } else if (element.isErroneous()) { |
| 4653 return e; | 4665 return element; |
| 4654 } else if (identical(e.kind, ElementKind.TYPEDEF)) { | 4666 } else if (element.isTypedef()) { |
| 4655 error(node, MessageKind.CANNOT_INSTANTIATE_TYPEDEF, | 4667 error(node, MessageKind.CANNOT_INSTANTIATE_TYPEDEF, |
| 4656 {'typedefName': name}); | 4668 {'typedefName': name}); |
| 4657 } else if (identical(e.kind, ElementKind.TYPE_VARIABLE)) { | 4669 } else if (element.isTypeVariable()) { |
| 4658 error(node, MessageKind.CANNOT_INSTANTIATE_TYPE_VARIABLE, | 4670 error(node, MessageKind.CANNOT_INSTANTIATE_TYPE_VARIABLE, |
| 4659 {'typeVariableName': name}); | 4671 {'typeVariableName': name}); |
| 4660 } else if (!identical(e.kind, ElementKind.CLASS) | 4672 } else if (!element.isClass() && !element.isPrefix()) { |
| 4661 && !identical(e.kind, ElementKind.PREFIX)) { | |
| 4662 error(node, MessageKind.NOT_A_TYPE.error, {'node': name}); | 4673 error(node, MessageKind.NOT_A_TYPE.error, {'node': name}); |
| 4663 } | 4674 } |
| 4664 return e; | 4675 return element; |
| 4665 } | 4676 } |
| 4666 | 4677 |
| 4667 /// Assumed to be called by [resolveRedirectingFactory]. | 4678 /// Assumed to be called by [resolveRedirectingFactory]. |
| 4668 Element visitReturn(Return node) { | 4679 Element visitReturn(Return node) { |
| 4669 Node expression = node.expression; | 4680 Node expression = node.expression; |
| 4670 return finishConstructorReference(visit(expression), | 4681 return finishConstructorReference(visit(expression), |
| 4671 expression, expression); | 4682 expression, expression); |
| 4672 } | 4683 } |
| 4673 } | 4684 } |
| 4674 | 4685 |
| 4675 /// Looks up [name] in [scope] and unwraps the result. | 4686 /// Looks up [name] in [scope] and unwraps the result. |
| 4676 Element lookupInScope(Compiler compiler, Node node, | 4687 Element lookupInScope(Compiler compiler, Node node, |
| 4677 Scope scope, String name) { | 4688 Scope scope, String name) { |
| 4678 return Elements.unwrap(scope.lookup(name), compiler, node); | 4689 return Elements.unwrap(scope.lookup(name), compiler, node); |
| 4679 } | 4690 } |
| OLD | NEW |