| 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 AnalyzableElement get analyzedElement; | 8 AnalyzableElement get analyzedElement; |
| 9 Iterable<Node> get superUses; | 9 Iterable<Node> get superUses; |
| 10 | 10 |
| (...skipping 598 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 609 'originParameterCount': originSignature.optionalParameterCount, | 609 'originParameterCount': originSignature.optionalParameterCount, |
| 610 'patchParameterCount': patchSignature.optionalParameterCount}); | 610 'patchParameterCount': patchSignature.optionalParameterCount}); |
| 611 }); | 611 }); |
| 612 } else { | 612 } else { |
| 613 checkMatchingPatchParameters(origin, | 613 checkMatchingPatchParameters(origin, |
| 614 originSignature.optionalParameters, | 614 originSignature.optionalParameters, |
| 615 patchSignature.optionalParameters); | 615 patchSignature.optionalParameters); |
| 616 } | 616 } |
| 617 } | 617 } |
| 618 | 618 |
| 619 static void processAsyncMarker(Compiler compiler, |
| 620 BaseFunctionElementX element) { |
| 621 FunctionExpression functionExpression = element.node; |
| 622 AsyncModifier asyncModifier = functionExpression.asyncModifier; |
| 623 if (asyncModifier != null) { |
| 624 if (!compiler.enableAsyncAwait) { |
| 625 compiler.reportError(asyncModifier, |
| 626 MessageKind.EXPERIMENTAL_ASYNC_AWAIT, |
| 627 {'modifier': element.asyncMarker}); |
| 628 } else if (!compiler.analyzeOnly) { |
| 629 compiler.reportError(asyncModifier, |
| 630 MessageKind.EXPERIMENTAL_ASYNC_AWAIT, |
| 631 {'modifier': element.asyncMarker}); |
| 632 } |
| 633 |
| 634 if (asyncModifier.isAsynchronous) { |
| 635 element.asyncMarker = asyncModifier.isYielding |
| 636 ? AsyncMarker.ASYNC_STAR : AsyncMarker.ASYNC; |
| 637 } else { |
| 638 element.asyncMarker = AsyncMarker.SYNC_STAR; |
| 639 } |
| 640 if (element.isAbstract) { |
| 641 compiler.reportError(asyncModifier, |
| 642 MessageKind.ASYNC_MODIFIER_ON_ABSTRACT_METHOD, |
| 643 {'modifier': element.asyncMarker}); |
| 644 } else if (element.isConstructor) { |
| 645 compiler.reportError(asyncModifier, |
| 646 MessageKind.ASYNC_MODIFIER_ON_CONSTRUCTOR, |
| 647 {'modifier': element.asyncMarker}); |
| 648 } else if (functionExpression.body.asReturn() != null && |
| 649 element.asyncMarker.isYielding) { |
| 650 compiler.reportError(asyncModifier, |
| 651 MessageKind.YIELDING_MODIFIER_ON_ARROW_BODY, |
| 652 {'modifier': element.asyncMarker}); |
| 653 } |
| 654 } |
| 655 } |
| 656 |
| 619 TreeElements resolveMethodElement(FunctionElementX element) { | 657 TreeElements resolveMethodElement(FunctionElementX element) { |
| 620 assert(invariant(element, element.isDeclaration)); | 658 assert(invariant(element, element.isDeclaration)); |
| 621 return compiler.withCurrentElement(element, () { | 659 return compiler.withCurrentElement(element, () { |
| 622 bool isConstructor = | 660 bool isConstructor = |
| 623 identical(element.kind, ElementKind.GENERATIVE_CONSTRUCTOR); | 661 identical(element.kind, ElementKind.GENERATIVE_CONSTRUCTOR); |
| 624 if (compiler.enqueuer.resolution.hasBeenResolved(element)) { | 662 if (compiler.enqueuer.resolution.hasBeenResolved(element)) { |
| 625 // TODO(karlklose): Remove the check for [isConstructor]. [elememts] | 663 // TODO(karlklose): Remove the check for [isConstructor]. [elememts] |
| 626 // should never be non-null, not even for constructors. | 664 // should never be non-null, not even for constructors. |
| 627 assert(invariant(element, element.isConstructor, | 665 assert(invariant(element, element.isConstructor, |
| 628 message: 'Non-constructor element $element ' | 666 message: 'Non-constructor element $element ' |
| (...skipping 15 matching lines...) Expand all Loading... |
| 644 registry.registerImplicitSuperCall(target); | 682 registry.registerImplicitSuperCall(target); |
| 645 } | 683 } |
| 646 return registry.mapping; | 684 return registry.mapping; |
| 647 } else { | 685 } else { |
| 648 assert(element.isDeferredLoaderGetter); | 686 assert(element.isDeferredLoaderGetter); |
| 649 return _ensureTreeElements(element); | 687 return _ensureTreeElements(element); |
| 650 } | 688 } |
| 651 } | 689 } |
| 652 element.parseNode(compiler); | 690 element.parseNode(compiler); |
| 653 element.computeType(compiler); | 691 element.computeType(compiler); |
| 692 processAsyncMarker(compiler, element); |
| 654 if (element.isPatched) { | 693 if (element.isPatched) { |
| 655 FunctionElementX patch = element.patch; | 694 FunctionElementX patch = element.patch; |
| 656 compiler.withCurrentElement(patch, () { | 695 compiler.withCurrentElement(patch, () { |
| 657 patch.parseNode(compiler); | 696 patch.parseNode(compiler); |
| 658 patch.computeType(compiler); | 697 patch.computeType(compiler); |
| 659 }); | 698 }); |
| 660 checkMatchingPatchSignatures(element, patch); | 699 checkMatchingPatchSignatures(element, patch); |
| 661 element = patch; | 700 element = patch; |
| 701 processAsyncMarker(compiler, element); |
| 662 } | 702 } |
| 663 return compiler.withCurrentElement(element, () { | 703 return compiler.withCurrentElement(element, () { |
| 664 FunctionExpression tree = element.node; | 704 FunctionExpression tree = element.node; |
| 665 if (tree.modifiers.isExternal) { | 705 if (tree.modifiers.isExternal) { |
| 666 error(tree, MessageKind.PATCH_EXTERNAL_WITHOUT_IMPLEMENTATION); | 706 error(tree, MessageKind.PATCH_EXTERNAL_WITHOUT_IMPLEMENTATION); |
| 667 return null; | 707 return null; |
| 668 } | 708 } |
| 669 if (isConstructor || element.isFactoryConstructor) { | 709 if (isConstructor || element.isFactoryConstructor) { |
| 670 if (tree.returnType != null) { | 710 if (tree.returnType != null) { |
| 671 error(tree, MessageKind.CONSTRUCTOR_WITH_RETURN_TYPE); | 711 error(tree, MessageKind.CONSTRUCTOR_WITH_RETURN_TYPE); |
| (...skipping 1425 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2097 final TypeResolver typeResolver; | 2137 final TypeResolver typeResolver; |
| 2098 /// The current enclosing element for the visited AST nodes. | 2138 /// The current enclosing element for the visited AST nodes. |
| 2099 Element get enclosingElement; | 2139 Element get enclosingElement; |
| 2100 /// The current scope of the visitor. | 2140 /// The current scope of the visitor. |
| 2101 Scope get scope; | 2141 Scope get scope; |
| 2102 | 2142 |
| 2103 MappingVisitor(Compiler compiler, ResolutionRegistry this.registry) | 2143 MappingVisitor(Compiler compiler, ResolutionRegistry this.registry) |
| 2104 : typeResolver = new TypeResolver(compiler), | 2144 : typeResolver = new TypeResolver(compiler), |
| 2105 super(compiler); | 2145 super(compiler); |
| 2106 | 2146 |
| 2147 AsyncMarker get currentAsyncMarker => AsyncMarker.SYNC; |
| 2148 |
| 2107 /// Add [element] to the current scope and check for duplicate definitions. | 2149 /// Add [element] to the current scope and check for duplicate definitions. |
| 2108 void addToScope(Element element) { | 2150 void addToScope(Element element) { |
| 2109 Element existing = scope.add(element); | 2151 Element existing = scope.add(element); |
| 2110 if (existing != element) { | 2152 if (existing != element) { |
| 2111 reportDuplicateDefinition(element.name, element, existing); | 2153 reportDuplicateDefinition(element.name, element, existing); |
| 2112 } | 2154 } |
| 2113 } | 2155 } |
| 2114 | 2156 |
| 2157 void checkLocalDefinitionName(Node node, Element element) { |
| 2158 if (currentAsyncMarker != AsyncMarker.SYNC) { |
| 2159 if (element.name == 'yield' || |
| 2160 element.name == 'async' || |
| 2161 element.name == 'await') { |
| 2162 compiler.reportError( |
| 2163 node, MessageKind.ASYNC_KEYWORD_AS_IDENTIFIER, |
| 2164 {'keyword': element.name, |
| 2165 'modifier': currentAsyncMarker}); |
| 2166 } |
| 2167 } |
| 2168 } |
| 2169 |
| 2115 /// Register [node] as the definition of [element]. | 2170 /// Register [node] as the definition of [element]. |
| 2116 void defineLocalVariable(Node node, LocalVariableElement element) { | 2171 void defineLocalVariable(Node node, LocalVariableElement element) { |
| 2117 invariant(node, element != null); | 2172 invariant(node, element != null); |
| 2173 checkLocalDefinitionName(node, element); |
| 2118 registry.defineElement(node, element); | 2174 registry.defineElement(node, element); |
| 2119 } | 2175 } |
| 2120 | 2176 |
| 2121 void reportDuplicateDefinition(String name, | 2177 void reportDuplicateDefinition(String name, |
| 2122 Spannable definition, | 2178 Spannable definition, |
| 2123 Spannable existing) { | 2179 Spannable existing) { |
| 2124 compiler.reportError(definition, | 2180 compiler.reportError(definition, |
| 2125 MessageKind.DUPLICATE_DEFINITION, {'name': name}); | 2181 MessageKind.DUPLICATE_DEFINITION, {'name': name}); |
| 2126 compiler.reportInfo(existing, | 2182 compiler.reportInfo(existing, |
| 2127 MessageKind.EXISTING_DEFINITION, {'name': name}); | 2183 MessageKind.EXISTING_DEFINITION, {'name': name}); |
| (...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2216 ? Scope.buildEnclosingScope(element) : element.buildScope(), | 2272 ? Scope.buildEnclosingScope(element) : element.buildScope(), |
| 2217 // The type annotations on a typedef do not imply type checks. | 2273 // The type annotations on a typedef do not imply type checks. |
| 2218 // TODO(karlklose): clean this up (dartbug.com/8870). | 2274 // TODO(karlklose): clean this up (dartbug.com/8870). |
| 2219 inCheckContext = compiler.enableTypeAssertions && | 2275 inCheckContext = compiler.enableTypeAssertions && |
| 2220 !element.isLibrary && | 2276 !element.isLibrary && |
| 2221 !element.isTypedef && | 2277 !element.isTypedef && |
| 2222 !element.enclosingElement.isTypedef, | 2278 !element.enclosingElement.isTypedef, |
| 2223 inCatchBlock = false, | 2279 inCatchBlock = false, |
| 2224 super(compiler, registry); | 2280 super(compiler, registry); |
| 2225 | 2281 |
| 2282 AsyncMarker get currentAsyncMarker { |
| 2283 if (enclosingElement is FunctionElement) { |
| 2284 FunctionElement function = enclosingElement; |
| 2285 return function.asyncMarker; |
| 2286 } |
| 2287 return AsyncMarker.SYNC; |
| 2288 } |
| 2289 |
| 2226 Element reportLookupErrorIfAny(Element result, Node node, String name) { | 2290 Element reportLookupErrorIfAny(Element result, Node node, String name) { |
| 2227 if (!Elements.isUnresolved(result)) { | 2291 if (!Elements.isUnresolved(result)) { |
| 2228 if (!inInstanceContext && result.isInstanceMember) { | 2292 if (!inInstanceContext && result.isInstanceMember) { |
| 2229 compiler.reportError( | 2293 compiler.reportError( |
| 2230 node, MessageKind.NO_INSTANCE_AVAILABLE, {'name': name}); | 2294 node, MessageKind.NO_INSTANCE_AVAILABLE, {'name': name}); |
| 2231 return new ErroneousElementX(MessageKind.NO_INSTANCE_AVAILABLE, | 2295 return new ErroneousElementX(MessageKind.NO_INSTANCE_AVAILABLE, |
| 2232 {'name': name}, | 2296 {'name': name}, |
| 2233 name, enclosingElement); | 2297 name, enclosingElement); |
| 2234 } else if (result.isAmbiguous) { | 2298 } else if (result.isAmbiguous) { |
| 2235 AmbiguousElement ambiguous = result; | 2299 AmbiguousElement ambiguous = result; |
| (...skipping 275 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2511 name = ""; | 2575 name = ""; |
| 2512 } else { | 2576 } else { |
| 2513 name = node.name.asIdentifier().source; | 2577 name = node.name.asIdentifier().source; |
| 2514 } | 2578 } |
| 2515 LocalFunctionElementX function = new LocalFunctionElementX( | 2579 LocalFunctionElementX function = new LocalFunctionElementX( |
| 2516 name, node, ElementKind.FUNCTION, Modifiers.EMPTY, | 2580 name, node, ElementKind.FUNCTION, Modifiers.EMPTY, |
| 2517 enclosingElement); | 2581 enclosingElement); |
| 2518 function.functionSignatureCache = | 2582 function.functionSignatureCache = |
| 2519 SignatureResolver.analyze(compiler, node.parameters, node.returnType, | 2583 SignatureResolver.analyze(compiler, node.parameters, node.returnType, |
| 2520 function, registry, createRealParameters: true); | 2584 function, registry, createRealParameters: true); |
| 2585 ResolverTask.processAsyncMarker(compiler, function); |
| 2586 checkLocalDefinitionName(node, function); |
| 2521 registry.defineFunction(node, function); | 2587 registry.defineFunction(node, function); |
| 2522 if (doAddToScope) { | 2588 if (doAddToScope) { |
| 2523 addToScope(function); | 2589 addToScope(function); |
| 2524 } | 2590 } |
| 2525 Scope oldScope = scope; // The scope is modified by [setupFunction]. | 2591 Scope oldScope = scope; // The scope is modified by [setupFunction]. |
| 2526 setupFunction(node, function); | 2592 setupFunction(node, function); |
| 2527 | 2593 |
| 2528 Element previousEnclosingElement = enclosingElement; | 2594 Element previousEnclosingElement = enclosingElement; |
| 2529 enclosingElement = function; | 2595 enclosingElement = function; |
| 2530 // Run the body in a fresh statement scope. | 2596 // Run the body in a fresh statement scope. |
| (...skipping 605 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3136 enclosingElement.isGenerativeConstructor) { | 3202 enclosingElement.isGenerativeConstructor) { |
| 3137 // It is a compile-time error if a return statement of the form | 3203 // It is a compile-time error if a return statement of the form |
| 3138 // `return e;` appears in a generative constructor. (Dart Language | 3204 // `return e;` appears in a generative constructor. (Dart Language |
| 3139 // Specification 13.12.) | 3205 // Specification 13.12.) |
| 3140 compiler.reportError(expression, | 3206 compiler.reportError(expression, |
| 3141 MessageKind.CANNOT_RETURN_FROM_CONSTRUCTOR); | 3207 MessageKind.CANNOT_RETURN_FROM_CONSTRUCTOR); |
| 3142 } | 3208 } |
| 3143 visit(node.expression); | 3209 visit(node.expression); |
| 3144 } | 3210 } |
| 3145 | 3211 |
| 3212 visitYield(Yield node) { |
| 3213 compiler.streamClass.ensureResolved(compiler); |
| 3214 compiler.iterableClass.ensureResolved(compiler); |
| 3215 visit(node.expression); |
| 3216 } |
| 3217 |
| 3146 visitRedirectingFactoryBody(RedirectingFactoryBody node) { | 3218 visitRedirectingFactoryBody(RedirectingFactoryBody node) { |
| 3147 final isSymbolConstructor = enclosingElement == compiler.symbolConstructor; | 3219 final isSymbolConstructor = enclosingElement == compiler.symbolConstructor; |
| 3148 if (!enclosingElement.isFactoryConstructor) { | 3220 if (!enclosingElement.isFactoryConstructor) { |
| 3149 compiler.reportError( | 3221 compiler.reportError( |
| 3150 node, MessageKind.FACTORY_REDIRECTION_IN_NON_FACTORY); | 3222 node, MessageKind.FACTORY_REDIRECTION_IN_NON_FACTORY); |
| 3151 compiler.reportHint( | 3223 compiler.reportHint( |
| 3152 enclosingElement, MessageKind.MISSING_FACTORY_KEYWORD); | 3224 enclosingElement, MessageKind.MISSING_FACTORY_KEYWORD); |
| 3153 } | 3225 } |
| 3154 ConstructorElementX constructor = enclosingElement; | 3226 ConstructorElementX constructor = enclosingElement; |
| 3155 bool isConstConstructor = constructor.isConst; | 3227 bool isConstConstructor = constructor.isConst; |
| (...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3206 if (isSymbolConstructor) { | 3278 if (isSymbolConstructor) { |
| 3207 registry.registerSymbolConstructor(); | 3279 registry.registerSymbolConstructor(); |
| 3208 } | 3280 } |
| 3209 } | 3281 } |
| 3210 | 3282 |
| 3211 visitThrow(Throw node) { | 3283 visitThrow(Throw node) { |
| 3212 registry.registerThrowExpression(); | 3284 registry.registerThrowExpression(); |
| 3213 visit(node.expression); | 3285 visit(node.expression); |
| 3214 } | 3286 } |
| 3215 | 3287 |
| 3288 visitAwait(Await node) { |
| 3289 compiler.futureClass.ensureResolved(compiler); |
| 3290 visit(node.expression); |
| 3291 } |
| 3292 |
| 3216 visitVariableDefinitions(VariableDefinitions node) { | 3293 visitVariableDefinitions(VariableDefinitions node) { |
| 3217 DartType type; | 3294 DartType type; |
| 3218 if (node.type != null) { | 3295 if (node.type != null) { |
| 3219 type = resolveTypeAnnotation(node.type); | 3296 type = resolveTypeAnnotation(node.type); |
| 3220 } else { | 3297 } else { |
| 3221 type = const DynamicType(); | 3298 type = const DynamicType(); |
| 3222 } | 3299 } |
| 3223 VariableList variables = new VariableList.node(node, type); | 3300 VariableList variables = new VariableList.node(node, type); |
| 3224 VariableDefinitionsVisitor visitor = | 3301 VariableDefinitionsVisitor visitor = |
| 3225 new VariableDefinitionsVisitor(compiler, node, this, variables); | 3302 new VariableDefinitionsVisitor(compiler, node, this, variables); |
| (...skipping 1742 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4968 } | 5045 } |
| 4969 | 5046 |
| 4970 /// The result for the resolution of the `assert` method. | 5047 /// The result for the resolution of the `assert` method. |
| 4971 class AssertResult implements ResolutionResult { | 5048 class AssertResult implements ResolutionResult { |
| 4972 const AssertResult(); | 5049 const AssertResult(); |
| 4973 | 5050 |
| 4974 Element get element => null; | 5051 Element get element => null; |
| 4975 | 5052 |
| 4976 String toString() => 'AssertResult()'; | 5053 String toString() => 'AssertResult()'; |
| 4977 } | 5054 } |
| OLD | NEW |