Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1)

Side by Side Diff: sdk/lib/_internal/compiler/implementation/resolution/members.dart

Issue 34993002: Check const expressions for malformed types. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Status updated Created 7 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « no previous file | sdk/lib/_internal/compiler/implementation/warnings.dart » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
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
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
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
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 }
OLDNEW
« no previous file with comments | « no previous file | sdk/lib/_internal/compiler/implementation/warnings.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698