| 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 /// The state of constants in resolutions. | 7 /// The state of constants in resolutions. |
| 8 enum ConstantState { | 8 enum ConstantState { |
| 9 /// Expressions are not required to be constants. | 9 /// Expressions are not required to be constants. |
| 10 NON_CONSTANT, | 10 NON_CONSTANT, |
| (...skipping 1671 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1682 return const AssertResult(); | 1682 return const AssertResult(); |
| 1683 } | 1683 } |
| 1684 | 1684 |
| 1685 /// Handle access of a property of [name] on `this`, like `this.name` and | 1685 /// Handle access of a property of [name] on `this`, like `this.name` and |
| 1686 /// `this.name()`, or `name` and `name()` in instance context. | 1686 /// `this.name()`, or `name` and `name()` in instance context. |
| 1687 ResolutionResult handleThisPropertyAccess(Send node, Name name) { | 1687 ResolutionResult handleThisPropertyAccess(Send node, Name name) { |
| 1688 AccessSemantics semantics = const DynamicAccess.thisProperty(); | 1688 AccessSemantics semantics = const DynamicAccess.thisProperty(); |
| 1689 return handleDynamicAccessSemantics(node, name, semantics); | 1689 return handleDynamicAccessSemantics(node, name, semantics); |
| 1690 } | 1690 } |
| 1691 | 1691 |
| 1692 /// Handle update of a property of [name] on `this`, like `this.name = b` and |
| 1693 /// `this.name++`, or `name = b` and `name++` in instance context. |
| 1694 ResolutionResult handleThisPropertyUpdate( |
| 1695 SendSet node, Name name, Element element) { |
| 1696 AccessSemantics semantics = const DynamicAccess.thisProperty(); |
| 1697 return handleDynamicUpdateSemantics(node, name, element, semantics); |
| 1698 } |
| 1699 |
| 1692 /// Handle access on `this`, like `this()` and `this` when it is parsed as a | 1700 /// Handle access on `this`, like `this()` and `this` when it is parsed as a |
| 1693 /// [Send] node. | 1701 /// [Send] node. |
| 1694 ResolutionResult handleThisAccess(Send node) { | 1702 ResolutionResult handleThisAccess(Send node) { |
| 1695 AccessSemantics accessSemantics = const DynamicAccess.thisAccess(); | 1703 AccessSemantics accessSemantics = const DynamicAccess.thisAccess(); |
| 1696 if (node.isCall) { | 1704 if (node.isCall) { |
| 1697 CallStructure callStructure = | 1705 CallStructure callStructure = |
| 1698 resolveArguments(node.argumentsNode).callStructure; | 1706 resolveArguments(node.argumentsNode).callStructure; |
| 1699 Selector selector = callStructure.callSelector; | 1707 Selector selector = callStructure.callSelector; |
| 1700 // TODO(johnniwinther): Handle invalid this access as an | 1708 // TODO(johnniwinther): Handle invalid this access as an |
| 1701 // [AccessSemantics]. | 1709 // [AccessSemantics]. |
| (...skipping 340 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2042 analyzeConstantDeferred(node, enforceConst: false); | 2050 analyzeConstantDeferred(node, enforceConst: false); |
| 2043 | 2051 |
| 2044 // TODO(johnniwinther): Avoid the need for a [Selector] here. | 2052 // TODO(johnniwinther): Avoid the need for a [Selector] here. |
| 2045 registry.registerSendStructure(node, | 2053 registry.registerSendStructure(node, |
| 2046 new GetStructure(semantics, | 2054 new GetStructure(semantics, |
| 2047 new Selector(SelectorKind.GETTER, name, CallStructure.NO_ARGS))); | 2055 new Selector(SelectorKind.GETTER, name, CallStructure.NO_ARGS))); |
| 2048 return new ConstantResult(node, semantics.constant); | 2056 return new ConstantResult(node, semantics.constant); |
| 2049 } | 2057 } |
| 2050 } | 2058 } |
| 2051 | 2059 |
| 2060 /// Handle access to a constant type literal of [type]. |
| 2061 // TODO(johnniwinther): Remove [name] when [Selector] is not required for the |
| 2062 // the [GetStructure]. |
| 2063 // TODO(johnniwinther): Remove [element] when it is no longer needed for |
| 2064 // evaluating constants. |
| 2065 ResolutionResult handleConstantTypeLiteralUpdate( |
| 2066 SendSet node, |
| 2067 Name name, |
| 2068 TypeDeclarationElement element, |
| 2069 DartType type, |
| 2070 ConstantAccess semantics) { |
| 2071 ErroneousElement error = |
| 2072 reportAndCreateErroneousElement( |
| 2073 node.selector, name.text, MessageKind.ASSIGNING_TYPE, const {}); |
| 2074 registry.useElement(node, error); |
| 2075 registry.registerTypeLiteral(node, type); |
| 2076 registry.registerThrowNoSuchMethod(); |
| 2077 |
| 2078 return handleUpdate(node, name, semantics); |
| 2079 } |
| 2080 |
| 2052 /// Handle access to a type literal of a typedef. Like `F` or | 2081 /// Handle access to a type literal of a typedef. Like `F` or |
| 2053 /// `F()` where 'F' is typedef. | 2082 /// `F()` where 'F' is typedef. |
| 2054 ResolutionResult handleTypedefTypeLiteralAccess( | 2083 ResolutionResult handleTypedefTypeLiteralAccess( |
| 2055 Send node, | 2084 Send node, |
| 2056 Name name, | 2085 Name name, |
| 2057 TypedefElement typdef) { | 2086 TypedefElement typdef) { |
| 2058 typdef.ensureResolved(compiler); | 2087 typdef.ensureResolved(compiler); |
| 2059 DartType type = typdef.rawType; | 2088 DartType type = typdef.rawType; |
| 2060 ConstantExpression constant = new TypeConstantExpression(type); | 2089 ConstantExpression constant = new TypeConstantExpression(type); |
| 2061 AccessSemantics semantics = new ConstantAccess.typedefTypeLiteral(constant); | 2090 AccessSemantics semantics = new ConstantAccess.typedefTypeLiteral(constant); |
| 2062 return handleConstantTypeLiteralAccess(node, name, typdef, type, semantics); | 2091 return handleConstantTypeLiteralAccess(node, name, typdef, type, semantics); |
| 2063 } | 2092 } |
| 2064 | 2093 |
| 2065 /// Handle access to a type literal of the type 'dynamic'. Like `dynamic` or | 2094 /// Handle access to a type literal of the type 'dynamic'. Like `dynamic` or |
| 2066 /// `dynamic()`. | 2095 /// `dynamic()`. |
| 2067 ResolutionResult handleDynamicTypeLiteralAccess(Send node) { | 2096 ResolutionResult handleDynamicTypeLiteralAccess(Send node) { |
| 2068 DartType type = const DynamicType(); | 2097 DartType type = const DynamicType(); |
| 2069 ConstantExpression constant = new TypeConstantExpression( | 2098 ConstantExpression constant = new TypeConstantExpression( |
| 2070 // TODO(johnniwinther): Use [type] when evaluation of constants is done | 2099 // TODO(johnniwinther): Use [type] when evaluation of constants is done |
| 2071 // directly on the constant expressions. | 2100 // directly on the constant expressions. |
| 2072 node.isCall ? coreTypes.typeType : type); | 2101 node.isCall ? coreTypes.typeType : type); |
| 2073 AccessSemantics semantics = new ConstantAccess.dynamicTypeLiteral(constant); | 2102 AccessSemantics semantics = new ConstantAccess.dynamicTypeLiteral(constant); |
| 2074 return handleConstantTypeLiteralAccess( | 2103 return handleConstantTypeLiteralAccess( |
| 2075 node, const PublicName('dynamic'), compiler.typeClass, type, semantics); | 2104 node, const PublicName('dynamic'), compiler.typeClass, type, semantics); |
| 2076 } | 2105 } |
| 2077 | 2106 |
| 2107 /// Handle update to a type literal of the type 'dynamic'. Like `dynamic++` or |
| 2108 /// `dynamic = 0`. |
| 2109 ResolutionResult handleDynamicTypeLiteralUpdate(SendSet node) { |
| 2110 DartType type = const DynamicType(); |
| 2111 ConstantExpression constant = |
| 2112 new TypeConstantExpression(const DynamicType()); |
| 2113 AccessSemantics semantics = new ConstantAccess.dynamicTypeLiteral(constant); |
| 2114 // TODO(johnniwinther): Remove this when all constants are evaluated. |
| 2115 compiler.resolver.constantCompiler.evaluate(constant); |
| 2116 |
| 2117 return handleConstantTypeLiteralUpdate( |
| 2118 node, const PublicName('dynamic'), compiler.typeClass, type, semantics); |
| 2119 } |
| 2120 |
| 2078 /// Handle access to a type literal of a class. Like `C` or | 2121 /// Handle access to a type literal of a class. Like `C` or |
| 2079 /// `C()` where 'C' is class. | 2122 /// `C()` where 'C' is class. |
| 2080 ResolutionResult handleClassTypeLiteralAccess( | 2123 ResolutionResult handleClassTypeLiteralAccess( |
| 2081 Send node, | 2124 Send node, |
| 2082 Name name, | 2125 Name name, |
| 2083 ClassElement cls) { | 2126 ClassElement cls) { |
| 2084 DartType type = cls.rawType; | 2127 DartType type = cls.rawType; |
| 2085 ConstantExpression constant = new TypeConstantExpression(type); | 2128 ConstantExpression constant = new TypeConstantExpression(type); |
| 2086 AccessSemantics semantics = new ConstantAccess.classTypeLiteral(constant); | 2129 AccessSemantics semantics = new ConstantAccess.classTypeLiteral(constant); |
| 2087 return handleConstantTypeLiteralAccess(node, name, cls, type, semantics); | 2130 return handleConstantTypeLiteralAccess(node, name, cls, type, semantics); |
| (...skipping 128 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2216 new UniverseSelector(selector, null)); | 2259 new UniverseSelector(selector, null)); |
| 2217 sendStructure = new GetStructure(semantics, selector); | 2260 sendStructure = new GetStructure(semantics, selector); |
| 2218 } | 2261 } |
| 2219 registry.registerSendStructure(node, sendStructure); | 2262 registry.registerSendStructure(node, sendStructure); |
| 2220 // TODO(23998): Remove this when all information goes through | 2263 // TODO(23998): Remove this when all information goes through |
| 2221 // the [SendStructure]. | 2264 // the [SendStructure]. |
| 2222 registry.setSelector(node, selector); | 2265 registry.setSelector(node, selector); |
| 2223 return const NoneResult(); | 2266 return const NoneResult(); |
| 2224 } | 2267 } |
| 2225 | 2268 |
| 2269 /// Handle dynamic update of [semantics]. |
| 2270 ResolutionResult handleDynamicUpdateSemantics( |
| 2271 SendSet node, Name name, Element element, AccessSemantics semantics) { |
| 2272 Selector getterSelector = |
| 2273 new Selector(SelectorKind.GETTER, name, CallStructure.NO_ARGS); |
| 2274 Selector setterSelector = |
| 2275 new Selector(SelectorKind.SETTER, name.setter, CallStructure.ONE_ARG); |
| 2276 registry.registerDynamicSetter( |
| 2277 new UniverseSelector(setterSelector, null)); |
| 2278 if (node.isComplex) { |
| 2279 registry.registerDynamicGetter( |
| 2280 new UniverseSelector(getterSelector, null)); |
| 2281 } |
| 2282 |
| 2283 // TODO(23998): Remove these when elements are only accessed through the |
| 2284 // send structure. |
| 2285 Element getter = element; |
| 2286 Element setter = element; |
| 2287 if (element != null && element.isAbstractField) { |
| 2288 AbstractFieldElement abstractField = element; |
| 2289 getter = abstractField.getter; |
| 2290 setter = abstractField.setter; |
| 2291 } |
| 2292 if (setter != null) { |
| 2293 registry.useElement(node, setter); |
| 2294 if (getter != null && node.isComplex) { |
| 2295 registry.useElement(node.selector, getter); |
| 2296 } |
| 2297 } |
| 2298 |
| 2299 return handleUpdate(node, name, semantics); |
| 2300 } |
| 2301 |
| 2226 /// Handle dynamic property access, like `a.b` or `a.b()` where `a` is not a | 2302 /// Handle dynamic property access, like `a.b` or `a.b()` where `a` is not a |
| 2227 /// prefix or class. | 2303 /// prefix or class. |
| 2228 ResolutionResult handleDynamicPropertyAccess(Send node, Name name) { | 2304 ResolutionResult handleDynamicPropertyAccess(Send node, Name name) { |
| 2229 AccessSemantics semantics = const DynamicAccess.dynamicProperty(); | 2305 AccessSemantics semantics = const DynamicAccess.dynamicProperty(); |
| 2230 return handleDynamicAccessSemantics(node, name, semantics); | 2306 return handleDynamicAccessSemantics(node, name, semantics); |
| 2231 } | 2307 } |
| 2232 | 2308 |
| 2233 /// Handle conditional access, like `a?.b` or `a?.b()`. | 2309 /// Handle conditional access, like `a?.b` or `a?.b()`. |
| 2234 ResolutionResult handleConditionalAccess(Send node, Name name) { | 2310 ResolutionResult handleConditionalAccess(Send node, Name name) { |
| 2235 Node receiver = node.receiver; | 2311 Node receiver = node.receiver; |
| (...skipping 414 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2650 return handleAmbiguousUpdate(node, name, element); | 2726 return handleAmbiguousUpdate(node, name, element); |
| 2651 } | 2727 } |
| 2652 if (element.isErroneous) { | 2728 if (element.isErroneous) { |
| 2653 // This handles elements with parser errors. | 2729 // This handles elements with parser errors. |
| 2654 // TODO(johnniwinther): Elements with parse error should not set | 2730 // TODO(johnniwinther): Elements with parse error should not set |
| 2655 // [isErroneous] to `true`. | 2731 // [isErroneous] to `true`. |
| 2656 assert(invariant(node, element is! ErroneousElement, | 2732 assert(invariant(node, element is! ErroneousElement, |
| 2657 message: "Unexpected erroneous element $element.")); | 2733 message: "Unexpected erroneous element $element.")); |
| 2658 return handleUpdate(node, name,new StaticAccess.unresolved(element)); | 2734 return handleUpdate(node, name,new StaticAccess.unresolved(element)); |
| 2659 } | 2735 } |
| 2736 if (element.isInstanceMember) { |
| 2737 if (inInstanceContext) { |
| 2738 return handleThisPropertyUpdate(node, name, element); |
| 2739 } |
| 2740 } |
| 2660 return oldVisitSendSet(node); | 2741 return oldVisitSendSet(node); |
| 2661 } | 2742 } |
| 2662 | 2743 |
| 2663 /// Handle an unqualified [Send], that is where the `node.receiver` is null, | 2744 /// Handle an unqualified [Send], that is where the `node.receiver` is null, |
| 2664 /// like `a`, `a()`, `this()`, `assert()`, and `(){}()`. | 2745 /// like `a`, `a()`, `this()`, `assert()`, and `(){}()`. |
| 2665 ResolutionResult handleUnqualifiedSend(Send node) { | 2746 ResolutionResult handleUnqualifiedSend(Send node) { |
| 2666 Identifier selector = node.selector.asIdentifier(); | 2747 Identifier selector = node.selector.asIdentifier(); |
| 2667 if (selector == null) { | 2748 if (selector == null) { |
| 2668 // `(){}()` and `(foo)()`. | 2749 // `(){}()` and `(foo)()`. |
| 2669 return handleExpressionInvoke(node); | 2750 return handleExpressionInvoke(node); |
| (...skipping 28 matching lines...) Expand all Loading... |
| 2698 } | 2779 } |
| 2699 | 2780 |
| 2700 /// Handle an unqualified [SendSet], that is where the `node.receiver` is | 2781 /// Handle an unqualified [SendSet], that is where the `node.receiver` is |
| 2701 /// null, like `a = b`, `a++`, and `a += b`. | 2782 /// null, like `a = b`, `a++`, and `a += b`. |
| 2702 ResolutionResult handleUnqualifiedSendSet(SendSet node) { | 2783 ResolutionResult handleUnqualifiedSendSet(SendSet node) { |
| 2703 Identifier selector = node.selector.asIdentifier(); | 2784 Identifier selector = node.selector.asIdentifier(); |
| 2704 String text = selector.source; | 2785 String text = selector.source; |
| 2705 Name name = new Name(text, enclosingElement.library); | 2786 Name name = new Name(text, enclosingElement.library); |
| 2706 Element element = lookupInScope(compiler, node, scope, text); | 2787 Element element = lookupInScope(compiler, node, scope, text); |
| 2707 if (element == null) { | 2788 if (element == null) { |
| 2789 if (text == 'dynamic') { |
| 2790 // `dynamic = b`, `dynamic++`, or `dynamic += b` where 'dynamic' is not |
| 2791 // declared in the current scope. |
| 2792 return handleDynamicTypeLiteralUpdate(node); |
| 2793 } else if (inInstanceContext) { |
| 2794 // Left-hand side is implicitly `this.name`. |
| 2795 return handleThisPropertyUpdate(node, name, null); |
| 2796 } else { |
| 2797 // Create [ErroneousElement] for unresolved access. |
| 2798 ErroneousElement error = reportCannotResolve(node, text); |
| 2799 return handleUpdate(node, name, new StaticAccess.unresolved(error)); |
| 2800 } |
| 2708 return oldVisitSendSet(node); | 2801 return oldVisitSendSet(node); |
| 2709 } else { | 2802 } else { |
| 2710 return handleResolvedSendSet(node, name, element); | 2803 return handleResolvedSendSet(node, name, element); |
| 2711 } | 2804 } |
| 2712 } | 2805 } |
| 2713 | 2806 |
| 2714 ResolutionResult visitSend(Send node) { | 2807 ResolutionResult visitSend(Send node) { |
| 2715 if (node.isOperator) { | 2808 if (node.isOperator) { |
| 2716 // `a && b`, `a + b`, `-a`, or `a is T`. | 2809 // `a && b`, `a + b`, `-a`, or `a is T`. |
| 2717 return handleOperatorSend(node); | 2810 return handleOperatorSend(node); |
| (...skipping 250 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2968 Selector getterSelector = new Selector( | 3061 Selector getterSelector = new Selector( |
| 2969 SelectorKind.GETTER, name, CallStructure.NO_ARGS); | 3062 SelectorKind.GETTER, name, CallStructure.NO_ARGS); |
| 2970 Selector setterSelector = new Selector( | 3063 Selector setterSelector = new Selector( |
| 2971 SelectorKind.SETTER, name.setter, CallStructure.ONE_ARG); | 3064 SelectorKind.SETTER, name.setter, CallStructure.ONE_ARG); |
| 2972 AccessSemantics semantics = checkSuperAccess(node); | 3065 AccessSemantics semantics = checkSuperAccess(node); |
| 2973 if (node.isPrefix || node.isPostfix) { | 3066 if (node.isPrefix || node.isPostfix) { |
| 2974 // `super.a++` or `++super.a`. | 3067 // `super.a++` or `++super.a`. |
| 2975 if (semantics == null) { | 3068 if (semantics == null) { |
| 2976 semantics = computeSuperAccessSemanticsForSelectors( | 3069 semantics = computeSuperAccessSemanticsForSelectors( |
| 2977 node, getterSelector, setterSelector); | 3070 node, getterSelector, setterSelector); |
| 3071 registry.registerStaticInvocation(semantics.getter); |
| 3072 registry.registerStaticInvocation(semantics.setter); |
| 2978 } | 3073 } |
| 2979 return handleUpdate(node, name, semantics); | 3074 return handleUpdate(node, name, semantics); |
| 2980 } else { | 3075 } else { |
| 2981 AssignmentOperator operator = AssignmentOperator.parse(operatorText); | 3076 AssignmentOperator operator = AssignmentOperator.parse(operatorText); |
| 2982 if (operator.kind == AssignmentOperatorKind.ASSIGN) { | 3077 if (operator.kind == AssignmentOperatorKind.ASSIGN) { |
| 2983 // `super.a = b`. | 3078 // `super.a = b`. |
| 2984 if (semantics == null) { | 3079 if (semantics == null) { |
| 2985 semantics = | 3080 semantics = |
| 2986 computeSuperAccessSemanticsForSelector( | 3081 computeSuperAccessSemanticsForSelector( |
| 2987 node, setterSelector, alternateName: name); | 3082 node, setterSelector, alternateName: name); |
| 3083 registry.registerStaticInvocation(semantics.setter); |
| 2988 switch (semantics.kind) { | 3084 switch (semantics.kind) { |
| 2989 case AccessKind.SUPER_FINAL_FIELD: | 3085 case AccessKind.SUPER_FINAL_FIELD: |
| 2990 compiler.reportWarning( | 3086 compiler.reportWarning( |
| 2991 node, | 3087 node, |
| 2992 MessageKind.ASSIGNING_FINAL_FIELD_IN_SUPER, | 3088 MessageKind.ASSIGNING_FINAL_FIELD_IN_SUPER, |
| 2993 {'name': name, | 3089 {'name': name, |
| 2994 'superclassName': semantics.setter.enclosingClass.name}); | 3090 'superclassName': semantics.setter.enclosingClass.name}); |
| 3091 // TODO(johnniwinther): This shouldn't be needed. |
| 2995 registry.registerDynamicInvocation( | 3092 registry.registerDynamicInvocation( |
| 2996 new UniverseSelector(setterSelector, null)); | 3093 new UniverseSelector(setterSelector, null)); |
| 2997 registry.registerSuperNoSuchMethod(); | 3094 registry.registerSuperNoSuchMethod(); |
| 2998 break; | 3095 break; |
| 2999 case AccessKind.SUPER_METHOD: | 3096 case AccessKind.SUPER_METHOD: |
| 3000 compiler.reportWarning( | 3097 compiler.reportWarning( |
| 3001 node, MessageKind.ASSIGNING_METHOD_IN_SUPER, | 3098 node, MessageKind.ASSIGNING_METHOD_IN_SUPER, |
| 3002 {'name': name, | 3099 {'name': name, |
| 3003 'superclassName': semantics.setter.enclosingClass.name}); | 3100 'superclassName': semantics.setter.enclosingClass.name}); |
| 3101 // TODO(johnniwinther): This shouldn't be needed. |
| 3004 registry.registerDynamicInvocation( | 3102 registry.registerDynamicInvocation( |
| 3005 new UniverseSelector(setterSelector, null)); | 3103 new UniverseSelector(setterSelector, null)); |
| 3006 registry.registerSuperNoSuchMethod(); | 3104 registry.registerSuperNoSuchMethod(); |
| 3007 break; | 3105 break; |
| 3008 default: | 3106 default: |
| 3009 registry.registerStaticInvocation(semantics.setter); | 3107 registry.registerStaticInvocation(semantics.setter); |
| 3010 break; | 3108 break; |
| 3011 } | 3109 } |
| 3012 } | 3110 } |
| 3013 return handleUpdate(node, name, semantics); | 3111 return handleUpdate(node, name, semantics); |
| 3014 } else { | 3112 } else { |
| 3015 // `super.a += b`. | 3113 // `super.a += b`. |
| 3016 if (semantics == null) { | 3114 if (semantics == null) { |
| 3017 semantics = computeSuperAccessSemanticsForSelectors( | 3115 semantics = computeSuperAccessSemanticsForSelectors( |
| 3018 node, getterSelector, setterSelector); | 3116 node, getterSelector, setterSelector); |
| 3117 registry.registerStaticInvocation(semantics.getter); |
| 3118 registry.registerStaticInvocation(semantics.setter); |
| 3019 } | 3119 } |
| 3020 return handleUpdate(node, name, semantics); | 3120 return handleUpdate(node, name, semantics); |
| 3021 } | 3121 } |
| 3022 } | 3122 } |
| 3023 } | 3123 } |
| 3024 | 3124 |
| 3025 /// Handle update of an entity defined by [semantics]. For instance `a = b`, | 3125 /// Handle update of an entity defined by [semantics]. For instance `a = b`, |
| 3026 /// `a++` or `a += b` where [semantics] describe `a`. | 3126 /// `a++` or `a += b` where [semantics] describe `a`. |
| 3027 ResolutionResult handleUpdate( | 3127 ResolutionResult handleUpdate( |
| 3028 SendSet node, | 3128 SendSet node, |
| (...skipping 10 matching lines...) Expand all Loading... |
| 3039 IncDecOperator operator = IncDecOperator.parse(operatorText); | 3139 IncDecOperator operator = IncDecOperator.parse(operatorText); |
| 3040 Selector operatorSelector = | 3140 Selector operatorSelector = |
| 3041 new Selector.binaryOperator(operator.selectorName); | 3141 new Selector.binaryOperator(operator.selectorName); |
| 3042 | 3142 |
| 3043 // TODO(23998): Remove these when selectors are only accessed | 3143 // TODO(23998): Remove these when selectors are only accessed |
| 3044 // through the send structure. | 3144 // through the send structure. |
| 3045 registry.setGetterSelectorInComplexSendSet(node, getterSelector); | 3145 registry.setGetterSelectorInComplexSendSet(node, getterSelector); |
| 3046 registry.setSelector(node, setterSelector); | 3146 registry.setSelector(node, setterSelector); |
| 3047 registry.setOperatorSelectorInComplexSendSet(node, operatorSelector); | 3147 registry.setOperatorSelectorInComplexSendSet(node, operatorSelector); |
| 3048 | 3148 |
| 3049 if (semantics.isAccessedStatically) { | |
| 3050 registry.registerStaticInvocation(semantics.getter); | |
| 3051 registry.registerStaticInvocation(semantics.setter); | |
| 3052 } | |
| 3053 // TODO(23998): Remove these when elements are only accessed | 3149 // TODO(23998): Remove these when elements are only accessed |
| 3054 // through the send structure. | 3150 // through the send structure. |
| 3055 registry.useElement(node, semantics.setter); | 3151 registry.useElement(node, semantics.setter); |
| 3056 registry.useElement(node.selector, semantics.getter); | 3152 registry.useElement(node.selector, semantics.getter); |
| 3057 | 3153 |
| 3058 registry.registerDynamicInvocation( | 3154 registry.registerDynamicInvocation( |
| 3059 new UniverseSelector(operatorSelector, null)); | 3155 new UniverseSelector(operatorSelector, null)); |
| 3060 | 3156 |
| 3061 SendStructure sendStructure = node.isPrefix | 3157 SendStructure sendStructure = node.isPrefix |
| 3062 ? new PrefixStructure( | 3158 ? new PrefixStructure( |
| 3063 semantics, operator, getterSelector, setterSelector) | 3159 semantics, operator, getterSelector, setterSelector) |
| 3064 : new PostfixStructure( | 3160 : new PostfixStructure( |
| 3065 semantics, operator, getterSelector, setterSelector); | 3161 semantics, operator, getterSelector, setterSelector); |
| 3066 registry.registerSendStructure(node, sendStructure); | 3162 registry.registerSendStructure(node, sendStructure); |
| 3067 return const NoneResult(); | |
| 3068 } else { | 3163 } else { |
| 3069 Node rhs = node.arguments.head; | 3164 Node rhs = node.arguments.head; |
| 3070 visitExpression(rhs); | 3165 visitExpression(rhs); |
| 3071 | 3166 |
| 3072 AssignmentOperator operator = AssignmentOperator.parse(operatorText); | 3167 AssignmentOperator operator = AssignmentOperator.parse(operatorText); |
| 3073 if (operator.kind == AssignmentOperatorKind.ASSIGN) { | 3168 if (operator.kind == AssignmentOperatorKind.ASSIGN) { |
| 3074 // `e1 = e2`. | 3169 // `e1 = e2`. |
| 3075 if (semantics.isAccessedStatically) { | |
| 3076 registry.registerStaticInvocation(semantics.setter); | |
| 3077 } | |
| 3078 | 3170 |
| 3079 // TODO(23998): Remove these when elements are only accessed | 3171 // TODO(23998): Remove these when elements are only accessed |
| 3080 // through the send structure. | 3172 // through the send structure. |
| 3081 registry.useElement(node, semantics.setter); | 3173 registry.useElement(node, semantics.setter); |
| 3082 | 3174 |
| 3083 // TODO(23998): Remove this when selectors are only accessed | 3175 // TODO(23998): Remove this when selectors are only accessed |
| 3084 // through the send structure. | 3176 // through the send structure. |
| 3085 registry.setSelector(node, setterSelector); | 3177 registry.setSelector(node, setterSelector); |
| 3086 | 3178 |
| 3087 SendStructure sendStructure = | 3179 SendStructure sendStructure = |
| 3088 new SetStructure(semantics, setterSelector); | 3180 new SetStructure(semantics, setterSelector); |
| 3089 registry.registerSendStructure(node, sendStructure); | 3181 registry.registerSendStructure(node, sendStructure); |
| 3090 return const NoneResult(); | |
| 3091 } else { | 3182 } else { |
| 3092 // `e1 += e2`. | 3183 // `e1 += e2`. |
| 3093 Selector operatorSelector = | 3184 Selector operatorSelector = |
| 3094 new Selector.binaryOperator(operator.selectorName); | 3185 new Selector.binaryOperator(operator.selectorName); |
| 3095 if (semantics.isAccessedStatically) { | |
| 3096 registry.registerStaticInvocation(semantics.getter); | |
| 3097 registry.registerStaticInvocation(semantics.setter); | |
| 3098 } | |
| 3099 | 3186 |
| 3100 // TODO(23998): Remove these when elements are only accessed | 3187 // TODO(23998): Remove these when elements are only accessed |
| 3101 // through the send structure. | 3188 // through the send structure. |
| 3102 registry.useElement(node, semantics.setter); | 3189 registry.useElement(node, semantics.setter); |
| 3103 registry.useElement(node.selector, semantics.getter); | 3190 registry.useElement(node.selector, semantics.getter); |
| 3104 | 3191 |
| 3105 // TODO(23998): Remove these when selectors are only accessed | 3192 // TODO(23998): Remove these when selectors are only accessed |
| 3106 // through the send structure. | 3193 // through the send structure. |
| 3107 registry.setGetterSelectorInComplexSendSet(node, getterSelector); | 3194 registry.setGetterSelectorInComplexSendSet(node, getterSelector); |
| 3108 registry.setSelector(node, setterSelector); | 3195 registry.setSelector(node, setterSelector); |
| 3109 registry.setOperatorSelectorInComplexSendSet(node, operatorSelector); | 3196 registry.setOperatorSelectorInComplexSendSet(node, operatorSelector); |
| 3110 | 3197 |
| 3111 registry.registerDynamicInvocation( | 3198 registry.registerDynamicInvocation( |
| 3112 new UniverseSelector(operatorSelector, null)); | 3199 new UniverseSelector(operatorSelector, null)); |
| 3113 | 3200 |
| 3114 SendStructure sendStructure = new CompoundStructure( | 3201 SendStructure sendStructure = new CompoundStructure( |
| 3115 semantics, operator, getterSelector, setterSelector); | 3202 semantics, operator, getterSelector, setterSelector); |
| 3116 registry.registerSendStructure(node, sendStructure); | 3203 registry.registerSendStructure(node, sendStructure); |
| 3117 return const NoneResult(); | |
| 3118 } | 3204 } |
| 3119 } | 3205 } |
| 3206 return new ResolutionResult.forElement(semantics.setter); |
| 3120 } | 3207 } |
| 3121 | 3208 |
| 3122 ResolutionResult visitSendSet(SendSet node) { | 3209 ResolutionResult visitSendSet(SendSet node) { |
| 3123 if (node.isIndex) { | 3210 if (node.isIndex) { |
| 3124 if (node.isSuperCall) { | 3211 if (node.isSuperCall) { |
| 3125 return handleSuperIndexSendSet(node); | 3212 return handleSuperIndexSendSet(node); |
| 3126 } else { | 3213 } else { |
| 3127 return handleIndexSendSet(node); | 3214 return handleIndexSendSet(node); |
| 3128 } | 3215 } |
| 3129 } else if (node.isSuperCall) { | 3216 } else if (node.isSuperCall) { |
| (...skipping 1289 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4419 } | 4506 } |
| 4420 return const NoneResult(); | 4507 return const NoneResult(); |
| 4421 } | 4508 } |
| 4422 } | 4509 } |
| 4423 | 4510 |
| 4424 /// Looks up [name] in [scope] and unwraps the result. | 4511 /// Looks up [name] in [scope] and unwraps the result. |
| 4425 Element lookupInScope(Compiler compiler, Node node, | 4512 Element lookupInScope(Compiler compiler, Node node, |
| 4426 Scope scope, String name) { | 4513 Scope scope, String name) { |
| 4427 return Elements.unwrap(scope.lookup(name), compiler, node); | 4514 return Elements.unwrap(scope.lookup(name), compiler, node); |
| 4428 } | 4515 } |
| OLD | NEW |