| 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 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 78 | 78 |
| 79 final int hashCode = ++hashCodeCounter; | 79 final int hashCode = ++hashCodeCounter; |
| 80 static int hashCodeCounter = 0; | 80 static int hashCodeCounter = 0; |
| 81 | 81 |
| 82 TreeElementMapping(this.currentElement); | 82 TreeElementMapping(this.currentElement); |
| 83 | 83 |
| 84 operator []=(Node node, Element element) { | 84 operator []=(Node node, Element element) { |
| 85 assert(invariant(node, () { | 85 assert(invariant(node, () { |
| 86 FunctionExpression functionExpression = node.asFunctionExpression(); | 86 FunctionExpression functionExpression = node.asFunctionExpression(); |
| 87 if (functionExpression != null) { | 87 if (functionExpression != null) { |
| 88 return !functionExpression.modifiers.isExternal(); | 88 return !functionExpression.modifiers.isExternal; |
| 89 } | 89 } |
| 90 return true; | 90 return true; |
| 91 })); | 91 })); |
| 92 // TODO(johnniwinther): Simplify this invariant to use only declarations in | 92 // TODO(johnniwinther): Simplify this invariant to use only declarations in |
| 93 // [TreeElements]. | 93 // [TreeElements]. |
| 94 assert(invariant(node, () { | 94 assert(invariant(node, () { |
| 95 if (!element.isErroneous() && currentElement != null && element.isPatch) { | 95 if (!element.isErroneous && currentElement != null && element.isPatch) { |
| 96 return currentElement.getImplementationLibrary().isPatch; | 96 return currentElement.implementationLibrary.isPatch; |
| 97 } | 97 } |
| 98 return true; | 98 return true; |
| 99 })); | 99 })); |
| 100 // TODO(ahe): Investigate why the invariant below doesn't hold. | 100 // TODO(ahe): Investigate why the invariant below doesn't hold. |
| 101 // assert(invariant(node, | 101 // assert(invariant(node, |
| 102 // getTreeElement(node) == element || | 102 // getTreeElement(node) == element || |
| 103 // getTreeElement(node) == null, | 103 // getTreeElement(node) == null, |
| 104 // message: '${getTreeElement(node)}; $element')); | 104 // message: '${getTreeElement(node)}; $element')); |
| 105 | 105 |
| 106 elements.add(element); | 106 elements.add(element); |
| (...skipping 159 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 266 ElementKind kind = element.kind; | 266 ElementKind kind = element.kind; |
| 267 if (identical(kind, ElementKind.GENERATIVE_CONSTRUCTOR) || | 267 if (identical(kind, ElementKind.GENERATIVE_CONSTRUCTOR) || |
| 268 identical(kind, ElementKind.FUNCTION) || | 268 identical(kind, ElementKind.FUNCTION) || |
| 269 identical(kind, ElementKind.GETTER) || | 269 identical(kind, ElementKind.GETTER) || |
| 270 identical(kind, ElementKind.SETTER)) { | 270 identical(kind, ElementKind.SETTER)) { |
| 271 return resolveMethodElement(element); | 271 return resolveMethodElement(element); |
| 272 } | 272 } |
| 273 | 273 |
| 274 if (identical(kind, ElementKind.FIELD)) return resolveField(element); | 274 if (identical(kind, ElementKind.FIELD)) return resolveField(element); |
| 275 | 275 |
| 276 if (element.isClass()) { | 276 if (element.isClass) { |
| 277 ClassElement cls = element; | 277 ClassElement cls = element; |
| 278 cls.ensureResolved(compiler); | 278 cls.ensureResolved(compiler); |
| 279 return null; | 279 return null; |
| 280 } else if (element.isTypedef()) { | 280 } else if (element.isTypedef) { |
| 281 TypedefElement typdef = element; | 281 TypedefElement typdef = element; |
| 282 return resolveTypedef(typdef); | 282 return resolveTypedef(typdef); |
| 283 } | 283 } |
| 284 | 284 |
| 285 compiler.unimplemented(element, "resolve($element)"); | 285 compiler.unimplemented(element, "resolve($element)"); |
| 286 }); | 286 }); |
| 287 } | 287 } |
| 288 | 288 |
| 289 String constructorNameForDiagnostics(String className, | 289 String constructorNameForDiagnostics(String className, |
| 290 String constructorName) { | 290 String constructorName) { |
| (...skipping 139 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 430 TreeElements resolveMethodElement(FunctionElementX element) { | 430 TreeElements resolveMethodElement(FunctionElementX element) { |
| 431 assert(invariant(element, element.isDeclaration)); | 431 assert(invariant(element, element.isDeclaration)); |
| 432 return compiler.withCurrentElement(element, () { | 432 return compiler.withCurrentElement(element, () { |
| 433 bool isConstructor = | 433 bool isConstructor = |
| 434 identical(element.kind, ElementKind.GENERATIVE_CONSTRUCTOR); | 434 identical(element.kind, ElementKind.GENERATIVE_CONSTRUCTOR); |
| 435 TreeElements elements = | 435 TreeElements elements = |
| 436 compiler.enqueuer.resolution.getCachedElements(element); | 436 compiler.enqueuer.resolution.getCachedElements(element); |
| 437 if (elements != null) { | 437 if (elements != null) { |
| 438 // TODO(karlklose): Remove the check for [isConstructor]. [elememts] | 438 // TODO(karlklose): Remove the check for [isConstructor]. [elememts] |
| 439 // should never be non-null, not even for constructors. | 439 // should never be non-null, not even for constructors. |
| 440 assert(invariant(element, element.isConstructor(), | 440 assert(invariant(element, element.isConstructor, |
| 441 message: 'Non-constructor element $element ' | 441 message: 'Non-constructor element $element ' |
| 442 'has already been analyzed.')); | 442 'has already been analyzed.')); |
| 443 return elements; | 443 return elements; |
| 444 } | 444 } |
| 445 if (element.isSynthesized) { | 445 if (element.isSynthesized) { |
| 446 if (isConstructor) { | 446 if (isConstructor) { |
| 447 TreeElements elements = _ensureTreeElements(element); | 447 TreeElements elements = _ensureTreeElements(element); |
| 448 Element target = element.targetConstructor; | 448 Element target = element.targetConstructor; |
| 449 // Ensure the signature of the synthesized element is | 449 // Ensure the signature of the synthesized element is |
| 450 // resolved. This is the only place where the resolver is | 450 // resolved. This is the only place where the resolver is |
| 451 // seeing this element. | 451 // seeing this element. |
| 452 element.computeSignature(compiler); | 452 element.computeSignature(compiler); |
| 453 if (!target.isErroneous()) { | 453 if (!target.isErroneous) { |
| 454 compiler.enqueuer.resolution.registerStaticUse(target); | 454 compiler.enqueuer.resolution.registerStaticUse(target); |
| 455 compiler.world.registerImplicitSuperCall(elements, target); | 455 compiler.world.registerImplicitSuperCall(elements, target); |
| 456 } | 456 } |
| 457 return elements; | 457 return elements; |
| 458 } else { | 458 } else { |
| 459 assert(element.isDeferredLoaderGetter()); | 459 assert(element.isDeferredLoaderGetter); |
| 460 return _ensureTreeElements(element); | 460 return _ensureTreeElements(element); |
| 461 } | 461 } |
| 462 } | 462 } |
| 463 element.parseNode(compiler); | 463 element.parseNode(compiler); |
| 464 element.computeType(compiler); | 464 element.computeType(compiler); |
| 465 if (element.isPatched) { | 465 if (element.isPatched) { |
| 466 FunctionElementX patch = element.patch; | 466 FunctionElementX patch = element.patch; |
| 467 compiler.withCurrentElement(patch, () { | 467 compiler.withCurrentElement(patch, () { |
| 468 patch.parseNode(compiler); | 468 patch.parseNode(compiler); |
| 469 patch.computeSignature(compiler); | 469 patch.computeSignature(compiler); |
| 470 }); | 470 }); |
| 471 checkMatchingPatchSignatures(element, patch); | 471 checkMatchingPatchSignatures(element, patch); |
| 472 element = patch; | 472 element = patch; |
| 473 } | 473 } |
| 474 return compiler.withCurrentElement(element, () { | 474 return compiler.withCurrentElement(element, () { |
| 475 FunctionExpression tree = element.node; | 475 FunctionExpression tree = element.node; |
| 476 if (tree.modifiers.isExternal()) { | 476 if (tree.modifiers.isExternal) { |
| 477 error(tree, MessageKind.PATCH_EXTERNAL_WITHOUT_IMPLEMENTATION); | 477 error(tree, MessageKind.PATCH_EXTERNAL_WITHOUT_IMPLEMENTATION); |
| 478 return null; | 478 return null; |
| 479 } | 479 } |
| 480 if (isConstructor || element.isFactoryConstructor()) { | 480 if (isConstructor || element.isFactoryConstructor) { |
| 481 if (tree.returnType != null) { | 481 if (tree.returnType != null) { |
| 482 error(tree, MessageKind.CONSTRUCTOR_WITH_RETURN_TYPE); | 482 error(tree, MessageKind.CONSTRUCTOR_WITH_RETURN_TYPE); |
| 483 } | 483 } |
| 484 if (element.modifiers.isConst() && | 484 if (element.modifiers.isConst && |
| 485 tree.hasBody() && | 485 tree.hasBody() && |
| 486 !tree.isRedirectingFactory) { | 486 !tree.isRedirectingFactory) { |
| 487 compiler.reportError(tree, MessageKind.CONST_CONSTRUCTOR_HAS_BODY); | 487 compiler.reportError(tree, MessageKind.CONST_CONSTRUCTOR_HAS_BODY); |
| 488 } | 488 } |
| 489 } | 489 } |
| 490 | 490 |
| 491 ResolverVisitor visitor = visitorFor(element); | 491 ResolverVisitor visitor = visitorFor(element); |
| 492 visitor.useElement(tree, element); | 492 visitor.useElement(tree, element); |
| 493 visitor.setupFunction(tree, element); | 493 visitor.setupFunction(tree, element); |
| 494 | 494 |
| (...skipping 17 matching lines...) Expand all Loading... |
| 512 // we can analyze compile-time constants. | 512 // we can analyze compile-time constants. |
| 513 visitor.visit(tree.body); | 513 visitor.visit(tree.body); |
| 514 } | 514 } |
| 515 | 515 |
| 516 // Get the resolution tree and check that the resolved | 516 // Get the resolution tree and check that the resolved |
| 517 // function doesn't use 'super' if it is mixed into another | 517 // function doesn't use 'super' if it is mixed into another |
| 518 // class. This is the part of the 'super' mixin check that | 518 // class. This is the part of the 'super' mixin check that |
| 519 // happens when a function is resolved after the mixin | 519 // happens when a function is resolved after the mixin |
| 520 // application has been performed. | 520 // application has been performed. |
| 521 TreeElements resolutionTree = visitor.mapping; | 521 TreeElements resolutionTree = visitor.mapping; |
| 522 ClassElement enclosingClass = element.getEnclosingClass(); | 522 ClassElement enclosingClass = element.enclosingClass; |
| 523 if (enclosingClass != null) { | 523 if (enclosingClass != null) { |
| 524 Set<MixinApplicationElement> mixinUses = | 524 Set<MixinApplicationElement> mixinUses = |
| 525 compiler.world.mixinUses[enclosingClass]; | 525 compiler.world.mixinUses[enclosingClass]; |
| 526 if (mixinUses != null) { | 526 if (mixinUses != null) { |
| 527 ClassElement mixin = enclosingClass; | 527 ClassElement mixin = enclosingClass; |
| 528 for (MixinApplicationElement mixinApplication in mixinUses) { | 528 for (MixinApplicationElement mixinApplication in mixinUses) { |
| 529 checkMixinSuperUses(resolutionTree, mixinApplication, mixin); | 529 checkMixinSuperUses(resolutionTree, mixinApplication, mixin); |
| 530 } | 530 } |
| 531 } | 531 } |
| 532 } | 532 } |
| 533 return resolutionTree; | 533 return resolutionTree; |
| 534 }); | 534 }); |
| 535 }); | 535 }); |
| 536 } | 536 } |
| 537 | 537 |
| 538 /// This method should only be used by this library (or tests of | 538 /// This method should only be used by this library (or tests of |
| 539 /// this library). | 539 /// this library). |
| 540 ResolverVisitor visitorFor(Element element) { | 540 ResolverVisitor visitorFor(Element element) { |
| 541 return new ResolverVisitor(compiler, element, _ensureTreeElements(element)); | 541 return new ResolverVisitor(compiler, element, _ensureTreeElements(element)); |
| 542 } | 542 } |
| 543 | 543 |
| 544 TreeElements resolveField(VariableElementX element) { | 544 TreeElements resolveField(VariableElementX element) { |
| 545 VariableDefinitions tree = element.parseNode(compiler); | 545 VariableDefinitions tree = element.parseNode(compiler); |
| 546 if(element.modifiers.isStatic() && element.isTopLevel()) { | 546 if(element.modifiers.isStatic && element.isTopLevel) { |
| 547 error(element.modifiers.getStatic(), | 547 error(element.modifiers.getStatic(), |
| 548 MessageKind.TOP_LEVEL_VARIABLE_DECLARED_STATIC); | 548 MessageKind.TOP_LEVEL_VARIABLE_DECLARED_STATIC); |
| 549 } | 549 } |
| 550 ResolverVisitor visitor = visitorFor(element); | 550 ResolverVisitor visitor = visitorFor(element); |
| 551 // TODO(johnniwinther): Share the resolved type between all variables | 551 // TODO(johnniwinther): Share the resolved type between all variables |
| 552 // declared in the same declaration. | 552 // declared in the same declaration. |
| 553 if (tree.type != null) { | 553 if (tree.type != null) { |
| 554 element.variables.type = visitor.resolveTypeAnnotation(tree.type); | 554 element.variables.type = visitor.resolveTypeAnnotation(tree.type); |
| 555 } else { | 555 } else { |
| 556 element.variables.type = compiler.types.dynamicType; | 556 element.variables.type = compiler.types.dynamicType; |
| 557 } | 557 } |
| 558 visitor.useElement(tree, element); | 558 visitor.useElement(tree, element); |
| 559 | 559 |
| 560 Expression initializer = element.initializer; | 560 Expression initializer = element.initializer; |
| 561 Modifiers modifiers = element.modifiers; | 561 Modifiers modifiers = element.modifiers; |
| 562 if (initializer != null) { | 562 if (initializer != null) { |
| 563 // TODO(johnniwinther): Avoid analyzing initializers if | 563 // TODO(johnniwinther): Avoid analyzing initializers if |
| 564 // [Compiler.analyzeSignaturesOnly] is set. | 564 // [Compiler.analyzeSignaturesOnly] is set. |
| 565 visitor.visit(initializer); | 565 visitor.visit(initializer); |
| 566 } else if (modifiers.isConst()) { | 566 } else if (modifiers.isConst) { |
| 567 compiler.reportError(element, MessageKind.CONST_WITHOUT_INITIALIZER); | 567 compiler.reportError(element, MessageKind.CONST_WITHOUT_INITIALIZER); |
| 568 } else if (modifiers.isFinal() && !element.isInstanceMember()) { | 568 } else if (modifiers.isFinal && !element.isInstanceMember) { |
| 569 compiler.reportError(element, MessageKind.FINAL_WITHOUT_INITIALIZER); | 569 compiler.reportError(element, MessageKind.FINAL_WITHOUT_INITIALIZER); |
| 570 } else { | 570 } else { |
| 571 compiler.enqueuer.resolution.registerInstantiatedClass( | 571 compiler.enqueuer.resolution.registerInstantiatedClass( |
| 572 compiler.nullClass, visitor.mapping); | 572 compiler.nullClass, visitor.mapping); |
| 573 } | 573 } |
| 574 | 574 |
| 575 if (Elements.isStaticOrTopLevelField(element)) { | 575 if (Elements.isStaticOrTopLevelField(element)) { |
| 576 visitor.addDeferredAction(element, () { | 576 visitor.addDeferredAction(element, () { |
| 577 if (element.modifiers.isConst()) { | 577 if (element.modifiers.isConst) { |
| 578 constantCompiler.compileConstant(element); | 578 constantCompiler.compileConstant(element); |
| 579 } else { | 579 } else { |
| 580 constantCompiler.compileVariable(element); | 580 constantCompiler.compileVariable(element); |
| 581 } | 581 } |
| 582 }); | 582 }); |
| 583 if (initializer != null) { | 583 if (initializer != null) { |
| 584 if (!element.modifiers.isConst()) { | 584 if (!element.modifiers.isConst) { |
| 585 // TODO(johnniwinther): Determine the const-ness eagerly to avoid | 585 // TODO(johnniwinther): Determine the const-ness eagerly to avoid |
| 586 // unnecessary registrations. | 586 // unnecessary registrations. |
| 587 compiler.backend.registerLazyField(visitor.mapping); | 587 compiler.backend.registerLazyField(visitor.mapping); |
| 588 } | 588 } |
| 589 } | 589 } |
| 590 } | 590 } |
| 591 | 591 |
| 592 // Perform various checks as side effect of "computing" the type. | 592 // Perform various checks as side effect of "computing" the type. |
| 593 element.computeType(compiler); | 593 element.computeType(compiler); |
| 594 | 594 |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 633 if (seen.contains(nextTarget)) { | 633 if (seen.contains(nextTarget)) { |
| 634 error(node, MessageKind.CYCLIC_REDIRECTING_FACTORY); | 634 error(node, MessageKind.CYCLIC_REDIRECTING_FACTORY); |
| 635 break; | 635 break; |
| 636 } | 636 } |
| 637 seen.add(target); | 637 seen.add(target); |
| 638 target = nextTarget; | 638 target = nextTarget; |
| 639 } | 639 } |
| 640 | 640 |
| 641 if (targetType == null) { | 641 if (targetType == null) { |
| 642 assert(!target.isRedirectingFactory); | 642 assert(!target.isRedirectingFactory); |
| 643 targetType = target.getEnclosingClass().thisType; | 643 targetType = target.enclosingClass.thisType; |
| 644 } | 644 } |
| 645 | 645 |
| 646 // [target] is now the actual target of the redirections. Run through | 646 // [target] is now the actual target of the redirections. Run through |
| 647 // the constructors again and set their [redirectionTarget], so that we | 647 // the constructors again and set their [redirectionTarget], so that we |
| 648 // do not have to run the loop for these constructors again. Furthermore, | 648 // do not have to run the loop for these constructors again. Furthermore, |
| 649 // compute [redirectionTargetType] for each factory by computing the | 649 // compute [redirectionTargetType] for each factory by computing the |
| 650 // substitution of the target type with respect to the factory type. | 650 // substitution of the target type with respect to the factory type. |
| 651 while (!seen.isEmpty) { | 651 while (!seen.isEmpty) { |
| 652 FunctionElementX factory = seen.removeLast(); | 652 FunctionElementX factory = seen.removeLast(); |
| 653 | 653 |
| (...skipping 164 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 818 element.isProxy = true; | 818 element.isProxy = true; |
| 819 } | 819 } |
| 820 } | 820 } |
| 821 | 821 |
| 822 // Force resolution of metadata on non-instance members since they may be | 822 // Force resolution of metadata on non-instance members since they may be |
| 823 // inspected by the backend while emitting. Metadata on instance members is | 823 // inspected by the backend while emitting. Metadata on instance members is |
| 824 // handled as a result of processing instantiated class members in the | 824 // handled as a result of processing instantiated class members in the |
| 825 // enqueuer. | 825 // enqueuer. |
| 826 // TODO(ahe): Avoid this eager resolution. | 826 // TODO(ahe): Avoid this eager resolution. |
| 827 element.forEachMember((_, Element member) { | 827 element.forEachMember((_, Element member) { |
| 828 if (!member.isInstanceMember()) { | 828 if (!member.isInstanceMember) { |
| 829 compiler.withCurrentElement(member, () { | 829 compiler.withCurrentElement(member, () { |
| 830 for (MetadataAnnotation metadata in member.metadata) { | 830 for (MetadataAnnotation metadata in member.metadata) { |
| 831 metadata.ensureResolved(compiler); | 831 metadata.ensureResolved(compiler); |
| 832 } | 832 } |
| 833 }); | 833 }); |
| 834 } | 834 } |
| 835 }); | 835 }); |
| 836 | 836 |
| 837 computeClassMember(element, Compiler.CALL_OPERATOR_NAME); | 837 computeClassMember(element, Compiler.CALL_OPERATOR_NAME); |
| 838 } | 838 } |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 880 } | 880 } |
| 881 | 881 |
| 882 // Check that the mixed in class has Object as its superclass. | 882 // Check that the mixed in class has Object as its superclass. |
| 883 if (!mixin.superclass.isObject(compiler)) { | 883 if (!mixin.superclass.isObject(compiler)) { |
| 884 compiler.reportError(mixin, MessageKind.ILLEGAL_MIXIN_SUPERCLASS); | 884 compiler.reportError(mixin, MessageKind.ILLEGAL_MIXIN_SUPERCLASS); |
| 885 } | 885 } |
| 886 | 886 |
| 887 // Check that the mixed in class doesn't have any constructors and | 887 // Check that the mixed in class doesn't have any constructors and |
| 888 // make sure we aren't mixing in methods that use 'super'. | 888 // make sure we aren't mixing in methods that use 'super'. |
| 889 mixin.forEachLocalMember((Element member) { | 889 mixin.forEachLocalMember((Element member) { |
| 890 if (member.isGenerativeConstructor() && !member.isSynthesized) { | 890 if (member.isGenerativeConstructor && !member.isSynthesized) { |
| 891 compiler.reportError(member, MessageKind.ILLEGAL_MIXIN_CONSTRUCTOR); | 891 compiler.reportError(member, MessageKind.ILLEGAL_MIXIN_CONSTRUCTOR); |
| 892 } else { | 892 } else { |
| 893 // Get the resolution tree and check that the resolved member | 893 // Get the resolution tree and check that the resolved member |
| 894 // doesn't use 'super'. This is the part of the 'super' mixin | 894 // doesn't use 'super'. This is the part of the 'super' mixin |
| 895 // check that happens when a function is resolved before the | 895 // check that happens when a function is resolved before the |
| 896 // mixin application has been performed. | 896 // mixin application has been performed. |
| 897 checkMixinSuperUses( | 897 checkMixinSuperUses( |
| 898 compiler.enqueuer.resolution.resolvedElements[member], | 898 compiler.enqueuer.resolution.resolvedElements[member], |
| 899 mixinApplication, | 899 mixinApplication, |
| 900 mixin); | 900 mixin); |
| (...skipping 24 matching lines...) Expand all Loading... |
| 925 // TODO(johnniwinther): Should this be done on the implementation element as | 925 // TODO(johnniwinther): Should this be done on the implementation element as |
| 926 // well? | 926 // well? |
| 927 List<Element> constConstructors = <Element>[]; | 927 List<Element> constConstructors = <Element>[]; |
| 928 List<Element> nonFinalInstanceFields = <Element>[]; | 928 List<Element> nonFinalInstanceFields = <Element>[]; |
| 929 cls.forEachMember((holder, member) { | 929 cls.forEachMember((holder, member) { |
| 930 compiler.withCurrentElement(member, () { | 930 compiler.withCurrentElement(member, () { |
| 931 // Perform various checks as side effect of "computing" the type. | 931 // Perform various checks as side effect of "computing" the type. |
| 932 member.computeType(compiler); | 932 member.computeType(compiler); |
| 933 | 933 |
| 934 // Check modifiers. | 934 // Check modifiers. |
| 935 if (member.isFunction() && member.modifiers.isFinal()) { | 935 if (member.isFunction && member.modifiers.isFinal) { |
| 936 compiler.reportError( | 936 compiler.reportError( |
| 937 member, MessageKind.ILLEGAL_FINAL_METHOD_MODIFIER); | 937 member, MessageKind.ILLEGAL_FINAL_METHOD_MODIFIER); |
| 938 } | 938 } |
| 939 if (member.isConstructor()) { | 939 if (member.isConstructor) { |
| 940 final mismatchedFlagsBits = | 940 final mismatchedFlagsBits = |
| 941 member.modifiers.flags & | 941 member.modifiers.flags & |
| 942 (Modifiers.FLAG_STATIC | Modifiers.FLAG_ABSTRACT); | 942 (Modifiers.FLAG_STATIC | Modifiers.FLAG_ABSTRACT); |
| 943 if (mismatchedFlagsBits != 0) { | 943 if (mismatchedFlagsBits != 0) { |
| 944 final mismatchedFlags = | 944 final mismatchedFlags = |
| 945 new Modifiers.withFlags(null, mismatchedFlagsBits); | 945 new Modifiers.withFlags(null, mismatchedFlagsBits); |
| 946 compiler.reportError( | 946 compiler.reportError( |
| 947 member, | 947 member, |
| 948 MessageKind.ILLEGAL_CONSTRUCTOR_MODIFIERS, | 948 MessageKind.ILLEGAL_CONSTRUCTOR_MODIFIERS, |
| 949 {'modifiers': mismatchedFlags}); | 949 {'modifiers': mismatchedFlags}); |
| 950 } | 950 } |
| 951 if (member.modifiers.isConst()) { | 951 if (member.modifiers.isConst) { |
| 952 constConstructors.add(member); | 952 constConstructors.add(member); |
| 953 } | 953 } |
| 954 } | 954 } |
| 955 if (member.isField()) { | 955 if (member.isField) { |
| 956 if (!member.modifiers.isStatic() && | 956 if (!member.modifiers.isStatic && |
| 957 !member.modifiers.isFinal()) { | 957 !member.modifiers.isFinal) { |
| 958 nonFinalInstanceFields.add(member); | 958 nonFinalInstanceFields.add(member); |
| 959 } | 959 } |
| 960 } | 960 } |
| 961 checkAbstractField(member); | 961 checkAbstractField(member); |
| 962 checkUserDefinableOperator(member); | 962 checkUserDefinableOperator(member); |
| 963 }); | 963 }); |
| 964 }); | 964 }); |
| 965 if (!constConstructors.isEmpty && !nonFinalInstanceFields.isEmpty) { | 965 if (!constConstructors.isEmpty && !nonFinalInstanceFields.isEmpty) { |
| 966 Spannable span = constConstructors.length > 1 | 966 Spannable span = constConstructors.length > 1 |
| 967 ? cls : constConstructors[0]; | 967 ? cls : constConstructors[0]; |
| (...skipping 10 matching lines...) Expand all Loading... |
| 978 compiler.reportInfo(field, | 978 compiler.reportInfo(field, |
| 979 MessageKind.CONST_CONSTRUCTOR_WITH_NONFINAL_FIELDS_FIELD); | 979 MessageKind.CONST_CONSTRUCTOR_WITH_NONFINAL_FIELDS_FIELD); |
| 980 } | 980 } |
| 981 } | 981 } |
| 982 } | 982 } |
| 983 | 983 |
| 984 void checkAbstractField(Element member) { | 984 void checkAbstractField(Element member) { |
| 985 // Only check for getters. The test can only fail if there is both a setter | 985 // Only check for getters. The test can only fail if there is both a setter |
| 986 // and a getter with the same name, and we only need to check each abstract | 986 // and a getter with the same name, and we only need to check each abstract |
| 987 // field once, so we just ignore setters. | 987 // field once, so we just ignore setters. |
| 988 if (!member.isGetter()) return; | 988 if (!member.isGetter) return; |
| 989 | 989 |
| 990 // Find the associated abstract field. | 990 // Find the associated abstract field. |
| 991 ClassElement classElement = member.getEnclosingClass(); | 991 ClassElement classElement = member.enclosingClass; |
| 992 Element lookupElement = classElement.lookupLocalMember(member.name); | 992 Element lookupElement = classElement.lookupLocalMember(member.name); |
| 993 if (lookupElement == null) { | 993 if (lookupElement == null) { |
| 994 compiler.internalError(member, | 994 compiler.internalError(member, |
| 995 "No abstract field for accessor"); | 995 "No abstract field for accessor"); |
| 996 } else if (!identical(lookupElement.kind, ElementKind.ABSTRACT_FIELD)) { | 996 } else if (!identical(lookupElement.kind, ElementKind.ABSTRACT_FIELD)) { |
| 997 compiler.internalError(member, | 997 compiler.internalError(member, |
| 998 "Inaccessible abstract field for accessor"); | 998 "Inaccessible abstract field for accessor"); |
| 999 } | 999 } |
| 1000 AbstractFieldElement field = lookupElement; | 1000 AbstractFieldElement field = lookupElement; |
| 1001 | 1001 |
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1047 requiredParameterCount = 2; | 1047 requiredParameterCount = 2; |
| 1048 } else { | 1048 } else { |
| 1049 compiler.internalError(function, | 1049 compiler.internalError(function, |
| 1050 'Unexpected user defined operator $value'); | 1050 'Unexpected user defined operator $value'); |
| 1051 } | 1051 } |
| 1052 checkArity(function, requiredParameterCount, messageKind, isMinus); | 1052 checkArity(function, requiredParameterCount, messageKind, isMinus); |
| 1053 } | 1053 } |
| 1054 | 1054 |
| 1055 void checkOverrideHashCode(FunctionElement operatorEquals) { | 1055 void checkOverrideHashCode(FunctionElement operatorEquals) { |
| 1056 if (operatorEquals.isAbstract) return; | 1056 if (operatorEquals.isAbstract) return; |
| 1057 ClassElement cls = operatorEquals.getEnclosingClass(); | 1057 ClassElement cls = operatorEquals.enclosingClass; |
| 1058 Element hashCodeImplementation = | 1058 Element hashCodeImplementation = |
| 1059 cls.lookupLocalMember('hashCode'); | 1059 cls.lookupLocalMember('hashCode'); |
| 1060 if (hashCodeImplementation != null) return; | 1060 if (hashCodeImplementation != null) return; |
| 1061 compiler.reportHint( | 1061 compiler.reportHint( |
| 1062 operatorEquals, MessageKind.OVERRIDE_EQUALS_NOT_HASH_CODE, | 1062 operatorEquals, MessageKind.OVERRIDE_EQUALS_NOT_HASH_CODE, |
| 1063 {'class': cls.name}); | 1063 {'class': cls.name}); |
| 1064 } | 1064 } |
| 1065 | 1065 |
| 1066 void checkArity(FunctionElement function, | 1066 void checkArity(FunctionElement function, |
| 1067 int requiredParameterCount, MessageKind messageKind, | 1067 int requiredParameterCount, MessageKind messageKind, |
| (...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1120 } | 1120 } |
| 1121 | 1121 |
| 1122 reportErrorWithContext(Element errorneousElement, | 1122 reportErrorWithContext(Element errorneousElement, |
| 1123 MessageKind errorMessage, | 1123 MessageKind errorMessage, |
| 1124 Element contextElement, | 1124 Element contextElement, |
| 1125 MessageKind contextMessage) { | 1125 MessageKind contextMessage) { |
| 1126 compiler.reportError( | 1126 compiler.reportError( |
| 1127 errorneousElement, | 1127 errorneousElement, |
| 1128 errorMessage, | 1128 errorMessage, |
| 1129 {'memberName': contextElement.name, | 1129 {'memberName': contextElement.name, |
| 1130 'className': contextElement.getEnclosingClass().name}); | 1130 'className': contextElement.enclosingClass.name}); |
| 1131 compiler.reportInfo(contextElement, contextMessage); | 1131 compiler.reportInfo(contextElement, contextMessage); |
| 1132 } | 1132 } |
| 1133 | 1133 |
| 1134 | 1134 |
| 1135 FunctionSignature resolveSignature(FunctionElementX element) { | 1135 FunctionSignature resolveSignature(FunctionElementX element) { |
| 1136 MessageKind defaultValuesError = null; | 1136 MessageKind defaultValuesError = null; |
| 1137 if (element.isFactoryConstructor()) { | 1137 if (element.isFactoryConstructor) { |
| 1138 FunctionExpression body = element.parseNode(compiler); | 1138 FunctionExpression body = element.parseNode(compiler); |
| 1139 if (body.isRedirectingFactory) { | 1139 if (body.isRedirectingFactory) { |
| 1140 defaultValuesError = MessageKind.REDIRECTING_FACTORY_WITH_DEFAULT; | 1140 defaultValuesError = MessageKind.REDIRECTING_FACTORY_WITH_DEFAULT; |
| 1141 } | 1141 } |
| 1142 } | 1142 } |
| 1143 return compiler.withCurrentElement(element, () { | 1143 return compiler.withCurrentElement(element, () { |
| 1144 FunctionExpression node = | 1144 FunctionExpression node = |
| 1145 compiler.parser.measure(() => element.parseNode(compiler)); | 1145 compiler.parser.measure(() => element.parseNode(compiler)); |
| 1146 return measure(() => SignatureResolver.analyze( | 1146 return measure(() => SignatureResolver.analyze( |
| 1147 compiler, node.parameters, node.returnType, element, | 1147 compiler, node.parameters, node.returnType, element, |
| (...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1246 existing, | 1246 existing, |
| 1247 MessageKind.ALREADY_INITIALIZED, {'fieldName': field.name}); | 1247 MessageKind.ALREADY_INITIALIZED, {'fieldName': field.name}); |
| 1248 } | 1248 } |
| 1249 | 1249 |
| 1250 void checkForDuplicateInitializers(VariableElement field, Node init) { | 1250 void checkForDuplicateInitializers(VariableElement field, Node init) { |
| 1251 // [field] can be null if it could not be resolved. | 1251 // [field] can be null if it could not be resolved. |
| 1252 if (field == null) return; | 1252 if (field == null) return; |
| 1253 String name = field.name; | 1253 String name = field.name; |
| 1254 if (initialized.containsKey(field)) { | 1254 if (initialized.containsKey(field)) { |
| 1255 reportDuplicateInitializerError(field, init, initialized[field]); | 1255 reportDuplicateInitializerError(field, init, initialized[field]); |
| 1256 } else if (field.modifiers.isFinal()) { | 1256 } else if (field.modifiers.isFinal) { |
| 1257 field.parseNode(visitor.compiler); | 1257 field.parseNode(visitor.compiler); |
| 1258 Expression initializer = field.initializer; | 1258 Expression initializer = field.initializer; |
| 1259 if (initializer != null) { | 1259 if (initializer != null) { |
| 1260 reportDuplicateInitializerError(field, init, initializer); | 1260 reportDuplicateInitializerError(field, init, initializer); |
| 1261 } | 1261 } |
| 1262 } | 1262 } |
| 1263 initialized[field] = init; | 1263 initialized[field] = init; |
| 1264 } | 1264 } |
| 1265 | 1265 |
| 1266 void resolveFieldInitializer(FunctionElement constructor, SendSet init) { | 1266 void resolveFieldInitializer(FunctionElement constructor, SendSet init) { |
| 1267 // init is of the form [this.]field = value. | 1267 // init is of the form [this.]field = value. |
| 1268 final Node selector = init.selector; | 1268 final Node selector = init.selector; |
| 1269 final String name = selector.asIdentifier().source; | 1269 final String name = selector.asIdentifier().source; |
| 1270 // Lookup target field. | 1270 // Lookup target field. |
| 1271 Element target; | 1271 Element target; |
| 1272 if (isFieldInitializer(init)) { | 1272 if (isFieldInitializer(init)) { |
| 1273 target = constructor.getEnclosingClass().lookupLocalMember(name); | 1273 target = constructor.enclosingClass.lookupLocalMember(name); |
| 1274 if (target == null) { | 1274 if (target == null) { |
| 1275 error(selector, MessageKind.CANNOT_RESOLVE, {'name': name}); | 1275 error(selector, MessageKind.CANNOT_RESOLVE, {'name': name}); |
| 1276 } else if (target.kind != ElementKind.FIELD) { | 1276 } else if (target.kind != ElementKind.FIELD) { |
| 1277 error(selector, MessageKind.NOT_A_FIELD, {'fieldName': name}); | 1277 error(selector, MessageKind.NOT_A_FIELD, {'fieldName': name}); |
| 1278 } else if (!target.isInstanceMember()) { | 1278 } else if (!target.isInstanceMember) { |
| 1279 error(selector, MessageKind.INIT_STATIC_FIELD, {'fieldName': name}); | 1279 error(selector, MessageKind.INIT_STATIC_FIELD, {'fieldName': name}); |
| 1280 } | 1280 } |
| 1281 } else { | 1281 } else { |
| 1282 error(init, MessageKind.INVALID_RECEIVER_IN_INITIALIZER); | 1282 error(init, MessageKind.INVALID_RECEIVER_IN_INITIALIZER); |
| 1283 } | 1283 } |
| 1284 visitor.useElement(init, target); | 1284 visitor.useElement(init, target); |
| 1285 visitor.world.registerStaticUse(target); | 1285 visitor.world.registerStaticUse(target); |
| 1286 checkForDuplicateInitializers(target, init); | 1286 checkForDuplicateInitializers(target, init); |
| 1287 // Resolve initializing value. | 1287 // Resolve initializing value. |
| 1288 visitor.visitInStaticContext(init.arguments.head); | 1288 visitor.visitInStaticContext(init.arguments.head); |
| 1289 } | 1289 } |
| 1290 | 1290 |
| 1291 ClassElement getSuperOrThisLookupTarget(FunctionElement constructor, | 1291 ClassElement getSuperOrThisLookupTarget(FunctionElement constructor, |
| 1292 bool isSuperCall, | 1292 bool isSuperCall, |
| 1293 Node diagnosticNode) { | 1293 Node diagnosticNode) { |
| 1294 ClassElement lookupTarget = constructor.getEnclosingClass(); | 1294 ClassElement lookupTarget = constructor.enclosingClass; |
| 1295 if (isSuperCall) { | 1295 if (isSuperCall) { |
| 1296 // Calculate correct lookup target and constructor name. | 1296 // Calculate correct lookup target and constructor name. |
| 1297 if (identical(lookupTarget, visitor.compiler.objectClass)) { | 1297 if (identical(lookupTarget, visitor.compiler.objectClass)) { |
| 1298 error(diagnosticNode, MessageKind.SUPER_INITIALIZER_IN_OBJECT); | 1298 error(diagnosticNode, MessageKind.SUPER_INITIALIZER_IN_OBJECT); |
| 1299 } else { | 1299 } else { |
| 1300 return lookupTarget.supertype.element; | 1300 return lookupTarget.supertype.element; |
| 1301 } | 1301 } |
| 1302 } | 1302 } |
| 1303 return lookupTarget; | 1303 return lookupTarget; |
| 1304 } | 1304 } |
| (...skipping 29 matching lines...) Expand all Loading... |
| 1334 constructorSelector); | 1334 constructorSelector); |
| 1335 | 1335 |
| 1336 visitor.useElement(call, calledConstructor); | 1336 visitor.useElement(call, calledConstructor); |
| 1337 visitor.world.registerStaticUse(calledConstructor); | 1337 visitor.world.registerStaticUse(calledConstructor); |
| 1338 return calledConstructor; | 1338 return calledConstructor; |
| 1339 } | 1339 } |
| 1340 | 1340 |
| 1341 void resolveImplicitSuperConstructorSend(FunctionElement constructor, | 1341 void resolveImplicitSuperConstructorSend(FunctionElement constructor, |
| 1342 FunctionExpression functionNode) { | 1342 FunctionExpression functionNode) { |
| 1343 // If the class has a super resolve the implicit super call. | 1343 // If the class has a super resolve the implicit super call. |
| 1344 ClassElement classElement = constructor.getEnclosingClass(); | 1344 ClassElement classElement = constructor.enclosingClass; |
| 1345 ClassElement superClass = classElement.superclass; | 1345 ClassElement superClass = classElement.superclass; |
| 1346 if (classElement != visitor.compiler.objectClass) { | 1346 if (classElement != visitor.compiler.objectClass) { |
| 1347 assert(superClass != null); | 1347 assert(superClass != null); |
| 1348 assert(superClass.resolutionState == STATE_DONE); | 1348 assert(superClass.resolutionState == STATE_DONE); |
| 1349 String constructorName = ''; | 1349 String constructorName = ''; |
| 1350 Selector callToMatch = new Selector.call( | 1350 Selector callToMatch = new Selector.call( |
| 1351 constructorName, | 1351 constructorName, |
| 1352 classElement.getLibrary(), | 1352 classElement.library, |
| 1353 0); | 1353 0); |
| 1354 | 1354 |
| 1355 final bool isSuperCall = true; | 1355 final bool isSuperCall = true; |
| 1356 ClassElement lookupTarget = getSuperOrThisLookupTarget(constructor, | 1356 ClassElement lookupTarget = getSuperOrThisLookupTarget(constructor, |
| 1357 isSuperCall, | 1357 isSuperCall, |
| 1358 functionNode); | 1358 functionNode); |
| 1359 Selector constructorSelector = new Selector.callDefaultConstructor( | 1359 Selector constructorSelector = new Selector.callDefaultConstructor( |
| 1360 visitor.enclosingElement.getLibrary()); | 1360 visitor.enclosingElement.library); |
| 1361 Element calledConstructor = lookupTarget.lookupConstructor( | 1361 Element calledConstructor = lookupTarget.lookupConstructor( |
| 1362 constructorSelector); | 1362 constructorSelector); |
| 1363 | 1363 |
| 1364 final String className = lookupTarget.name; | 1364 final String className = lookupTarget.name; |
| 1365 final bool isImplicitSuperCall = true; | 1365 final bool isImplicitSuperCall = true; |
| 1366 verifyThatConstructorMatchesCall(constructor, | 1366 verifyThatConstructorMatchesCall(constructor, |
| 1367 calledConstructor, | 1367 calledConstructor, |
| 1368 callToMatch, | 1368 callToMatch, |
| 1369 isImplicitSuperCall, | 1369 isImplicitSuperCall, |
| 1370 functionNode, | 1370 functionNode, |
| 1371 className, | 1371 className, |
| 1372 constructorSelector); | 1372 constructorSelector); |
| 1373 visitor.compiler.world | 1373 visitor.compiler.world |
| 1374 .registerImplicitSuperCall(visitor.mapping, calledConstructor); | 1374 .registerImplicitSuperCall(visitor.mapping, calledConstructor); |
| 1375 visitor.world.registerStaticUse(calledConstructor); | 1375 visitor.world.registerStaticUse(calledConstructor); |
| 1376 } | 1376 } |
| 1377 } | 1377 } |
| 1378 | 1378 |
| 1379 void verifyThatConstructorMatchesCall( | 1379 void verifyThatConstructorMatchesCall( |
| 1380 FunctionElement caller, | 1380 FunctionElement caller, |
| 1381 FunctionElement lookedupConstructor, | 1381 FunctionElement lookedupConstructor, |
| 1382 Selector call, | 1382 Selector call, |
| 1383 bool isImplicitSuperCall, | 1383 bool isImplicitSuperCall, |
| 1384 Node diagnosticNode, | 1384 Node diagnosticNode, |
| 1385 String className, | 1385 String className, |
| 1386 Selector constructorSelector) { | 1386 Selector constructorSelector) { |
| 1387 if (lookedupConstructor == null | 1387 if (lookedupConstructor == null |
| 1388 || !lookedupConstructor.isGenerativeConstructor()) { | 1388 || !lookedupConstructor.isGenerativeConstructor) { |
| 1389 var fullConstructorName = | 1389 var fullConstructorName = |
| 1390 visitor.compiler.resolver.constructorNameForDiagnostics( | 1390 visitor.compiler.resolver.constructorNameForDiagnostics( |
| 1391 className, | 1391 className, |
| 1392 constructorSelector.name); | 1392 constructorSelector.name); |
| 1393 MessageKind kind = isImplicitSuperCall | 1393 MessageKind kind = isImplicitSuperCall |
| 1394 ? MessageKind.CANNOT_RESOLVE_CONSTRUCTOR_FOR_IMPLICIT | 1394 ? MessageKind.CANNOT_RESOLVE_CONSTRUCTOR_FOR_IMPLICIT |
| 1395 : MessageKind.CANNOT_RESOLVE_CONSTRUCTOR; | 1395 : MessageKind.CANNOT_RESOLVE_CONSTRUCTOR; |
| 1396 visitor.compiler.reportError( | 1396 visitor.compiler.reportError( |
| 1397 diagnosticNode, kind, {'constructorName': fullConstructorName}); | 1397 diagnosticNode, kind, {'constructorName': fullConstructorName}); |
| 1398 } else { | 1398 } else { |
| 1399 if (!call.applies(lookedupConstructor, visitor.compiler)) { | 1399 if (!call.applies(lookedupConstructor, visitor.compiler)) { |
| 1400 MessageKind kind = isImplicitSuperCall | 1400 MessageKind kind = isImplicitSuperCall |
| 1401 ? MessageKind.NO_MATCHING_CONSTRUCTOR_FOR_IMPLICIT | 1401 ? MessageKind.NO_MATCHING_CONSTRUCTOR_FOR_IMPLICIT |
| 1402 : MessageKind.NO_MATCHING_CONSTRUCTOR; | 1402 : MessageKind.NO_MATCHING_CONSTRUCTOR; |
| 1403 visitor.compiler.reportError(diagnosticNode, kind); | 1403 visitor.compiler.reportError(diagnosticNode, kind); |
| 1404 } else if (caller.modifiers.isConst() | 1404 } else if (caller.modifiers.isConst |
| 1405 && !lookedupConstructor.modifiers.isConst()) { | 1405 && !lookedupConstructor.modifiers.isConst) { |
| 1406 visitor.compiler.reportError( | 1406 visitor.compiler.reportError( |
| 1407 diagnosticNode, MessageKind.CONST_CALLS_NON_CONST); | 1407 diagnosticNode, MessageKind.CONST_CALLS_NON_CONST); |
| 1408 } | 1408 } |
| 1409 } | 1409 } |
| 1410 } | 1410 } |
| 1411 | 1411 |
| 1412 /** | 1412 /** |
| 1413 * Resolve all initializers of this constructor. In the case of a redirecting | 1413 * Resolve all initializers of this constructor. In the case of a redirecting |
| 1414 * constructor, the resolved constructor's function element is returned. | 1414 * constructor, the resolved constructor's function element is returned. |
| 1415 */ | 1415 */ |
| (...skipping 30 matching lines...) Expand all Loading... |
| 1446 if (Initializers.isSuperConstructorCall(call)) { | 1446 if (Initializers.isSuperConstructorCall(call)) { |
| 1447 if (resolvedSuper) { | 1447 if (resolvedSuper) { |
| 1448 error(call, MessageKind.DUPLICATE_SUPER_INITIALIZER); | 1448 error(call, MessageKind.DUPLICATE_SUPER_INITIALIZER); |
| 1449 } | 1449 } |
| 1450 resolveSuperOrThisForSend(constructor, functionNode, call); | 1450 resolveSuperOrThisForSend(constructor, functionNode, call); |
| 1451 resolvedSuper = true; | 1451 resolvedSuper = true; |
| 1452 } else if (Initializers.isConstructorRedirect(call)) { | 1452 } else if (Initializers.isConstructorRedirect(call)) { |
| 1453 // Check that there is no body (Language specification 7.5.1). If the | 1453 // Check that there is no body (Language specification 7.5.1). If the |
| 1454 // constructor is also const, we already reported an error in | 1454 // constructor is also const, we already reported an error in |
| 1455 // [resolveMethodElement]. | 1455 // [resolveMethodElement]. |
| 1456 if (functionNode.hasBody() && !constructor.modifiers.isConst()) { | 1456 if (functionNode.hasBody() && !constructor.modifiers.isConst) { |
| 1457 error(functionNode, MessageKind.REDIRECTING_CONSTRUCTOR_HAS_BODY); | 1457 error(functionNode, MessageKind.REDIRECTING_CONSTRUCTOR_HAS_BODY); |
| 1458 } | 1458 } |
| 1459 // Check that there are no other initializers. | 1459 // Check that there are no other initializers. |
| 1460 if (!initializers.tail.isEmpty) { | 1460 if (!initializers.tail.isEmpty) { |
| 1461 error(call, MessageKind.REDIRECTING_CONSTRUCTOR_HAS_INITIALIZER); | 1461 error(call, MessageKind.REDIRECTING_CONSTRUCTOR_HAS_INITIALIZER); |
| 1462 } | 1462 } |
| 1463 // Check that there are no field initializing parameters. | 1463 // Check that there are no field initializing parameters. |
| 1464 Compiler compiler = visitor.compiler; | 1464 Compiler compiler = visitor.compiler; |
| 1465 FunctionSignature signature = constructor.functionSignature; | 1465 FunctionSignature signature = constructor.functionSignature; |
| 1466 signature.forEachParameter((ParameterElement parameter) { | 1466 signature.forEachParameter((ParameterElement parameter) { |
| 1467 if (parameter.isFieldParameter()) { | 1467 if (parameter.isFieldParameter) { |
| 1468 Node node = parameter.node; | 1468 Node node = parameter.node; |
| 1469 error(node, MessageKind.INITIALIZING_FORMAL_NOT_ALLOWED); | 1469 error(node, MessageKind.INITIALIZING_FORMAL_NOT_ALLOWED); |
| 1470 } | 1470 } |
| 1471 }); | 1471 }); |
| 1472 return resolveSuperOrThisForSend(constructor, functionNode, call); | 1472 return resolveSuperOrThisForSend(constructor, functionNode, call); |
| 1473 } else { | 1473 } else { |
| 1474 visitor.error(call, MessageKind.CONSTRUCTOR_CALL_EXPECTED); | 1474 visitor.error(call, MessageKind.CONSTRUCTOR_CALL_EXPECTED); |
| 1475 return null; | 1475 return null; |
| 1476 } | 1476 } |
| 1477 } else { | 1477 } else { |
| (...skipping 144 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1622 /// Tries to resolve the type name as an element. | 1622 /// Tries to resolve the type name as an element. |
| 1623 Element resolveTypeName(Identifier prefixName, | 1623 Element resolveTypeName(Identifier prefixName, |
| 1624 Identifier typeName, | 1624 Identifier typeName, |
| 1625 Scope scope, | 1625 Scope scope, |
| 1626 {bool deferredIsMalformed: true}) { | 1626 {bool deferredIsMalformed: true}) { |
| 1627 Element element; | 1627 Element element; |
| 1628 bool deferredTypeAnnotation = false; | 1628 bool deferredTypeAnnotation = false; |
| 1629 if (prefixName != null) { | 1629 if (prefixName != null) { |
| 1630 Element prefixElement = | 1630 Element prefixElement = |
| 1631 lookupInScope(compiler, prefixName, scope, prefixName.source); | 1631 lookupInScope(compiler, prefixName, scope, prefixName.source); |
| 1632 if (prefixElement != null && prefixElement.isPrefix()) { | 1632 if (prefixElement != null && prefixElement.isPrefix) { |
| 1633 // The receiver is a prefix. Lookup in the imported members. | 1633 // The receiver is a prefix. Lookup in the imported members. |
| 1634 PrefixElement prefix = prefixElement; | 1634 PrefixElement prefix = prefixElement; |
| 1635 element = prefix.lookupLocalMember(typeName.source); | 1635 element = prefix.lookupLocalMember(typeName.source); |
| 1636 // TODO(17260, sigurdm): The test for DartBackend is there because | 1636 // TODO(17260, sigurdm): The test for DartBackend is there because |
| 1637 // dart2dart outputs malformed types with prefix. | 1637 // dart2dart outputs malformed types with prefix. |
| 1638 if (element != null && | 1638 if (element != null && |
| 1639 prefix.isDeferred && | 1639 prefix.isDeferred && |
| 1640 deferredIsMalformed && | 1640 deferredIsMalformed && |
| 1641 compiler.backend is! DartBackend) { | 1641 compiler.backend is! DartBackend) { |
| 1642 element = new ErroneousElementX(MessageKind.DEFERRED_TYPE_ANNOTATION, | 1642 element = new ErroneousElementX(MessageKind.DEFERRED_TYPE_ANNOTATION, |
| (...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1711 type, arguments.toLink()); | 1711 type, arguments.toLink()); |
| 1712 } | 1712 } |
| 1713 return type; | 1713 return type; |
| 1714 } | 1714 } |
| 1715 | 1715 |
| 1716 // Try to construct the type from the element. | 1716 // Try to construct the type from the element. |
| 1717 DartType type; | 1717 DartType type; |
| 1718 if (element == null) { | 1718 if (element == null) { |
| 1719 type = reportFailureAndCreateType( | 1719 type = reportFailureAndCreateType( |
| 1720 MessageKind.CANNOT_RESOLVE_TYPE, {'typeName': node.typeName}); | 1720 MessageKind.CANNOT_RESOLVE_TYPE, {'typeName': node.typeName}); |
| 1721 } else if (element.isAmbiguous()) { | 1721 } else if (element.isAmbiguous) { |
| 1722 AmbiguousElement ambiguous = element; | 1722 AmbiguousElement ambiguous = element; |
| 1723 type = reportFailureAndCreateType( | 1723 type = reportFailureAndCreateType( |
| 1724 ambiguous.messageKind, ambiguous.messageArguments); | 1724 ambiguous.messageKind, ambiguous.messageArguments); |
| 1725 ambiguous.diagnose(visitor.mapping.currentElement, compiler); | 1725 ambiguous.diagnose(visitor.mapping.currentElement, compiler); |
| 1726 } else if (element.isErroneous()) { | 1726 } else if (element.isErroneous) { |
| 1727 ErroneousElement erroneousElement = element; | 1727 ErroneousElement erroneousElement = element; |
| 1728 type = reportFailureAndCreateType( | 1728 type = reportFailureAndCreateType( |
| 1729 erroneousElement.messageKind, erroneousElement.messageArguments, | 1729 erroneousElement.messageKind, erroneousElement.messageArguments, |
| 1730 erroneousElement: erroneousElement); | 1730 erroneousElement: erroneousElement); |
| 1731 } else if (!element.impliesType()) { | 1731 } else if (!element.impliesType) { |
| 1732 type = reportFailureAndCreateType( | 1732 type = reportFailureAndCreateType( |
| 1733 MessageKind.NOT_A_TYPE, {'node': node.typeName}); | 1733 MessageKind.NOT_A_TYPE, {'node': node.typeName}); |
| 1734 } else { | 1734 } else { |
| 1735 bool addTypeVariableBoundsCheck = false; | 1735 bool addTypeVariableBoundsCheck = false; |
| 1736 if (identical(element, compiler.types.voidType.element) || | 1736 if (identical(element, compiler.types.voidType.element) || |
| 1737 identical(element, compiler.dynamicClass)) { | 1737 identical(element, compiler.dynamicClass)) { |
| 1738 type = checkNoTypeArguments(element.computeType(compiler)); | 1738 type = checkNoTypeArguments(element.computeType(compiler)); |
| 1739 } else if (element.isClass()) { | 1739 } else if (element.isClass) { |
| 1740 ClassElement cls = element; | 1740 ClassElement cls = element; |
| 1741 compiler.resolver._ensureClassWillBeResolved(cls); | 1741 compiler.resolver._ensureClassWillBeResolved(cls); |
| 1742 element.computeType(compiler); | 1742 element.computeType(compiler); |
| 1743 var arguments = new LinkBuilder<DartType>(); | 1743 var arguments = new LinkBuilder<DartType>(); |
| 1744 bool hasTypeArgumentMismatch = resolveTypeArguments( | 1744 bool hasTypeArgumentMismatch = resolveTypeArguments( |
| 1745 visitor, node, cls.typeVariables, arguments); | 1745 visitor, node, cls.typeVariables, arguments); |
| 1746 if (hasTypeArgumentMismatch) { | 1746 if (hasTypeArgumentMismatch) { |
| 1747 type = new BadInterfaceType(cls.declaration, | 1747 type = new BadInterfaceType(cls.declaration, |
| 1748 new InterfaceType.forUserProvidedBadType(cls.declaration, | 1748 new InterfaceType.forUserProvidedBadType(cls.declaration, |
| 1749 arguments.toLink())); | 1749 arguments.toLink())); |
| 1750 } else { | 1750 } else { |
| 1751 if (arguments.isEmpty) { | 1751 if (arguments.isEmpty) { |
| 1752 type = cls.rawType; | 1752 type = cls.rawType; |
| 1753 } else { | 1753 } else { |
| 1754 type = new InterfaceType(cls.declaration, arguments.toLink()); | 1754 type = new InterfaceType(cls.declaration, arguments.toLink()); |
| 1755 addTypeVariableBoundsCheck = true; | 1755 addTypeVariableBoundsCheck = true; |
| 1756 } | 1756 } |
| 1757 } | 1757 } |
| 1758 } else if (element.isTypedef()) { | 1758 } else if (element.isTypedef) { |
| 1759 TypedefElement typdef = element; | 1759 TypedefElement typdef = element; |
| 1760 // TODO(ahe): Should be [ensureResolved]. | 1760 // TODO(ahe): Should be [ensureResolved]. |
| 1761 compiler.resolveTypedef(typdef); | 1761 compiler.resolveTypedef(typdef); |
| 1762 var arguments = new LinkBuilder<DartType>(); | 1762 var arguments = new LinkBuilder<DartType>(); |
| 1763 bool hasTypeArgumentMismatch = resolveTypeArguments( | 1763 bool hasTypeArgumentMismatch = resolveTypeArguments( |
| 1764 visitor, node, typdef.typeVariables, arguments); | 1764 visitor, node, typdef.typeVariables, arguments); |
| 1765 if (hasTypeArgumentMismatch) { | 1765 if (hasTypeArgumentMismatch) { |
| 1766 type = new BadTypedefType(typdef, | 1766 type = new BadTypedefType(typdef, |
| 1767 new TypedefType.forUserProvidedBadType(typdef, | 1767 new TypedefType.forUserProvidedBadType(typdef, |
| 1768 arguments.toLink())); | 1768 arguments.toLink())); |
| 1769 } else { | 1769 } else { |
| 1770 if (arguments.isEmpty) { | 1770 if (arguments.isEmpty) { |
| 1771 type = typdef.rawType; | 1771 type = typdef.rawType; |
| 1772 } else { | 1772 } else { |
| 1773 type = new TypedefType(typdef, arguments.toLink()); | 1773 type = new TypedefType(typdef, arguments.toLink()); |
| 1774 addTypeVariableBoundsCheck = true; | 1774 addTypeVariableBoundsCheck = true; |
| 1775 } | 1775 } |
| 1776 } | 1776 } |
| 1777 } else if (element.isTypeVariable()) { | 1777 } else if (element.isTypeVariable) { |
| 1778 Element outer = | 1778 Element outer = |
| 1779 visitor.enclosingElement.getOutermostEnclosingMemberOrTopLevel(); | 1779 visitor.enclosingElement.outermostEnclosingMemberOrTopLevel; |
| 1780 bool isInFactoryConstructor = | 1780 bool isInFactoryConstructor = |
| 1781 outer != null && outer.isFactoryConstructor(); | 1781 outer != null && outer.isFactoryConstructor; |
| 1782 if (!outer.isClass() && | 1782 if (!outer.isClass && |
| 1783 !outer.isTypedef() && | 1783 !outer.isTypedef && |
| 1784 !isInFactoryConstructor && | 1784 !isInFactoryConstructor && |
| 1785 Elements.isInStaticContext(visitor.enclosingElement)) { | 1785 Elements.isInStaticContext(visitor.enclosingElement)) { |
| 1786 compiler.backend.registerThrowRuntimeError(visitor.mapping); | 1786 compiler.backend.registerThrowRuntimeError(visitor.mapping); |
| 1787 type = reportFailureAndCreateType( | 1787 type = reportFailureAndCreateType( |
| 1788 MessageKind.TYPE_VARIABLE_WITHIN_STATIC_MEMBER, | 1788 MessageKind.TYPE_VARIABLE_WITHIN_STATIC_MEMBER, |
| 1789 {'typeVariableName': node}, | 1789 {'typeVariableName': node}, |
| 1790 userProvidedBadType: element.computeType(compiler)); | 1790 userProvidedBadType: element.computeType(compiler)); |
| 1791 } else { | 1791 } else { |
| 1792 type = element.computeType(compiler); | 1792 type = element.computeType(compiler); |
| 1793 } | 1793 } |
| (...skipping 160 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1954 /// the initializer of the variable is implicit and we should not emit an | 1954 /// the initializer of the variable is implicit and we should not emit an |
| 1955 /// error when verifying that all final variables are initialized. | 1955 /// error when verifying that all final variables are initialized. |
| 1956 bool allowFinalWithoutInitializer = false; | 1956 bool allowFinalWithoutInitializer = false; |
| 1957 | 1957 |
| 1958 /// The nodes for which variable access and mutation must be registered in | 1958 /// The nodes for which variable access and mutation must be registered in |
| 1959 /// order to determine when the static type of variables types is promoted. | 1959 /// order to determine when the static type of variables types is promoted. |
| 1960 Link<Node> promotionScope = const Link<Node>(); | 1960 Link<Node> promotionScope = const Link<Node>(); |
| 1961 | 1961 |
| 1962 bool isPotentiallyMutableTarget(Element target) { | 1962 bool isPotentiallyMutableTarget(Element target) { |
| 1963 if (target == null) return false; | 1963 if (target == null) return false; |
| 1964 return (target.isVariable() || target.isParameter()) && | 1964 return (target.isVariable || target.isParameter) && |
| 1965 !(target.modifiers.isFinal() || target.modifiers.isConst()); | 1965 !(target.modifiers.isFinal || target.modifiers.isConst); |
| 1966 } | 1966 } |
| 1967 | 1967 |
| 1968 // TODO(ahe): Find a way to share this with runtime implementation. | 1968 // TODO(ahe): Find a way to share this with runtime implementation. |
| 1969 static final RegExp symbolValidationPattern = | 1969 static final RegExp symbolValidationPattern = |
| 1970 new RegExp(r'^(?:[a-zA-Z$][a-zA-Z$0-9_]*\.)*(?:[a-zA-Z$][a-zA-Z$0-9_]*=?|' | 1970 new RegExp(r'^(?:[a-zA-Z$][a-zA-Z$0-9_]*\.)*(?:[a-zA-Z$][a-zA-Z$0-9_]*=?|' |
| 1971 r'-|' | 1971 r'-|' |
| 1972 r'unary-|' | 1972 r'unary-|' |
| 1973 r'\[\]=|' | 1973 r'\[\]=|' |
| 1974 r'~|' | 1974 r'~|' |
| 1975 r'==|' | 1975 r'==|' |
| (...skipping 14 matching lines...) Expand all Loading... |
| 1990 r'\|' | 1990 r'\|' |
| 1991 r')$'); | 1991 r')$'); |
| 1992 | 1992 |
| 1993 ResolverVisitor(Compiler compiler, | 1993 ResolverVisitor(Compiler compiler, |
| 1994 Element element, | 1994 Element element, |
| 1995 TreeElementMapping mapping) | 1995 TreeElementMapping mapping) |
| 1996 : this.enclosingElement = element, | 1996 : this.enclosingElement = element, |
| 1997 // When the element is a field, we are actually resolving its | 1997 // When the element is a field, we are actually resolving its |
| 1998 // initial value, which should not have access to instance | 1998 // initial value, which should not have access to instance |
| 1999 // fields. | 1999 // fields. |
| 2000 inInstanceContext = (element.isInstanceMember() && !element.isField()) | 2000 inInstanceContext = (element.isInstanceMember && !element.isField) |
| 2001 || element.isGenerativeConstructor(), | 2001 || element.isGenerativeConstructor, |
| 2002 this.currentClass = element.isMember() ? element.getEnclosingClass() | 2002 this.currentClass = element.isMember ? element.enclosingClass |
| 2003 : null, | 2003 : null, |
| 2004 this.statementScope = new StatementScope(), | 2004 this.statementScope = new StatementScope(), |
| 2005 scope = element.buildScope(), | 2005 scope = element.buildScope(), |
| 2006 // The type annotations on a typedef do not imply type checks. | 2006 // The type annotations on a typedef do not imply type checks. |
| 2007 // TODO(karlklose): clean this up (dartbug.com/8870). | 2007 // TODO(karlklose): clean this up (dartbug.com/8870). |
| 2008 inCheckContext = compiler.enableTypeAssertions && | 2008 inCheckContext = compiler.enableTypeAssertions && |
| 2009 !element.isLibrary() && | 2009 !element.isLibrary && |
| 2010 !element.isTypedef() && | 2010 !element.isTypedef && |
| 2011 !element.enclosingElement.isTypedef(), | 2011 !element.enclosingElement.isTypedef, |
| 2012 inCatchBlock = false, | 2012 inCatchBlock = false, |
| 2013 super(compiler, mapping); | 2013 super(compiler, mapping); |
| 2014 | 2014 |
| 2015 ResolutionEnqueuer get world => compiler.enqueuer.resolution; | 2015 ResolutionEnqueuer get world => compiler.enqueuer.resolution; |
| 2016 | 2016 |
| 2017 Element reportLookupErrorIfAny(Element result, Node node, String name) { | 2017 Element reportLookupErrorIfAny(Element result, Node node, String name) { |
| 2018 if (!Elements.isUnresolved(result)) { | 2018 if (!Elements.isUnresolved(result)) { |
| 2019 if (!inInstanceContext && result.isInstanceMember()) { | 2019 if (!inInstanceContext && result.isInstanceMember) { |
| 2020 compiler.reportError( | 2020 compiler.reportError( |
| 2021 node, MessageKind.NO_INSTANCE_AVAILABLE, {'name': name}); | 2021 node, MessageKind.NO_INSTANCE_AVAILABLE, {'name': name}); |
| 2022 return new ErroneousElementX(MessageKind.NO_INSTANCE_AVAILABLE, | 2022 return new ErroneousElementX(MessageKind.NO_INSTANCE_AVAILABLE, |
| 2023 {'name': name}, | 2023 {'name': name}, |
| 2024 name, enclosingElement); | 2024 name, enclosingElement); |
| 2025 } else if (result.isAmbiguous()) { | 2025 } else if (result.isAmbiguous) { |
| 2026 AmbiguousElement ambiguous = result; | 2026 AmbiguousElement ambiguous = result; |
| 2027 compiler.reportError( | 2027 compiler.reportError( |
| 2028 node, ambiguous.messageKind, ambiguous.messageArguments); | 2028 node, ambiguous.messageKind, ambiguous.messageArguments); |
| 2029 ambiguous.diagnose(enclosingElement, compiler); | 2029 ambiguous.diagnose(enclosingElement, compiler); |
| 2030 return new ErroneousElementX(ambiguous.messageKind, | 2030 return new ErroneousElementX(ambiguous.messageKind, |
| 2031 ambiguous.messageArguments, | 2031 ambiguous.messageArguments, |
| 2032 name, enclosingElement); | 2032 name, enclosingElement); |
| 2033 } | 2033 } |
| 2034 } | 2034 } |
| 2035 return result; | 2035 return result; |
| (...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2101 element = compiler.dynamicClass; | 2101 element = compiler.dynamicClass; |
| 2102 } | 2102 } |
| 2103 element = reportLookupErrorIfAny(element, node, node.source); | 2103 element = reportLookupErrorIfAny(element, node, node.source); |
| 2104 if (element == null) { | 2104 if (element == null) { |
| 2105 if (!inInstanceContext) { | 2105 if (!inInstanceContext) { |
| 2106 element = warnAndCreateErroneousElement( | 2106 element = warnAndCreateErroneousElement( |
| 2107 node, node.source, MessageKind.CANNOT_RESOLVE, | 2107 node, node.source, MessageKind.CANNOT_RESOLVE, |
| 2108 {'name': node}); | 2108 {'name': node}); |
| 2109 compiler.backend.registerThrowNoSuchMethod(mapping); | 2109 compiler.backend.registerThrowNoSuchMethod(mapping); |
| 2110 } | 2110 } |
| 2111 } else if (element.isErroneous()) { | 2111 } else if (element.isErroneous) { |
| 2112 // Use the erroneous element. | 2112 // Use the erroneous element. |
| 2113 } else { | 2113 } else { |
| 2114 if ((element.kind.category & allowedCategory) == 0) { | 2114 if ((element.kind.category & allowedCategory) == 0) { |
| 2115 // TODO(ahe): Improve error message. Need UX input. | 2115 // TODO(ahe): Improve error message. Need UX input. |
| 2116 error(node, MessageKind.GENERIC, | 2116 error(node, MessageKind.GENERIC, |
| 2117 {'text': "is not an expression $element"}); | 2117 {'text': "is not an expression $element"}); |
| 2118 } | 2118 } |
| 2119 } | 2119 } |
| 2120 if (!Elements.isUnresolved(element) && element.isClass()) { | 2120 if (!Elements.isUnresolved(element) && element.isClass) { |
| 2121 ClassElement classElement = element; | 2121 ClassElement classElement = element; |
| 2122 classElement.ensureResolved(compiler); | 2122 classElement.ensureResolved(compiler); |
| 2123 } | 2123 } |
| 2124 return useElement(node, element); | 2124 return useElement(node, element); |
| 2125 } | 2125 } |
| 2126 } | 2126 } |
| 2127 | 2127 |
| 2128 Element visitTypeAnnotation(TypeAnnotation node) { | 2128 Element visitTypeAnnotation(TypeAnnotation node) { |
| 2129 DartType type = resolveTypeAnnotation(node); | 2129 DartType type = resolveTypeAnnotation(node); |
| 2130 if (type != null) { | 2130 if (type != null) { |
| 2131 if (inCheckContext) { | 2131 if (inCheckContext) { |
| 2132 compiler.enqueuer.resolution.registerIsCheck(type, mapping); | 2132 compiler.enqueuer.resolution.registerIsCheck(type, mapping); |
| 2133 } | 2133 } |
| 2134 return type.element; | 2134 return type.element; |
| 2135 } | 2135 } |
| 2136 return null; | 2136 return null; |
| 2137 } | 2137 } |
| 2138 | 2138 |
| 2139 bool isNamedConstructor(Send node) => node.receiver != null; | 2139 bool isNamedConstructor(Send node) => node.receiver != null; |
| 2140 | 2140 |
| 2141 Selector getRedirectingThisOrSuperConstructorSelector(Send node) { | 2141 Selector getRedirectingThisOrSuperConstructorSelector(Send node) { |
| 2142 if (isNamedConstructor(node)) { | 2142 if (isNamedConstructor(node)) { |
| 2143 String constructorName = node.selector.asIdentifier().source; | 2143 String constructorName = node.selector.asIdentifier().source; |
| 2144 return new Selector.callConstructor( | 2144 return new Selector.callConstructor( |
| 2145 constructorName, | 2145 constructorName, |
| 2146 enclosingElement.getLibrary()); | 2146 enclosingElement.library); |
| 2147 } else { | 2147 } else { |
| 2148 return new Selector.callDefaultConstructor( | 2148 return new Selector.callDefaultConstructor( |
| 2149 enclosingElement.getLibrary()); | 2149 enclosingElement.library); |
| 2150 } | 2150 } |
| 2151 } | 2151 } |
| 2152 | 2152 |
| 2153 FunctionElement resolveConstructorRedirection(FunctionElement constructor) { | 2153 FunctionElement resolveConstructorRedirection(FunctionElement constructor) { |
| 2154 FunctionExpression node = constructor.parseNode(compiler); | 2154 FunctionExpression node = constructor.parseNode(compiler); |
| 2155 | 2155 |
| 2156 // A synthetic constructor does not have a node. | 2156 // A synthetic constructor does not have a node. |
| 2157 if (node == null) return null; | 2157 if (node == null) return null; |
| 2158 if (node.initializers == null) return null; | 2158 if (node.initializers == null) return null; |
| 2159 Link<Node> initializers = node.initializers.nodes; | 2159 Link<Node> initializers = node.initializers.nodes; |
| 2160 if (!initializers.isEmpty && | 2160 if (!initializers.isEmpty && |
| 2161 Initializers.isConstructorRedirect(initializers.head)) { | 2161 Initializers.isConstructorRedirect(initializers.head)) { |
| 2162 Selector selector = | 2162 Selector selector = |
| 2163 getRedirectingThisOrSuperConstructorSelector(initializers.head); | 2163 getRedirectingThisOrSuperConstructorSelector(initializers.head); |
| 2164 final ClassElement classElement = constructor.getEnclosingClass(); | 2164 final ClassElement classElement = constructor.enclosingClass; |
| 2165 return classElement.lookupConstructor(selector); | 2165 return classElement.lookupConstructor(selector); |
| 2166 } | 2166 } |
| 2167 return null; | 2167 return null; |
| 2168 } | 2168 } |
| 2169 | 2169 |
| 2170 void setupFunction(FunctionExpression node, FunctionElement function) { | 2170 void setupFunction(FunctionExpression node, FunctionElement function) { |
| 2171 Element enclosingElement = function.enclosingElement; | 2171 Element enclosingElement = function.enclosingElement; |
| 2172 if (node.modifiers.isStatic() && | 2172 if (node.modifiers.isStatic && |
| 2173 enclosingElement.kind != ElementKind.CLASS) { | 2173 enclosingElement.kind != ElementKind.CLASS) { |
| 2174 compiler.reportError(node, MessageKind.ILLEGAL_STATIC); | 2174 compiler.reportError(node, MessageKind.ILLEGAL_STATIC); |
| 2175 } | 2175 } |
| 2176 | 2176 |
| 2177 scope = new MethodScope(scope, function); | 2177 scope = new MethodScope(scope, function); |
| 2178 // Put the parameters in scope. | 2178 // Put the parameters in scope. |
| 2179 FunctionSignature functionParameters = function.functionSignature; | 2179 FunctionSignature functionParameters = function.functionSignature; |
| 2180 Link<Node> parameterNodes = (node.parameters == null) | 2180 Link<Node> parameterNodes = (node.parameters == null) |
| 2181 ? const Link<Node>() : node.parameters.nodes; | 2181 ? const Link<Node>() : node.parameters.nodes; |
| 2182 functionParameters.forEachParameter((ParameterElement element) { | 2182 functionParameters.forEachParameter((ParameterElement element) { |
| (...skipping 135 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2318 visitIn(node.elsePart, new BlockScope(scope)); | 2318 visitIn(node.elsePart, new BlockScope(scope)); |
| 2319 } | 2319 } |
| 2320 | 2320 |
| 2321 Element resolveSend(Send node) { | 2321 Element resolveSend(Send node) { |
| 2322 Selector selector = resolveSelector(node, null); | 2322 Selector selector = resolveSelector(node, null); |
| 2323 if (node.isSuperCall) mapping.superUses.add(node); | 2323 if (node.isSuperCall) mapping.superUses.add(node); |
| 2324 | 2324 |
| 2325 if (node.receiver == null) { | 2325 if (node.receiver == null) { |
| 2326 // If this send is of the form "assert(expr);", then | 2326 // If this send is of the form "assert(expr);", then |
| 2327 // this is an assertion. | 2327 // this is an assertion. |
| 2328 if (selector.isAssert()) { | 2328 if (selector.isAssert) { |
| 2329 if (selector.argumentCount != 1) { | 2329 if (selector.argumentCount != 1) { |
| 2330 error(node.selector, | 2330 error(node.selector, |
| 2331 MessageKind.WRONG_NUMBER_OF_ARGUMENTS_FOR_ASSERT, | 2331 MessageKind.WRONG_NUMBER_OF_ARGUMENTS_FOR_ASSERT, |
| 2332 {'argumentCount': selector.argumentCount}); | 2332 {'argumentCount': selector.argumentCount}); |
| 2333 } else if (selector.namedArgumentCount != 0) { | 2333 } else if (selector.namedArgumentCount != 0) { |
| 2334 error(node.selector, | 2334 error(node.selector, |
| 2335 MessageKind.ASSERT_IS_GIVEN_NAMED_ARGUMENTS, | 2335 MessageKind.ASSERT_IS_GIVEN_NAMED_ARGUMENTS, |
| 2336 {'argumentCount': selector.namedArgumentCount}); | 2336 {'argumentCount': selector.namedArgumentCount}); |
| 2337 } | 2337 } |
| 2338 return compiler.assertMethod; | 2338 return compiler.assertMethod; |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2380 node, name, MessageKind.NO_SUCH_SUPER_MEMBER, | 2380 node, name, MessageKind.NO_SUCH_SUPER_MEMBER, |
| 2381 {'className': currentClass, 'memberName': name}); | 2381 {'className': currentClass, 'memberName': name}); |
| 2382 // We still need to register the invocation, because we might | 2382 // We still need to register the invocation, because we might |
| 2383 // call [:super.noSuchMethod:] which calls | 2383 // call [:super.noSuchMethod:] which calls |
| 2384 // [JSInvocationMirror._invokeOn]. | 2384 // [JSInvocationMirror._invokeOn]. |
| 2385 world.registerDynamicInvocation(selector); | 2385 world.registerDynamicInvocation(selector); |
| 2386 compiler.backend.registerSuperNoSuchMethod(mapping); | 2386 compiler.backend.registerSuperNoSuchMethod(mapping); |
| 2387 } | 2387 } |
| 2388 } else if (Elements.isUnresolved(resolvedReceiver)) { | 2388 } else if (Elements.isUnresolved(resolvedReceiver)) { |
| 2389 return null; | 2389 return null; |
| 2390 } else if (resolvedReceiver.isClass()) { | 2390 } else if (resolvedReceiver.isClass) { |
| 2391 ClassElement receiverClass = resolvedReceiver; | 2391 ClassElement receiverClass = resolvedReceiver; |
| 2392 receiverClass.ensureResolved(compiler); | 2392 receiverClass.ensureResolved(compiler); |
| 2393 if (node.isOperator) { | 2393 if (node.isOperator) { |
| 2394 // When the resolved receiver is a class, we can have two cases: | 2394 // When the resolved receiver is a class, we can have two cases: |
| 2395 // 1) a static send: C.foo, or | 2395 // 1) a static send: C.foo, or |
| 2396 // 2) an operator send, where the receiver is a class literal: 'C + 1'. | 2396 // 2) an operator send, where the receiver is a class literal: 'C + 1'. |
| 2397 // The following code that looks up the selector on the resolved | 2397 // The following code that looks up the selector on the resolved |
| 2398 // receiver will treat the second as the invocation of a static operator | 2398 // receiver will treat the second as the invocation of a static operator |
| 2399 // if the resolved receiver is not null. | 2399 // if the resolved receiver is not null. |
| 2400 return null; | 2400 return null; |
| 2401 } | 2401 } |
| 2402 MembersCreator.computeClassMembersByName( | 2402 MembersCreator.computeClassMembersByName( |
| 2403 compiler, receiverClass.declaration, name); | 2403 compiler, receiverClass.declaration, name); |
| 2404 target = receiverClass.lookupLocalMember(name); | 2404 target = receiverClass.lookupLocalMember(name); |
| 2405 if (target == null || target.isInstanceMember()) { | 2405 if (target == null || target.isInstanceMember) { |
| 2406 compiler.backend.registerThrowNoSuchMethod(mapping); | 2406 compiler.backend.registerThrowNoSuchMethod(mapping); |
| 2407 // TODO(johnniwinther): With the simplified [TreeElements] invariant, | 2407 // TODO(johnniwinther): With the simplified [TreeElements] invariant, |
| 2408 // try to resolve injected elements if [currentClass] is in the patch | 2408 // try to resolve injected elements if [currentClass] is in the patch |
| 2409 // library of [receiverClass]. | 2409 // library of [receiverClass]. |
| 2410 | 2410 |
| 2411 // TODO(karlklose): this should be reported by the caller of | 2411 // TODO(karlklose): this should be reported by the caller of |
| 2412 // [resolveSend] to select better warning messages for getters and | 2412 // [resolveSend] to select better warning messages for getters and |
| 2413 // setters. | 2413 // setters. |
| 2414 MessageKind kind = (target == null) | 2414 MessageKind kind = (target == null) |
| 2415 ? MessageKind.MEMBER_NOT_FOUND | 2415 ? MessageKind.MEMBER_NOT_FOUND |
| (...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2483 !link.isEmpty; | 2483 !link.isEmpty; |
| 2484 link = link.tail) { | 2484 link = link.tail) { |
| 2485 Expression argument = link.head; | 2485 Expression argument = link.head; |
| 2486 NamedArgument namedArgument = argument.asNamedArgument(); | 2486 NamedArgument namedArgument = argument.asNamedArgument(); |
| 2487 if (namedArgument != null) { | 2487 if (namedArgument != null) { |
| 2488 named.add(namedArgument.name.source); | 2488 named.add(namedArgument.name.source); |
| 2489 } | 2489 } |
| 2490 arity++; | 2490 arity++; |
| 2491 } | 2491 } |
| 2492 | 2492 |
| 2493 if (element != null && element.isConstructor()) { | 2493 if (element != null && element.isConstructor) { |
| 2494 return new Selector.callConstructor( | 2494 return new Selector.callConstructor( |
| 2495 element.name, library, arity, named); | 2495 element.name, library, arity, named); |
| 2496 } | 2496 } |
| 2497 | 2497 |
| 2498 // If we're invoking a closure, we do not have an identifier. | 2498 // If we're invoking a closure, we do not have an identifier. |
| 2499 return (identifier == null) | 2499 return (identifier == null) |
| 2500 ? new Selector.callClosure(arity, named) | 2500 ? new Selector.callClosure(arity, named) |
| 2501 : new Selector.call(identifier.source, library, arity, named); | 2501 : new Selector.call(identifier.source, library, arity, named); |
| 2502 } | 2502 } |
| 2503 | 2503 |
| 2504 Selector resolveSelector(Send node, Element element) { | 2504 Selector resolveSelector(Send node, Element element) { |
| 2505 LibraryElement library = enclosingElement.getLibrary(); | 2505 LibraryElement library = enclosingElement.library; |
| 2506 Selector selector = computeSendSelector(node, library, element); | 2506 Selector selector = computeSendSelector(node, library, element); |
| 2507 if (selector != null) mapping.setSelector(node, selector); | 2507 if (selector != null) mapping.setSelector(node, selector); |
| 2508 return selector; | 2508 return selector; |
| 2509 } | 2509 } |
| 2510 | 2510 |
| 2511 void resolveArguments(NodeList list) { | 2511 void resolveArguments(NodeList list) { |
| 2512 if (list == null) return; | 2512 if (list == null) return; |
| 2513 bool oldSendIsMemberAccess = sendIsMemberAccess; | 2513 bool oldSendIsMemberAccess = sendIsMemberAccess; |
| 2514 sendIsMemberAccess = false; | 2514 sendIsMemberAccess = false; |
| 2515 Map<String, Node> seenNamedArguments = new Map<String, Node>(); | 2515 Map<String, Node> seenNamedArguments = new Map<String, Node>(); |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2548 if (target != null | 2548 if (target != null |
| 2549 && target == compiler.mirrorSystemGetNameFunction | 2549 && target == compiler.mirrorSystemGetNameFunction |
| 2550 && !compiler.mirrorUsageAnalyzerTask.hasMirrorUsage(enclosingElement)) { | 2550 && !compiler.mirrorUsageAnalyzerTask.hasMirrorUsage(enclosingElement)) { |
| 2551 compiler.reportHint( | 2551 compiler.reportHint( |
| 2552 node.selector, MessageKind.STATIC_FUNCTION_BLOAT, | 2552 node.selector, MessageKind.STATIC_FUNCTION_BLOAT, |
| 2553 {'class': compiler.mirrorSystemClass.name, | 2553 {'class': compiler.mirrorSystemClass.name, |
| 2554 'name': compiler.mirrorSystemGetNameFunction.name}); | 2554 'name': compiler.mirrorSystemGetNameFunction.name}); |
| 2555 } | 2555 } |
| 2556 | 2556 |
| 2557 if (!Elements.isUnresolved(target)) { | 2557 if (!Elements.isUnresolved(target)) { |
| 2558 if (target.isAbstractField()) { | 2558 if (target.isAbstractField) { |
| 2559 AbstractFieldElement field = target; | 2559 AbstractFieldElement field = target; |
| 2560 target = field.getter; | 2560 target = field.getter; |
| 2561 if (target == null && !inInstanceContext) { | 2561 if (target == null && !inInstanceContext) { |
| 2562 compiler.backend.registerThrowNoSuchMethod(mapping); | 2562 compiler.backend.registerThrowNoSuchMethod(mapping); |
| 2563 target = | 2563 target = |
| 2564 warnAndCreateErroneousElement(node.selector, field.name, | 2564 warnAndCreateErroneousElement(node.selector, field.name, |
| 2565 MessageKind.CANNOT_RESOLVE_GETTER); | 2565 MessageKind.CANNOT_RESOLVE_GETTER); |
| 2566 } | 2566 } |
| 2567 } else if (target.isTypeVariable()) { | 2567 } else if (target.isTypeVariable) { |
| 2568 ClassElement cls = target.getEnclosingClass(); | 2568 ClassElement cls = target.enclosingClass; |
| 2569 assert(enclosingElement.getEnclosingClass() == cls); | 2569 assert(enclosingElement.enclosingClass == cls); |
| 2570 compiler.backend.registerClassUsingVariableExpression(cls); | 2570 compiler.backend.registerClassUsingVariableExpression(cls); |
| 2571 compiler.backend.registerTypeVariableExpression(mapping); | 2571 compiler.backend.registerTypeVariableExpression(mapping); |
| 2572 // Set the type of the node to [Type] to mark this send as a | 2572 // Set the type of the node to [Type] to mark this send as a |
| 2573 // type variable expression. | 2573 // type variable expression. |
| 2574 mapping.setType(node, compiler.typeClass.computeType(compiler)); | 2574 mapping.setType(node, compiler.typeClass.computeType(compiler)); |
| 2575 world.registerTypeLiteral(target, mapping); | 2575 world.registerTypeLiteral(target, mapping); |
| 2576 } else if (target.impliesType() && (!sendIsMemberAccess || node.isCall)) { | 2576 } else if (target.impliesType && (!sendIsMemberAccess || node.isCall)) { |
| 2577 // Set the type of the node to [Type] to mark this send as a | 2577 // Set the type of the node to [Type] to mark this send as a |
| 2578 // type literal. | 2578 // type literal. |
| 2579 mapping.setType(node, compiler.typeClass.computeType(compiler)); | 2579 mapping.setType(node, compiler.typeClass.computeType(compiler)); |
| 2580 world.registerTypeLiteral(target, mapping); | 2580 world.registerTypeLiteral(target, mapping); |
| 2581 | 2581 |
| 2582 // Don't try to make constants of calls to type literals. | 2582 // Don't try to make constants of calls to type literals. |
| 2583 if (!node.isCall) { | 2583 if (!node.isCall) { |
| 2584 analyzeConstant(node); | 2584 analyzeConstant(node); |
| 2585 } else { | 2585 } else { |
| 2586 // The node itself is not a constant but we register the selector (the | 2586 // The node itself is not a constant but we register the selector (the |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2626 resolveArguments(node.argumentsNode); | 2626 resolveArguments(node.argumentsNode); |
| 2627 } | 2627 } |
| 2628 | 2628 |
| 2629 // If the selector is null, it means that we will not be generating | 2629 // If the selector is null, it means that we will not be generating |
| 2630 // code for this as a send. | 2630 // code for this as a send. |
| 2631 Selector selector = mapping.getSelector(node); | 2631 Selector selector = mapping.getSelector(node); |
| 2632 if (selector == null) return null; | 2632 if (selector == null) return null; |
| 2633 | 2633 |
| 2634 if (node.isCall) { | 2634 if (node.isCall) { |
| 2635 if (Elements.isUnresolved(target) || | 2635 if (Elements.isUnresolved(target) || |
| 2636 target.isGetter() || | 2636 target.isGetter || |
| 2637 target.isField() || | 2637 target.isField || |
| 2638 Elements.isClosureSend(node, target)) { | 2638 Elements.isClosureSend(node, target)) { |
| 2639 // If we don't know what we're calling or if we are calling a getter, | 2639 // If we don't know what we're calling or if we are calling a getter, |
| 2640 // we need to register that fact that we may be calling a closure | 2640 // we need to register that fact that we may be calling a closure |
| 2641 // with the same arguments. | 2641 // with the same arguments. |
| 2642 Selector call = new Selector.callClosureFrom(selector); | 2642 Selector call = new Selector.callClosureFrom(selector); |
| 2643 world.registerDynamicInvocation(call); | 2643 world.registerDynamicInvocation(call); |
| 2644 } else if (target.impliesType()) { | 2644 } else if (target.impliesType) { |
| 2645 // We call 'call()' on a Type instance returned from the reference to a | 2645 // We call 'call()' on a Type instance returned from the reference to a |
| 2646 // class or typedef literal. We do not need to register this call as a | 2646 // class or typedef literal. We do not need to register this call as a |
| 2647 // dynamic invocation, because we statically know what the target is. | 2647 // dynamic invocation, because we statically know what the target is. |
| 2648 } else if (!selector.applies(target, compiler)) { | 2648 } else if (!selector.applies(target, compiler)) { |
| 2649 warnArgumentMismatch(node, target); | 2649 warnArgumentMismatch(node, target); |
| 2650 if (node.isSuperCall) { | 2650 if (node.isSuperCall) { |
| 2651 // Similar to what we do when we can't find super via selector | 2651 // Similar to what we do when we can't find super via selector |
| 2652 // in [resolveSend] above, we still need to register the invocation, | 2652 // in [resolveSend] above, we still need to register the invocation, |
| 2653 // because we might call [:super.noSuchMethod:] which calls | 2653 // because we might call [:super.noSuchMethod:] which calls |
| 2654 // [JSInvocationMirror._invokeOn]. | 2654 // [JSInvocationMirror._invokeOn]. |
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2703 bool oldSendIsMemberAccess = sendIsMemberAccess; | 2703 bool oldSendIsMemberAccess = sendIsMemberAccess; |
| 2704 sendIsMemberAccess = node.isPropertyAccess || node.isCall; | 2704 sendIsMemberAccess = node.isPropertyAccess || node.isCall; |
| 2705 Element target = resolveSend(node); | 2705 Element target = resolveSend(node); |
| 2706 sendIsMemberAccess = oldSendIsMemberAccess; | 2706 sendIsMemberAccess = oldSendIsMemberAccess; |
| 2707 Element setter = target; | 2707 Element setter = target; |
| 2708 Element getter = target; | 2708 Element getter = target; |
| 2709 String operatorName = node.assignmentOperator.source; | 2709 String operatorName = node.assignmentOperator.source; |
| 2710 String source = operatorName; | 2710 String source = operatorName; |
| 2711 bool isComplex = !identical(source, '='); | 2711 bool isComplex = !identical(source, '='); |
| 2712 if (!Elements.isUnresolved(target)) { | 2712 if (!Elements.isUnresolved(target)) { |
| 2713 if (target.isAbstractField()) { | 2713 if (target.isAbstractField) { |
| 2714 AbstractFieldElement field = target; | 2714 AbstractFieldElement field = target; |
| 2715 setter = field.setter; | 2715 setter = field.setter; |
| 2716 getter = field.getter; | 2716 getter = field.getter; |
| 2717 if (setter == null && !inInstanceContext) { | 2717 if (setter == null && !inInstanceContext) { |
| 2718 setter = warnAndCreateErroneousElement( | 2718 setter = warnAndCreateErroneousElement( |
| 2719 node.selector, field.name, MessageKind.CANNOT_RESOLVE_SETTER); | 2719 node.selector, field.name, MessageKind.CANNOT_RESOLVE_SETTER); |
| 2720 compiler.backend.registerThrowNoSuchMethod(mapping); | 2720 compiler.backend.registerThrowNoSuchMethod(mapping); |
| 2721 } | 2721 } |
| 2722 if (isComplex && getter == null && !inInstanceContext) { | 2722 if (isComplex && getter == null && !inInstanceContext) { |
| 2723 getter = warnAndCreateErroneousElement( | 2723 getter = warnAndCreateErroneousElement( |
| 2724 node.selector, field.name, MessageKind.CANNOT_RESOLVE_GETTER); | 2724 node.selector, field.name, MessageKind.CANNOT_RESOLVE_GETTER); |
| 2725 compiler.backend.registerThrowNoSuchMethod(mapping); | 2725 compiler.backend.registerThrowNoSuchMethod(mapping); |
| 2726 } | 2726 } |
| 2727 } else if (target.impliesType()) { | 2727 } else if (target.impliesType) { |
| 2728 setter = warnAndCreateErroneousElement( | 2728 setter = warnAndCreateErroneousElement( |
| 2729 node.selector, target.name, MessageKind.ASSIGNING_TYPE); | 2729 node.selector, target.name, MessageKind.ASSIGNING_TYPE); |
| 2730 compiler.backend.registerThrowNoSuchMethod(mapping); | 2730 compiler.backend.registerThrowNoSuchMethod(mapping); |
| 2731 } else if (target.modifiers.isFinal() || | 2731 } else if (target.modifiers.isFinal || |
| 2732 target.modifiers.isConst() || | 2732 target.modifiers.isConst || |
| 2733 (target.isFunction() && | 2733 (target.isFunction && |
| 2734 Elements.isStaticOrTopLevelFunction(target) && | 2734 Elements.isStaticOrTopLevelFunction(target) && |
| 2735 !target.isSetter())) { | 2735 !target.isSetter)) { |
| 2736 if (target.isFunction()) { | 2736 if (target.isFunction) { |
| 2737 setter = warnAndCreateErroneousElement( | 2737 setter = warnAndCreateErroneousElement( |
| 2738 node.selector, target.name, MessageKind.ASSIGNING_METHOD); | 2738 node.selector, target.name, MessageKind.ASSIGNING_METHOD); |
| 2739 } else { | 2739 } else { |
| 2740 setter = warnAndCreateErroneousElement( | 2740 setter = warnAndCreateErroneousElement( |
| 2741 node.selector, target.name, MessageKind.CANNOT_RESOLVE_SETTER); | 2741 node.selector, target.name, MessageKind.CANNOT_RESOLVE_SETTER); |
| 2742 } | 2742 } |
| 2743 compiler.backend.registerThrowNoSuchMethod(mapping); | 2743 compiler.backend.registerThrowNoSuchMethod(mapping); |
| 2744 } | 2744 } |
| 2745 if (isPotentiallyMutableTarget(target)) { | 2745 if (isPotentiallyMutableTarget(target)) { |
| 2746 mapping.setPotentiallyMutated(target, node); | 2746 mapping.setPotentiallyMutated(target, node); |
| 2747 if (enclosingElement != target.enclosingElement) { | 2747 if (enclosingElement != target.enclosingElement) { |
| 2748 mapping.registerPotentiallyMutatedInClosure(target, node); | 2748 mapping.registerPotentiallyMutatedInClosure(target, node); |
| 2749 } | 2749 } |
| 2750 for (Node scope in promotionScope) { | 2750 for (Node scope in promotionScope) { |
| 2751 mapping.registerPotentiallyMutatedIn(scope, target, node); | 2751 mapping.registerPotentiallyMutatedIn(scope, target, node); |
| 2752 } | 2752 } |
| 2753 } | 2753 } |
| 2754 } | 2754 } |
| 2755 | 2755 |
| 2756 resolveArguments(node.argumentsNode); | 2756 resolveArguments(node.argumentsNode); |
| 2757 | 2757 |
| 2758 Selector selector = mapping.getSelector(node); | 2758 Selector selector = mapping.getSelector(node); |
| 2759 if (isComplex) { | 2759 if (isComplex) { |
| 2760 Selector getterSelector; | 2760 Selector getterSelector; |
| 2761 if (selector.isSetter()) { | 2761 if (selector.isSetter) { |
| 2762 getterSelector = new Selector.getterFrom(selector); | 2762 getterSelector = new Selector.getterFrom(selector); |
| 2763 } else { | 2763 } else { |
| 2764 assert(selector.isIndexSet()); | 2764 assert(selector.isIndexSet); |
| 2765 getterSelector = new Selector.index(); | 2765 getterSelector = new Selector.index(); |
| 2766 } | 2766 } |
| 2767 registerSend(getterSelector, getter); | 2767 registerSend(getterSelector, getter); |
| 2768 mapping.setGetterSelectorInComplexSendSet(node, getterSelector); | 2768 mapping.setGetterSelectorInComplexSendSet(node, getterSelector); |
| 2769 if (node.isSuperCall) { | 2769 if (node.isSuperCall) { |
| 2770 getter = currentClass.lookupSuperSelector(getterSelector, compiler); | 2770 getter = currentClass.lookupSuperSelector(getterSelector, compiler); |
| 2771 if (getter == null) { | 2771 if (getter == null) { |
| 2772 target = warnAndCreateErroneousElement( | 2772 target = warnAndCreateErroneousElement( |
| 2773 node, selector.name, MessageKind.NO_SUCH_SUPER_MEMBER, | 2773 node, selector.name, MessageKind.NO_SUCH_SUPER_MEMBER, |
| 2774 {'className': currentClass, 'memberName': selector.name}); | 2774 {'className': currentClass, 'memberName': selector.name}); |
| (...skipping 18 matching lines...) Expand all Loading... |
| 2793 } else if (source.endsWith('=')) { | 2793 } else if (source.endsWith('=')) { |
| 2794 registerBinaryOperator(Elements.mapToUserOperator(operatorName)); | 2794 registerBinaryOperator(Elements.mapToUserOperator(operatorName)); |
| 2795 } | 2795 } |
| 2796 } | 2796 } |
| 2797 | 2797 |
| 2798 registerSend(selector, setter); | 2798 registerSend(selector, setter); |
| 2799 return useElement(node, setter); | 2799 return useElement(node, setter); |
| 2800 } | 2800 } |
| 2801 | 2801 |
| 2802 void registerSend(Selector selector, Element target) { | 2802 void registerSend(Selector selector, Element target) { |
| 2803 if (target == null || target.isInstanceMember()) { | 2803 if (target == null || target.isInstanceMember) { |
| 2804 if (selector.isGetter()) { | 2804 if (selector.isGetter) { |
| 2805 world.registerDynamicGetter(selector); | 2805 world.registerDynamicGetter(selector); |
| 2806 } else if (selector.isSetter()) { | 2806 } else if (selector.isSetter) { |
| 2807 world.registerDynamicSetter(selector); | 2807 world.registerDynamicSetter(selector); |
| 2808 } else { | 2808 } else { |
| 2809 world.registerDynamicInvocation(selector); | 2809 world.registerDynamicInvocation(selector); |
| 2810 } | 2810 } |
| 2811 } else if (Elements.isStaticOrTopLevel(target)) { | 2811 } else if (Elements.isStaticOrTopLevel(target)) { |
| 2812 // Avoid registration of type variables since they are not analyzable but | 2812 // Avoid registration of type variables since they are not analyzable but |
| 2813 // instead resolved through their enclosing type declaration. | 2813 // instead resolved through their enclosing type declaration. |
| 2814 if (!target.isTypeVariable()) { | 2814 if (!target.isTypeVariable) { |
| 2815 // [target] might be the implementation element and only declaration | 2815 // [target] might be the implementation element and only declaration |
| 2816 // elements may be registered. | 2816 // elements may be registered. |
| 2817 world.registerStaticUse(target.declaration); | 2817 world.registerStaticUse(target.declaration); |
| 2818 } | 2818 } |
| 2819 } | 2819 } |
| 2820 } | 2820 } |
| 2821 | 2821 |
| 2822 visitLiteralInt(LiteralInt node) { | 2822 visitLiteralInt(LiteralInt node) { |
| 2823 world.registerInstantiatedClass(compiler.intClass, mapping); | 2823 world.registerInstantiatedClass(compiler.intClass, mapping); |
| 2824 } | 2824 } |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2871 error(node, MessageKind.THROW_WITHOUT_EXPRESSION); | 2871 error(node, MessageKind.THROW_WITHOUT_EXPRESSION); |
| 2872 } | 2872 } |
| 2873 } | 2873 } |
| 2874 | 2874 |
| 2875 visitReturn(Return node) { | 2875 visitReturn(Return node) { |
| 2876 if (node.isRedirectingFactoryBody) { | 2876 if (node.isRedirectingFactoryBody) { |
| 2877 handleRedirectingFactoryBody(node); | 2877 handleRedirectingFactoryBody(node); |
| 2878 } else { | 2878 } else { |
| 2879 Node expression = node.expression; | 2879 Node expression = node.expression; |
| 2880 if (expression != null && | 2880 if (expression != null && |
| 2881 enclosingElement.isGenerativeConstructor()) { | 2881 enclosingElement.isGenerativeConstructor) { |
| 2882 // It is a compile-time error if a return statement of the form | 2882 // It is a compile-time error if a return statement of the form |
| 2883 // `return e;` appears in a generative constructor. (Dart Language | 2883 // `return e;` appears in a generative constructor. (Dart Language |
| 2884 // Specification 13.12.) | 2884 // Specification 13.12.) |
| 2885 compiler.reportError(expression, | 2885 compiler.reportError(expression, |
| 2886 MessageKind.CANNOT_RETURN_FROM_CONSTRUCTOR); | 2886 MessageKind.CANNOT_RETURN_FROM_CONSTRUCTOR); |
| 2887 } | 2887 } |
| 2888 visit(node.expression); | 2888 visit(node.expression); |
| 2889 } | 2889 } |
| 2890 } | 2890 } |
| 2891 | 2891 |
| 2892 void handleRedirectingFactoryBody(Return node) { | 2892 void handleRedirectingFactoryBody(Return node) { |
| 2893 final isSymbolConstructor = enclosingElement == compiler.symbolConstructor; | 2893 final isSymbolConstructor = enclosingElement == compiler.symbolConstructor; |
| 2894 if (!enclosingElement.isFactoryConstructor()) { | 2894 if (!enclosingElement.isFactoryConstructor) { |
| 2895 compiler.reportError( | 2895 compiler.reportError( |
| 2896 node, MessageKind.FACTORY_REDIRECTION_IN_NON_FACTORY); | 2896 node, MessageKind.FACTORY_REDIRECTION_IN_NON_FACTORY); |
| 2897 compiler.reportHint( | 2897 compiler.reportHint( |
| 2898 enclosingElement, MessageKind.MISSING_FACTORY_KEYWORD); | 2898 enclosingElement, MessageKind.MISSING_FACTORY_KEYWORD); |
| 2899 } | 2899 } |
| 2900 FunctionElement constructor = enclosingElement; | 2900 FunctionElement constructor = enclosingElement; |
| 2901 bool isConstConstructor = constructor.modifiers.isConst(); | 2901 bool isConstConstructor = constructor.modifiers.isConst; |
| 2902 FunctionElement redirectionTarget = resolveRedirectingFactory( | 2902 FunctionElement redirectionTarget = resolveRedirectingFactory( |
| 2903 node, inConstContext: isConstConstructor); | 2903 node, inConstContext: isConstConstructor); |
| 2904 constructor.defaultImplementation = redirectionTarget; | 2904 constructor.defaultImplementation = redirectionTarget; |
| 2905 useElement(node.expression, redirectionTarget); | 2905 useElement(node.expression, redirectionTarget); |
| 2906 if (Elements.isUnresolved(redirectionTarget)) { | 2906 if (Elements.isUnresolved(redirectionTarget)) { |
| 2907 compiler.backend.registerThrowNoSuchMethod(mapping); | 2907 compiler.backend.registerThrowNoSuchMethod(mapping); |
| 2908 return; | 2908 return; |
| 2909 } else { | 2909 } else { |
| 2910 if (isConstConstructor && | 2910 if (isConstConstructor && |
| 2911 !redirectionTarget.modifiers.isConst()) { | 2911 !redirectionTarget.modifiers.isConst) { |
| 2912 compiler.reportError(node, MessageKind.CONSTRUCTOR_IS_NOT_CONST); | 2912 compiler.reportError(node, MessageKind.CONSTRUCTOR_IS_NOT_CONST); |
| 2913 } | 2913 } |
| 2914 if (redirectionTarget == constructor) { | 2914 if (redirectionTarget == constructor) { |
| 2915 compiler.reportError(node, MessageKind.CYCLIC_REDIRECTING_FACTORY); | 2915 compiler.reportError(node, MessageKind.CYCLIC_REDIRECTING_FACTORY); |
| 2916 return; | 2916 return; |
| 2917 } | 2917 } |
| 2918 } | 2918 } |
| 2919 | 2919 |
| 2920 // Check that the target constructor is type compatible with the | 2920 // Check that the target constructor is type compatible with the |
| 2921 // redirecting constructor. | 2921 // redirecting constructor. |
| 2922 ClassElement targetClass = redirectionTarget.getEnclosingClass(); | 2922 ClassElement targetClass = redirectionTarget.enclosingClass; |
| 2923 InterfaceType type = mapping.getType(node.expression); | 2923 InterfaceType type = mapping.getType(node.expression); |
| 2924 FunctionType targetType = redirectionTarget.computeType(compiler) | 2924 FunctionType targetType = redirectionTarget.computeType(compiler) |
| 2925 .subst(type.typeArguments, targetClass.typeVariables); | 2925 .subst(type.typeArguments, targetClass.typeVariables); |
| 2926 FunctionType constructorType = constructor.computeType(compiler); | 2926 FunctionType constructorType = constructor.computeType(compiler); |
| 2927 bool isSubtype = compiler.types.isSubtype(targetType, constructorType); | 2927 bool isSubtype = compiler.types.isSubtype(targetType, constructorType); |
| 2928 if (!isSubtype) { | 2928 if (!isSubtype) { |
| 2929 warning(node, MessageKind.NOT_ASSIGNABLE, | 2929 warning(node, MessageKind.NOT_ASSIGNABLE, |
| 2930 {'fromType': targetType, 'toType': constructorType}); | 2930 {'fromType': targetType, 'toType': constructorType}); |
| 2931 } | 2931 } |
| 2932 | 2932 |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2979 nodes = nodes.tail) { | 2979 nodes = nodes.tail) { |
| 2980 if (modifier == nodes.head.asIdentifier().source) { | 2980 if (modifier == nodes.head.asIdentifier().source) { |
| 2981 modifierNode = nodes.head; | 2981 modifierNode = nodes.head; |
| 2982 break; | 2982 break; |
| 2983 } | 2983 } |
| 2984 } | 2984 } |
| 2985 assert(modifierNode != null); | 2985 assert(modifierNode != null); |
| 2986 compiler.reportError(modifierNode, MessageKind.EXTRANEOUS_MODIFIER, | 2986 compiler.reportError(modifierNode, MessageKind.EXTRANEOUS_MODIFIER, |
| 2987 {'modifier': modifier}); | 2987 {'modifier': modifier}); |
| 2988 } | 2988 } |
| 2989 if (modifiers.isFinal() && (modifiers.isConst() || modifiers.isVar())) { | 2989 if (modifiers.isFinal && (modifiers.isConst || modifiers.isVar)) { |
| 2990 reportExtraModifier('final'); | 2990 reportExtraModifier('final'); |
| 2991 } | 2991 } |
| 2992 if (modifiers.isVar() && (modifiers.isConst() || node.type != null)) { | 2992 if (modifiers.isVar && (modifiers.isConst || node.type != null)) { |
| 2993 reportExtraModifier('var'); | 2993 reportExtraModifier('var'); |
| 2994 } | 2994 } |
| 2995 if (enclosingElement.isFunction()) { | 2995 if (enclosingElement.isFunction) { |
| 2996 if (modifiers.isAbstract()) { | 2996 if (modifiers.isAbstract) { |
| 2997 reportExtraModifier('abstract'); | 2997 reportExtraModifier('abstract'); |
| 2998 } | 2998 } |
| 2999 if (modifiers.isStatic()) { | 2999 if (modifiers.isStatic) { |
| 3000 reportExtraModifier('static'); | 3000 reportExtraModifier('static'); |
| 3001 } | 3001 } |
| 3002 } | 3002 } |
| 3003 if (node.metadata != null) { | 3003 if (node.metadata != null) { |
| 3004 variables.metadata = | 3004 variables.metadata = |
| 3005 compiler.resolver.resolveMetadata(enclosingElement, node); | 3005 compiler.resolver.resolveMetadata(enclosingElement, node); |
| 3006 } | 3006 } |
| 3007 visitor.visit(node.definitions); | 3007 visitor.visit(node.definitions); |
| 3008 } | 3008 } |
| 3009 | 3009 |
| 3010 visitWhile(While node) { | 3010 visitWhile(While node) { |
| 3011 visit(node.condition); | 3011 visit(node.condition); |
| 3012 visitLoopBodyIn(node, node.body, new BlockScope(scope)); | 3012 visitLoopBodyIn(node, node.body, new BlockScope(scope)); |
| 3013 } | 3013 } |
| 3014 | 3014 |
| 3015 visitParenthesizedExpression(ParenthesizedExpression node) { | 3015 visitParenthesizedExpression(ParenthesizedExpression node) { |
| 3016 bool oldSendIsMemberAccess = sendIsMemberAccess; | 3016 bool oldSendIsMemberAccess = sendIsMemberAccess; |
| 3017 sendIsMemberAccess = false; | 3017 sendIsMemberAccess = false; |
| 3018 visit(node.expression); | 3018 visit(node.expression); |
| 3019 sendIsMemberAccess = oldSendIsMemberAccess; | 3019 sendIsMemberAccess = oldSendIsMemberAccess; |
| 3020 } | 3020 } |
| 3021 | 3021 |
| 3022 visitNewExpression(NewExpression node) { | 3022 visitNewExpression(NewExpression node) { |
| 3023 Node selector = node.send.selector; | 3023 Node selector = node.send.selector; |
| 3024 FunctionElement constructor = resolveConstructor(node); | 3024 FunctionElement constructor = resolveConstructor(node); |
| 3025 final bool isSymbolConstructor = constructor == compiler.symbolConstructor; | 3025 final bool isSymbolConstructor = constructor == compiler.symbolConstructor; |
| 3026 final bool isMirrorsUsedConstant = | 3026 final bool isMirrorsUsedConstant = |
| 3027 node.isConst() && (constructor == compiler.mirrorsUsedConstructor); | 3027 node.isConst && (constructor == compiler.mirrorsUsedConstructor); |
| 3028 resolveSelector(node.send, constructor); | 3028 resolveSelector(node.send, constructor); |
| 3029 resolveArguments(node.send.argumentsNode); | 3029 resolveArguments(node.send.argumentsNode); |
| 3030 useElement(node.send, constructor); | 3030 useElement(node.send, constructor); |
| 3031 if (Elements.isUnresolved(constructor)) return constructor; | 3031 if (Elements.isUnresolved(constructor)) return constructor; |
| 3032 Selector callSelector = mapping.getSelector(node.send); | 3032 Selector callSelector = mapping.getSelector(node.send); |
| 3033 if (!callSelector.applies(constructor, compiler)) { | 3033 if (!callSelector.applies(constructor, compiler)) { |
| 3034 warnArgumentMismatch(node.send, constructor); | 3034 warnArgumentMismatch(node.send, constructor); |
| 3035 compiler.backend.registerThrowNoSuchMethod(mapping); | 3035 compiler.backend.registerThrowNoSuchMethod(mapping); |
| 3036 } | 3036 } |
| 3037 | 3037 |
| 3038 // [constructor] might be the implementation element | 3038 // [constructor] might be the implementation element |
| 3039 // and only declaration elements may be registered. | 3039 // and only declaration elements may be registered. |
| 3040 world.registerStaticUse(constructor.declaration); | 3040 world.registerStaticUse(constructor.declaration); |
| 3041 ClassElement cls = constructor.getEnclosingClass(); | 3041 ClassElement cls = constructor.enclosingClass; |
| 3042 InterfaceType type = mapping.getType(node); | 3042 InterfaceType type = mapping.getType(node); |
| 3043 if (node.isConst() && type.containsTypeVariables) { | 3043 if (node.isConst && type.containsTypeVariables) { |
| 3044 compiler.reportError(node.send.selector, | 3044 compiler.reportError(node.send.selector, |
| 3045 MessageKind.TYPE_VARIABLE_IN_CONSTANT); | 3045 MessageKind.TYPE_VARIABLE_IN_CONSTANT); |
| 3046 } | 3046 } |
| 3047 world.registerInstantiatedType(type, mapping); | 3047 world.registerInstantiatedType(type, mapping); |
| 3048 if (constructor.isFactoryConstructor() && !type.typeArguments.isEmpty) { | 3048 if (constructor.isFactoryConstructor && !type.typeArguments.isEmpty) { |
| 3049 world.registerFactoryWithTypeArguments(mapping); | 3049 world.registerFactoryWithTypeArguments(mapping); |
| 3050 } | 3050 } |
| 3051 if (constructor.isGenerativeConstructor() && cls.isAbstract) { | 3051 if (constructor.isGenerativeConstructor && cls.isAbstract) { |
| 3052 warning(node, MessageKind.ABSTRACT_CLASS_INSTANTIATION); | 3052 warning(node, MessageKind.ABSTRACT_CLASS_INSTANTIATION); |
| 3053 compiler.backend.registerAbstractClassInstantiation(mapping); | 3053 compiler.backend.registerAbstractClassInstantiation(mapping); |
| 3054 } | 3054 } |
| 3055 | 3055 |
| 3056 if (isSymbolConstructor) { | 3056 if (isSymbolConstructor) { |
| 3057 if (node.isConst()) { | 3057 if (node.isConst) { |
| 3058 Node argumentNode = node.send.arguments.head; | 3058 Node argumentNode = node.send.arguments.head; |
| 3059 Constant name = compiler.resolver.constantCompiler.compileNode( | 3059 Constant name = compiler.resolver.constantCompiler.compileNode( |
| 3060 argumentNode, mapping); | 3060 argumentNode, mapping); |
| 3061 if (!name.isString) { | 3061 if (!name.isString) { |
| 3062 DartType type = name.computeType(compiler); | 3062 DartType type = name.computeType(compiler); |
| 3063 compiler.reportError(argumentNode, MessageKind.STRING_EXPECTED, | 3063 compiler.reportError(argumentNode, MessageKind.STRING_EXPECTED, |
| 3064 {'type': type}); | 3064 {'type': type}); |
| 3065 } else { | 3065 } else { |
| 3066 StringConstant stringConstant = name; | 3066 StringConstant stringConstant = name; |
| 3067 String nameString = stringConstant.toDartString().slowToString(); | 3067 String nameString = stringConstant.toDartString().slowToString(); |
| 3068 if (validateSymbol(argumentNode, nameString)) { | 3068 if (validateSymbol(argumentNode, nameString)) { |
| 3069 world.registerConstSymbol(nameString, mapping); | 3069 world.registerConstSymbol(nameString, mapping); |
| 3070 } | 3070 } |
| 3071 } | 3071 } |
| 3072 } else { | 3072 } else { |
| 3073 if (!compiler.mirrorUsageAnalyzerTask.hasMirrorUsage( | 3073 if (!compiler.mirrorUsageAnalyzerTask.hasMirrorUsage( |
| 3074 enclosingElement)) { | 3074 enclosingElement)) { |
| 3075 compiler.reportHint( | 3075 compiler.reportHint( |
| 3076 node.newToken, MessageKind.NON_CONST_BLOAT, | 3076 node.newToken, MessageKind.NON_CONST_BLOAT, |
| 3077 {'name': compiler.symbolClass.name}); | 3077 {'name': compiler.symbolClass.name}); |
| 3078 } | 3078 } |
| 3079 world.registerNewSymbol(mapping); | 3079 world.registerNewSymbol(mapping); |
| 3080 } | 3080 } |
| 3081 } else if (isMirrorsUsedConstant) { | 3081 } else if (isMirrorsUsedConstant) { |
| 3082 compiler.mirrorUsageAnalyzerTask.validate(node, mapping); | 3082 compiler.mirrorUsageAnalyzerTask.validate(node, mapping); |
| 3083 } | 3083 } |
| 3084 if (node.isConst()) { | 3084 if (node.isConst) { |
| 3085 analyzeConstant(node); | 3085 analyzeConstant(node); |
| 3086 } | 3086 } |
| 3087 | 3087 |
| 3088 return null; | 3088 return null; |
| 3089 } | 3089 } |
| 3090 | 3090 |
| 3091 void checkConstMapKeysDontOverrideEquals(Spannable spannable, | 3091 void checkConstMapKeysDontOverrideEquals(Spannable spannable, |
| 3092 MapConstant map) { | 3092 MapConstant map) { |
| 3093 for (Constant key in map.keys.entries) { | 3093 for (Constant key in map.keys.entries) { |
| 3094 if (!key.isObject) continue; | 3094 if (!key.isObject) continue; |
| 3095 ObjectConstant objectConstant = key; | 3095 ObjectConstant objectConstant = key; |
| 3096 DartType keyType = objectConstant.type; | 3096 DartType keyType = objectConstant.type; |
| 3097 ClassElement cls = keyType.element; | 3097 ClassElement cls = keyType.element; |
| 3098 if (cls == compiler.stringClass) continue; | 3098 if (cls == compiler.stringClass) continue; |
| 3099 Element equals = cls.lookupMember('=='); | 3099 Element equals = cls.lookupMember('=='); |
| 3100 if (equals.getEnclosingClass() != compiler.objectClass) { | 3100 if (equals.enclosingClass != compiler.objectClass) { |
| 3101 compiler.reportError(spannable, | 3101 compiler.reportError(spannable, |
| 3102 MessageKind.CONST_MAP_KEY_OVERRIDES_EQUALS, | 3102 MessageKind.CONST_MAP_KEY_OVERRIDES_EQUALS, |
| 3103 {'type': keyType}); | 3103 {'type': keyType}); |
| 3104 } | 3104 } |
| 3105 } | 3105 } |
| 3106 } | 3106 } |
| 3107 | 3107 |
| 3108 void analyzeConstant(Node node) { | 3108 void analyzeConstant(Node node) { |
| 3109 addDeferredAction(enclosingElement, () { | 3109 addDeferredAction(enclosingElement, () { |
| 3110 Constant constant = | 3110 Constant constant = |
| (...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3202 } else { | 3202 } else { |
| 3203 typeArgument = resolveTypeAnnotation(nodes.head); | 3203 typeArgument = resolveTypeAnnotation(nodes.head); |
| 3204 for (nodes = nodes.tail; !nodes.isEmpty; nodes = nodes.tail) { | 3204 for (nodes = nodes.tail; !nodes.isEmpty; nodes = nodes.tail) { |
| 3205 warning(nodes.head, MessageKind.ADDITIONAL_TYPE_ARGUMENT); | 3205 warning(nodes.head, MessageKind.ADDITIONAL_TYPE_ARGUMENT); |
| 3206 resolveTypeAnnotation(nodes.head); | 3206 resolveTypeAnnotation(nodes.head); |
| 3207 } | 3207 } |
| 3208 } | 3208 } |
| 3209 } | 3209 } |
| 3210 DartType listType; | 3210 DartType listType; |
| 3211 if (typeArgument != null) { | 3211 if (typeArgument != null) { |
| 3212 if (node.isConst() && typeArgument.containsTypeVariables) { | 3212 if (node.isConst && typeArgument.containsTypeVariables) { |
| 3213 compiler.reportError(arguments.nodes.head, | 3213 compiler.reportError(arguments.nodes.head, |
| 3214 MessageKind.TYPE_VARIABLE_IN_CONSTANT); | 3214 MessageKind.TYPE_VARIABLE_IN_CONSTANT); |
| 3215 } | 3215 } |
| 3216 listType = new InterfaceType(compiler.listClass, | 3216 listType = new InterfaceType(compiler.listClass, |
| 3217 new Link<DartType>.fromList([typeArgument])); | 3217 new Link<DartType>.fromList([typeArgument])); |
| 3218 } else { | 3218 } else { |
| 3219 compiler.listClass.computeType(compiler); | 3219 compiler.listClass.computeType(compiler); |
| 3220 listType = compiler.listClass.rawType; | 3220 listType = compiler.listClass.rawType; |
| 3221 } | 3221 } |
| 3222 mapping.setType(node, listType); | 3222 mapping.setType(node, listType); |
| 3223 world.registerInstantiatedType(listType, mapping); | 3223 world.registerInstantiatedType(listType, mapping); |
| 3224 compiler.backend.registerRequiredType(listType, enclosingElement); | 3224 compiler.backend.registerRequiredType(listType, enclosingElement); |
| 3225 visit(node.elements); | 3225 visit(node.elements); |
| 3226 if (node.isConst()) { | 3226 if (node.isConst) { |
| 3227 analyzeConstant(node); | 3227 analyzeConstant(node); |
| 3228 } | 3228 } |
| 3229 | 3229 |
| 3230 sendIsMemberAccess = false; | 3230 sendIsMemberAccess = false; |
| 3231 } | 3231 } |
| 3232 | 3232 |
| 3233 visitConditional(Conditional node) { | 3233 visitConditional(Conditional node) { |
| 3234 doInPromotionScope(node.condition, () => visit(node.condition)); | 3234 doInPromotionScope(node.condition, () => visit(node.condition)); |
| 3235 doInPromotionScope(node.thenExpression, () => visit(node.thenExpression)); | 3235 doInPromotionScope(node.thenExpression, () => visit(node.thenExpression)); |
| 3236 visit(node.elseExpression); | 3236 visit(node.elseExpression); |
| (...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3305 } | 3305 } |
| 3306 mapping[node] = target; | 3306 mapping[node] = target; |
| 3307 } | 3307 } |
| 3308 | 3308 |
| 3309 registerImplicitInvocation(String name, int arity) { | 3309 registerImplicitInvocation(String name, int arity) { |
| 3310 Selector selector = new Selector.call(name, null, arity); | 3310 Selector selector = new Selector.call(name, null, arity); |
| 3311 world.registerDynamicInvocation(selector); | 3311 world.registerDynamicInvocation(selector); |
| 3312 } | 3312 } |
| 3313 | 3313 |
| 3314 visitForIn(ForIn node) { | 3314 visitForIn(ForIn node) { |
| 3315 LibraryElement library = enclosingElement.getLibrary(); | 3315 LibraryElement library = enclosingElement.library; |
| 3316 mapping.setIteratorSelector(node, compiler.iteratorSelector); | 3316 mapping.setIteratorSelector(node, compiler.iteratorSelector); |
| 3317 world.registerDynamicGetter(compiler.iteratorSelector); | 3317 world.registerDynamicGetter(compiler.iteratorSelector); |
| 3318 mapping.setCurrentSelector(node, compiler.currentSelector); | 3318 mapping.setCurrentSelector(node, compiler.currentSelector); |
| 3319 world.registerDynamicGetter(compiler.currentSelector); | 3319 world.registerDynamicGetter(compiler.currentSelector); |
| 3320 mapping.setMoveNextSelector(node, compiler.moveNextSelector); | 3320 mapping.setMoveNextSelector(node, compiler.moveNextSelector); |
| 3321 world.registerDynamicInvocation(compiler.moveNextSelector); | 3321 world.registerDynamicInvocation(compiler.moveNextSelector); |
| 3322 | 3322 |
| 3323 visit(node.expression); | 3323 visit(node.expression); |
| 3324 Scope blockScope = new BlockScope(scope); | 3324 Scope blockScope = new BlockScope(scope); |
| 3325 Node declaration = node.declaredIdentifier; | 3325 Node declaration = node.declaredIdentifier; |
| (...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3434 } | 3434 } |
| 3435 } | 3435 } |
| 3436 DartType mapType; | 3436 DartType mapType; |
| 3437 if (valueTypeArgument != null) { | 3437 if (valueTypeArgument != null) { |
| 3438 mapType = new InterfaceType(compiler.mapClass, | 3438 mapType = new InterfaceType(compiler.mapClass, |
| 3439 new Link<DartType>.fromList([keyTypeArgument, valueTypeArgument])); | 3439 new Link<DartType>.fromList([keyTypeArgument, valueTypeArgument])); |
| 3440 } else { | 3440 } else { |
| 3441 compiler.mapClass.computeType(compiler); | 3441 compiler.mapClass.computeType(compiler); |
| 3442 mapType = compiler.mapClass.rawType; | 3442 mapType = compiler.mapClass.rawType; |
| 3443 } | 3443 } |
| 3444 if (node.isConst() && mapType.containsTypeVariables) { | 3444 if (node.isConst && mapType.containsTypeVariables) { |
| 3445 compiler.reportError(arguments, | 3445 compiler.reportError(arguments, |
| 3446 MessageKind.TYPE_VARIABLE_IN_CONSTANT); | 3446 MessageKind.TYPE_VARIABLE_IN_CONSTANT); |
| 3447 } | 3447 } |
| 3448 mapping.setType(node, mapType); | 3448 mapping.setType(node, mapType); |
| 3449 world.registerInstantiatedType(mapType, mapping); | 3449 world.registerInstantiatedType(mapType, mapping); |
| 3450 if (node.isConst()) { | 3450 if (node.isConst) { |
| 3451 compiler.backend.registerConstantMap(mapping); | 3451 compiler.backend.registerConstantMap(mapping); |
| 3452 } | 3452 } |
| 3453 compiler.backend.registerRequiredType(mapType, enclosingElement); | 3453 compiler.backend.registerRequiredType(mapType, enclosingElement); |
| 3454 node.visitChildren(this); | 3454 node.visitChildren(this); |
| 3455 if (node.isConst()) { | 3455 if (node.isConst) { |
| 3456 analyzeConstant(node); | 3456 analyzeConstant(node); |
| 3457 } | 3457 } |
| 3458 | 3458 |
| 3459 sendIsMemberAccess = false; | 3459 sendIsMemberAccess = false; |
| 3460 } | 3460 } |
| 3461 | 3461 |
| 3462 visitLiteralMapEntry(LiteralMapEntry node) { | 3462 visitLiteralMapEntry(LiteralMapEntry node) { |
| 3463 node.visitChildren(this); | 3463 node.visitChildren(this); |
| 3464 } | 3464 } |
| 3465 | 3465 |
| 3466 visitNamedArgument(NamedArgument node) { | 3466 visitNamedArgument(NamedArgument node) { |
| 3467 visit(node.expression); | 3467 visit(node.expression); |
| 3468 } | 3468 } |
| 3469 | 3469 |
| 3470 DartType typeOfConstant(Constant constant) { | 3470 DartType typeOfConstant(Constant constant) { |
| 3471 if (constant.isInt) return compiler.intClass.rawType; | 3471 if (constant.isInt) return compiler.intClass.rawType; |
| 3472 if (constant.isBool) return compiler.boolClass.rawType; | 3472 if (constant.isBool) return compiler.boolClass.rawType; |
| 3473 if (constant.isDouble) return compiler.doubleClass.rawType; | 3473 if (constant.isDouble) return compiler.doubleClass.rawType; |
| 3474 if (constant.isString) return compiler.stringClass.rawType; | 3474 if (constant.isString) return compiler.stringClass.rawType; |
| 3475 if (constant.isNull) return compiler.nullClass.rawType; | 3475 if (constant.isNull) return compiler.nullClass.rawType; |
| 3476 if (constant.isFunction) return compiler.functionClass.rawType; | 3476 if (constant.isFunction) return compiler.functionClass.rawType; |
| 3477 assert(constant.isObject); | 3477 assert(constant.isObject); |
| 3478 ObjectConstant objectConstant = constant; | 3478 ObjectConstant objectConstant = constant; |
| 3479 return objectConstant.type; | 3479 return objectConstant.type; |
| 3480 } | 3480 } |
| 3481 | 3481 |
| 3482 bool overridesEquals(DartType type) { | 3482 bool overridesEquals(DartType type) { |
| 3483 ClassElement cls = type.element; | 3483 ClassElement cls = type.element; |
| 3484 Element equals = cls.lookupMember('=='); | 3484 Element equals = cls.lookupMember('=='); |
| 3485 return equals.getEnclosingClass() != compiler.objectClass; | 3485 return equals.enclosingClass != compiler.objectClass; |
| 3486 } | 3486 } |
| 3487 | 3487 |
| 3488 void checkCaseExpressions(SwitchStatement node) { | 3488 void checkCaseExpressions(SwitchStatement node) { |
| 3489 TargetElement breakElement = getOrCreateTargetElement(node); | 3489 TargetElement breakElement = getOrCreateTargetElement(node); |
| 3490 Map<String, LabelElement> continueLabels = <String, LabelElement>{}; | 3490 Map<String, LabelElement> continueLabels = <String, LabelElement>{}; |
| 3491 | 3491 |
| 3492 Link<Node> cases = node.cases.nodes; | 3492 Link<Node> cases = node.cases.nodes; |
| 3493 SwitchCase switchCase = cases.head; | 3493 SwitchCase switchCase = cases.head; |
| 3494 CaseMatch firstCase = null; | 3494 CaseMatch firstCase = null; |
| 3495 DartType firstCaseType = null; | 3495 DartType firstCaseType = null; |
| (...skipping 258 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3754 if (typeNode.bound != null) { | 3754 if (typeNode.bound != null) { |
| 3755 DartType boundType = typeResolver.resolveTypeAnnotation( | 3755 DartType boundType = typeResolver.resolveTypeAnnotation( |
| 3756 this, typeNode.bound); | 3756 this, typeNode.bound); |
| 3757 variableElement.boundCache = boundType; | 3757 variableElement.boundCache = boundType; |
| 3758 | 3758 |
| 3759 void checkTypeVariableBound() { | 3759 void checkTypeVariableBound() { |
| 3760 Link<TypeVariableElement> seenTypeVariables = | 3760 Link<TypeVariableElement> seenTypeVariables = |
| 3761 const Link<TypeVariableElement>(); | 3761 const Link<TypeVariableElement>(); |
| 3762 seenTypeVariables = seenTypeVariables.prepend(variableElement); | 3762 seenTypeVariables = seenTypeVariables.prepend(variableElement); |
| 3763 DartType bound = boundType; | 3763 DartType bound = boundType; |
| 3764 while (bound.element.isTypeVariable()) { | 3764 while (bound.element.isTypeVariable) { |
| 3765 TypeVariableElement element = bound.element; | 3765 TypeVariableElement element = bound.element; |
| 3766 if (seenTypeVariables.contains(element)) { | 3766 if (seenTypeVariables.contains(element)) { |
| 3767 if (identical(element, variableElement)) { | 3767 if (identical(element, variableElement)) { |
| 3768 // Only report an error on the checked type variable to avoid | 3768 // Only report an error on the checked type variable to avoid |
| 3769 // generating multiple errors for the same cyclicity. | 3769 // generating multiple errors for the same cyclicity. |
| 3770 warning(typeNode.name, MessageKind.CYCLIC_TYPE_VARIABLE, | 3770 warning(typeNode.name, MessageKind.CYCLIC_TYPE_VARIABLE, |
| 3771 {'typeVariableName': variableElement.name}); | 3771 {'typeVariableName': variableElement.name}); |
| 3772 } | 3772 } |
| 3773 break; | 3773 break; |
| 3774 } | 3774 } |
| (...skipping 201 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3976 | 3976 |
| 3977 if (element.interfaces == null) { | 3977 if (element.interfaces == null) { |
| 3978 element.interfaces = resolveInterfaces(node.interfaces, node.superclass); | 3978 element.interfaces = resolveInterfaces(node.interfaces, node.superclass); |
| 3979 } else { | 3979 } else { |
| 3980 assert(invariant(element, element.hasIncompleteHierarchy)); | 3980 assert(invariant(element, element.hasIncompleteHierarchy)); |
| 3981 } | 3981 } |
| 3982 calculateAllSupertypes(element); | 3982 calculateAllSupertypes(element); |
| 3983 | 3983 |
| 3984 if (!element.hasConstructor) { | 3984 if (!element.hasConstructor) { |
| 3985 Element superMember = element.superclass.localLookup(''); | 3985 Element superMember = element.superclass.localLookup(''); |
| 3986 if (superMember == null || !superMember.isGenerativeConstructor()) { | 3986 if (superMember == null || !superMember.isGenerativeConstructor) { |
| 3987 MessageKind kind = MessageKind.CANNOT_FIND_CONSTRUCTOR; | 3987 MessageKind kind = MessageKind.CANNOT_FIND_CONSTRUCTOR; |
| 3988 Map arguments = {'constructorName': ''}; | 3988 Map arguments = {'constructorName': ''}; |
| 3989 // TODO(ahe): Why is this a compile-time error? Or if it is an error, | 3989 // TODO(ahe): Why is this a compile-time error? Or if it is an error, |
| 3990 // why do we bother to registerThrowNoSuchMethod below? | 3990 // why do we bother to registerThrowNoSuchMethod below? |
| 3991 compiler.reportError(node, kind, arguments); | 3991 compiler.reportError(node, kind, arguments); |
| 3992 superMember = new ErroneousElementX( | 3992 superMember = new ErroneousElementX( |
| 3993 kind, arguments, '', element); | 3993 kind, arguments, '', element); |
| 3994 compiler.backend.registerThrowNoSuchMethod(mapping); | 3994 compiler.backend.registerThrowNoSuchMethod(mapping); |
| 3995 } else { | 3995 } else { |
| 3996 Selector callToMatch = new Selector.call("", element.getLibrary(), 0); | 3996 Selector callToMatch = new Selector.call("", element.library, 0); |
| 3997 if (!callToMatch.applies(superMember, compiler)) { | 3997 if (!callToMatch.applies(superMember, compiler)) { |
| 3998 MessageKind kind = MessageKind.NO_MATCHING_CONSTRUCTOR_FOR_IMPLICIT; | 3998 MessageKind kind = MessageKind.NO_MATCHING_CONSTRUCTOR_FOR_IMPLICIT; |
| 3999 compiler.reportError(node, kind); | 3999 compiler.reportError(node, kind); |
| 4000 superMember = new ErroneousElementX(kind, {}, '', element); | 4000 superMember = new ErroneousElementX(kind, {}, '', element); |
| 4001 } | 4001 } |
| 4002 } | 4002 } |
| 4003 FunctionElement constructor = | 4003 FunctionElement constructor = |
| 4004 new SynthesizedConstructorElementX.forDefault(superMember, element); | 4004 new SynthesizedConstructorElementX.forDefault(superMember, element); |
| 4005 element.setDefaultConstructor(constructor, compiler); | 4005 element.setDefaultConstructor(constructor, compiler); |
| 4006 } | 4006 } |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4048 } | 4048 } |
| 4049 doApplyMixinTo(element, supertype, checkMixinType(link.head)); | 4049 doApplyMixinTo(element, supertype, checkMixinType(link.head)); |
| 4050 return element.computeType(compiler); | 4050 return element.computeType(compiler); |
| 4051 } | 4051 } |
| 4052 | 4052 |
| 4053 DartType applyMixin(DartType supertype, DartType mixinType, Node node) { | 4053 DartType applyMixin(DartType supertype, DartType mixinType, Node node) { |
| 4054 String superName = supertype.name; | 4054 String superName = supertype.name; |
| 4055 String mixinName = mixinType.name; | 4055 String mixinName = mixinType.name; |
| 4056 MixinApplicationElementX mixinApplication = new MixinApplicationElementX( | 4056 MixinApplicationElementX mixinApplication = new MixinApplicationElementX( |
| 4057 "${superName}+${mixinName}", | 4057 "${superName}+${mixinName}", |
| 4058 element.getCompilationUnit(), | 4058 element.compilationUnit, |
| 4059 compiler.getNextFreeClassId(), | 4059 compiler.getNextFreeClassId(), |
| 4060 node, | 4060 node, |
| 4061 new Modifiers.withFlags(new NodeList.empty(), Modifiers.FLAG_ABSTRACT)); | 4061 new Modifiers.withFlags(new NodeList.empty(), Modifiers.FLAG_ABSTRACT)); |
| 4062 // Create synthetic type variables for the mixin application. | 4062 // Create synthetic type variables for the mixin application. |
| 4063 LinkBuilder<DartType> typeVariablesBuilder = new LinkBuilder<DartType>(); | 4063 LinkBuilder<DartType> typeVariablesBuilder = new LinkBuilder<DartType>(); |
| 4064 element.typeVariables.forEach((TypeVariableType type) { | 4064 element.typeVariables.forEach((TypeVariableType type) { |
| 4065 TypeVariableElementX typeVariableElement = new TypeVariableElementX( | 4065 TypeVariableElementX typeVariableElement = new TypeVariableElementX( |
| 4066 type.name, mixinApplication, type.element.parseNode(compiler)); | 4066 type.name, mixinApplication, type.element.parseNode(compiler)); |
| 4067 TypeVariableType typeVariable = new TypeVariableType(typeVariableElement); | 4067 TypeVariableType typeVariable = new TypeVariableType(typeVariableElement); |
| 4068 typeVariablesBuilder.addLast(typeVariable); | 4068 typeVariablesBuilder.addLast(typeVariable); |
| (...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4147 mixinApplication.allSupertypesAndSelf = superclass.allSupertypesAndSelf; | 4147 mixinApplication.allSupertypesAndSelf = superclass.allSupertypesAndSelf; |
| 4148 return; | 4148 return; |
| 4149 } | 4149 } |
| 4150 | 4150 |
| 4151 assert(mixinApplication.mixinType == null); | 4151 assert(mixinApplication.mixinType == null); |
| 4152 mixinApplication.mixinType = resolveMixinFor(mixinApplication, mixinType); | 4152 mixinApplication.mixinType = resolveMixinFor(mixinApplication, mixinType); |
| 4153 | 4153 |
| 4154 // Create forwarding constructors for constructor defined in the superclass | 4154 // Create forwarding constructors for constructor defined in the superclass |
| 4155 // because they are now hidden by the mixin application. | 4155 // because they are now hidden by the mixin application. |
| 4156 superclass.forEachLocalMember((Element member) { | 4156 superclass.forEachLocalMember((Element member) { |
| 4157 if (!member.isGenerativeConstructor()) return; | 4157 if (!member.isGenerativeConstructor) return; |
| 4158 FunctionElement forwarder = | 4158 FunctionElement forwarder = |
| 4159 createForwardingConstructor(member, mixinApplication); | 4159 createForwardingConstructor(member, mixinApplication); |
| 4160 mixinApplication.addConstructor(forwarder); | 4160 mixinApplication.addConstructor(forwarder); |
| 4161 }); | 4161 }); |
| 4162 calculateAllSupertypes(mixinApplication); | 4162 calculateAllSupertypes(mixinApplication); |
| 4163 } | 4163 } |
| 4164 | 4164 |
| 4165 InterfaceType resolveMixinFor(MixinApplicationElement mixinApplication, | 4165 InterfaceType resolveMixinFor(MixinApplicationElement mixinApplication, |
| 4166 DartType mixinType) { | 4166 DartType mixinType) { |
| 4167 ClassElement mixin = mixinType.element; | 4167 ClassElement mixin = mixinType.element; |
| (...skipping 141 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4309 message: "Supertypes not computed on $classElement " | 4309 message: "Supertypes not computed on $classElement " |
| 4310 "during resolution of $element")); | 4310 "during resolution of $element")); |
| 4311 while (!supertypes.isEmpty) { | 4311 while (!supertypes.isEmpty) { |
| 4312 DartType supertype = supertypes.head; | 4312 DartType supertype = supertypes.head; |
| 4313 allSupertypes.add(compiler, supertype.substByContext(type)); | 4313 allSupertypes.add(compiler, supertype.substByContext(type)); |
| 4314 supertypes = supertypes.tail; | 4314 supertypes = supertypes.tail; |
| 4315 } | 4315 } |
| 4316 } | 4316 } |
| 4317 | 4317 |
| 4318 isBlackListed(DartType type) { | 4318 isBlackListed(DartType type) { |
| 4319 LibraryElement lib = element.getLibrary(); | 4319 LibraryElement lib = element.library; |
| 4320 return | 4320 return |
| 4321 !identical(lib, compiler.coreLibrary) && | 4321 !identical(lib, compiler.coreLibrary) && |
| 4322 !identical(lib, compiler.jsHelperLibrary) && | 4322 !identical(lib, compiler.jsHelperLibrary) && |
| 4323 !identical(lib, compiler.interceptorsLibrary) && | 4323 !identical(lib, compiler.interceptorsLibrary) && |
| 4324 (identical(type, compiler.types.dynamicType) || | 4324 (identical(type, compiler.types.dynamicType) || |
| 4325 identical(type.element, compiler.boolClass) || | 4325 identical(type.element, compiler.boolClass) || |
| 4326 identical(type.element, compiler.numClass) || | 4326 identical(type.element, compiler.numClass) || |
| 4327 identical(type.element, compiler.intClass) || | 4327 identical(type.element, compiler.intClass) || |
| 4328 identical(type.element, compiler.doubleClass) || | 4328 identical(type.element, compiler.doubleClass) || |
| 4329 identical(type.element, compiler.stringClass) || | 4329 identical(type.element, compiler.stringClass) || |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4374 visitNodeList(node.mixins); | 4374 visitNodeList(node.mixins); |
| 4375 visitNodeList(node.interfaces); | 4375 visitNodeList(node.interfaces); |
| 4376 } | 4376 } |
| 4377 | 4377 |
| 4378 void visitTypeAnnotation(TypeAnnotation node) { | 4378 void visitTypeAnnotation(TypeAnnotation node) { |
| 4379 node.typeName.accept(this); | 4379 node.typeName.accept(this); |
| 4380 } | 4380 } |
| 4381 | 4381 |
| 4382 void visitIdentifier(Identifier node) { | 4382 void visitIdentifier(Identifier node) { |
| 4383 Element element = lookupInScope(compiler, node, context, node.source); | 4383 Element element = lookupInScope(compiler, node, context, node.source); |
| 4384 if (element != null && element.isClass()) { | 4384 if (element != null && element.isClass) { |
| 4385 loadSupertype(element, node); | 4385 loadSupertype(element, node); |
| 4386 } | 4386 } |
| 4387 } | 4387 } |
| 4388 | 4388 |
| 4389 void visitSend(Send node) { | 4389 void visitSend(Send node) { |
| 4390 Identifier prefix = node.receiver.asIdentifier(); | 4390 Identifier prefix = node.receiver.asIdentifier(); |
| 4391 if (prefix == null) { | 4391 if (prefix == null) { |
| 4392 error(node.receiver, MessageKind.NOT_A_PREFIX, {'node': node.receiver}); | 4392 error(node.receiver, MessageKind.NOT_A_PREFIX, {'node': node.receiver}); |
| 4393 return; | 4393 return; |
| 4394 } | 4394 } |
| 4395 Element element = lookupInScope(compiler, prefix, context, prefix.source); | 4395 Element element = lookupInScope(compiler, prefix, context, prefix.source); |
| 4396 if (element == null || !identical(element.kind, ElementKind.PREFIX)) { | 4396 if (element == null || !identical(element.kind, ElementKind.PREFIX)) { |
| 4397 error(node.receiver, MessageKind.NOT_A_PREFIX, {'node': node.receiver}); | 4397 error(node.receiver, MessageKind.NOT_A_PREFIX, {'node': node.receiver}); |
| 4398 return; | 4398 return; |
| 4399 } | 4399 } |
| 4400 PrefixElement prefixElement = element; | 4400 PrefixElement prefixElement = element; |
| 4401 Identifier selector = node.selector.asIdentifier(); | 4401 Identifier selector = node.selector.asIdentifier(); |
| 4402 var e = prefixElement.lookupLocalMember(selector.source); | 4402 var e = prefixElement.lookupLocalMember(selector.source); |
| 4403 if (e == null || !e.impliesType()) { | 4403 if (e == null || !e.impliesType) { |
| 4404 error(node.selector, MessageKind.CANNOT_RESOLVE_TYPE, | 4404 error(node.selector, MessageKind.CANNOT_RESOLVE_TYPE, |
| 4405 {'typeName': node.selector}); | 4405 {'typeName': node.selector}); |
| 4406 return; | 4406 return; |
| 4407 } | 4407 } |
| 4408 loadSupertype(e, node); | 4408 loadSupertype(e, node); |
| 4409 } | 4409 } |
| 4410 } | 4410 } |
| 4411 | 4411 |
| 4412 class VariableDefinitionsVisitor extends CommonResolverVisitor<Identifier> { | 4412 class VariableDefinitionsVisitor extends CommonResolverVisitor<Identifier> { |
| 4413 VariableDefinitions definitions; | 4413 VariableDefinitions definitions; |
| (...skipping 21 matching lines...) Expand all Loading... |
| 4435 identifier, MessageKind.REFERENCE_IN_INITIALIZATION, | 4435 identifier, MessageKind.REFERENCE_IN_INITIALIZATION, |
| 4436 {'variableName': name}); | 4436 {'variableName': name}); |
| 4437 } | 4437 } |
| 4438 return identifier; | 4438 return identifier; |
| 4439 } | 4439 } |
| 4440 | 4440 |
| 4441 Identifier visitIdentifier(Identifier node) { | 4441 Identifier visitIdentifier(Identifier node) { |
| 4442 // The variable is initialized to null. | 4442 // The variable is initialized to null. |
| 4443 resolver.world.registerInstantiatedClass(compiler.nullClass, | 4443 resolver.world.registerInstantiatedClass(compiler.nullClass, |
| 4444 resolver.mapping); | 4444 resolver.mapping); |
| 4445 if (definitions.modifiers.isConst()) { | 4445 if (definitions.modifiers.isConst) { |
| 4446 compiler.reportError(node, MessageKind.CONST_WITHOUT_INITIALIZER); | 4446 compiler.reportError(node, MessageKind.CONST_WITHOUT_INITIALIZER); |
| 4447 } | 4447 } |
| 4448 if (definitions.modifiers.isFinal() && | 4448 if (definitions.modifiers.isFinal && |
| 4449 !resolver.allowFinalWithoutInitializer) { | 4449 !resolver.allowFinalWithoutInitializer) { |
| 4450 compiler.reportError(node, MessageKind.FINAL_WITHOUT_INITIALIZER); | 4450 compiler.reportError(node, MessageKind.FINAL_WITHOUT_INITIALIZER); |
| 4451 } | 4451 } |
| 4452 return node; | 4452 return node; |
| 4453 } | 4453 } |
| 4454 | 4454 |
| 4455 visitNodeList(NodeList node) { | 4455 visitNodeList(NodeList node) { |
| 4456 for (Link<Node> link = node.nodes; !link.isEmpty; link = link.tail) { | 4456 for (Link<Node> link = node.nodes; !link.isEmpty; link = link.tail) { |
| 4457 Identifier name = visit(link.head); | 4457 Identifier name = visit(link.head); |
| 4458 VariableElement element = new VariableElementX( | 4458 VariableElement element = new VariableElementX( |
| 4459 name.source, kind, resolver.enclosingElement, | 4459 name.source, kind, resolver.enclosingElement, |
| 4460 variables, name.token); | 4460 variables, name.token); |
| 4461 resolver.defineElement(link.head, element); | 4461 resolver.defineElement(link.head, element); |
| 4462 if (definitions.modifiers.isConst()) { | 4462 if (definitions.modifiers.isConst) { |
| 4463 compiler.enqueuer.resolution.addDeferredAction(element, () { | 4463 compiler.enqueuer.resolution.addDeferredAction(element, () { |
| 4464 compiler.resolver.constantCompiler.compileConstant(element); | 4464 compiler.resolver.constantCompiler.compileConstant(element); |
| 4465 }); | 4465 }); |
| 4466 } | 4466 } |
| 4467 } | 4467 } |
| 4468 } | 4468 } |
| 4469 } | 4469 } |
| 4470 | 4470 |
| 4471 class ConstructorResolver extends CommonResolverVisitor<Element> { | 4471 class ConstructorResolver extends CommonResolverVisitor<Element> { |
| 4472 final ResolverVisitor resolver; | 4472 final ResolverVisitor resolver; |
| (...skipping 20 matching lines...) Expand all Loading... |
| 4493 compiler.reportError(diagnosticNode, kind, arguments); | 4493 compiler.reportError(diagnosticNode, kind, arguments); |
| 4494 } else { | 4494 } else { |
| 4495 compiler.reportWarning(diagnosticNode, kind, arguments); | 4495 compiler.reportWarning(diagnosticNode, kind, arguments); |
| 4496 } | 4496 } |
| 4497 return new ErroneousElementX(kind, arguments, targetName, enclosing); | 4497 return new ErroneousElementX(kind, arguments, targetName, enclosing); |
| 4498 } | 4498 } |
| 4499 | 4499 |
| 4500 Selector createConstructorSelector(String constructorName) { | 4500 Selector createConstructorSelector(String constructorName) { |
| 4501 return constructorName == '' | 4501 return constructorName == '' |
| 4502 ? new Selector.callDefaultConstructor( | 4502 ? new Selector.callDefaultConstructor( |
| 4503 resolver.enclosingElement.getLibrary()) | 4503 resolver.enclosingElement.library) |
| 4504 : new Selector.callConstructor( | 4504 : new Selector.callConstructor( |
| 4505 constructorName, | 4505 constructorName, |
| 4506 resolver.enclosingElement.getLibrary()); | 4506 resolver.enclosingElement.library); |
| 4507 } | 4507 } |
| 4508 | 4508 |
| 4509 FunctionElement resolveConstructor(ClassElement cls, | 4509 FunctionElement resolveConstructor(ClassElement cls, |
| 4510 Node diagnosticNode, | 4510 Node diagnosticNode, |
| 4511 String constructorName) { | 4511 String constructorName) { |
| 4512 cls.ensureResolved(compiler); | 4512 cls.ensureResolved(compiler); |
| 4513 Selector selector = createConstructorSelector(constructorName); | 4513 Selector selector = createConstructorSelector(constructorName); |
| 4514 Element result = cls.lookupConstructor(selector); | 4514 Element result = cls.lookupConstructor(selector); |
| 4515 if (result == null) { | 4515 if (result == null) { |
| 4516 String fullConstructorName = | 4516 String fullConstructorName = |
| 4517 resolver.compiler.resolver.constructorNameForDiagnostics( | 4517 resolver.compiler.resolver.constructorNameForDiagnostics( |
| 4518 cls.name, | 4518 cls.name, |
| 4519 constructorName); | 4519 constructorName); |
| 4520 return failOrReturnErroneousElement( | 4520 return failOrReturnErroneousElement( |
| 4521 cls, | 4521 cls, |
| 4522 diagnosticNode, | 4522 diagnosticNode, |
| 4523 fullConstructorName, | 4523 fullConstructorName, |
| 4524 MessageKind.CANNOT_FIND_CONSTRUCTOR, | 4524 MessageKind.CANNOT_FIND_CONSTRUCTOR, |
| 4525 {'constructorName': fullConstructorName}); | 4525 {'constructorName': fullConstructorName}); |
| 4526 } else if (inConstContext && !result.modifiers.isConst()) { | 4526 } else if (inConstContext && !result.modifiers.isConst) { |
| 4527 error(diagnosticNode, MessageKind.CONSTRUCTOR_IS_NOT_CONST); | 4527 error(diagnosticNode, MessageKind.CONSTRUCTOR_IS_NOT_CONST); |
| 4528 } | 4528 } |
| 4529 return result; | 4529 return result; |
| 4530 } | 4530 } |
| 4531 | 4531 |
| 4532 Element visitNewExpression(NewExpression node) { | 4532 Element visitNewExpression(NewExpression node) { |
| 4533 inConstContext = node.isConst(); | 4533 inConstContext = node.isConst; |
| 4534 Node selector = node.send.selector; | 4534 Node selector = node.send.selector; |
| 4535 Element element = visit(selector); | 4535 Element element = visit(selector); |
| 4536 assert(invariant(selector, element != null, | 4536 assert(invariant(selector, element != null, |
| 4537 message: 'No element return for $selector.')); | 4537 message: 'No element return for $selector.')); |
| 4538 return finishConstructorReference(element, node.send.selector, node); | 4538 return finishConstructorReference(element, node.send.selector, node); |
| 4539 } | 4539 } |
| 4540 | 4540 |
| 4541 /// Finishes resolution of a constructor reference and records the | 4541 /// Finishes resolution of a constructor reference and records the |
| 4542 /// type of the constructed instance on [expression]. | 4542 /// type of the constructed instance on [expression]. |
| 4543 FunctionElement finishConstructorReference(Element element, | 4543 FunctionElement finishConstructorReference(Element element, |
| 4544 Node diagnosticNode, | 4544 Node diagnosticNode, |
| 4545 Node expression) { | 4545 Node expression) { |
| 4546 assert(invariant(diagnosticNode, element != null, | 4546 assert(invariant(diagnosticNode, element != null, |
| 4547 message: 'No element return for $diagnosticNode.')); | 4547 message: 'No element return for $diagnosticNode.')); |
| 4548 // Find the unnamed constructor if the reference resolved to a | 4548 // Find the unnamed constructor if the reference resolved to a |
| 4549 // class. | 4549 // class. |
| 4550 if (!Elements.isUnresolved(element) && !element.isConstructor()) { | 4550 if (!Elements.isUnresolved(element) && !element.isConstructor) { |
| 4551 if (element.isClass()) { | 4551 if (element.isClass) { |
| 4552 ClassElement cls = element; | 4552 ClassElement cls = element; |
| 4553 cls.ensureResolved(compiler); | 4553 cls.ensureResolved(compiler); |
| 4554 // The unnamed constructor may not exist, so [e] may become unresolved. | 4554 // The unnamed constructor may not exist, so [e] may become unresolved. |
| 4555 element = resolveConstructor(cls, diagnosticNode, ''); | 4555 element = resolveConstructor(cls, diagnosticNode, ''); |
| 4556 } else { | 4556 } else { |
| 4557 element = failOrReturnErroneousElement( | 4557 element = failOrReturnErroneousElement( |
| 4558 element, diagnosticNode, element.name, MessageKind.NOT_A_TYPE, | 4558 element, diagnosticNode, element.name, MessageKind.NOT_A_TYPE, |
| 4559 {'node': diagnosticNode}); | 4559 {'node': diagnosticNode}); |
| 4560 } | 4560 } |
| 4561 } | 4561 } |
| 4562 if (type == null) { | 4562 if (type == null) { |
| 4563 if (Elements.isUnresolved(element)) { | 4563 if (Elements.isUnresolved(element)) { |
| 4564 type = compiler.types.dynamicType; | 4564 type = compiler.types.dynamicType; |
| 4565 } else { | 4565 } else { |
| 4566 type = element.getEnclosingClass().rawType; | 4566 type = element.enclosingClass.rawType; |
| 4567 } | 4567 } |
| 4568 } | 4568 } |
| 4569 resolver.mapping.setType(expression, type); | 4569 resolver.mapping.setType(expression, type); |
| 4570 return element; | 4570 return element; |
| 4571 } | 4571 } |
| 4572 | 4572 |
| 4573 Element visitTypeAnnotation(TypeAnnotation node) { | 4573 Element visitTypeAnnotation(TypeAnnotation node) { |
| 4574 assert(invariant(node, type == null)); | 4574 assert(invariant(node, type == null)); |
| 4575 // This is not really resolving a type-annotation, but the name of the | 4575 // This is not really resolving a type-annotation, but the name of the |
| 4576 // constructor. Therefore we allow deferred types. | 4576 // constructor. Therefore we allow deferred types. |
| 4577 type = resolver.resolveTypeAnnotation(node, | 4577 type = resolver.resolveTypeAnnotation(node, |
| 4578 malformedIsError: inConstContext, | 4578 malformedIsError: inConstContext, |
| 4579 deferredIsMalformed: false); | 4579 deferredIsMalformed: false); |
| 4580 compiler.backend.registerRequiredType(type, resolver.enclosingElement); | 4580 compiler.backend.registerRequiredType(type, resolver.enclosingElement); |
| 4581 return type.element; | 4581 return type.element; |
| 4582 } | 4582 } |
| 4583 | 4583 |
| 4584 Element visitSend(Send node) { | 4584 Element visitSend(Send node) { |
| 4585 Element element = visit(node.receiver); | 4585 Element element = visit(node.receiver); |
| 4586 assert(invariant(node.receiver, element != null, | 4586 assert(invariant(node.receiver, element != null, |
| 4587 message: 'No element return for $node.receiver.')); | 4587 message: 'No element return for $node.receiver.')); |
| 4588 if (Elements.isUnresolved(element)) return element; | 4588 if (Elements.isUnresolved(element)) return element; |
| 4589 Identifier name = node.selector.asIdentifier(); | 4589 Identifier name = node.selector.asIdentifier(); |
| 4590 if (name == null) internalError(node.selector, 'unexpected node'); | 4590 if (name == null) internalError(node.selector, 'unexpected node'); |
| 4591 | 4591 |
| 4592 if (element.isClass()) { | 4592 if (element.isClass) { |
| 4593 ClassElement cls = element; | 4593 ClassElement cls = element; |
| 4594 cls.ensureResolved(compiler); | 4594 cls.ensureResolved(compiler); |
| 4595 return resolveConstructor(cls, name, name.source); | 4595 return resolveConstructor(cls, name, name.source); |
| 4596 } else if (element.isPrefix()) { | 4596 } else if (element.isPrefix) { |
| 4597 PrefixElement prefix = element; | 4597 PrefixElement prefix = element; |
| 4598 element = prefix.lookupLocalMember(name.source); | 4598 element = prefix.lookupLocalMember(name.source); |
| 4599 element = Elements.unwrap(element, compiler, node); | 4599 element = Elements.unwrap(element, compiler, node); |
| 4600 if (element == null) { | 4600 if (element == null) { |
| 4601 return failOrReturnErroneousElement( | 4601 return failOrReturnErroneousElement( |
| 4602 resolver.enclosingElement, name, | 4602 resolver.enclosingElement, name, |
| 4603 name.source, | 4603 name.source, |
| 4604 MessageKind.CANNOT_RESOLVE, | 4604 MessageKind.CANNOT_RESOLVE, |
| 4605 {'name': name}); | 4605 {'name': name}); |
| 4606 } else if (!element.isClass()) { | 4606 } else if (!element.isClass) { |
| 4607 error(node, MessageKind.NOT_A_TYPE, {'node': name}); | 4607 error(node, MessageKind.NOT_A_TYPE, {'node': name}); |
| 4608 } | 4608 } |
| 4609 } else { | 4609 } else { |
| 4610 internalError(node.receiver, 'unexpected element $element'); | 4610 internalError(node.receiver, 'unexpected element $element'); |
| 4611 } | 4611 } |
| 4612 return element; | 4612 return element; |
| 4613 } | 4613 } |
| 4614 | 4614 |
| 4615 Element visitIdentifier(Identifier node) { | 4615 Element visitIdentifier(Identifier node) { |
| 4616 String name = node.source; | 4616 String name = node.source; |
| 4617 Element element = resolver.reportLookupErrorIfAny( | 4617 Element element = resolver.reportLookupErrorIfAny( |
| 4618 lookupInScope(compiler, node, resolver.scope, name), node, name); | 4618 lookupInScope(compiler, node, resolver.scope, name), node, name); |
| 4619 resolver.useElement(node, element); | 4619 resolver.useElement(node, element); |
| 4620 // TODO(johnniwinther): Change errors to warnings, cf. 11.11.1. | 4620 // TODO(johnniwinther): Change errors to warnings, cf. 11.11.1. |
| 4621 if (element == null) { | 4621 if (element == null) { |
| 4622 return failOrReturnErroneousElement(resolver.enclosingElement, node, name, | 4622 return failOrReturnErroneousElement(resolver.enclosingElement, node, name, |
| 4623 MessageKind.CANNOT_RESOLVE, | 4623 MessageKind.CANNOT_RESOLVE, |
| 4624 {'name': name}); | 4624 {'name': name}); |
| 4625 } else if (element.isErroneous()) { | 4625 } else if (element.isErroneous) { |
| 4626 return element; | 4626 return element; |
| 4627 } else if (element.isTypedef()) { | 4627 } else if (element.isTypedef) { |
| 4628 error(node, MessageKind.CANNOT_INSTANTIATE_TYPEDEF, | 4628 error(node, MessageKind.CANNOT_INSTANTIATE_TYPEDEF, |
| 4629 {'typedefName': name}); | 4629 {'typedefName': name}); |
| 4630 } else if (element.isTypeVariable()) { | 4630 } else if (element.isTypeVariable) { |
| 4631 error(node, MessageKind.CANNOT_INSTANTIATE_TYPE_VARIABLE, | 4631 error(node, MessageKind.CANNOT_INSTANTIATE_TYPE_VARIABLE, |
| 4632 {'typeVariableName': name}); | 4632 {'typeVariableName': name}); |
| 4633 } else if (!element.isClass() && !element.isPrefix()) { | 4633 } else if (!element.isClass && !element.isPrefix) { |
| 4634 error(node, MessageKind.NOT_A_TYPE, {'node': name}); | 4634 error(node, MessageKind.NOT_A_TYPE, {'node': name}); |
| 4635 } | 4635 } |
| 4636 return element; | 4636 return element; |
| 4637 } | 4637 } |
| 4638 | 4638 |
| 4639 /// Assumed to be called by [resolveRedirectingFactory]. | 4639 /// Assumed to be called by [resolveRedirectingFactory]. |
| 4640 Element visitReturn(Return node) { | 4640 Element visitReturn(Return node) { |
| 4641 Node expression = node.expression; | 4641 Node expression = node.expression; |
| 4642 return finishConstructorReference(visit(expression), | 4642 return finishConstructorReference(visit(expression), |
| 4643 expression, expression); | 4643 expression, expression); |
| (...skipping 17 matching lines...) Expand all Loading... |
| 4661 TreeElements _treeElements; | 4661 TreeElements _treeElements; |
| 4662 | 4662 |
| 4663 bool get hasTreeElements => _treeElements != null; | 4663 bool get hasTreeElements => _treeElements != null; |
| 4664 | 4664 |
| 4665 TreeElements get treeElements { | 4665 TreeElements get treeElements { |
| 4666 assert(invariant(this, _treeElements !=null, | 4666 assert(invariant(this, _treeElements !=null, |
| 4667 message: "TreeElements have not been computed for $this.")); | 4667 message: "TreeElements have not been computed for $this.")); |
| 4668 return _treeElements; | 4668 return _treeElements; |
| 4669 } | 4669 } |
| 4670 } | 4670 } |
| OLD | NEW |