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 library dart2js.resolution.members; | 5 library dart2js.resolution.members; |
6 | 6 |
7 import '../common.dart'; | 7 import '../common.dart'; |
8 import '../common/names.dart' show Selectors; | 8 import '../common/names.dart' show Selectors; |
9 import '../common/resolution.dart' show Feature; | 9 import '../common/resolution.dart' show Feature, Resolution; |
10 import '../compiler.dart' show Compiler; | 10 import '../compile_time_constants.dart'; |
11 import '../constants/constructors.dart' | 11 import '../constants/constructors.dart' |
12 show RedirectingFactoryConstantConstructor; | 12 show RedirectingFactoryConstantConstructor; |
13 import '../constants/expressions.dart'; | 13 import '../constants/expressions.dart'; |
14 import '../constants/values.dart'; | 14 import '../constants/values.dart'; |
15 import '../core_types.dart'; | 15 import '../core_types.dart'; |
16 import '../dart_types.dart'; | 16 import '../dart_types.dart'; |
17 import '../elements/elements.dart'; | 17 import '../elements/elements.dart'; |
18 import '../elements/modelx.dart' | 18 import '../elements/modelx.dart' |
19 show | 19 show |
20 ConstructorElementX, | 20 ConstructorElementX, |
21 ErroneousElementX, | 21 ErroneousElementX, |
22 FunctionElementX, | 22 FunctionElementX, |
23 InitializingFormalElementX, | 23 InitializingFormalElementX, |
24 JumpTargetX, | 24 JumpTargetX, |
25 LocalFunctionElementX, | 25 LocalFunctionElementX, |
26 LocalParameterElementX, | 26 LocalParameterElementX, |
27 ParameterElementX, | 27 ParameterElementX, |
28 VariableElementX, | 28 VariableElementX, |
29 VariableList; | 29 VariableList; |
30 import '../options.dart'; | |
30 import '../tokens/token.dart' show isUserDefinableOperator; | 31 import '../tokens/token.dart' show isUserDefinableOperator; |
31 import '../tree/tree.dart'; | 32 import '../tree/tree.dart'; |
32 import '../universe/call_structure.dart' show CallStructure; | 33 import '../universe/call_structure.dart' show CallStructure; |
33 import '../universe/selector.dart' show Selector; | 34 import '../universe/selector.dart' show Selector; |
34 import '../universe/use.dart' show DynamicUse, StaticUse, TypeUse; | 35 import '../universe/use.dart' show DynamicUse, StaticUse, TypeUse; |
35 import '../util/util.dart' show Link; | 36 import '../util/util.dart' show Link; |
36 import 'access_semantics.dart'; | 37 import 'access_semantics.dart'; |
37 import 'class_members.dart' show MembersCreator; | 38 import 'class_members.dart' show MembersCreator; |
38 import 'constructors.dart' | 39 import 'constructors.dart' |
39 show ConstructorResolver, ConstructorResult, ConstructorResultKind; | 40 show ConstructorResolver, ConstructorResult, ConstructorResultKind; |
(...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
135 r'>=|' | 136 r'>=|' |
136 r'>|' | 137 r'>|' |
137 r'<=|' | 138 r'<=|' |
138 r'<|' | 139 r'<|' |
139 r'&|' | 140 r'&|' |
140 r'\^|' | 141 r'\^|' |
141 r'\|' | 142 r'\|' |
142 r')$'); | 143 r')$'); |
143 | 144 |
144 ResolverVisitor( | 145 ResolverVisitor( |
145 Compiler compiler, Element element, ResolutionRegistry registry, | 146 Resolution resolution, Element element, ResolutionRegistry registry, |
146 {Scope scope, bool useEnclosingScope: false}) | 147 {Scope scope, bool useEnclosingScope: false}) |
147 : this.enclosingElement = element, | 148 : this.enclosingElement = element, |
148 // When the element is a field, we are actually resolving its | 149 // When the element is a field, we are actually resolving its |
149 // initial value, which should not have access to instance | 150 // initial value, which should not have access to instance |
150 // fields. | 151 // fields. |
151 inInstanceContext = (element.isInstanceMember && !element.isField) || | 152 inInstanceContext = (element.isInstanceMember && !element.isField) || |
152 element.isGenerativeConstructor, | 153 element.isGenerativeConstructor, |
153 this.currentClass = | 154 this.currentClass = |
154 element.isClassMember ? element.enclosingClass : null, | 155 element.isClassMember ? element.enclosingClass : null, |
155 this.statementScope = new StatementScope(), | 156 this.statementScope = new StatementScope(), |
156 this.scope = scope ?? | 157 this.scope = scope ?? |
157 (useEnclosingScope | 158 (useEnclosingScope |
158 ? Scope.buildEnclosingScope(element) | 159 ? Scope.buildEnclosingScope(element) |
159 : element.buildScope()), | 160 : element.buildScope()), |
160 // The type annotations on a typedef do not imply type checks. | 161 // The type annotations on a typedef do not imply type checks. |
161 // TODO(karlklose): clean this up (dartbug.com/8870). | 162 // TODO(karlklose): clean this up (dartbug.com/8870). |
162 inCheckContext = compiler.options.enableTypeAssertions && | 163 inCheckContext = resolution.options.enableTypeAssertions && |
163 !element.isLibrary && | 164 !element.isLibrary && |
164 !element.isTypedef && | 165 !element.isTypedef && |
165 !element.enclosingElement.isTypedef, | 166 !element.enclosingElement.isTypedef, |
166 inCatchBlock = false, | 167 inCatchBlock = false, |
167 constantState = element.isConst | 168 constantState = element.isConst |
168 ? ConstantState.CONSTANT | 169 ? ConstantState.CONSTANT |
169 : ConstantState.NON_CONSTANT, | 170 : ConstantState.NON_CONSTANT, |
170 super(compiler, registry); | 171 super(resolution, registry); |
171 | 172 |
172 CoreClasses get coreClasses => compiler.coreClasses; | 173 CoreClasses get coreClasses => resolution.coreClasses; |
173 | 174 CoreTypes get coreTypes => resolution.coreTypes; |
174 CoreTypes get coreTypes => compiler.coreTypes; | 175 ConstantEnvironment get constants => resolution.constants; |
176 ResolverTask get resolver => resolution.resolver; | |
177 CompilerOptions get options => resolution.options; | |
175 | 178 |
176 AsyncMarker get currentAsyncMarker { | 179 AsyncMarker get currentAsyncMarker { |
177 if (enclosingElement is FunctionElement) { | 180 if (enclosingElement is FunctionElement) { |
178 FunctionElement function = enclosingElement; | 181 FunctionElement function = enclosingElement; |
179 return function.asyncMarker; | 182 return function.asyncMarker; |
180 } | 183 } |
181 return AsyncMarker.SYNC; | 184 return AsyncMarker.SYNC; |
182 } | 185 } |
183 | 186 |
184 Element reportLookupErrorIfAny(Element result, Node node, String name) { | 187 Element reportLookupErrorIfAny(Element result, Node node, String name) { |
(...skipping 262 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
447 } else { | 450 } else { |
448 LocalParameterElementX parameterElement = element; | 451 LocalParameterElementX parameterElement = element; |
449 defineLocalVariable(parameterNode, parameterElement); | 452 defineLocalVariable(parameterNode, parameterElement); |
450 addToScope(parameterElement); | 453 addToScope(parameterElement); |
451 } | 454 } |
452 parameterNodes = parameterNodes.tail; | 455 parameterNodes = parameterNodes.tail; |
453 }); | 456 }); |
454 addDeferredAction(enclosingElement, () { | 457 addDeferredAction(enclosingElement, () { |
455 functionSignature.forEachOptionalParameter((ParameterElementX parameter) { | 458 functionSignature.forEachOptionalParameter((ParameterElementX parameter) { |
456 parameter.constant = | 459 parameter.constant = |
457 compiler.resolver.constantCompiler.compileConstant(parameter); | 460 resolver.constantCompiler.compileConstant(parameter); |
458 }); | 461 }); |
459 }); | 462 }); |
460 if (inCheckContext) { | 463 if (inCheckContext) { |
461 functionSignature.forEachParameter((ParameterElement element) { | 464 functionSignature.forEachParameter((ParameterElement element) { |
462 registry.registerTypeUse(new TypeUse.checkedModeCheck(element.type)); | 465 registry.registerTypeUse(new TypeUse.checkedModeCheck(element.type)); |
463 }); | 466 }); |
464 } | 467 } |
465 } | 468 } |
466 | 469 |
467 ResolutionResult visitAssert(Assert node) { | 470 ResolutionResult visitAssert(Assert node) { |
468 if (!compiler.options.enableAssertMessage) { | 471 if (!options.enableAssertMessage) { |
469 if (node.hasMessage) { | 472 if (node.hasMessage) { |
470 reporter.reportErrorMessage( | 473 reporter.reportErrorMessage( |
471 node, MessageKind.EXPERIMENTAL_ASSERT_MESSAGE); | 474 node, MessageKind.EXPERIMENTAL_ASSERT_MESSAGE); |
472 } | 475 } |
473 } | 476 } |
474 // TODO(sra): We could completely ignore the assert in production mode if we | 477 // TODO(sra): We could completely ignore the assert in production mode if we |
475 // didn't need it to be resolved for type checking. | 478 // didn't need it to be resolved for type checking. |
476 registry.registerFeature( | 479 registry.registerFeature( |
477 node.hasMessage ? Feature.ASSERT_WITH_MESSAGE : Feature.ASSERT); | 480 node.hasMessage ? Feature.ASSERT_WITH_MESSAGE : Feature.ASSERT); |
478 visit(node.condition); | 481 visit(node.condition); |
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
566 } | 569 } |
567 visit(node.returnType); | 570 visit(node.returnType); |
568 String name; | 571 String name; |
569 if (node.name == null) { | 572 if (node.name == null) { |
570 name = ""; | 573 name = ""; |
571 } else { | 574 } else { |
572 name = node.name.asIdentifier().source; | 575 name = node.name.asIdentifier().source; |
573 } | 576 } |
574 LocalFunctionElementX function = new LocalFunctionElementX( | 577 LocalFunctionElementX function = new LocalFunctionElementX( |
575 name, node, ElementKind.FUNCTION, Modifiers.EMPTY, enclosingElement); | 578 name, node, ElementKind.FUNCTION, Modifiers.EMPTY, enclosingElement); |
576 ResolverTask.processAsyncMarker(compiler, function, registry); | 579 ResolverTask.processAsyncMarker(resolution, function, registry); |
577 function.functionSignature = SignatureResolver.analyze( | 580 function.functionSignature = SignatureResolver.analyze( |
578 compiler, | 581 resolution, |
579 scope, | 582 scope, |
580 node.typeVariables, | 583 node.typeVariables, |
581 node.parameters, | 584 node.parameters, |
582 node.returnType, | 585 node.returnType, |
583 function, | 586 function, |
584 registry, | 587 registry, |
585 createRealParameters: true, | 588 createRealParameters: true, |
586 isFunctionExpression: !inFunctionDeclaration); | 589 isFunctionExpression: !inFunctionDeclaration); |
587 checkLocalDefinitionName(node, function); | 590 checkLocalDefinitionName(node, function); |
588 registry.defineFunction(node, function); | 591 registry.defineFunction(node, function); |
(...skipping 1421 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2010 } | 2013 } |
2011 | 2014 |
2012 /// Handle access to a constant type literal of [type]. | 2015 /// Handle access to a constant type literal of [type]. |
2013 // TODO(johnniwinther): Remove [name] when [Selector] is not required for the | 2016 // TODO(johnniwinther): Remove [name] when [Selector] is not required for the |
2014 // the [GetStructure]. | 2017 // the [GetStructure]. |
2015 // TODO(johnniwinther): Remove [element] when it is no longer needed for | 2018 // TODO(johnniwinther): Remove [element] when it is no longer needed for |
2016 // evaluating constants. | 2019 // evaluating constants. |
2017 ResolutionResult handleConstantTypeLiteralUpdate(SendSet node, Name name, | 2020 ResolutionResult handleConstantTypeLiteralUpdate(SendSet node, Name name, |
2018 TypeDeclarationElement element, DartType type, ConstantAccess semantics) { | 2021 TypeDeclarationElement element, DartType type, ConstantAccess semantics) { |
2019 // TODO(johnniwinther): Remove this when all constants are evaluated. | 2022 // TODO(johnniwinther): Remove this when all constants are evaluated. |
2020 compiler.resolver.constantCompiler.evaluate(semantics.constant); | 2023 resolver.constantCompiler.evaluate(semantics.constant); |
2021 | 2024 |
2022 ErroneousElement error; | 2025 ErroneousElement error; |
2023 if (node.isIfNullAssignment) { | 2026 if (node.isIfNullAssignment) { |
2024 error = reportAndCreateErroneousElement(node.selector, name.text, | 2027 error = reportAndCreateErroneousElement(node.selector, name.text, |
2025 MessageKind.IF_NULL_ASSIGNING_TYPE, const {}); | 2028 MessageKind.IF_NULL_ASSIGNING_TYPE, const {}); |
2026 // TODO(23998): Remove these when all information goes through | 2029 // TODO(23998): Remove these when all information goes through |
2027 // the [SendStructure]. | 2030 // the [SendStructure]. |
2028 registry.setConstant(node.selector, semantics.constant); | 2031 registry.setConstant(node.selector, semantics.constant); |
2029 registry.useElement(node.selector, element); | 2032 registry.useElement(node.selector, element); |
2030 } else { | 2033 } else { |
(...skipping 531 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2562 ErroneousElement error; | 2565 ErroneousElement error; |
2563 if (element.isParameter) { | 2566 if (element.isParameter) { |
2564 if (element.isFinal) { | 2567 if (element.isFinal) { |
2565 error = reportAndCreateErroneousElement(node.selector, name.text, | 2568 error = reportAndCreateErroneousElement(node.selector, name.text, |
2566 MessageKind.UNDEFINED_STATIC_SETTER_BUT_GETTER, {'name': name}); | 2569 MessageKind.UNDEFINED_STATIC_SETTER_BUT_GETTER, {'name': name}); |
2567 semantics = new StaticAccess.finalParameter(element); | 2570 semantics = new StaticAccess.finalParameter(element); |
2568 } else { | 2571 } else { |
2569 semantics = new StaticAccess.parameter(element); | 2572 semantics = new StaticAccess.parameter(element); |
2570 } | 2573 } |
2571 } else if (element.isInitializingFormal && | 2574 } else if (element.isInitializingFormal && |
2572 compiler.options.enableInitializingFormalAccess) { | 2575 options.enableInitializingFormalAccess) { |
2573 error = reportAndCreateErroneousElement(node.selector, name.text, | 2576 error = reportAndCreateErroneousElement(node.selector, name.text, |
2574 MessageKind.UNDEFINED_STATIC_SETTER_BUT_GETTER, {'name': name}); | 2577 MessageKind.UNDEFINED_STATIC_SETTER_BUT_GETTER, {'name': name}); |
2575 semantics = new StaticAccess.finalParameter(element); | 2578 semantics = new StaticAccess.finalParameter(element); |
2576 } else if (element.isVariable) { | 2579 } else if (element.isVariable) { |
2577 if (element.isFinal || element.isConst) { | 2580 if (element.isFinal || element.isConst) { |
2578 error = reportAndCreateErroneousElement(node.selector, name.text, | 2581 error = reportAndCreateErroneousElement(node.selector, name.text, |
2579 MessageKind.UNDEFINED_STATIC_SETTER_BUT_GETTER, {'name': name}); | 2582 MessageKind.UNDEFINED_STATIC_SETTER_BUT_GETTER, {'name': name}); |
2580 semantics = new StaticAccess.finalLocalVariable(element); | 2583 semantics = new StaticAccess.finalLocalVariable(element); |
2581 } else { | 2584 } else { |
2582 semantics = new StaticAccess.localVariable(element); | 2585 semantics = new StaticAccess.localVariable(element); |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2620 } else { | 2623 } else { |
2621 member = abstractField.setter; | 2624 member = abstractField.setter; |
2622 } | 2625 } |
2623 } else { | 2626 } else { |
2624 member = element; | 2627 member = element; |
2625 } | 2628 } |
2626 // TODO(johnniwinther): Needed to provoke a parsing and with it discovery | 2629 // TODO(johnniwinther): Needed to provoke a parsing and with it discovery |
2627 // of parse errors to make [element] erroneous. Fix this! | 2630 // of parse errors to make [element] erroneous. Fix this! |
2628 member.computeType(resolution); | 2631 member.computeType(resolution); |
2629 | 2632 |
2630 if (member == compiler.mirrorSystemGetNameFunction && | 2633 if (member == resolution.mirrorSystemGetNameFunction && |
2631 !compiler.mirrorUsageAnalyzerTask.hasMirrorUsage(enclosingElement)) { | 2634 !resolution.mirrorUsageAnalyzerTask.hasMirrorUsage(enclosingElement)) { |
2632 reporter | 2635 reporter |
2633 .reportHintMessage(node.selector, MessageKind.STATIC_FUNCTION_BLOAT, { | 2636 .reportHintMessage(node.selector, MessageKind.STATIC_FUNCTION_BLOAT, { |
2634 'class': compiler.mirrorSystemClass.name, | 2637 'class': resolution.mirrorSystemClass.name, |
2635 'name': compiler.mirrorSystemGetNameFunction.name | 2638 'name': resolution.mirrorSystemGetNameFunction.name |
2636 }); | 2639 }); |
2637 } | 2640 } |
2638 | 2641 |
2639 Selector selector; | 2642 Selector selector; |
2640 AccessSemantics semantics = | 2643 AccessSemantics semantics = |
2641 computeStaticOrTopLevelAccessSemantics(node, member); | 2644 computeStaticOrTopLevelAccessSemantics(node, member); |
2642 if (node.isCall) { | 2645 if (node.isCall) { |
2643 ArgumentsResult argumentsResult = resolveArguments(node.argumentsNode); | 2646 ArgumentsResult argumentsResult = resolveArguments(node.argumentsNode); |
2644 CallStructure callStructure = argumentsResult.callStructure; | 2647 CallStructure callStructure = argumentsResult.callStructure; |
2645 selector = new Selector.call(name, callStructure); | 2648 selector = new Selector.call(name, callStructure); |
2646 | 2649 |
2647 bool isIncompatibleInvoke = false; | 2650 bool isIncompatibleInvoke = false; |
2648 switch (semantics.kind) { | 2651 switch (semantics.kind) { |
2649 case AccessKind.STATIC_METHOD: | 2652 case AccessKind.STATIC_METHOD: |
2650 case AccessKind.TOPLEVEL_METHOD: | 2653 case AccessKind.TOPLEVEL_METHOD: |
2651 MethodElement method = semantics.element; | 2654 MethodElement method = semantics.element; |
2652 method.computeType(resolution); | 2655 method.computeType(resolution); |
2653 if (!callStructure.signatureApplies(method.functionSignature)) { | 2656 if (!callStructure.signatureApplies(method.functionSignature)) { |
2654 registry.registerFeature(Feature.THROW_NO_SUCH_METHOD); | 2657 registry.registerFeature(Feature.THROW_NO_SUCH_METHOD); |
2655 registry.registerDynamicUse(new DynamicUse(selector, null)); | 2658 registry.registerDynamicUse(new DynamicUse(selector, null)); |
2656 isIncompatibleInvoke = true; | 2659 isIncompatibleInvoke = true; |
2657 } else { | 2660 } else { |
2658 registry.registerStaticUse( | 2661 registry.registerStaticUse( |
2659 new StaticUse.staticInvoke(semantics.element, callStructure)); | 2662 new StaticUse.staticInvoke(semantics.element, callStructure)); |
2660 handleForeignCall(node, semantics.element, callStructure); | 2663 handleForeignCall(node, semantics.element, callStructure); |
2661 if (method == compiler.identicalFunction && | 2664 if (method == resolution.identicalFunction && |
2662 argumentsResult.isValidAsConstant) { | 2665 argumentsResult.isValidAsConstant) { |
2663 result = new ConstantResult( | 2666 result = new ConstantResult( |
2664 node, | 2667 node, |
2665 new IdenticalConstantExpression( | 2668 new IdenticalConstantExpression( |
2666 argumentsResult.argumentResults[0].constant, | 2669 argumentsResult.argumentResults[0].constant, |
2667 argumentsResult.argumentResults[1].constant)); | 2670 argumentsResult.argumentResults[1].constant)); |
2668 } | 2671 } |
2669 } | 2672 } |
2670 break; | 2673 break; |
2671 case AccessKind.STATIC_FIELD: | 2674 case AccessKind.STATIC_FIELD: |
(...skipping 349 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3021 for (Node scope in promotionScope) { | 3024 for (Node scope in promotionScope) { |
3022 registry.setAccessedByClosureIn(scope, target, node); | 3025 registry.setAccessedByClosureIn(scope, target, node); |
3023 } | 3026 } |
3024 } | 3027 } |
3025 } | 3028 } |
3026 } | 3029 } |
3027 | 3030 |
3028 // TODO(johnniwinther): Move this to the backend resolution callbacks. | 3031 // TODO(johnniwinther): Move this to the backend resolution callbacks. |
3029 void handleForeignCall( | 3032 void handleForeignCall( |
3030 Send node, Element target, CallStructure callStructure) { | 3033 Send node, Element target, CallStructure callStructure) { |
3031 if (target != null && compiler.backend.isForeign(target)) { | 3034 if (target != null && resolution.target.isForeign(target)) { |
3032 registry.registerForeignCall(node, target, callStructure, this); | 3035 registry.registerForeignCall(node, target, callStructure, this); |
3033 } | 3036 } |
3034 } | 3037 } |
3035 | 3038 |
3036 /// Callback for native enqueuer to parse a type. Returns [:null:] on error. | 3039 /// Callback for native enqueuer to parse a type. Returns [:null:] on error. |
3037 DartType resolveTypeFromString(Node node, String typeName) { | 3040 DartType resolveTypeFromString(Node node, String typeName) { |
3038 Element element = lookupInScope(reporter, node, scope, typeName); | 3041 Element element = lookupInScope(reporter, node, scope, typeName); |
3039 if (element == null) return null; | 3042 if (element == null) return null; |
3040 if (element is! ClassElement) return null; | 3043 if (element is! ClassElement) return null; |
3041 ClassElement cls = element; | 3044 ClassElement cls = element; |
(...skipping 528 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3570 } else if (!node.isArrowBody && currentAsyncMarker.isYielding) { | 3573 } else if (!node.isArrowBody && currentAsyncMarker.isYielding) { |
3571 reporter.reportErrorMessage(node, MessageKind.RETURN_IN_GENERATOR, | 3574 reporter.reportErrorMessage(node, MessageKind.RETURN_IN_GENERATOR, |
3572 {'modifier': currentAsyncMarker}); | 3575 {'modifier': currentAsyncMarker}); |
3573 } | 3576 } |
3574 } | 3577 } |
3575 visit(node.expression); | 3578 visit(node.expression); |
3576 return const NoneResult(); | 3579 return const NoneResult(); |
3577 } | 3580 } |
3578 | 3581 |
3579 ResolutionResult visitYield(Yield node) { | 3582 ResolutionResult visitYield(Yield node) { |
3580 if (!compiler.backend.supportsAsyncAwait) { | 3583 if (!currentAsyncMarker.isYielding) { |
Johnni Winther
2016/07/08 08:05:39
Dartino still needs this. Move the [supportsAsyncA
Harry Terkelsen
2016/07/18 17:35:58
Done.
| |
3581 reporter.reportErrorMessage( | 3584 reporter.reportErrorMessage(node, MessageKind.INVALID_YIELD); |
3582 node.yieldToken, MessageKind.ASYNC_AWAIT_NOT_SUPPORTED); | 3585 } |
3586 if (currentAsyncMarker.isAsync) { | |
3587 coreClasses.streamClass.ensureResolved(resolution); | |
3583 } else { | 3588 } else { |
3584 if (!currentAsyncMarker.isYielding) { | 3589 coreClasses.iterableClass.ensureResolved(resolution); |
3585 reporter.reportErrorMessage(node, MessageKind.INVALID_YIELD); | |
3586 } | |
3587 if (currentAsyncMarker.isAsync) { | |
3588 coreClasses.streamClass.ensureResolved(resolution); | |
3589 } else { | |
3590 coreClasses.iterableClass.ensureResolved(resolution); | |
3591 } | |
3592 } | 3590 } |
3593 visit(node.expression); | 3591 visit(node.expression); |
3594 return const NoneResult(); | 3592 return const NoneResult(); |
3595 } | 3593 } |
3596 | 3594 |
3597 ResolutionResult visitRedirectingFactoryBody(RedirectingFactoryBody node) { | 3595 ResolutionResult visitRedirectingFactoryBody(RedirectingFactoryBody node) { |
3598 if (!enclosingElement.isFactoryConstructor) { | 3596 if (!enclosingElement.isFactoryConstructor) { |
3599 reporter.reportErrorMessage( | 3597 reporter.reportErrorMessage( |
3600 node, MessageKind.FACTORY_REDIRECTION_IN_NON_FACTORY); | 3598 node, MessageKind.FACTORY_REDIRECTION_IN_NON_FACTORY); |
3601 reporter.reportHintMessage( | 3599 reporter.reportHintMessage( |
(...skipping 12 matching lines...) Expand all Loading... | |
3614 constructor.redirectionDeferredPrefix = result.prefix; | 3612 constructor.redirectionDeferredPrefix = result.prefix; |
3615 } | 3613 } |
3616 | 3614 |
3617 registry.setRedirectingTargetConstructor(node, redirectionTarget); | 3615 registry.setRedirectingTargetConstructor(node, redirectionTarget); |
3618 switch (result.kind) { | 3616 switch (result.kind) { |
3619 case ConstructorResultKind.GENERATIVE: | 3617 case ConstructorResultKind.GENERATIVE: |
3620 case ConstructorResultKind.FACTORY: | 3618 case ConstructorResultKind.FACTORY: |
3621 // Register a post process to check for cycles in the redirection chain | 3619 // Register a post process to check for cycles in the redirection chain |
3622 // and set the actual generative constructor at the end of the chain. | 3620 // and set the actual generative constructor at the end of the chain. |
3623 addDeferredAction(constructor, () { | 3621 addDeferredAction(constructor, () { |
3624 compiler.resolver.resolveRedirectionChain(constructor, node); | 3622 resolver.resolveRedirectionChain(constructor, node); |
3625 }); | 3623 }); |
3626 break; | 3624 break; |
3627 case ConstructorResultKind.ABSTRACT: | 3625 case ConstructorResultKind.ABSTRACT: |
3628 case ConstructorResultKind.INVALID_TYPE: | 3626 case ConstructorResultKind.INVALID_TYPE: |
3629 case ConstructorResultKind.UNRESOLVED_CONSTRUCTOR: | 3627 case ConstructorResultKind.UNRESOLVED_CONSTRUCTOR: |
3630 case ConstructorResultKind.NON_CONSTANT: | 3628 case ConstructorResultKind.NON_CONSTANT: |
3631 isValidAsConstant = false; | 3629 isValidAsConstant = false; |
3632 constructor.setEffectiveTarget(result.element, result.type, | 3630 constructor.setEffectiveTarget(result.element, result.type, |
3633 isMalformed: true); | 3631 isMalformed: true); |
3634 break; | 3632 break; |
(...skipping 17 matching lines...) Expand all Loading... | |
3652 | 3650 |
3653 // Check that the target constructor is type compatible with the | 3651 // Check that the target constructor is type compatible with the |
3654 // redirecting constructor. | 3652 // redirecting constructor. |
3655 ClassElement targetClass = redirectionTarget.enclosingClass; | 3653 ClassElement targetClass = redirectionTarget.enclosingClass; |
3656 InterfaceType type = registry.getType(node); | 3654 InterfaceType type = registry.getType(node); |
3657 FunctionType targetConstructorType = redirectionTarget | 3655 FunctionType targetConstructorType = redirectionTarget |
3658 .computeType(resolution) | 3656 .computeType(resolution) |
3659 .subst(type.typeArguments, targetClass.typeVariables); | 3657 .subst(type.typeArguments, targetClass.typeVariables); |
3660 FunctionType constructorType = constructor.computeType(resolution); | 3658 FunctionType constructorType = constructor.computeType(resolution); |
3661 bool isSubtype = | 3659 bool isSubtype = |
3662 compiler.types.isSubtype(targetConstructorType, constructorType); | 3660 resolution.types.isSubtype(targetConstructorType, constructorType); |
3663 if (!isSubtype) { | 3661 if (!isSubtype) { |
3664 reporter.reportWarningMessage(node, MessageKind.NOT_ASSIGNABLE, | 3662 reporter.reportWarningMessage(node, MessageKind.NOT_ASSIGNABLE, |
3665 {'fromType': targetConstructorType, 'toType': constructorType}); | 3663 {'fromType': targetConstructorType, 'toType': constructorType}); |
3666 // TODO(johnniwinther): Handle this (potentially) erroneous case. | 3664 // TODO(johnniwinther): Handle this (potentially) erroneous case. |
3667 isValidAsConstant = false; | 3665 isValidAsConstant = false; |
3668 } | 3666 } |
3669 | 3667 |
3670 redirectionTarget.computeType(resolution); | 3668 redirectionTarget.computeType(resolution); |
3671 FunctionSignature targetSignature = redirectionTarget.functionSignature; | 3669 FunctionSignature targetSignature = redirectionTarget.functionSignature; |
3672 constructor.computeType(resolution); | 3670 constructor.computeType(resolution); |
3673 FunctionSignature constructorSignature = constructor.functionSignature; | 3671 FunctionSignature constructorSignature = constructor.functionSignature; |
3674 if (!targetSignature.isCompatibleWith(constructorSignature)) { | 3672 if (!targetSignature.isCompatibleWith(constructorSignature)) { |
3675 assert(!isSubtype); | 3673 assert(!isSubtype); |
3676 registry.registerFeature(Feature.THROW_NO_SUCH_METHOD); | 3674 registry.registerFeature(Feature.THROW_NO_SUCH_METHOD); |
3677 isValidAsConstant = false; | 3675 isValidAsConstant = false; |
3678 } | 3676 } |
3679 | 3677 |
3680 registry.registerStaticUse( | 3678 registry.registerStaticUse( |
3681 new StaticUse.constructorRedirect(redirectionTarget)); | 3679 new StaticUse.constructorRedirect(redirectionTarget)); |
3682 // TODO(johnniwinther): Register the effective target type as part of the | 3680 // TODO(johnniwinther): Register the effective target type as part of the |
3683 // static use instead. | 3681 // static use instead. |
3684 registry.registerTypeUse(new TypeUse.instantiation(redirectionTarget | 3682 registry.registerTypeUse(new TypeUse.instantiation(redirectionTarget |
3685 .enclosingClass.thisType | 3683 .enclosingClass.thisType |
3686 .subst(type.typeArguments, targetClass.typeVariables))); | 3684 .subst(type.typeArguments, targetClass.typeVariables))); |
3687 if (enclosingElement == compiler.symbolConstructor) { | 3685 if (enclosingElement == resolution.symbolConstructor) { |
3688 registry.registerFeature(Feature.SYMBOL_CONSTRUCTOR); | 3686 registry.registerFeature(Feature.SYMBOL_CONSTRUCTOR); |
3689 } | 3687 } |
3690 if (isValidAsConstant) { | 3688 if (isValidAsConstant) { |
3691 List<String> names = <String>[]; | 3689 List<String> names = <String>[]; |
3692 List<ConstantExpression> arguments = <ConstantExpression>[]; | 3690 List<ConstantExpression> arguments = <ConstantExpression>[]; |
3693 int index = 0; | 3691 int index = 0; |
3694 constructorSignature.forEachParameter((ParameterElement parameter) { | 3692 constructorSignature.forEachParameter((ParameterElement parameter) { |
3695 if (parameter.isNamed) { | 3693 if (parameter.isNamed) { |
3696 String name = parameter.name; | 3694 String name = parameter.name; |
3697 names.add(name); | 3695 names.add(name); |
(...skipping 13 matching lines...) Expand all Loading... | |
3711 return const NoneResult(); | 3709 return const NoneResult(); |
3712 } | 3710 } |
3713 | 3711 |
3714 ResolutionResult visitThrow(Throw node) { | 3712 ResolutionResult visitThrow(Throw node) { |
3715 registry.registerFeature(Feature.THROW_EXPRESSION); | 3713 registry.registerFeature(Feature.THROW_EXPRESSION); |
3716 visit(node.expression); | 3714 visit(node.expression); |
3717 return const NoneResult(); | 3715 return const NoneResult(); |
3718 } | 3716 } |
3719 | 3717 |
3720 ResolutionResult visitAwait(Await node) { | 3718 ResolutionResult visitAwait(Await node) { |
3721 if (!compiler.backend.supportsAsyncAwait) { | 3719 if (!currentAsyncMarker.isAsync) { |
Johnni Winther
2016/07/08 08:05:39
Ditto.
Harry Terkelsen
2016/07/18 17:35:58
Done.
| |
3722 reporter.reportErrorMessage( | 3720 reporter.reportErrorMessage(node, MessageKind.INVALID_AWAIT); |
3723 node.awaitToken, MessageKind.ASYNC_AWAIT_NOT_SUPPORTED); | |
3724 } else { | |
3725 if (!currentAsyncMarker.isAsync) { | |
3726 reporter.reportErrorMessage(node, MessageKind.INVALID_AWAIT); | |
3727 } | |
3728 coreClasses.futureClass.ensureResolved(resolution); | |
3729 } | 3721 } |
3722 coreClasses.futureClass.ensureResolved(resolution); | |
3730 visit(node.expression); | 3723 visit(node.expression); |
3731 return const NoneResult(); | 3724 return const NoneResult(); |
3732 } | 3725 } |
3733 | 3726 |
3734 ResolutionResult visitVariableDefinitions(VariableDefinitions node) { | 3727 ResolutionResult visitVariableDefinitions(VariableDefinitions node) { |
3735 DartType type; | 3728 DartType type; |
3736 if (node.type != null) { | 3729 if (node.type != null) { |
3737 type = resolveTypeAnnotation(node.type); | 3730 type = resolveTypeAnnotation(node.type); |
3738 } else { | 3731 } else { |
3739 type = const DynamicType(); | 3732 type = const DynamicType(); |
3740 } | 3733 } |
3741 VariableList variables = new VariableList.node(node, type); | 3734 VariableList variables = new VariableList.node(node, type); |
3742 VariableDefinitionsVisitor visitor = | 3735 VariableDefinitionsVisitor visitor = |
3743 new VariableDefinitionsVisitor(compiler, node, this, variables); | 3736 new VariableDefinitionsVisitor(resolution, node, this, variables); |
3744 | 3737 |
3745 Modifiers modifiers = node.modifiers; | 3738 Modifiers modifiers = node.modifiers; |
3746 void reportExtraModifier(String modifier) { | 3739 void reportExtraModifier(String modifier) { |
3747 Node modifierNode; | 3740 Node modifierNode; |
3748 for (Link<Node> nodes = modifiers.nodes.nodes; | 3741 for (Link<Node> nodes = modifiers.nodes.nodes; |
3749 !nodes.isEmpty; | 3742 !nodes.isEmpty; |
3750 nodes = nodes.tail) { | 3743 nodes = nodes.tail) { |
3751 if (modifier == nodes.head.asIdentifier().source) { | 3744 if (modifier == nodes.head.asIdentifier().source) { |
3752 modifierNode = nodes.head; | 3745 modifierNode = nodes.head; |
3753 break; | 3746 break; |
(...skipping 12 matching lines...) Expand all Loading... | |
3766 if (enclosingElement.isFunction || enclosingElement.isConstructor) { | 3759 if (enclosingElement.isFunction || enclosingElement.isConstructor) { |
3767 if (modifiers.isAbstract) { | 3760 if (modifiers.isAbstract) { |
3768 reportExtraModifier('abstract'); | 3761 reportExtraModifier('abstract'); |
3769 } | 3762 } |
3770 if (modifiers.isStatic) { | 3763 if (modifiers.isStatic) { |
3771 reportExtraModifier('static'); | 3764 reportExtraModifier('static'); |
3772 } | 3765 } |
3773 } | 3766 } |
3774 if (node.metadata != null) { | 3767 if (node.metadata != null) { |
3775 variables.metadataInternal = | 3768 variables.metadataInternal = |
3776 compiler.resolver.resolveMetadata(enclosingElement, node); | 3769 resolver.resolveMetadata(enclosingElement, node); |
3777 } | 3770 } |
3778 visitor.visit(node.definitions); | 3771 visitor.visit(node.definitions); |
3779 return const NoneResult(); | 3772 return const NoneResult(); |
3780 } | 3773 } |
3781 | 3774 |
3782 ResolutionResult visitWhile(While node) { | 3775 ResolutionResult visitWhile(While node) { |
3783 visit(node.condition); | 3776 visit(node.condition); |
3784 visitLoopBodyIn(node, node.body, new BlockScope(scope)); | 3777 visitLoopBodyIn(node, node.body, new BlockScope(scope)); |
3785 return const NoneResult(); | 3778 return const NoneResult(); |
3786 } | 3779 } |
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3886 constructor.declaration, callStructure)); | 3879 constructor.declaration, callStructure)); |
3887 // TODO(johniwinther): Avoid registration of `type` in face of redirecting | 3880 // TODO(johniwinther): Avoid registration of `type` in face of redirecting |
3888 // factory constructors. | 3881 // factory constructors. |
3889 registry.registerTypeUse(new TypeUse.instantiation(type)); | 3882 registry.registerTypeUse(new TypeUse.instantiation(type)); |
3890 } | 3883 } |
3891 | 3884 |
3892 ResolutionResult resolutionResult = const NoneResult(); | 3885 ResolutionResult resolutionResult = const NoneResult(); |
3893 if (node.isConst) { | 3886 if (node.isConst) { |
3894 bool isValidAsConstant = !isInvalid && constructor.isConst; | 3887 bool isValidAsConstant = !isInvalid && constructor.isConst; |
3895 | 3888 |
3896 if (constructor == compiler.symbolConstructor) { | 3889 if (constructor == resolution.symbolConstructor) { |
3897 Node argumentNode = node.send.arguments.head; | 3890 Node argumentNode = node.send.arguments.head; |
3898 ConstantExpression constant = compiler.resolver.constantCompiler | 3891 ConstantExpression constant = resolver.constantCompiler |
3899 .compileNode(argumentNode, registry.mapping); | 3892 .compileNode(argumentNode, registry.mapping); |
3900 ConstantValue name = compiler.constants.getConstantValue(constant); | 3893 ConstantValue name = resolution.constants.getConstantValue(constant); |
3901 if (!name.isString) { | 3894 if (!name.isString) { |
3902 DartType type = name.getType(coreTypes); | 3895 DartType type = name.getType(coreTypes); |
3903 reporter.reportErrorMessage( | 3896 reporter.reportErrorMessage( |
3904 argumentNode, MessageKind.STRING_EXPECTED, {'type': type}); | 3897 argumentNode, MessageKind.STRING_EXPECTED, {'type': type}); |
3905 } else { | 3898 } else { |
3906 StringConstantValue stringConstant = name; | 3899 StringConstantValue stringConstant = name; |
3907 String nameString = stringConstant.toDartString().slowToString(); | 3900 String nameString = stringConstant.toDartString().slowToString(); |
3908 if (validateSymbol(argumentNode, nameString)) { | 3901 if (validateSymbol(argumentNode, nameString)) { |
3909 registry.registerConstSymbol(nameString); | 3902 registry.registerConstSymbol(nameString); |
3910 } | 3903 } |
3911 } | 3904 } |
3912 } else if (constructor == compiler.mirrorsUsedConstructor) { | 3905 } else if (constructor == resolution.mirrorsUsedConstructor) { |
3913 compiler.mirrorUsageAnalyzerTask.validate(node, registry.mapping); | 3906 resolution.mirrorUsageAnalyzerTask.validate(node, registry.mapping); |
3914 } | 3907 } |
3915 | 3908 |
3916 analyzeConstantDeferred(node); | 3909 analyzeConstantDeferred(node); |
3917 | 3910 |
3918 if (type.containsTypeVariables) { | 3911 if (type.containsTypeVariables) { |
3919 reporter.reportErrorMessage( | 3912 reporter.reportErrorMessage( |
3920 node.send.selector, MessageKind.TYPE_VARIABLE_IN_CONSTANT); | 3913 node.send.selector, MessageKind.TYPE_VARIABLE_IN_CONSTANT); |
3921 isValidAsConstant = false; | 3914 isValidAsConstant = false; |
3922 isInvalid = true; | 3915 isInvalid = true; |
3923 } | 3916 } |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3962 // [LateConstInvokeStructure]; it might not be necessary. | 3955 // [LateConstInvokeStructure]; it might not be necessary. |
3963 registry.registerNewStructure(node, structure); | 3956 registry.registerNewStructure(node, structure); |
3964 onAnalyzed = () { | 3957 onAnalyzed = () { |
3965 registry.registerNewStructure(node, structure.resolve(node)); | 3958 registry.registerNewStructure(node, structure.resolve(node)); |
3966 }; | 3959 }; |
3967 } | 3960 } |
3968 | 3961 |
3969 analyzeConstantDeferred(node, onAnalyzed: onAnalyzed); | 3962 analyzeConstantDeferred(node, onAnalyzed: onAnalyzed); |
3970 } else { | 3963 } else { |
3971 // Not constant. | 3964 // Not constant. |
3972 if (constructor == compiler.symbolConstructor && | 3965 if (constructor == resolution.symbolConstructor && |
3973 !compiler.mirrorUsageAnalyzerTask.hasMirrorUsage(enclosingElement)) { | 3966 !resolution.mirrorUsageAnalyzerTask |
3967 .hasMirrorUsage(enclosingElement)) { | |
3974 reporter.reportHintMessage(node.newToken, MessageKind.NON_CONST_BLOAT, | 3968 reporter.reportHintMessage(node.newToken, MessageKind.NON_CONST_BLOAT, |
3975 {'name': coreClasses.symbolClass.name}); | 3969 {'name': coreClasses.symbolClass.name}); |
3976 } | 3970 } |
3977 registry.registerNewStructure( | 3971 registry.registerNewStructure( |
3978 node, | 3972 node, |
3979 new NewInvokeStructure( | 3973 new NewInvokeStructure( |
3980 new ConstructorAccessSemantics(kind, constructor, type), | 3974 new ConstructorAccessSemantics(kind, constructor, type), |
3981 selector)); | 3975 selector)); |
3982 } | 3976 } |
3983 | 3977 |
(...skipping 10 matching lines...) Expand all Loading... | |
3994 if (cls == coreClasses.stringClass) continue; | 3988 if (cls == coreClasses.stringClass) continue; |
3995 Element equals = cls.lookupMember('=='); | 3989 Element equals = cls.lookupMember('=='); |
3996 if (equals.enclosingClass != coreClasses.objectClass) { | 3990 if (equals.enclosingClass != coreClasses.objectClass) { |
3997 reporter.reportErrorMessage(spannable, | 3991 reporter.reportErrorMessage(spannable, |
3998 MessageKind.CONST_MAP_KEY_OVERRIDES_EQUALS, {'type': keyType}); | 3992 MessageKind.CONST_MAP_KEY_OVERRIDES_EQUALS, {'type': keyType}); |
3999 } | 3993 } |
4000 } | 3994 } |
4001 } | 3995 } |
4002 | 3996 |
4003 void analyzeConstant(Node node, {enforceConst: true}) { | 3997 void analyzeConstant(Node node, {enforceConst: true}) { |
4004 ConstantExpression constant = compiler.resolver.constantCompiler | 3998 ConstantExpression constant = resolver.constantCompiler |
4005 .compileNode(node, registry.mapping, enforceConst: enforceConst); | 3999 .compileNode(node, registry.mapping, enforceConst: enforceConst); |
4006 | 4000 |
4007 if (constant == null) { | 4001 if (constant == null) { |
4008 assert(invariant(node, compiler.compilationFailed)); | 4002 assert(invariant(node, reporter.hasReportedError)); |
4009 return; | 4003 return; |
4010 } | 4004 } |
4011 | 4005 |
4012 ConstantValue value = compiler.constants.getConstantValue(constant); | 4006 ConstantValue value = resolution.constants.getConstantValue(constant); |
4013 if (value.isMap) { | 4007 if (value.isMap) { |
4014 checkConstMapKeysDontOverrideEquals(node, value); | 4008 checkConstMapKeysDontOverrideEquals(node, value); |
4015 } | 4009 } |
4016 } | 4010 } |
4017 | 4011 |
4018 void analyzeConstantDeferred(Node node, | 4012 void analyzeConstantDeferred(Node node, |
4019 {bool enforceConst: true, void onAnalyzed()}) { | 4013 {bool enforceConst: true, void onAnalyzed()}) { |
4020 addDeferredAction(enclosingElement, () { | 4014 addDeferredAction(enclosingElement, () { |
4021 analyzeConstant(node, enforceConst: enforceConst); | 4015 analyzeConstant(node, enforceConst: enforceConst); |
4022 if (onAnalyzed != null) { | 4016 if (onAnalyzed != null) { |
(...skipping 20 matching lines...) Expand all Loading... | |
4043 } | 4037 } |
4044 return true; | 4038 return true; |
4045 } | 4039 } |
4046 | 4040 |
4047 /** | 4041 /** |
4048 * Try to resolve the constructor that is referred to by [node]. | 4042 * Try to resolve the constructor that is referred to by [node]. |
4049 * Note: this function may return an ErroneousFunctionElement instead of | 4043 * Note: this function may return an ErroneousFunctionElement instead of |
4050 * [:null:], if there is no corresponding constructor, class or library. | 4044 * [:null:], if there is no corresponding constructor, class or library. |
4051 */ | 4045 */ |
4052 ConstructorResult resolveConstructor(NewExpression node) { | 4046 ConstructorResult resolveConstructor(NewExpression node) { |
4053 return node.accept( | 4047 return node.accept(new ConstructorResolver(resolution, this, |
4054 new ConstructorResolver(compiler, this, inConstContext: node.isConst)); | 4048 inConstContext: node.isConst)); |
4055 } | 4049 } |
4056 | 4050 |
4057 ConstructorResult resolveRedirectingFactory(RedirectingFactoryBody node, | 4051 ConstructorResult resolveRedirectingFactory(RedirectingFactoryBody node, |
4058 {bool inConstContext: false}) { | 4052 {bool inConstContext: false}) { |
4059 return node.accept(new ConstructorResolver(compiler, this, | 4053 return node.accept(new ConstructorResolver(resolution, this, |
4060 inConstContext: inConstContext)); | 4054 inConstContext: inConstContext)); |
4061 } | 4055 } |
4062 | 4056 |
4063 DartType resolveTypeAnnotation(TypeAnnotation node, | 4057 DartType resolveTypeAnnotation(TypeAnnotation node, |
4064 {bool malformedIsError: false, bool deferredIsMalformed: true}) { | 4058 {bool malformedIsError: false, bool deferredIsMalformed: true}) { |
4065 DartType type = typeResolver.resolveTypeAnnotation(this, node, | 4059 DartType type = typeResolver.resolveTypeAnnotation(this, node, |
4066 malformedIsError: malformedIsError, | 4060 malformedIsError: malformedIsError, |
4067 deferredIsMalformed: deferredIsMalformed); | 4061 deferredIsMalformed: deferredIsMalformed); |
4068 if (inCheckContext) { | 4062 if (inCheckContext) { |
4069 registry.registerTypeUse(new TypeUse.checkedModeCheck(type)); | 4063 registry.registerTypeUse(new TypeUse.checkedModeCheck(type)); |
(...skipping 168 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
4238 } | 4232 } |
4239 registry.registerTargetOf(node, target); | 4233 registry.registerTargetOf(node, target); |
4240 return const NoneResult(); | 4234 return const NoneResult(); |
4241 } | 4235 } |
4242 | 4236 |
4243 registerImplicitInvocation(Selector selector) { | 4237 registerImplicitInvocation(Selector selector) { |
4244 registry.registerDynamicUse(new DynamicUse(selector, null)); | 4238 registry.registerDynamicUse(new DynamicUse(selector, null)); |
4245 } | 4239 } |
4246 | 4240 |
4247 ResolutionResult visitAsyncForIn(AsyncForIn node) { | 4241 ResolutionResult visitAsyncForIn(AsyncForIn node) { |
4248 if (!compiler.backend.supportsAsyncAwait) { | 4242 if (!currentAsyncMarker.isAsync) { |
Johnni Winther
2016/07/08 08:05:39
Ditto.
| |
4249 reporter.reportErrorMessage( | 4243 reporter.reportErrorMessage( |
4250 node.awaitToken, MessageKind.ASYNC_AWAIT_NOT_SUPPORTED); | 4244 node.awaitToken, MessageKind.INVALID_AWAIT_FOR_IN); |
4251 } else { | |
4252 if (!currentAsyncMarker.isAsync) { | |
4253 reporter.reportErrorMessage( | |
4254 node.awaitToken, MessageKind.INVALID_AWAIT_FOR_IN); | |
4255 } | |
4256 registry.registerFeature(Feature.ASYNC_FOR_IN); | |
4257 registry.registerDynamicUse(new DynamicUse(Selectors.current, null)); | |
4258 registry.registerDynamicUse(new DynamicUse(Selectors.moveNext, null)); | |
4259 } | 4245 } |
4246 registry.registerFeature(Feature.ASYNC_FOR_IN); | |
4247 registry.registerDynamicUse(new DynamicUse(Selectors.current, null)); | |
4248 registry.registerDynamicUse(new DynamicUse(Selectors.moveNext, null)); | |
4249 | |
4260 visit(node.expression); | 4250 visit(node.expression); |
4261 | 4251 |
4262 Scope blockScope = new BlockScope(scope); | 4252 Scope blockScope = new BlockScope(scope); |
4263 visitForInDeclaredIdentifierIn(node.declaredIdentifier, node, blockScope); | 4253 visitForInDeclaredIdentifierIn(node.declaredIdentifier, node, blockScope); |
4264 visitLoopBodyIn(node, node.body, blockScope); | 4254 visitLoopBodyIn(node, node.body, blockScope); |
4265 return const NoneResult(); | 4255 return const NoneResult(); |
4266 } | 4256 } |
4267 | 4257 |
4268 ResolutionResult visitSyncForIn(SyncForIn node) { | 4258 ResolutionResult visitSyncForIn(SyncForIn node) { |
4269 registry.registerFeature(Feature.SYNC_FOR_IN); | 4259 registry.registerFeature(Feature.SYNC_FOR_IN); |
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
4326 if (loopVariableSelector != null) { | 4316 if (loopVariableSelector != null) { |
4327 registry.setSelector(declaration, loopVariableSelector); | 4317 registry.setSelector(declaration, loopVariableSelector); |
4328 if (loopVariable == null || loopVariable.isInstanceMember) { | 4318 if (loopVariable == null || loopVariable.isInstanceMember) { |
4329 registry.registerDynamicUse(new DynamicUse(loopVariableSelector, null)); | 4319 registry.registerDynamicUse(new DynamicUse(loopVariableSelector, null)); |
4330 } else if (loopVariable.isStatic || loopVariable.isTopLevel) { | 4320 } else if (loopVariable.isStatic || loopVariable.isTopLevel) { |
4331 registry.registerStaticUse( | 4321 registry.registerStaticUse( |
4332 new StaticUse.staticSet(loopVariable.declaration)); | 4322 new StaticUse.staticSet(loopVariable.declaration)); |
4333 } | 4323 } |
4334 } else { | 4324 } else { |
4335 // The selector may only be null if we reported an error. | 4325 // The selector may only be null if we reported an error. |
4336 assert(invariant(declaration, compiler.compilationFailed)); | 4326 assert(invariant(declaration, reporter.hasReportedError)); |
4337 } | 4327 } |
4338 if (loopVariable != null) { | 4328 if (loopVariable != null) { |
4339 // loopVariable may be null if it could not be resolved. | 4329 // loopVariable may be null if it could not be resolved. |
4340 registry.setForInVariable(node, loopVariable); | 4330 registry.setForInVariable(node, loopVariable); |
4341 } | 4331 } |
4342 } | 4332 } |
4343 | 4333 |
4344 visitLabel(Label node) { | 4334 visitLabel(Label node) { |
4345 // Labels are handled by their containing statements/cases. | 4335 // Labels are handled by their containing statements/cases. |
4346 } | 4336 } |
(...skipping 142 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
4489 for (Node labelOrCase in switchCase.labelsAndCases) { | 4479 for (Node labelOrCase in switchCase.labelsAndCases) { |
4490 CaseMatch caseMatch = labelOrCase.asCaseMatch(); | 4480 CaseMatch caseMatch = labelOrCase.asCaseMatch(); |
4491 if (caseMatch == null) continue; | 4481 if (caseMatch == null) continue; |
4492 | 4482 |
4493 // Analyze the constant. | 4483 // Analyze the constant. |
4494 ConstantExpression constant = | 4484 ConstantExpression constant = |
4495 registry.getConstant(caseMatch.expression); | 4485 registry.getConstant(caseMatch.expression); |
4496 assert(invariant(node, constant != null, | 4486 assert(invariant(node, constant != null, |
4497 message: 'No constant computed for $node')); | 4487 message: 'No constant computed for $node')); |
4498 | 4488 |
4499 ConstantValue value = compiler.constants.getConstantValue(constant); | 4489 ConstantValue value = resolution.constants.getConstantValue(constant); |
4500 DartType caseType = value.getType(coreTypes); //typeOfConstant(value); | 4490 DartType caseType = value.getType(coreTypes); //typeOfConstant(value); |
4501 | 4491 |
4502 if (firstCaseType == null) { | 4492 if (firstCaseType == null) { |
4503 firstCase = caseMatch; | 4493 firstCase = caseMatch; |
4504 firstCaseType = caseType; | 4494 firstCaseType = caseType; |
4505 | 4495 |
4506 // We only report the bad type on the first class element. All others | 4496 // We only report the bad type on the first class element. All others |
4507 // get a "type differs" error. | 4497 // get a "type differs" error. |
4508 if (caseType == coreTypes.doubleType) { | 4498 if (caseType == coreTypes.doubleType) { |
4509 reporter.reportErrorMessage( | 4499 reporter.reportErrorMessage( |
(...skipping 216 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
4726 } | 4716 } |
4727 return const NoneResult(); | 4717 return const NoneResult(); |
4728 } | 4718 } |
4729 } | 4719 } |
4730 | 4720 |
4731 /// Looks up [name] in [scope] and unwraps the result. | 4721 /// Looks up [name] in [scope] and unwraps the result. |
4732 Element lookupInScope( | 4722 Element lookupInScope( |
4733 DiagnosticReporter reporter, Node node, Scope scope, String name) { | 4723 DiagnosticReporter reporter, Node node, Scope scope, String name) { |
4734 return Elements.unwrap(scope.lookup(name), reporter, node); | 4724 return Elements.unwrap(scope.lookup(name), reporter, node); |
4735 } | 4725 } |
OLD | NEW |