Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(952)

Side by Side Diff: pkg/compiler/lib/src/resolution/members.dart

Issue 1279863005: Begin refactoring of visitSendSet for unqualified updates. (Closed) Base URL: https://github.com/dart-lang/sdk.git@master
Patch Set: Correctly update cf. comments. Created 5 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « pkg/compiler/lib/src/resolution/access_semantics.dart ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
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 handleUpdate(node, name, 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
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 handleUpdate(node, name,new StaticAccess.unresolved(element));
2661 }
2662 return oldVisitSendSet(node);
2663 }
2664
2629 /// Handle an unqualified [Send], that is where the `node.receiver` is null, 2665 /// Handle an unqualified [Send], that is where the `node.receiver` is null,
2630 /// like `a`, `a()`, `this()`, `assert()`, and `(){}()`. 2666 /// like `a`, `a()`, `this()`, `assert()`, and `(){}()`.
2631 ResolutionResult handleUnqualifiedSend(Send node) { 2667 ResolutionResult handleUnqualifiedSend(Send node) {
2632 Identifier selector = node.selector.asIdentifier(); 2668 Identifier selector = node.selector.asIdentifier();
2633 if (selector == null) { 2669 if (selector == null) {
2634 // `(){}()` and `(foo)()`. 2670 // `(){}()` and `(foo)()`.
2635 return handleExpressionInvoke(node); 2671 return handleExpressionInvoke(node);
2636 } 2672 }
2637 String text = selector.source; 2673 String text = selector.source;
2638 if (text == 'assert') { 2674 if (text == 'assert') {
(...skipping 17 matching lines...) Expand all
2656 } else { 2692 } else {
2657 // Create [ErroneousElement] for unresolved access. 2693 // Create [ErroneousElement] for unresolved access.
2658 ErroneousElement error = reportCannotResolve(node, text); 2694 ErroneousElement error = reportCannotResolve(node, text);
2659 return handleUnresolvedAccess(node, name, error); 2695 return handleUnresolvedAccess(node, name, error);
2660 } 2696 }
2661 } else { 2697 } else {
2662 return handleResolvedSend(node, name, element); 2698 return handleResolvedSend(node, name, element);
2663 } 2699 }
2664 } 2700 }
2665 2701
2702 /// Handle an unqualified [SendSet], that is where the `node.receiver` is
2703 /// null, like `a = b`, `a++`, and `a += b`.
2704 ResolutionResult handleUnqualifiedSendSet(SendSet node) {
2705 Identifier selector = node.selector.asIdentifier();
2706 String text = selector.source;
2707 Name name = new Name(text, enclosingElement.library);
2708 Element element = lookupInScope(compiler, node, scope, text);
2709 if (element == null) {
2710 return oldVisitSendSet(node);
2711 } else {
2712 return handleResolvedSendSet(node, name, element);
2713 }
2714 }
2715
2666 ResolutionResult visitSend(Send node) { 2716 ResolutionResult visitSend(Send node) {
2667 if (node.isOperator) { 2717 if (node.isOperator) {
2668 // `a && b`, `a + b`, `-a`, or `a is T`. 2718 // `a && b`, `a + b`, `-a`, or `a is T`.
2669 return handleOperatorSend(node); 2719 return handleOperatorSend(node);
2670 } else if (node.receiver != null) { 2720 } else if (node.receiver != null) {
2671 // `a.b`. 2721 // `a.b`.
2672 return handleQualifiedSend(node); 2722 return handleQualifiedSend(node);
2673 } else { 2723 } else {
2674 // `a`. 2724 // `a`.
2675 return handleUnqualifiedSend(node); 2725 return handleUnqualifiedSend(node);
(...skipping 234 matching lines...) Expand 10 before | Expand all | Expand 10 after
2910 } 2960 }
2911 2961
2912 /// Handle super index operations like `super.a = b`, `super.a += b`, and 2962 /// Handle super index operations like `super.a = b`, `super.a += b`, and
2913 /// `super.a++`. 2963 /// `super.a++`.
2914 // TODO(johnniwinther): Share code with [handleSuperIndexSendSet]. 2964 // TODO(johnniwinther): Share code with [handleSuperIndexSendSet].
2915 ResolutionResult handleSuperSendSet(SendSet node) { 2965 ResolutionResult handleSuperSendSet(SendSet node) {
2916 Identifier selector = node.selector.asIdentifier(); 2966 Identifier selector = node.selector.asIdentifier();
2917 String text = selector.source; 2967 String text = selector.source;
2918 Name name = new Name(text, enclosingElement.library); 2968 Name name = new Name(text, enclosingElement.library);
2919 String operatorText = node.assignmentOperator.source; 2969 String operatorText = node.assignmentOperator.source;
2970 Selector getterSelector = new Selector(
2971 SelectorKind.GETTER, name, CallStructure.NO_ARGS);
2972 Selector setterSelector = new Selector(
2973 SelectorKind.SETTER, name.setter, CallStructure.ONE_ARG);
2920 AccessSemantics semantics = checkSuperAccess(node); 2974 AccessSemantics semantics = checkSuperAccess(node);
2921 if (node.isPrefix || node.isPostfix) { 2975 if (node.isPrefix || node.isPostfix) {
2922 // `super.a++` or `++super.a`. 2976 // `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) { 2977 if (semantics == null) {
2938 semantics = computeSuperAccessSemanticsForSelectors( 2978 semantics = computeSuperAccessSemanticsForSelectors(
2939 node, getterSelector, setterSelector); 2979 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 } 2980 }
2949 registry.registerDynamicInvocation( 2981 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 { 2982 } else {
2960 Node rhs = node.arguments.head;
2961 visitExpression(rhs);
2962
2963 AssignmentOperator operator = AssignmentOperator.parse(operatorText); 2983 AssignmentOperator operator = AssignmentOperator.parse(operatorText);
2964 if (operator.kind == AssignmentOperatorKind.ASSIGN) { 2984 if (operator.kind == AssignmentOperatorKind.ASSIGN) {
2965 // `super.a = b`. 2985 // `super.a = b`.
2966 Selector setterSelector = new Selector(
2967 SelectorKind.SETTER, name.setter, CallStructure.ONE_ARG);
2968 if (semantics == null) { 2986 if (semantics == null) {
2969 semantics = 2987 semantics =
2970 computeSuperAccessSemanticsForSelector( 2988 computeSuperAccessSemanticsForSelector(
2971 node, setterSelector, alternateName: name); 2989 node, setterSelector, alternateName: name);
2972 switch (semantics.kind) { 2990 switch (semantics.kind) {
2973 case AccessKind.SUPER_FINAL_FIELD: 2991 case AccessKind.SUPER_FINAL_FIELD:
2974 compiler.reportWarning( 2992 compiler.reportWarning(
2975 node, 2993 node,
2976 MessageKind.ASSIGNING_FINAL_FIELD_IN_SUPER, 2994 MessageKind.ASSIGNING_FINAL_FIELD_IN_SUPER,
2977 {'name': name, 2995 {'name': name,
2978 'superclassName': semantics.setter.enclosingClass.name}); 2996 'superclassName': semantics.setter.enclosingClass.name});
2979 registry.registerDynamicInvocation( 2997 registry.registerDynamicInvocation(
2980 new UniverseSelector(setterSelector, null)); 2998 new UniverseSelector(setterSelector, null));
2981 registry.registerSuperNoSuchMethod(); 2999 registry.registerSuperNoSuchMethod();
2982 break; 3000 break;
2983 case AccessKind.SUPER_METHOD: 3001 case AccessKind.SUPER_METHOD:
2984 compiler.reportWarning( 3002 compiler.reportWarning(
2985 node, MessageKind.ASSIGNING_METHOD_IN_SUPER, 3003 node, MessageKind.ASSIGNING_METHOD_IN_SUPER,
2986 {'name': name, 3004 {'name': name,
2987 'superclassName': semantics.setter.enclosingClass.name}); 3005 'superclassName': semantics.setter.enclosingClass.name});
2988 registry.registerDynamicInvocation( 3006 registry.registerDynamicInvocation(
2989 new UniverseSelector(setterSelector, null)); 3007 new UniverseSelector(setterSelector, null));
2990 registry.registerSuperNoSuchMethod(); 3008 registry.registerSuperNoSuchMethod();
2991 break; 3009 break;
2992 default: 3010 default:
2993 registry.registerStaticInvocation(semantics.setter); 3011 registry.registerStaticInvocation(semantics.setter);
2994 break; 3012 break;
2995 } 3013 }
3014 }
3015 return handleUpdate(node, name, semantics);
3016 } else {
3017 // `super.a += b`.
3018 if (semantics == null) {
3019 semantics = computeSuperAccessSemanticsForSelectors(
3020 node, getterSelector, setterSelector);
3021 }
3022 return handleUpdate(node, name, semantics);
3023 }
3024 }
3025 }
2996 3026
2997 // TODO(23998): Remove these when elements are only accessed 3027 /// Handle update of an entity defined by [semantics]. For instance `a = b`,
2998 // through the send structure. 3028 /// `a++` or `a += b` where [semantics] describe `a`.
2999 registry.useElement(node, semantics.setter); 3029 ResolutionResult handleUpdate(
3030 SendSet node,
3031 Name name,
3032 AccessSemantics semantics) {
3033 SendStructure sendStructure;
3034 String operatorText = node.assignmentOperator.source;
3035 Selector getterSelector =
3036 new Selector(SelectorKind.GETTER, name, CallStructure.NO_ARGS);
3037 Selector setterSelector =
3038 new Selector(SelectorKind.SETTER, name.setter, CallStructure.ONE_ARG);
3039 if (node.isPrefix || node.isPostfix) {
3040 // `e++` or `++e`.
3041 IncDecOperator operator = IncDecOperator.parse(operatorText);
3042 Selector operatorSelector =
3043 new Selector.binaryOperator(operator.selectorName);
3044
3045 // TODO(23998): Remove these when selectors are only accessed
3046 // through the send structure.
3047 registry.setGetterSelectorInComplexSendSet(node, getterSelector);
3048 registry.setSelector(node, setterSelector);
3049 registry.setOperatorSelectorInComplexSendSet(node, operatorSelector);
3050
3051 if (semantics.isAccessedStatically) {
3052 registry.registerStaticInvocation(semantics.getter);
3053 registry.registerStaticInvocation(semantics.setter);
3054 }
3055 // TODO(23998): Remove these when elements are only accessed
3056 // through the send structure.
3057 registry.useElement(node, semantics.setter);
3058 registry.useElement(node.selector, semantics.getter);
3059
3060 registry.registerDynamicInvocation(
3061 new UniverseSelector(operatorSelector, null));
3062
3063 SendStructure sendStructure = node.isPrefix
3064 ? new PrefixStructure(
3065 semantics, operator, getterSelector, setterSelector)
3066 : new PostfixStructure(
3067 semantics, operator, getterSelector, setterSelector);
3068 registry.registerSendStructure(node, sendStructure);
3069 return const NoneResult();
3070 } else {
3071 Node rhs = node.arguments.head;
3072 visitExpression(rhs);
3073
3074 AssignmentOperator operator = AssignmentOperator.parse(operatorText);
3075 if (operator.kind == AssignmentOperatorKind.ASSIGN) {
3076 // `e1 = e2`.
3077 if (semantics.isAccessedStatically) {
3078 registry.registerStaticInvocation(semantics.setter);
3000 } 3079 }
3001 3080
3081 // TODO(23998): Remove these when elements are only accessed
3082 // through the send structure.
3083 registry.useElement(node, semantics.setter);
3084
3002 // TODO(23998): Remove this when selectors are only accessed 3085 // TODO(23998): Remove this when selectors are only accessed
3003 // through the send structure. 3086 // through the send structure.
3004 registry.setSelector(node, setterSelector); 3087 registry.setSelector(node, setterSelector);
3005 3088
3006 SendStructure sendStructure = 3089 SendStructure sendStructure =
3007 new SetStructure(semantics, setterSelector); 3090 new SetStructure(semantics, setterSelector);
3008 registry.registerSendStructure(node, sendStructure); 3091 registry.registerSendStructure(node, sendStructure);
3009 return const NoneResult(); 3092 return const NoneResult();
3010 } else { 3093 } else {
3011 // `super.a += b`. 3094 // `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 = 3095 Selector operatorSelector =
3017 new Selector.binaryOperator(operator.selectorName); 3096 new Selector.binaryOperator(operator.selectorName);
3018 if (semantics == null) { 3097 if (semantics.isAccessedStatically) {
3019 semantics = computeSuperAccessSemanticsForSelectors(
3020 node, getterSelector, setterSelector);
3021
3022 registry.registerStaticInvocation(semantics.getter); 3098 registry.registerStaticInvocation(semantics.getter);
3023 registry.registerStaticInvocation(semantics.setter); 3099 registry.registerStaticInvocation(semantics.setter);
3100 }
3024 3101
3025 // TODO(23998): Remove these when elements are only accessed 3102 // TODO(23998): Remove these when elements are only accessed
3026 // through the send structure. 3103 // through the send structure.
3027 registry.useElement(node, semantics.setter); 3104 registry.useElement(node, semantics.setter);
3028 registry.useElement(node.selector, semantics.getter); 3105 registry.useElement(node.selector, semantics.getter);
3029 }
3030 3106
3031 // TODO(23998): Remove these when selectors are only accessed 3107 // TODO(23998): Remove these when selectors are only accessed
3032 // through the send structure. 3108 // through the send structure.
3033 registry.setGetterSelectorInComplexSendSet(node, getterSelector); 3109 registry.setGetterSelectorInComplexSendSet(node, getterSelector);
3034 registry.setSelector(node, setterSelector); 3110 registry.setSelector(node, setterSelector);
3035 registry.setOperatorSelectorInComplexSendSet(node, operatorSelector); 3111 registry.setOperatorSelectorInComplexSendSet(node, operatorSelector);
3036 3112
3037 registry.registerDynamicInvocation( 3113 registry.registerDynamicInvocation(
3038 new UniverseSelector(operatorSelector, null)); 3114 new UniverseSelector(operatorSelector, null));
3039 3115
3040 SendStructure sendStructure = new CompoundStructure( 3116 SendStructure sendStructure = new CompoundStructure(
3041 semantics, operator, getterSelector, setterSelector); 3117 semantics, operator, getterSelector, setterSelector);
3042 registry.registerSendStructure(node, sendStructure); 3118 registry.registerSendStructure(node, sendStructure);
3043 return const NoneResult(); 3119 return const NoneResult();
3044 } 3120 }
3045 } 3121 }
3046 } 3122 }
3047 3123
3048 ResolutionResult visitSendSet(SendSet node) { 3124 ResolutionResult visitSendSet(SendSet node) {
3049 if (node.isIndex) { 3125 if (node.isIndex) {
3050 if (node.isSuperCall) { 3126 if (node.isSuperCall) {
3051 return handleSuperIndexSendSet(node); 3127 return handleSuperIndexSendSet(node);
3052 } else { 3128 } else {
3053 return handleIndexSendSet(node); 3129 return handleIndexSendSet(node);
3054 } 3130 }
3055 } else if (node.isSuperCall) { 3131 } else if (node.isSuperCall) {
3056 return handleSuperSendSet(node); 3132 return handleSuperSendSet(node);
3133 } else if (node.receiver == null) {
3134 return handleUnqualifiedSendSet(node);
3057 } 3135 }
3058 return oldVisitSendSet(node); 3136 return oldVisitSendSet(node);
3059 } 3137 }
3060 3138
3061 ResolutionResult oldVisitSendSet(SendSet node) { 3139 ResolutionResult oldVisitSendSet(SendSet node) {
3062 bool oldSendIsMemberAccess = sendIsMemberAccess; 3140 bool oldSendIsMemberAccess = sendIsMemberAccess;
3063 sendIsMemberAccess = node.isPropertyAccess || node.isCall; 3141 sendIsMemberAccess = node.isPropertyAccess || node.isCall;
3064 ResolutionResult result = resolveSend(node); 3142 ResolutionResult result = resolveSend(node);
3065 sendIsMemberAccess = oldSendIsMemberAccess; 3143 sendIsMemberAccess = oldSendIsMemberAccess;
3066 Element target = result.element; 3144 Element target = result.element;
(...skipping 1276 matching lines...) Expand 10 before | Expand all | Expand 10 after
4343 } 4421 }
4344 return const NoneResult(); 4422 return const NoneResult();
4345 } 4423 }
4346 } 4424 }
4347 4425
4348 /// Looks up [name] in [scope] and unwraps the result. 4426 /// Looks up [name] in [scope] and unwraps the result.
4349 Element lookupInScope(Compiler compiler, Node node, 4427 Element lookupInScope(Compiler compiler, Node node,
4350 Scope scope, String name) { 4428 Scope scope, String name) {
4351 return Elements.unwrap(scope.lookup(name), compiler, node); 4429 return Elements.unwrap(scope.lookup(name), compiler, node);
4352 } 4430 }
OLDNEW
« no previous file with comments | « pkg/compiler/lib/src/resolution/access_semantics.dart ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698