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

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

Issue 1306143002: Remove SendResolver.computeSendStructure. (Closed) Base URL: https://github.com/dart-lang/sdk.git@master
Patch Set: Fix handling of invalid this access. 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
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 library dart2js.resolution.members; 5 library dart2js.resolution.members;
6 6
7 import '../common/names.dart' show 7 import '../common/names.dart' show
8 Selectors; 8 Selectors;
9 import '../compiler.dart' show 9 import '../compiler.dart' show
10 Compiler, 10 Compiler,
(...skipping 744 matching lines...) Expand 10 before | Expand all | Expand 10 after
755 return new ArgumentsResult( 755 return new ArgumentsResult(
756 new CallStructure(argumentCount, namedArguments), 756 new CallStructure(argumentCount, namedArguments),
757 argumentResults, 757 argumentResults,
758 isValidAsConstant: isValidAsConstant); 758 isValidAsConstant: isValidAsConstant);
759 } 759 }
760 760
761 /// Check that access to `super` is currently allowed. Returns an 761 /// Check that access to `super` is currently allowed. Returns an
762 /// [AccessSemantics] in case of an error, `null` otherwise. 762 /// [AccessSemantics] in case of an error, `null` otherwise.
763 AccessSemantics checkSuperAccess(Send node) { 763 AccessSemantics checkSuperAccess(Send node) {
764 if (!inInstanceContext) { 764 if (!inInstanceContext) {
765 return new StaticAccess.invalid( 765 ErroneousElement error = reportAndCreateErroneousElement(
766 reportAndCreateErroneousElement( 766 node, 'super',
767 node, 'super', 767 MessageKind.NO_SUPER_IN_STATIC, {},
768 MessageKind.NO_SUPER_IN_STATIC, {}, 768 isError: true);
769 isError: true)); 769 registry.registerCompileTimeError(error);
770 return new StaticAccess.invalid(error);
770 } 771 }
771 if (node.isConditional) { 772 if (node.isConditional) {
772 // `super?.foo` is not allowed. 773 // `super?.foo` is not allowed.
773 return new StaticAccess.invalid( 774 ErroneousElement error = reportAndCreateErroneousElement(
774 reportAndCreateErroneousElement( 775 node, 'super',
775 node, 'super', 776 MessageKind.INVALID_USE_OF_SUPER, {},
776 MessageKind.INVALID_USE_OF_SUPER, {}, 777 isError: true);
777 isError: true)); 778 registry.registerCompileTimeError(error);
779 return new StaticAccess.invalid(error);
778 } 780 }
779 if (currentClass.supertype == null) { 781 if (currentClass.supertype == null) {
780 // This is just to guard against internal errors, so no need 782 // This is just to guard against internal errors, so no need
781 // for a real error message. 783 // for a real error message.
782 return new StaticAccess.invalid( 784 ErroneousElement error = reportAndCreateErroneousElement(
783 reportAndCreateErroneousElement( 785 node, 'super',
784 node, 'super', 786 MessageKind.GENERIC,
785 MessageKind.GENERIC, 787 {'text': "Object has no superclass"},
786 {'text': "Object has no superclass"}, 788 isError: true);
787 isError: true)); 789 registry.registerCompileTimeError(error);
790 return new StaticAccess.invalid(error);
788 } 791 }
789 registry.registerSuperUse(node); 792 registry.registerSuperUse(node);
790 return null; 793 return null;
791 } 794 }
792 795
793 /// Check that access to `this` is currently allowed. 796 /// Check that access to `this` is currently allowed. Returns an
794 bool checkThisAccess(Send node) { 797 /// [AccessSemantics] in case of an error, `null` otherwise.
798 AccessSemantics checkThisAccess(Send node) {
795 if (!inInstanceContext) { 799 if (!inInstanceContext) {
796 compiler.reportError(node, MessageKind.NO_THIS_AVAILABLE); 800 ErroneousElement error = reportAndCreateErroneousElement(
797 return false; 801 node, 'this',
802 MessageKind.NO_THIS_AVAILABLE, const {},
803 isError: true);
804 registry.registerCompileTimeError(error);
805 return new StaticAccess.invalid(error);
798 } 806 }
799 return true; 807 return null;
800 } 808 }
801 809
802 /// Compute the [AccessSemantics] corresponding to a super access of [target]. 810 /// Compute the [AccessSemantics] corresponding to a super access of [target].
803 AccessSemantics computeSuperAccessSemantics(Spannable node, Element target) { 811 AccessSemantics computeSuperAccessSemantics(Spannable node, Element target) {
804 if (target.isErroneous) { 812 if (target.isErroneous) {
805 return new StaticAccess.unresolvedSuper(target); 813 return new StaticAccess.unresolvedSuper(target);
806 } else if (target.isGetter) { 814 } else if (target.isGetter) {
807 return new StaticAccess.superGetter(target); 815 return new StaticAccess.superGetter(target);
808 } else if (target.isSetter) { 816 } else if (target.isSetter) {
809 return new StaticAccess.superSetter(target); 817 return new StaticAccess.superSetter(target);
(...skipping 747 matching lines...) Expand 10 before | Expand all | Expand 10 after
1557 /// `this.name++`, or `name = b` and `name++` in instance context. 1565 /// `this.name++`, or `name = b` and `name++` in instance context.
1558 ResolutionResult handleThisPropertyUpdate( 1566 ResolutionResult handleThisPropertyUpdate(
1559 SendSet node, Name name, Element element) { 1567 SendSet node, Name name, Element element) {
1560 AccessSemantics semantics = const DynamicAccess.thisProperty(); 1568 AccessSemantics semantics = const DynamicAccess.thisProperty();
1561 return handleDynamicUpdateSemantics(node, name, element, semantics); 1569 return handleDynamicUpdateSemantics(node, name, element, semantics);
1562 } 1570 }
1563 1571
1564 /// Handle access on `this`, like `this()` and `this` when it is parsed as a 1572 /// Handle access on `this`, like `this()` and `this` when it is parsed as a
1565 /// [Send] node. 1573 /// [Send] node.
1566 ResolutionResult handleThisAccess(Send node) { 1574 ResolutionResult handleThisAccess(Send node) {
1567 AccessSemantics accessSemantics = const DynamicAccess.thisAccess();
1568 if (node.isCall) { 1575 if (node.isCall) {
1569 CallStructure callStructure = 1576 CallStructure callStructure =
1570 resolveArguments(node.argumentsNode).callStructure; 1577 resolveArguments(node.argumentsNode).callStructure;
1571 Selector selector = callStructure.callSelector; 1578 Selector selector = callStructure.callSelector;
1572 // TODO(johnniwinther): Handle invalid this access as an 1579 // TODO(johnniwinther): Handle invalid this access as an
1573 // [AccessSemantics]. 1580 // [AccessSemantics].
1574 if (checkThisAccess(node)) { 1581 AccessSemantics accessSemantics = checkThisAccess(node);
1582 if (accessSemantics == null) {
1583 accessSemantics = const DynamicAccess.thisAccess();
1575 registry.registerDynamicInvocation( 1584 registry.registerDynamicInvocation(
1576 new UniverseSelector(selector, null)); 1585 new UniverseSelector(selector, null));
1577 registry.registerSendStructure(node,
1578 new InvokeStructure(accessSemantics, selector));
1579 } 1586 }
1587 registry.registerSendStructure(node,
1588 new InvokeStructure(accessSemantics, selector));
1580 // TODO(23998): Remove this when all information goes through 1589 // TODO(23998): Remove this when all information goes through
1581 // the [SendStructure]. 1590 // the [SendStructure].
1582 registry.setSelector(node, selector); 1591 registry.setSelector(node, selector);
1592 return const NoneResult();
1583 } else { 1593 } else {
1584 // TODO(johnniwinther): Handle get of `this` when it is a [Send] node. 1594 // TODO(johnniwinther): Handle get of `this` when it is a [Send] node.
1585 internalError(node, "Unexpected node '$node'."); 1595 internalError(node, "Unexpected node '$node'.");
1586 } 1596 }
1587 return const NoneResult(); 1597 return const NoneResult();
1588 } 1598 }
1589 1599
1590 /// Handle access of a super property, like `super.foo` and `super.foo()`. 1600 /// Handle access of a super property, like `super.foo` and `super.foo()`.
1591 ResolutionResult handleSuperPropertyAccess(Send node, Name name) { 1601 ResolutionResult handleSuperPropertyAccess(Send node, Name name) {
1592 Element target; 1602 Element target;
(...skipping 338 matching lines...) Expand 10 before | Expand all | Expand 10 after
1931 Name name, 1941 Name name,
1932 TypeVariableElement element) { 1942 TypeVariableElement element) {
1933 AccessSemantics semantics; 1943 AccessSemantics semantics;
1934 if (!Elements.hasAccessToTypeVariables(enclosingElement)) { 1944 if (!Elements.hasAccessToTypeVariables(enclosingElement)) {
1935 // TODO(johnniwinther): Add another access semantics for this. 1945 // TODO(johnniwinther): Add another access semantics for this.
1936 ErroneousElement error = reportAndCreateErroneousElement( 1946 ErroneousElement error = reportAndCreateErroneousElement(
1937 node, name.text, 1947 node, name.text,
1938 MessageKind.TYPE_VARIABLE_WITHIN_STATIC_MEMBER, 1948 MessageKind.TYPE_VARIABLE_WITHIN_STATIC_MEMBER,
1939 {'typeVariableName': name}, 1949 {'typeVariableName': name},
1940 isError: true); 1950 isError: true);
1951 registry.registerCompileTimeError(error);
1941 semantics = new StaticAccess.invalid(error); 1952 semantics = new StaticAccess.invalid(error);
1942 // TODO(johnniwinther): Clean up registration of elements and selectors 1953 // TODO(johnniwinther): Clean up registration of elements and selectors
1943 // for this case. 1954 // for this case.
1944 } else { 1955 } else {
1945 semantics = new StaticAccess.typeParameterTypeLiteral(element); 1956 semantics = new StaticAccess.typeParameterTypeLiteral(element);
1946 } 1957 }
1947 registry.registerClassUsingVariableExpression(element.enclosingClass); 1958 registry.registerClassUsingVariableExpression(element.enclosingClass);
1948 registry.registerTypeVariableExpression(); 1959 registry.registerTypeVariableExpression();
1949 1960
1950 registry.useElement(node, element); 1961 registry.useElement(node, element);
(...skipping 25 matching lines...) Expand all
1976 Name name, 1987 Name name,
1977 TypeVariableElement element) { 1988 TypeVariableElement element) {
1978 AccessSemantics semantics; 1989 AccessSemantics semantics;
1979 if (!Elements.hasAccessToTypeVariables(enclosingElement)) { 1990 if (!Elements.hasAccessToTypeVariables(enclosingElement)) {
1980 // TODO(johnniwinther): Add another access semantics for this. 1991 // TODO(johnniwinther): Add another access semantics for this.
1981 ErroneousElement error = reportAndCreateErroneousElement( 1992 ErroneousElement error = reportAndCreateErroneousElement(
1982 node, name.text, 1993 node, name.text,
1983 MessageKind.TYPE_VARIABLE_WITHIN_STATIC_MEMBER, 1994 MessageKind.TYPE_VARIABLE_WITHIN_STATIC_MEMBER,
1984 {'typeVariableName': name}, 1995 {'typeVariableName': name},
1985 isError: true); 1996 isError: true);
1997 registry.registerCompileTimeError(error);
1986 semantics = new StaticAccess.invalid(error); 1998 semantics = new StaticAccess.invalid(error);
1987 } else { 1999 } else {
1988 ErroneousElement error; 2000 ErroneousElement error;
1989 if (node.isIfNullAssignment) { 2001 if (node.isIfNullAssignment) {
1990 error = reportAndCreateErroneousElement( 2002 error = reportAndCreateErroneousElement(
1991 node.selector, name.text, 2003 node.selector, name.text,
1992 MessageKind.IF_NULL_ASSIGNING_TYPE, const {}); 2004 MessageKind.IF_NULL_ASSIGNING_TYPE, const {});
1993 // TODO(23998): Remove these when all information goes through 2005 // TODO(23998): Remove these when all information goes through
1994 // the [SendStructure]. 2006 // the [SendStructure].
1995 registry.useElement(node.selector, element); 2007 registry.useElement(node.selector, element);
(...skipping 270 matching lines...) Expand 10 before | Expand all | Expand 10 after
2266 Send node, 2278 Send node,
2267 Name name, 2279 Name name,
2268 PrefixElement prefix) { 2280 PrefixElement prefix) {
2269 if ((ElementCategory.PREFIX & allowedCategory) == 0) { 2281 if ((ElementCategory.PREFIX & allowedCategory) == 0) {
2270 ErroneousElement error = reportAndCreateErroneousElement( 2282 ErroneousElement error = reportAndCreateErroneousElement(
2271 node, 2283 node,
2272 name.text, 2284 name.text,
2273 MessageKind.PREFIX_AS_EXPRESSION, 2285 MessageKind.PREFIX_AS_EXPRESSION,
2274 {'prefix': name}, 2286 {'prefix': name},
2275 isError: true); 2287 isError: true);
2288 registry.registerCompileTimeError(error);
2276 return handleErroneousAccess( 2289 return handleErroneousAccess(
2277 node, name, new StaticAccess.invalid(error)); 2290 node, name, new StaticAccess.invalid(error));
2278 } 2291 }
2279 if (prefix.isDeferred) { 2292 if (prefix.isDeferred) {
2280 // TODO(23998): Remove this when deferred access is detected 2293 // TODO(23998): Remove this when deferred access is detected
2281 // through a [SendStructure]. 2294 // through a [SendStructure].
2282 registry.useElement(node.selector, prefix); 2295 registry.useElement(node.selector, prefix);
2283 } 2296 }
2284 registry.useElement(node, prefix); 2297 registry.useElement(node, prefix);
2285 return new PrefixResult(prefix, null); 2298 return new PrefixResult(prefix, null);
(...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after
2387 return handleUpdate(node, name, semantics); 2400 return handleUpdate(node, name, semantics);
2388 } 2401 }
2389 2402
2390 /// Handle `this` as a qualified property, like `a.this`. 2403 /// Handle `this` as a qualified property, like `a.this`.
2391 ResolutionResult handleQualifiedThisAccess(Send node, Name name) { 2404 ResolutionResult handleQualifiedThisAccess(Send node, Name name) {
2392 ErroneousElement error = reportAndCreateErroneousElement( 2405 ErroneousElement error = reportAndCreateErroneousElement(
2393 node.selector, 2406 node.selector,
2394 name.text, 2407 name.text,
2395 MessageKind.THIS_PROPERTY, {}, 2408 MessageKind.THIS_PROPERTY, {},
2396 isError: true); 2409 isError: true);
2410 registry.registerCompileTimeError(error);
2397 AccessSemantics accessSemantics = new StaticAccess.invalid(error); 2411 AccessSemantics accessSemantics = new StaticAccess.invalid(error);
2398 return handleErroneousAccess(node, name, accessSemantics); 2412 return handleErroneousAccess(node, name, accessSemantics);
2399 } 2413 }
2400 2414
2401 /// Handle a qualified [Send], that is where the receiver is non-null, like 2415 /// Handle a qualified [Send], that is where the receiver is non-null, like
2402 /// `a.b`, `a.b()`, `this.a()` and `super.a()`. 2416 /// `a.b`, `a.b()`, `this.a()` and `super.a()`.
2403 ResolutionResult handleQualifiedSend(Send node) { 2417 ResolutionResult handleQualifiedSend(Send node) {
2404 Identifier selector = node.selector.asIdentifier(); 2418 Identifier selector = node.selector.asIdentifier();
2405 String text = selector.source; 2419 String text = selector.source;
2406 Name name = new Name(text, enclosingElement.library); 2420 Name name = new Name(text, enclosingElement.library);
2407 if (text == 'this') { 2421 if (text == 'this') {
2408 return handleQualifiedThisAccess(node, name); 2422 return handleQualifiedThisAccess(node, name);
2409 } else if (node.isSuperCall) { 2423 } else if (node.isSuperCall) {
2410 return handleSuperPropertyAccess(node, name); 2424 return handleSuperPropertyAccess(node, name);
2411 } else if (node.receiver.isThis()) { 2425 } else if (node.receiver.isThis()) {
2412 if (checkThisAccess(node)) { 2426 AccessSemantics semantics = checkThisAccess(node);
2427 if (semantics == null) {
2413 return handleThisPropertyAccess(node, name); 2428 return handleThisPropertyAccess(node, name);
2429 } else {
2430 // TODO(johnniwinther): Handle invalid this access as an
2431 // [AccessSemantics].
2432 return handleErroneousAccess(node, name, semantics);
2414 } 2433 }
2415 // TODO(johnniwinther): Handle invalid this access as an
2416 // [AccessSemantics].
2417 return const NoneResult();
2418 } 2434 }
2419 ResolutionResult result = visitExpressionPrefix(node.receiver); 2435 ResolutionResult result = visitExpressionPrefix(node.receiver);
2420 if (result.kind == ResultKind.PREFIX) { 2436 if (result.kind == ResultKind.PREFIX) {
2421 return handlePrefixSend(node, name, result); 2437 return handlePrefixSend(node, name, result);
2422 } else if (node.isConditional) { 2438 } else if (node.isConditional) {
2423 return handleDynamicAccessSemantics( 2439 return handleDynamicAccessSemantics(
2424 node, name, const DynamicAccess.ifNotNullProperty()); 2440 node, name, const DynamicAccess.ifNotNullProperty());
2425 } else { 2441 } else {
2426 // Handle dynamic property access, like `a.b` or `a.b()` where `a` is not 2442 // Handle dynamic property access, like `a.b` or `a.b()` where `a` is not
2427 // a prefix or class. 2443 // a prefix or class.
2428 // TODO(johnniwinther): Use the `element` of [result]. 2444 // TODO(johnniwinther): Use the `element` of [result].
2429 return handleDynamicAccessSemantics( 2445 return handleDynamicAccessSemantics(
2430 node, name, const DynamicAccess.dynamicProperty()); 2446 node, name, const DynamicAccess.dynamicProperty());
2431 } 2447 }
2432 } 2448 }
2433 2449
2434 /// Handle a qualified [SendSet], that is where the receiver is non-null, like 2450 /// Handle a qualified [SendSet], that is where the receiver is non-null, like
2435 /// `a.b = c`, `a.b++`, and `a.b += c`. 2451 /// `a.b = c`, `a.b++`, and `a.b += c`.
2436 ResolutionResult handleQualifiedSendSet(SendSet node) { 2452 ResolutionResult handleQualifiedSendSet(SendSet node) {
2437 Identifier selector = node.selector.asIdentifier(); 2453 Identifier selector = node.selector.asIdentifier();
2438 String text = selector.source; 2454 String text = selector.source;
2439 Name name = new Name(text, enclosingElement.library); 2455 Name name = new Name(text, enclosingElement.library);
2440 if (text == 'this') { 2456 if (text == 'this') {
2441 return handleQualifiedThisAccess(node, name); 2457 return handleQualifiedThisAccess(node, name);
2442 } else if (node.receiver.isThis()) { 2458 } else if (node.receiver.isThis()) {
2443 if (checkThisAccess(node)) { 2459 AccessSemantics semantics = checkThisAccess(node);
2460 if (semantics == null) {
2444 return handleThisPropertyUpdate(node, name, null); 2461 return handleThisPropertyUpdate(node, name, null);
2462 } else {
2463 // TODO(johnniwinther): Handle invalid this access as an
2464 // [AccessSemantics].
2465 return handleUpdate(node, name, semantics);
2445 } 2466 }
2446 // TODO(johnniwinther): Handle invalid this access as an
2447 // [AccessSemantics].
2448 return const NoneResult();
2449 } 2467 }
2450 ResolutionResult result = visitExpressionPrefix(node.receiver); 2468 ResolutionResult result = visitExpressionPrefix(node.receiver);
2451 if (result.kind == ResultKind.PREFIX) { 2469 if (result.kind == ResultKind.PREFIX) {
2452 return handlePrefixSendSet(node, name, result); 2470 return handlePrefixSendSet(node, name, result);
2453 } else if (node.isConditional) { 2471 } else if (node.isConditional) {
2454 return handleDynamicUpdateSemantics( 2472 return handleDynamicUpdateSemantics(
2455 node, name, null, const DynamicAccess.ifNotNullProperty()); 2473 node, name, null, const DynamicAccess.ifNotNullProperty());
2456 } else { 2474 } else {
2457 // Handle dynamic property access, like `a.b = c`, `a.b++` or `a.b += c` 2475 // Handle dynamic property access, like `a.b = c`, `a.b++` or `a.b += c`
2458 // where `a` is not a prefix or class. 2476 // where `a` is not a prefix or class.
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after
2538 } 2556 }
2539 2557
2540 /// Report access of an instance [member] from a non-instance context. 2558 /// Report access of an instance [member] from a non-instance context.
2541 AccessSemantics reportStaticInstanceAccess(Send node, Name name) { 2559 AccessSemantics reportStaticInstanceAccess(Send node, Name name) {
2542 ErroneousElement error = reportAndCreateErroneousElement( 2560 ErroneousElement error = reportAndCreateErroneousElement(
2543 node, name.text, 2561 node, name.text,
2544 MessageKind.NO_INSTANCE_AVAILABLE, {'name': name}, 2562 MessageKind.NO_INSTANCE_AVAILABLE, {'name': name},
2545 isError: true); 2563 isError: true);
2546 // TODO(johnniwinther): Support static instance access as an 2564 // TODO(johnniwinther): Support static instance access as an
2547 // [AccessSemantics]. 2565 // [AccessSemantics].
2566 registry.registerCompileTimeError(error);
2548 return new StaticAccess.invalid(error); 2567 return new StaticAccess.invalid(error);
2549 } 2568 }
2550 2569
2551 /// Handle access of a parameter, local variable or local function. 2570 /// Handle access of a parameter, local variable or local function.
2552 ResolutionResult handleLocalAccess(Send node, Name name, Element element) { 2571 ResolutionResult handleLocalAccess(Send node, Name name, Element element) {
2553 ResolutionResult result = const NoneResult(); 2572 ResolutionResult result = const NoneResult();
2554 AccessSemantics semantics = computeLocalAccessSemantics(node, element); 2573 AccessSemantics semantics = computeLocalAccessSemantics(node, element);
2555 Selector selector; 2574 Selector selector;
2556 if (node.isCall) { 2575 if (node.isCall) {
2557 CallStructure callStructure = 2576 CallStructure callStructure =
(...skipping 2093 matching lines...) Expand 10 before | Expand all | Expand 10 after
4651 } 4670 }
4652 return const NoneResult(); 4671 return const NoneResult();
4653 } 4672 }
4654 } 4673 }
4655 4674
4656 /// Looks up [name] in [scope] and unwraps the result. 4675 /// Looks up [name] in [scope] and unwraps the result.
4657 Element lookupInScope(Compiler compiler, Node node, 4676 Element lookupInScope(Compiler compiler, Node node,
4658 Scope scope, String name) { 4677 Scope scope, String name) {
4659 return Elements.unwrap(scope.lookup(name), compiler, node); 4678 return Elements.unwrap(scope.lookup(name), compiler, node);
4660 } 4679 }
OLDNEW
« no previous file with comments | « pkg/compiler/lib/src/js_backend/backend.dart ('k') | pkg/compiler/lib/src/resolution/registry.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698