Chromium Code Reviews| 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 1871 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1882 | 1882 |
| 1883 // TODO(karlklose): this should be reported by the caller of | 1883 // TODO(karlklose): this should be reported by the caller of |
| 1884 // [resolveSend] to select better warning messages for getters and | 1884 // [resolveSend] to select better warning messages for getters and |
| 1885 // setters. | 1885 // setters. |
| 1886 ErroneousElement error = reportAndCreateErroneousElement( | 1886 ErroneousElement error = reportAndCreateErroneousElement( |
| 1887 node, name.text, MessageKind.MEMBER_NOT_FOUND, | 1887 node, name.text, MessageKind.MEMBER_NOT_FOUND, |
| 1888 {'className': receiverClass.name, 'memberName': name.text}); | 1888 {'className': receiverClass.name, 'memberName': name.text}); |
| 1889 // TODO(johnniwinther): Add an [AccessSemantics] for unresolved static | 1889 // TODO(johnniwinther): Add an [AccessSemantics] for unresolved static |
| 1890 // member access. | 1890 // member access. |
| 1891 return handleErroneousAccess( | 1891 return handleErroneousAccess( |
| 1892 node, name, error, new StaticAccess.unresolved(error)); | 1892 node, name, new StaticAccess.unresolved(error)); |
| 1893 } | 1893 } |
| 1894 | 1894 |
| 1895 /// Handle qualified access of an instance member, like `a.b` or `a.b()` where | 1895 /// Handle qualified access of an instance member, like `a.b` or `a.b()` where |
| 1896 /// `a` is a class and `b` is a non-static member. | 1896 /// `a` is a class and `b` is a non-static member. |
| 1897 ResolutionResult handleStaticInstanceMemberAccess( | 1897 ResolutionResult handleStaticInstanceMemberAccess( |
| 1898 Send node, Name name, ClassElement receiverClass, Element member) { | 1898 Send node, Name name, ClassElement receiverClass, Element member) { |
| 1899 | 1899 |
| 1900 registry.registerThrowNoSuchMethod(); | 1900 registry.registerThrowNoSuchMethod(); |
| 1901 // TODO(johnniwinther): With the simplified [TreeElements] invariant, | 1901 // TODO(johnniwinther): With the simplified [TreeElements] invariant, |
| 1902 // try to resolve injected elements if [currentClass] is in the patch | 1902 // try to resolve injected elements if [currentClass] is in the patch |
| 1903 // library of [receiverClass]. | 1903 // library of [receiverClass]. |
| 1904 | 1904 |
| 1905 // TODO(karlklose): this should be reported by the caller of | 1905 // TODO(karlklose): this should be reported by the caller of |
| 1906 // [resolveSend] to select better warning messages for getters and | 1906 // [resolveSend] to select better warning messages for getters and |
| 1907 // setters. | 1907 // setters. |
| 1908 ErroneousElement error = reportAndCreateErroneousElement( | 1908 ErroneousElement error = reportAndCreateErroneousElement( |
| 1909 node, name.text, MessageKind.MEMBER_NOT_STATIC, | 1909 node, name.text, MessageKind.MEMBER_NOT_STATIC, |
| 1910 {'className': receiverClass.name, 'memberName': name}); | 1910 {'className': receiverClass.name, 'memberName': name}); |
| 1911 | 1911 |
| 1912 // TODO(johnniwinther): Add an [AccessSemantics] for statically accessed | 1912 // TODO(johnniwinther): Add an [AccessSemantics] for statically accessed |
| 1913 // instance members. | 1913 // instance members. |
| 1914 return handleErroneousAccess( | 1914 return handleErroneousAccess( |
| 1915 node, name, error, new StaticAccess.unresolved(error)); | 1915 node, name, new StaticAccess.unresolved(error)); |
| 1916 } | 1916 } |
| 1917 | 1917 |
| 1918 /// Handle qualified access of an inaccessible private static class member, | 1918 /// Handle qualified access of an inaccessible private static class member, |
| 1919 /// like `a._b` or `a.b()` where `a` is class, `_b` is static member of `a` | 1919 /// like `a._b` or `a.b()` where `a` is class, `_b` is static member of `a` |
| 1920 /// but `a` is not defined in the current library. | 1920 /// but `a` is not defined in the current library. |
| 1921 ResolutionResult handlePrivateStaticMemberAccess( | 1921 ResolutionResult handlePrivateStaticMemberAccess( |
| 1922 Send node, Name name, ClassElement receiverClass, Element member) { | 1922 Send node, Name name, ClassElement receiverClass, Element member) { |
| 1923 registry.registerThrowNoSuchMethod(); | 1923 registry.registerThrowNoSuchMethod(); |
| 1924 ErroneousElement error = reportAndCreateErroneousElement( | 1924 ErroneousElement error = reportAndCreateErroneousElement( |
| 1925 node, name.text, MessageKind.PRIVATE_ACCESS, | 1925 node, name.text, MessageKind.PRIVATE_ACCESS, |
| 1926 {'libraryName': member.library.getLibraryOrScriptName(), | 1926 {'libraryName': member.library.getLibraryOrScriptName(), |
| 1927 'name': name}); | 1927 'name': name}); |
| 1928 // TODO(johnniwinther): Add an [AccessSemantics] for unresolved static | 1928 // TODO(johnniwinther): Add an [AccessSemantics] for unresolved static |
| 1929 // member access. | 1929 // member access. |
| 1930 return handleErroneousAccess( | 1930 return handleErroneousAccess( |
| 1931 node, name, error, new StaticAccess.unresolved(error)); | 1931 node, name, new StaticAccess.unresolved(error)); |
| 1932 } | 1932 } |
| 1933 | 1933 |
| 1934 /// Handle qualified access to a static member, like `a.b` or `a.b()` where | 1934 /// Handle qualified access to a static member, like `a.b` or `a.b()` where |
| 1935 /// `a` is a class and `b` is a static member of `a`. | 1935 /// `a` is a class and `b` is a static member of `a`. |
| 1936 ResolutionResult handleStaticMemberAccess( | 1936 ResolutionResult handleStaticMemberAccess( |
| 1937 Send node, Name memberName, ClassElement receiverClass) { | 1937 Send node, Name memberName, ClassElement receiverClass) { |
| 1938 String name = memberName.text; | 1938 String name = memberName.text; |
| 1939 receiverClass.ensureResolved(compiler); | 1939 receiverClass.ensureResolved(compiler); |
| 1940 if (node.isOperator) { | 1940 if (node.isOperator) { |
| 1941 // When the resolved receiver is a class, we can have two cases: | 1941 // When the resolved receiver is a class, we can have two cases: |
| (...skipping 219 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2161 Name name, | 2161 Name name, |
| 2162 PrefixElement prefix) { | 2162 PrefixElement prefix) { |
| 2163 if ((ElementCategory.PREFIX & allowedCategory) == 0) { | 2163 if ((ElementCategory.PREFIX & allowedCategory) == 0) { |
| 2164 ErroneousElement error = reportAndCreateErroneousElement( | 2164 ErroneousElement error = reportAndCreateErroneousElement( |
| 2165 node, | 2165 node, |
| 2166 name.text, | 2166 name.text, |
| 2167 MessageKind.PREFIX_AS_EXPRESSION, | 2167 MessageKind.PREFIX_AS_EXPRESSION, |
| 2168 {'prefix': name}, | 2168 {'prefix': name}, |
| 2169 isError: true); | 2169 isError: true); |
| 2170 return handleErroneousAccess( | 2170 return handleErroneousAccess( |
| 2171 node, name, error, new StaticAccess.invalid(error)); | 2171 node, name, new StaticAccess.invalid(error)); |
| 2172 } | 2172 } |
| 2173 if (prefix.isDeferred) { | 2173 if (prefix.isDeferred) { |
| 2174 // TODO(23998): Remove this when deferred access is detected | 2174 // TODO(23998): Remove this when deferred access is detected |
| 2175 // through a [SendStructure]. | 2175 // through a [SendStructure]. |
| 2176 registry.useElement(node.selector, prefix); | 2176 registry.useElement(node.selector, prefix); |
| 2177 } | 2177 } |
| 2178 registry.useElement(node, prefix); | 2178 registry.useElement(node, prefix); |
| 2179 return new PrefixResult(prefix, null); | 2179 return new PrefixResult(prefix, null); |
| 2180 } | 2180 } |
| 2181 | 2181 |
| (...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2241 } | 2241 } |
| 2242 | 2242 |
| 2243 /// Handle `this` as a qualified property, like `a.this`. | 2243 /// Handle `this` as a qualified property, like `a.this`. |
| 2244 ResolutionResult handleQualifiedThisAccess(Send node, Name name) { | 2244 ResolutionResult handleQualifiedThisAccess(Send node, Name name) { |
| 2245 ErroneousElement error = reportAndCreateErroneousElement( | 2245 ErroneousElement error = reportAndCreateErroneousElement( |
| 2246 node.selector, | 2246 node.selector, |
| 2247 name.text, | 2247 name.text, |
| 2248 MessageKind.THIS_PROPERTY, {}, | 2248 MessageKind.THIS_PROPERTY, {}, |
| 2249 isError: true); | 2249 isError: true); |
| 2250 AccessSemantics accessSemantics = new StaticAccess.invalid(error); | 2250 AccessSemantics accessSemantics = new StaticAccess.invalid(error); |
| 2251 return handleErroneousAccess(node, name, error, accessSemantics); | 2251 return handleErroneousAccess(node, name, accessSemantics); |
| 2252 } | 2252 } |
| 2253 | 2253 |
| 2254 /// Handle a qualified [Send], that is where the receiver is non-null, like | 2254 /// Handle a qualified [Send], that is where the receiver is non-null, like |
| 2255 /// `a.b`, `a.b()`, `this.a()` and `super.a()`. | 2255 /// `a.b`, `a.b()`, `this.a()` and `super.a()`. |
| 2256 ResolutionResult handleQualifiedSend(Send node) { | 2256 ResolutionResult handleQualifiedSend(Send node) { |
| 2257 Identifier selector = node.selector.asIdentifier(); | 2257 Identifier selector = node.selector.asIdentifier(); |
| 2258 String text = selector.source; | 2258 String text = selector.source; |
| 2259 Name name = new Name(text, enclosingElement.library); | 2259 Name name = new Name(text, enclosingElement.library); |
| 2260 if (text == 'this') { | 2260 if (text == 'this') { |
| 2261 return handleQualifiedThisAccess(node, name); | 2261 return handleQualifiedThisAccess(node, name); |
| (...skipping 16 matching lines...) Expand all Loading... | |
| 2278 // TODO(johnniwinther): Use the `element` of [result]. | 2278 // TODO(johnniwinther): Use the `element` of [result]. |
| 2279 return handleDynamicPropertyAccess(node, name); | 2279 return handleDynamicPropertyAccess(node, name); |
| 2280 } | 2280 } |
| 2281 } | 2281 } |
| 2282 | 2282 |
| 2283 /// Handle access unresolved access to [name] in a non-instance context. | 2283 /// Handle access unresolved access to [name] in a non-instance context. |
| 2284 ResolutionResult handleUnresolvedAccess( | 2284 ResolutionResult handleUnresolvedAccess( |
| 2285 Send node, Name name, Element element) { | 2285 Send node, Name name, Element element) { |
| 2286 // TODO(johnniwinther): Support unresolved top level access as an | 2286 // TODO(johnniwinther): Support unresolved top level access as an |
| 2287 // [AccessSemantics]. | 2287 // [AccessSemantics]. |
| 2288 AccessSemantics accessSemantics = new StaticAccess.unresolved(element); | 2288 AccessSemantics semantics = new StaticAccess.unresolved(element); |
| 2289 return handleErroneousAccess(node, name, element, accessSemantics); | 2289 return handleErroneousAccess(node, name, semantics); |
| 2290 } | 2290 } |
| 2291 | 2291 |
| 2292 /// Handle erroneous access of [element] of the given [accessSemantics]. | 2292 /// Handle erroneous access of [element] of the given [semantics]. |
| 2293 ResolutionResult handleErroneousAccess( | 2293 ResolutionResult handleErroneousAccess( |
| 2294 Send node, Name name, Element element, AccessSemantics accessSemantics) { | 2294 Send node, Name name, AccessSemantics semantics) { |
| 2295 SendStructure sendStructure; | 2295 SendStructure sendStructure; |
| 2296 Selector selector; | 2296 Selector selector; |
| 2297 if (node.isCall) { | 2297 if (node.isCall) { |
| 2298 CallStructure callStructure = | 2298 CallStructure callStructure = |
| 2299 resolveArguments(node.argumentsNode).callStructure; | 2299 resolveArguments(node.argumentsNode).callStructure; |
| 2300 selector = new Selector(SelectorKind.CALL, name, callStructure); | 2300 selector = new Selector(SelectorKind.CALL, name, callStructure); |
| 2301 registry.registerDynamicInvocation( | 2301 registry.registerDynamicInvocation( |
| 2302 new UniverseSelector(selector, null)); | 2302 new UniverseSelector(selector, null)); |
| 2303 sendStructure = new InvokeStructure(accessSemantics, selector); | 2303 sendStructure = new InvokeStructure(semantics, selector); |
| 2304 } else { | 2304 } else { |
| 2305 assert(invariant(node, node.isPropertyAccess)); | 2305 assert(invariant(node, node.isPropertyAccess)); |
| 2306 selector = new Selector( | 2306 selector = new Selector( |
| 2307 SelectorKind.GETTER, name, CallStructure.NO_ARGS); | 2307 SelectorKind.GETTER, name, CallStructure.NO_ARGS); |
| 2308 registry.registerDynamicGetter( | 2308 registry.registerDynamicGetter( |
| 2309 new UniverseSelector(selector, null)); | 2309 new UniverseSelector(selector, null)); |
| 2310 sendStructure = new GetStructure(accessSemantics, selector); | 2310 sendStructure = new GetStructure(semantics, selector); |
| 2311 } | 2311 } |
| 2312 // TODO(23998): Remove this when all information goes through | 2312 // TODO(23998): Remove this when all information goes through |
| 2313 // the [SendStructure]. | 2313 // the [SendStructure]. |
| 2314 registry.setSelector(node, selector); | 2314 registry.setSelector(node, selector); |
| 2315 registry.useElement(node, element); | 2315 registry.useElement(node, semantics.element); |
| 2316 registry.registerSendStructure(node, sendStructure); | 2316 registry.registerSendStructure(node, sendStructure); |
| 2317 return const NoneResult(); | 2317 return const NoneResult(); |
| 2318 } | 2318 } |
| 2319 | 2319 |
| 2320 /// Handle access to an ambiguous element, that is, a name imported twice. | 2320 /// Handle access to an ambiguous element, that is, a name imported twice. |
| 2321 ResolutionResult handleAmbiguousSend( | 2321 ResolutionResult handleAmbiguousSend( |
| 2322 Send node, | 2322 Send node, |
| 2323 Name name, | 2323 Name name, |
| 2324 AmbiguousElement element) { | 2324 AmbiguousElement element) { |
| 2325 | 2325 |
| 2326 ErroneousElement error = reportAndCreateErroneousElement( | 2326 ErroneousElement error = reportAndCreateErroneousElement( |
| 2327 node, | 2327 node, |
| 2328 name.text, | 2328 name.text, |
| 2329 element.messageKind, | 2329 element.messageKind, |
| 2330 element.messageArguments); | 2330 element.messageArguments); |
| 2331 element.diagnose(enclosingElement, compiler); | 2331 element.diagnose(enclosingElement, compiler); |
| 2332 registry.registerThrowNoSuchMethod(); | 2332 registry.registerThrowNoSuchMethod(); |
| 2333 | 2333 |
| 2334 // TODO(johnniwinther): Support ambiguous access as an [AccessSemantics]. | 2334 // TODO(johnniwinther): Support ambiguous access as an [AccessSemantics]. |
| 2335 AccessSemantics semantics = new StaticAccess.unresolved(error); | |
| 2336 return handleErroneousAccess(node, name, semantics); | |
| 2337 } | |
| 2338 | |
| 2339 /// Handle update to an ambiguous element, that is, a name imported twice. | |
| 2340 ResolutionResult handleAmbiguousUpdate( | |
| 2341 SendSet node, | |
| 2342 Name name, | |
| 2343 AmbiguousElement element) { | |
| 2344 | |
| 2345 ErroneousElement error = reportAndCreateErroneousElement( | |
| 2346 node, | |
| 2347 name.text, | |
| 2348 element.messageKind, | |
| 2349 element.messageArguments); | |
| 2350 element.diagnose(enclosingElement, compiler); | |
| 2351 registry.registerThrowNoSuchMethod(); | |
| 2352 | |
| 2353 // TODO(johnniwinther): Support ambiguous access as an [AccessSemantics]. | |
| 2335 AccessSemantics accessSemantics = new StaticAccess.unresolved(error); | 2354 AccessSemantics accessSemantics = new StaticAccess.unresolved(error); |
| 2336 return handleErroneousAccess(node, name, error, accessSemantics); | 2355 return handleErroneousUpdate(node, name, error, accessSemantics); |
| 2337 } | 2356 } |
| 2338 | 2357 |
| 2339 /// Handle access of an instance [member] from a non-instance context. | 2358 /// Handle access of an instance [member] from a non-instance context. |
| 2340 ResolutionResult handleStaticInstanceSend( | 2359 ResolutionResult handleStaticInstanceSend( |
| 2341 Send node, Name name, MemberElement member) { | 2360 Send node, Name name, MemberElement member) { |
| 2342 compiler.reportError( | 2361 compiler.reportError( |
| 2343 node, MessageKind.NO_INSTANCE_AVAILABLE, {'name': member.name}); | 2362 node, MessageKind.NO_INSTANCE_AVAILABLE, {'name': member.name}); |
| 2344 ErroneousElement error = new ErroneousElementX( | 2363 ErroneousElement error = new ErroneousElementX( |
| 2345 MessageKind.NO_INSTANCE_AVAILABLE, | 2364 MessageKind.NO_INSTANCE_AVAILABLE, |
| 2346 {'name': name}, | 2365 {'name': name}, |
| 2347 name.text, | 2366 name.text, |
| 2348 enclosingElement); | 2367 enclosingElement); |
| 2349 | 2368 |
| 2350 // TODO(johnniwinther): Support static instance access as an | 2369 // TODO(johnniwinther): Support static instance access as an |
| 2351 // [AccessSemantics]. | 2370 // [AccessSemantics]. |
| 2352 AccessSemantics accessSemantics = new StaticAccess.unresolved(error); | 2371 AccessSemantics semantics = new StaticAccess.unresolved(error); |
| 2353 return handleErroneousAccess(node, name, error, accessSemantics); | 2372 return handleErroneousAccess(node, name, semantics); |
| 2354 } | 2373 } |
| 2355 | 2374 |
| 2356 /// Handle access of a parameter, local variable or local function. | 2375 /// Handle access of a parameter, local variable or local function. |
| 2357 ResolutionResult handleLocalAccess(Send node, Name name, Element element) { | 2376 ResolutionResult handleLocalAccess(Send node, Name name, Element element) { |
| 2358 ResolutionResult result = const NoneResult(); | 2377 ResolutionResult result = const NoneResult(); |
| 2359 AccessSemantics semantics = computeLocalAccessSemantics(node, element); | 2378 AccessSemantics semantics = computeLocalAccessSemantics(node, element); |
| 2360 Selector selector; | 2379 Selector selector; |
| 2361 if (node.isCall) { | 2380 if (node.isCall) { |
| 2362 CallStructure callStructure = | 2381 CallStructure callStructure = |
| 2363 resolveArguments(node.argumentsNode).callStructure; | 2382 resolveArguments(node.argumentsNode).callStructure; |
| (...skipping 226 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2590 ResolutionResult handleResolvedSend(Send node, Name name, Element element) { | 2609 ResolutionResult handleResolvedSend(Send node, Name name, Element element) { |
| 2591 if (element.isAmbiguous) { | 2610 if (element.isAmbiguous) { |
| 2592 return handleAmbiguousSend(node, name, element); | 2611 return handleAmbiguousSend(node, name, element); |
| 2593 } | 2612 } |
| 2594 if (element.isErroneous) { | 2613 if (element.isErroneous) { |
| 2595 // This handles elements with parser errors. | 2614 // This handles elements with parser errors. |
| 2596 // TODO(johnniwinther): Elements with parse error should not set | 2615 // TODO(johnniwinther): Elements with parse error should not set |
| 2597 // [isErroneous] to `true`. | 2616 // [isErroneous] to `true`. |
| 2598 assert(invariant(node, element is! ErroneousElement, | 2617 assert(invariant(node, element is! ErroneousElement, |
| 2599 message: "Unexpected erroneous element $element.")); | 2618 message: "Unexpected erroneous element $element.")); |
| 2600 return handleErroneousAccess(node, name, element, | 2619 return handleErroneousAccess(node, name, |
| 2601 new StaticAccess.unresolved(element)); | 2620 new StaticAccess.unresolved(element)); |
| 2602 } | 2621 } |
| 2603 if (element.isInstanceMember) { | 2622 if (element.isInstanceMember) { |
| 2604 if (inInstanceContext) { | 2623 if (inInstanceContext) { |
| 2605 // TODO(johnniwinther): Maybe use the found [element]. | 2624 // TODO(johnniwinther): Maybe use the found [element]. |
| 2606 return handleThisPropertyAccess(node, name); | 2625 return handleThisPropertyAccess(node, name); |
| 2607 } else { | 2626 } else { |
| 2608 return handleStaticInstanceSend(node, name, element); | 2627 return handleStaticInstanceSend(node, name, element); |
| 2609 } | 2628 } |
| 2610 } | 2629 } |
| 2611 if (element.isClass) { | 2630 if (element.isClass) { |
| 2612 // `C`, `C()`, or 'C.b` where 'C' is a class. | 2631 // `C`, `C()`, or 'C.b` where 'C' is a class. |
| 2613 return handleClassSend(node, name, element); | 2632 return handleClassSend(node, name, element); |
| 2614 } else if (element.isTypedef) { | 2633 } else if (element.isTypedef) { |
| 2615 // `F` or `F()` where 'F' is a typedef. | 2634 // `F` or `F()` where 'F' is a typedef. |
| 2616 return handleTypedefTypeLiteralAccess(node, name, element); | 2635 return handleTypedefTypeLiteralAccess(node, name, element); |
| 2617 } else if (element.isTypeVariable) { | 2636 } else if (element.isTypeVariable) { |
| 2618 return handleTypeVariableTypeLiteralAccess(node, name, element); | 2637 return handleTypeVariableTypeLiteralAccess(node, name, element); |
| 2619 } else if (element.isPrefix) { | 2638 } else if (element.isPrefix) { |
| 2620 return handleLibraryPrefix(node, name, element); | 2639 return handleLibraryPrefix(node, name, element); |
| 2621 } else if (element.isLocal) { | 2640 } else if (element.isLocal) { |
| 2622 return handleLocalAccess(node, name, element); | 2641 return handleLocalAccess(node, name, element); |
| 2623 } else if (element.isStatic || element.isTopLevel) { | 2642 } else if (element.isStatic || element.isTopLevel) { |
| 2624 return handleStaticOrTopLevelAccess(node, name, element); | 2643 return handleStaticOrTopLevelAccess(node, name, element); |
| 2625 } | 2644 } |
| 2626 return internalError(node, "Unexpected resolved send: $element"); | 2645 return internalError(node, "Unexpected resolved send: $element"); |
| 2627 } | 2646 } |
| 2628 | 2647 |
| 2648 /// Handle update to resolved [element]. | |
| 2649 ResolutionResult handleResolvedSendSet( | |
| 2650 SendSet node, Name name, Element element) { | |
| 2651 if (element.isAmbiguous) { | |
| 2652 return handleAmbiguousUpdate(node, name, element); | |
| 2653 } | |
| 2654 if (element.isErroneous) { | |
| 2655 // This handles elements with parser errors. | |
| 2656 // TODO(johnniwinther): Elements with parse error should not set | |
| 2657 // [isErroneous] to `true`. | |
| 2658 assert(invariant(node, element is! ErroneousElement, | |
| 2659 message: "Unexpected erroneous element $element.")); | |
| 2660 return handleErroneousUpdate(node, name, element, | |
| 2661 new StaticAccess.unresolved(element)); | |
| 2662 } | |
| 2663 return oldVisitSendSet(node); | |
| 2664 } | |
| 2665 | |
| 2629 /// Handle an unqualified [Send], that is where the `node.receiver` is null, | 2666 /// Handle an unqualified [Send], that is where the `node.receiver` is null, |
| 2630 /// like `a`, `a()`, `this()`, `assert()`, and `(){}()`. | 2667 /// like `a`, `a()`, `this()`, `assert()`, and `(){}()`. |
| 2631 ResolutionResult handleUnqualifiedSend(Send node) { | 2668 ResolutionResult handleUnqualifiedSend(Send node) { |
| 2632 Identifier selector = node.selector.asIdentifier(); | 2669 Identifier selector = node.selector.asIdentifier(); |
| 2633 if (selector == null) { | 2670 if (selector == null) { |
| 2634 // `(){}()` and `(foo)()`. | 2671 // `(){}()` and `(foo)()`. |
| 2635 return handleExpressionInvoke(node); | 2672 return handleExpressionInvoke(node); |
| 2636 } | 2673 } |
| 2637 String text = selector.source; | 2674 String text = selector.source; |
| 2638 if (text == 'assert') { | 2675 if (text == 'assert') { |
| (...skipping 17 matching lines...) Expand all Loading... | |
| 2656 } else { | 2693 } else { |
| 2657 // Create [ErroneousElement] for unresolved access. | 2694 // Create [ErroneousElement] for unresolved access. |
| 2658 ErroneousElement error = reportCannotResolve(node, text); | 2695 ErroneousElement error = reportCannotResolve(node, text); |
| 2659 return handleUnresolvedAccess(node, name, error); | 2696 return handleUnresolvedAccess(node, name, error); |
| 2660 } | 2697 } |
| 2661 } else { | 2698 } else { |
| 2662 return handleResolvedSend(node, name, element); | 2699 return handleResolvedSend(node, name, element); |
| 2663 } | 2700 } |
| 2664 } | 2701 } |
| 2665 | 2702 |
| 2703 /// Handle an unqualified [SendSet], that is where the `node.receiver` is | |
| 2704 /// null, like `a = b`, `a++`, and `a += b`. | |
| 2705 ResolutionResult handleUnqualifiedSendSet(SendSet node) { | |
| 2706 Identifier selector = node.selector.asIdentifier(); | |
| 2707 String text = selector.source; | |
| 2708 Name name = new Name(text, enclosingElement.library); | |
| 2709 Element element = lookupInScope(compiler, node, scope, text); | |
| 2710 if (element == null) { | |
| 2711 return oldVisitSendSet(node); | |
| 2712 } else { | |
| 2713 return handleResolvedSendSet(node, name, element); | |
| 2714 } | |
| 2715 } | |
| 2716 | |
| 2666 ResolutionResult visitSend(Send node) { | 2717 ResolutionResult visitSend(Send node) { |
| 2667 if (node.isOperator) { | 2718 if (node.isOperator) { |
| 2668 // `a && b`, `a + b`, `-a`, or `a is T`. | 2719 // `a && b`, `a + b`, `-a`, or `a is T`. |
| 2669 return handleOperatorSend(node); | 2720 return handleOperatorSend(node); |
| 2670 } else if (node.receiver != null) { | 2721 } else if (node.receiver != null) { |
| 2671 // `a.b`. | 2722 // `a.b`. |
| 2672 return handleQualifiedSend(node); | 2723 return handleQualifiedSend(node); |
| 2673 } else { | 2724 } else { |
| 2674 // `a`. | 2725 // `a`. |
| 2675 return handleUnqualifiedSend(node); | 2726 return handleUnqualifiedSend(node); |
| (...skipping 234 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2910 } | 2961 } |
| 2911 | 2962 |
| 2912 /// Handle super index operations like `super.a = b`, `super.a += b`, and | 2963 /// Handle super index operations like `super.a = b`, `super.a += b`, and |
| 2913 /// `super.a++`. | 2964 /// `super.a++`. |
| 2914 // TODO(johnniwinther): Share code with [handleSuperIndexSendSet]. | 2965 // TODO(johnniwinther): Share code with [handleSuperIndexSendSet]. |
| 2915 ResolutionResult handleSuperSendSet(SendSet node) { | 2966 ResolutionResult handleSuperSendSet(SendSet node) { |
| 2916 Identifier selector = node.selector.asIdentifier(); | 2967 Identifier selector = node.selector.asIdentifier(); |
| 2917 String text = selector.source; | 2968 String text = selector.source; |
| 2918 Name name = new Name(text, enclosingElement.library); | 2969 Name name = new Name(text, enclosingElement.library); |
| 2919 String operatorText = node.assignmentOperator.source; | 2970 String operatorText = node.assignmentOperator.source; |
| 2971 Selector getterSelector = new Selector( | |
| 2972 SelectorKind.GETTER, name, CallStructure.NO_ARGS); | |
| 2973 Selector setterSelector = new Selector( | |
| 2974 SelectorKind.SETTER, name.setter, CallStructure.ONE_ARG); | |
| 2920 AccessSemantics semantics = checkSuperAccess(node); | 2975 AccessSemantics semantics = checkSuperAccess(node); |
| 2921 if (node.isPrefix || node.isPostfix) { | 2976 if (node.isPrefix || node.isPostfix) { |
| 2922 // `super.a++` or `++super.a`. | 2977 // `super.a++` or `++super.a`. |
| 2923 IncDecOperator operator = IncDecOperator.parse(operatorText); | |
| 2924 Selector getterSelector = | |
| 2925 new Selector(SelectorKind.GETTER, name, CallStructure.NO_ARGS); | |
| 2926 Selector setterSelector = | |
| 2927 new Selector(SelectorKind.SETTER, name.setter, CallStructure.ONE_ARG); | |
| 2928 Selector operatorSelector = | |
| 2929 new Selector.binaryOperator(operator.selectorName); | |
| 2930 | |
| 2931 // TODO(23998): Remove these when selectors are only accessed | |
| 2932 // through the send structure. | |
| 2933 registry.setGetterSelectorInComplexSendSet(node, getterSelector); | |
| 2934 registry.setSelector(node, setterSelector); | |
| 2935 registry.setOperatorSelectorInComplexSendSet(node, operatorSelector); | |
| 2936 | |
| 2937 if (semantics == null) { | 2978 if (semantics == null) { |
| 2938 semantics = computeSuperAccessSemanticsForSelectors( | 2979 semantics = computeSuperAccessSemanticsForSelectors( |
| 2939 node, getterSelector, setterSelector); | 2980 node, getterSelector, setterSelector); |
| 2940 | |
| 2941 registry.registerStaticInvocation(semantics.getter); | |
| 2942 registry.registerStaticInvocation(semantics.setter); | |
| 2943 | |
| 2944 // TODO(23998): Remove these when elements are only accessed | |
| 2945 // through the send structure. | |
| 2946 registry.useElement(node, semantics.setter); | |
| 2947 registry.useElement(node.selector, semantics.getter); | |
| 2948 } | 2981 } |
| 2949 registry.registerDynamicInvocation( | 2982 return handleUpdate(node, name, semantics); |
| 2950 new UniverseSelector(operatorSelector, null)); | |
| 2951 | |
| 2952 SendStructure sendStructure = node.isPrefix | |
| 2953 ? new PrefixStructure( | |
| 2954 semantics, operator, getterSelector, setterSelector) | |
| 2955 : new PostfixStructure( | |
| 2956 semantics, operator, getterSelector, setterSelector); | |
| 2957 registry.registerSendStructure(node, sendStructure); | |
| 2958 return const NoneResult(); | |
| 2959 } else { | 2983 } else { |
| 2960 Node rhs = node.arguments.head; | |
| 2961 visitExpression(rhs); | |
| 2962 | |
| 2963 AssignmentOperator operator = AssignmentOperator.parse(operatorText); | 2984 AssignmentOperator operator = AssignmentOperator.parse(operatorText); |
| 2964 if (operator.kind == AssignmentOperatorKind.ASSIGN) { | 2985 if (operator.kind == AssignmentOperatorKind.ASSIGN) { |
| 2965 // `super.a = b`. | 2986 // `super.a = b`. |
| 2966 Selector setterSelector = new Selector( | |
| 2967 SelectorKind.SETTER, name.setter, CallStructure.ONE_ARG); | |
| 2968 if (semantics == null) { | 2987 if (semantics == null) { |
| 2969 semantics = | 2988 semantics = |
| 2970 computeSuperAccessSemanticsForSelector( | 2989 computeSuperAccessSemanticsForSelector( |
| 2971 node, setterSelector, alternateName: name); | 2990 node, setterSelector, alternateName: name); |
| 2972 switch (semantics.kind) { | 2991 switch (semantics.kind) { |
| 2973 case AccessKind.SUPER_FINAL_FIELD: | 2992 case AccessKind.SUPER_FINAL_FIELD: |
| 2974 compiler.reportWarning( | 2993 compiler.reportWarning( |
| 2975 node, | 2994 node, |
| 2976 MessageKind.ASSIGNING_FINAL_FIELD_IN_SUPER, | 2995 MessageKind.ASSIGNING_FINAL_FIELD_IN_SUPER, |
| 2977 {'name': name, | 2996 {'name': name, |
| 2978 'superclassName': semantics.setter.enclosingClass.name}); | 2997 'superclassName': semantics.setter.enclosingClass.name}); |
| 2979 registry.registerDynamicInvocation( | 2998 registry.registerDynamicInvocation( |
| 2980 new UniverseSelector(setterSelector, null)); | 2999 new UniverseSelector(setterSelector, null)); |
| 2981 registry.registerSuperNoSuchMethod(); | 3000 registry.registerSuperNoSuchMethod(); |
| 2982 break; | 3001 break; |
| 2983 case AccessKind.SUPER_METHOD: | 3002 case AccessKind.SUPER_METHOD: |
| 2984 compiler.reportWarning( | 3003 compiler.reportWarning( |
| 2985 node, MessageKind.ASSIGNING_METHOD_IN_SUPER, | 3004 node, MessageKind.ASSIGNING_METHOD_IN_SUPER, |
| 2986 {'name': name, | 3005 {'name': name, |
| 2987 'superclassName': semantics.setter.enclosingClass.name}); | 3006 'superclassName': semantics.setter.enclosingClass.name}); |
| 2988 registry.registerDynamicInvocation( | 3007 registry.registerDynamicInvocation( |
| 2989 new UniverseSelector(setterSelector, null)); | 3008 new UniverseSelector(setterSelector, null)); |
| 2990 registry.registerSuperNoSuchMethod(); | 3009 registry.registerSuperNoSuchMethod(); |
| 2991 break; | 3010 break; |
| 2992 default: | 3011 default: |
| 2993 registry.registerStaticInvocation(semantics.setter); | 3012 registry.registerStaticInvocation(semantics.setter); |
| 2994 break; | 3013 break; |
| 2995 } | 3014 } |
| 3015 } | |
| 3016 return handleUpdate(node, name, semantics); | |
| 3017 } else { | |
| 3018 // `super.a += b`. | |
| 3019 if (semantics == null) { | |
| 3020 semantics = computeSuperAccessSemanticsForSelectors( | |
| 3021 node, getterSelector, setterSelector); | |
| 3022 } | |
| 3023 return handleUpdate(node, name, semantics); | |
| 3024 } | |
| 3025 } | |
| 3026 } | |
| 2996 | 3027 |
| 2997 // TODO(23998): Remove these when elements are only accessed | 3028 /// Handle erroneous update of [element] of the given [accessSemantics]. |
| 2998 // through the send structure. | 3029 ResolutionResult handleErroneousUpdate( |
|
karlklose
2015/08/07 08:53:49
Remove this and replace calls with calls to handle
Johnni Winther
2015/08/07 09:40:53
Done.
| |
| 2999 registry.useElement(node, semantics.setter); | 3030 SendSet node, |
| 3031 Name name, | |
| 3032 Element element, | |
| 3033 AccessSemantics accessSemantics) { | |
| 3034 return handleUpdate(node, name, accessSemantics); | |
| 3035 } | |
| 3036 | |
| 3037 /// Handle update of an entity defined by [semantics]. For instance `a = b`, | |
| 3038 /// `a++` or `a += b` where [semantics] describe `a`. | |
| 3039 ResolutionResult handleUpdate( | |
| 3040 SendSet node, | |
| 3041 Name name, | |
| 3042 AccessSemantics semantics) { | |
| 3043 SendStructure sendStructure; | |
| 3044 String operatorText = node.assignmentOperator.source; | |
| 3045 Selector getterSelector = | |
| 3046 new Selector(SelectorKind.GETTER, name, CallStructure.NO_ARGS); | |
| 3047 Selector setterSelector = | |
| 3048 new Selector(SelectorKind.SETTER, name.setter, CallStructure.ONE_ARG); | |
| 3049 if (node.isPrefix || node.isPostfix) { | |
| 3050 // `e++` or `++e`. | |
| 3051 IncDecOperator operator = IncDecOperator.parse(operatorText); | |
| 3052 Selector operatorSelector = | |
| 3053 new Selector.binaryOperator(operator.selectorName); | |
| 3054 | |
| 3055 // TODO(23998): Remove these when selectors are only accessed | |
| 3056 // through the send structure. | |
| 3057 registry.setGetterSelectorInComplexSendSet(node, getterSelector); | |
| 3058 registry.setSelector(node, setterSelector); | |
| 3059 registry.setOperatorSelectorInComplexSendSet(node, operatorSelector); | |
| 3060 | |
| 3061 if (semantics.isAccessedStatically) { | |
| 3062 registry.registerStaticInvocation(semantics.getter); | |
| 3063 registry.registerStaticInvocation(semantics.setter); | |
| 3064 } | |
| 3065 // TODO(23998): Remove these when elements are only accessed | |
| 3066 // through the send structure. | |
| 3067 registry.useElement(node, semantics.setter); | |
| 3068 registry.useElement(node.selector, semantics.getter); | |
| 3069 | |
| 3070 registry.registerDynamicInvocation( | |
| 3071 new UniverseSelector(operatorSelector, null)); | |
| 3072 | |
| 3073 SendStructure sendStructure = node.isPrefix | |
| 3074 ? new PrefixStructure( | |
| 3075 semantics, operator, getterSelector, setterSelector) | |
| 3076 : new PostfixStructure( | |
| 3077 semantics, operator, getterSelector, setterSelector); | |
| 3078 registry.registerSendStructure(node, sendStructure); | |
| 3079 return const NoneResult(); | |
| 3080 } else { | |
| 3081 Node rhs = node.arguments.head; | |
| 3082 visitExpression(rhs); | |
| 3083 | |
| 3084 AssignmentOperator operator = AssignmentOperator.parse(operatorText); | |
| 3085 if (operator.kind == AssignmentOperatorKind.ASSIGN) { | |
| 3086 // `e1 = e2`. | |
| 3087 if (semantics.isAccessedStatically) { | |
| 3088 registry.registerStaticInvocation(semantics.setter); | |
| 3000 } | 3089 } |
| 3001 | 3090 |
| 3091 // TODO(23998): Remove these when elements are only accessed | |
| 3092 // through the send structure. | |
| 3093 registry.useElement(node, semantics.setter); | |
| 3094 | |
| 3002 // TODO(23998): Remove this when selectors are only accessed | 3095 // TODO(23998): Remove this when selectors are only accessed |
| 3003 // through the send structure. | 3096 // through the send structure. |
| 3004 registry.setSelector(node, setterSelector); | 3097 registry.setSelector(node, setterSelector); |
| 3005 | 3098 |
| 3006 SendStructure sendStructure = | 3099 SendStructure sendStructure = |
| 3007 new SetStructure(semantics, setterSelector); | 3100 new SetStructure(semantics, setterSelector); |
| 3008 registry.registerSendStructure(node, sendStructure); | 3101 registry.registerSendStructure(node, sendStructure); |
| 3009 return const NoneResult(); | 3102 return const NoneResult(); |
| 3010 } else { | 3103 } else { |
| 3011 // `super.a += b`. | 3104 // `e1 += e2`. |
| 3012 Selector getterSelector = new Selector( | |
| 3013 SelectorKind.GETTER, name, CallStructure.NO_ARGS); | |
| 3014 Selector setterSelector = new Selector( | |
| 3015 SelectorKind.SETTER, name.setter, CallStructure.ONE_ARG); | |
| 3016 Selector operatorSelector = | 3105 Selector operatorSelector = |
| 3017 new Selector.binaryOperator(operator.selectorName); | 3106 new Selector.binaryOperator(operator.selectorName); |
| 3018 if (semantics == null) { | 3107 if (semantics.isAccessedStatically) { |
| 3019 semantics = computeSuperAccessSemanticsForSelectors( | |
| 3020 node, getterSelector, setterSelector); | |
| 3021 | |
| 3022 registry.registerStaticInvocation(semantics.getter); | 3108 registry.registerStaticInvocation(semantics.getter); |
| 3023 registry.registerStaticInvocation(semantics.setter); | 3109 registry.registerStaticInvocation(semantics.setter); |
| 3110 } | |
| 3024 | 3111 |
| 3025 // TODO(23998): Remove these when elements are only accessed | 3112 // TODO(23998): Remove these when elements are only accessed |
| 3026 // through the send structure. | 3113 // through the send structure. |
| 3027 registry.useElement(node, semantics.setter); | 3114 registry.useElement(node, semantics.setter); |
| 3028 registry.useElement(node.selector, semantics.getter); | 3115 registry.useElement(node.selector, semantics.getter); |
| 3029 } | |
| 3030 | 3116 |
| 3031 // TODO(23998): Remove these when selectors are only accessed | 3117 // TODO(23998): Remove these when selectors are only accessed |
| 3032 // through the send structure. | 3118 // through the send structure. |
| 3033 registry.setGetterSelectorInComplexSendSet(node, getterSelector); | 3119 registry.setGetterSelectorInComplexSendSet(node, getterSelector); |
| 3034 registry.setSelector(node, setterSelector); | 3120 registry.setSelector(node, setterSelector); |
| 3035 registry.setOperatorSelectorInComplexSendSet(node, operatorSelector); | 3121 registry.setOperatorSelectorInComplexSendSet(node, operatorSelector); |
| 3036 | 3122 |
| 3037 registry.registerDynamicInvocation( | 3123 registry.registerDynamicInvocation( |
| 3038 new UniverseSelector(operatorSelector, null)); | 3124 new UniverseSelector(operatorSelector, null)); |
| 3039 | 3125 |
| 3040 SendStructure sendStructure = new CompoundStructure( | 3126 SendStructure sendStructure = new CompoundStructure( |
| 3041 semantics, operator, getterSelector, setterSelector); | 3127 semantics, operator, getterSelector, setterSelector); |
| 3042 registry.registerSendStructure(node, sendStructure); | 3128 registry.registerSendStructure(node, sendStructure); |
| 3043 return const NoneResult(); | 3129 return const NoneResult(); |
| 3044 } | 3130 } |
| 3045 } | 3131 } |
| 3046 } | 3132 } |
| 3047 | 3133 |
| 3048 ResolutionResult visitSendSet(SendSet node) { | 3134 ResolutionResult visitSendSet(SendSet node) { |
| 3049 if (node.isIndex) { | 3135 if (node.isIndex) { |
| 3050 if (node.isSuperCall) { | 3136 if (node.isSuperCall) { |
| 3051 return handleSuperIndexSendSet(node); | 3137 return handleSuperIndexSendSet(node); |
| 3052 } else { | 3138 } else { |
| 3053 return handleIndexSendSet(node); | 3139 return handleIndexSendSet(node); |
| 3054 } | 3140 } |
| 3055 } else if (node.isSuperCall) { | 3141 } else if (node.isSuperCall) { |
| 3056 return handleSuperSendSet(node); | 3142 return handleSuperSendSet(node); |
| 3143 } else if (node.receiver == null) { | |
| 3144 return handleUnqualifiedSendSet(node); | |
| 3057 } | 3145 } |
| 3058 return oldVisitSendSet(node); | 3146 return oldVisitSendSet(node); |
| 3059 } | 3147 } |
| 3060 | 3148 |
| 3061 ResolutionResult oldVisitSendSet(SendSet node) { | 3149 ResolutionResult oldVisitSendSet(SendSet node) { |
| 3062 bool oldSendIsMemberAccess = sendIsMemberAccess; | 3150 bool oldSendIsMemberAccess = sendIsMemberAccess; |
| 3063 sendIsMemberAccess = node.isPropertyAccess || node.isCall; | 3151 sendIsMemberAccess = node.isPropertyAccess || node.isCall; |
| 3064 ResolutionResult result = resolveSend(node); | 3152 ResolutionResult result = resolveSend(node); |
| 3065 sendIsMemberAccess = oldSendIsMemberAccess; | 3153 sendIsMemberAccess = oldSendIsMemberAccess; |
| 3066 Element target = result.element; | 3154 Element target = result.element; |
| (...skipping 1276 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 4343 } | 4431 } |
| 4344 return const NoneResult(); | 4432 return const NoneResult(); |
| 4345 } | 4433 } |
| 4346 } | 4434 } |
| 4347 | 4435 |
| 4348 /// Looks up [name] in [scope] and unwraps the result. | 4436 /// Looks up [name] in [scope] and unwraps the result. |
| 4349 Element lookupInScope(Compiler compiler, Node node, | 4437 Element lookupInScope(Compiler compiler, Node node, |
| 4350 Scope scope, String name) { | 4438 Scope scope, String name) { |
| 4351 return Elements.unwrap(scope.lookup(name), compiler, node); | 4439 return Elements.unwrap(scope.lookup(name), compiler, node); |
| 4352 } | 4440 } |
| OLD | NEW |