| OLD | NEW |
| 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
| 3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 | 4 |
| 5 library dart2js.resolution.members; | 5 library dart2js.resolution.members; |
| 6 | 6 |
| 7 import 'package:front_end/src/fasta/scanner.dart' show isUserDefinableOperator; | 7 import 'package:front_end/src/fasta/scanner.dart' show isUserDefinableOperator; |
| 8 | 8 |
| 9 import '../common.dart'; | 9 import '../common.dart'; |
| 10 import '../common/names.dart' show Selectors; | 10 import '../common/names.dart' show Selectors; |
| (...skipping 239 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 250 } | 250 } |
| 251 var result = action(); | 251 var result = action(); |
| 252 constantState = oldConstantState; | 252 constantState = oldConstantState; |
| 253 return result; | 253 return result; |
| 254 } | 254 } |
| 255 | 255 |
| 256 /// Visit [node] where the constant state is `ConstantState.CONSTANT` if | 256 /// Visit [node] where the constant state is `ConstantState.CONSTANT` if |
| 257 /// not already `ConstantState.CONSTANT_INITIALIZER`. | 257 /// not already `ConstantState.CONSTANT_INITIALIZER`. |
| 258 ResolutionResult visitInConstantContext(Node node) { | 258 ResolutionResult visitInConstantContext(Node node) { |
| 259 ResolutionResult result = inConstantContext(() => visit(node)); | 259 ResolutionResult result = inConstantContext(() => visit(node)); |
| 260 assert(invariant(node, result != null, | 260 assert(result != null, failedAt(node, "No resolution result for $node.")); |
| 261 message: "No resolution result for $node.")); | |
| 262 | 261 |
| 263 return result; | 262 return result; |
| 264 } | 263 } |
| 265 | 264 |
| 266 ErroneousElement reportAndCreateErroneousElement( | 265 ErroneousElement reportAndCreateErroneousElement( |
| 267 Node node, String name, MessageKind kind, Map arguments, | 266 Node node, String name, MessageKind kind, Map arguments, |
| 268 {List<DiagnosticMessage> infos: const <DiagnosticMessage>[], | 267 {List<DiagnosticMessage> infos: const <DiagnosticMessage>[], |
| 269 bool isError: false}) { | 268 bool isError: false}) { |
| 270 if (isError) { | 269 if (isError) { |
| 271 reporter.reportError( | 270 reporter.reportError( |
| 272 reporter.createMessage(node, kind, arguments), infos); | 271 reporter.createMessage(node, kind, arguments), infos); |
| 273 } else { | 272 } else { |
| 274 reporter.reportWarning( | 273 reporter.reportWarning( |
| 275 reporter.createMessage(node, kind, arguments), infos); | 274 reporter.createMessage(node, kind, arguments), infos); |
| 276 } | 275 } |
| 277 // TODO(ahe): Use [allowedCategory] to synthesize a more precise subclass | 276 // TODO(ahe): Use [allowedCategory] to synthesize a more precise subclass |
| 278 // of [ErroneousElementX]. For example, [ErroneousFieldElementX], | 277 // of [ErroneousElementX]. For example, [ErroneousFieldElementX], |
| 279 // [ErroneousConstructorElementX], etc. | 278 // [ErroneousConstructorElementX], etc. |
| 280 return new ErroneousElementX(kind, arguments, name, enclosingElement); | 279 return new ErroneousElementX(kind, arguments, name, enclosingElement); |
| 281 } | 280 } |
| 282 | 281 |
| 283 /// Report a warning or error on an unresolved access in non-instance context. | 282 /// Report a warning or error on an unresolved access in non-instance context. |
| 284 /// | 283 /// |
| 285 /// The [ErroneousElement] corresponding to the message is returned. | 284 /// The [ErroneousElement] corresponding to the message is returned. |
| 286 ErroneousElement reportCannotResolve(Node node, String name) { | 285 ErroneousElement reportCannotResolve(Node node, String name) { |
| 287 assert(invariant(node, !inInstanceContext, | 286 assert( |
| 288 message: "ResolverVisitor.reportCannotResolve must not be called in " | 287 !inInstanceContext, |
| 288 failedAt( |
| 289 node, |
| 290 "ResolverVisitor.reportCannotResolve must not be called in " |
| 289 "instance context.")); | 291 "instance context.")); |
| 290 | 292 |
| 291 // We report an error within initializers because `this` is implicitly | 293 // We report an error within initializers because `this` is implicitly |
| 292 // accessed when unqualified identifiers are not resolved. For | 294 // accessed when unqualified identifiers are not resolved. For |
| 293 // details, see section 16.14.3 of the spec (2nd edition): | 295 // details, see section 16.14.3 of the spec (2nd edition): |
| 294 // An unqualified invocation `i` of the form `id(a1, ...)` | 296 // An unqualified invocation `i` of the form `id(a1, ...)` |
| 295 // ... | 297 // ... |
| 296 // If `i` does not occur inside a top level or static function, `i` | 298 // If `i` does not occur inside a top level or static function, `i` |
| 297 // is equivalent to `this.id(a1 , ...)`. | 299 // is equivalent to `this.id(a1 , ...)`. |
| 298 bool inInitializer = enclosingElement.isGenerativeConstructor || | 300 bool inInitializer = enclosingElement.isGenerativeConstructor || |
| (...skipping 480 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 779 return new StaticAccess.superGetter(target); | 781 return new StaticAccess.superGetter(target); |
| 780 } else if (target.isSetter) { | 782 } else if (target.isSetter) { |
| 781 return new StaticAccess.superSetter(target); | 783 return new StaticAccess.superSetter(target); |
| 782 } else if (target.isField) { | 784 } else if (target.isField) { |
| 783 if (target.isFinal) { | 785 if (target.isFinal) { |
| 784 return new StaticAccess.superFinalField(target); | 786 return new StaticAccess.superFinalField(target); |
| 785 } else { | 787 } else { |
| 786 return new StaticAccess.superField(target); | 788 return new StaticAccess.superField(target); |
| 787 } | 789 } |
| 788 } else { | 790 } else { |
| 789 assert(invariant(node, target.isFunction, | 791 assert(target.isFunction, |
| 790 message: "Unexpected super target '$target'.")); | 792 failedAt(node, "Unexpected super target '$target'.")); |
| 791 return new StaticAccess.superMethod(target); | 793 return new StaticAccess.superMethod(target); |
| 792 } | 794 } |
| 793 } | 795 } |
| 794 | 796 |
| 795 /// Compute the [AccessSemantics] corresponding to a compound super access | 797 /// Compute the [AccessSemantics] corresponding to a compound super access |
| 796 /// reading from [getter] and writing to [setter]. | 798 /// reading from [getter] and writing to [setter]. |
| 797 AccessSemantics computeCompoundSuperAccessSemantics( | 799 AccessSemantics computeCompoundSuperAccessSemantics( |
| 798 Spannable node, Element getter, Element setter, | 800 Spannable node, Element getter, Element setter, |
| 799 {bool isIndex: false}) { | 801 {bool isIndex: false}) { |
| 800 if (getter.isMalformed) { | 802 if (getter.isMalformed) { |
| 801 if (setter.isMalformed) { | 803 if (setter.isMalformed) { |
| 802 return new StaticAccess.unresolvedSuper(getter); | 804 return new StaticAccess.unresolvedSuper(getter); |
| 803 } else if (setter.isFunction) { | 805 } else if (setter.isFunction) { |
| 804 assert(invariant(node, setter.name == '[]=', | 806 assert(setter.name == '[]=', |
| 805 message: "Unexpected super setter '$setter'.")); | 807 failedAt(node, "Unexpected super setter '$setter'.")); |
| 806 return new CompoundAccessSemantics( | 808 return new CompoundAccessSemantics( |
| 807 CompoundAccessKind.UNRESOLVED_SUPER_GETTER, getter, setter); | 809 CompoundAccessKind.UNRESOLVED_SUPER_GETTER, getter, setter); |
| 808 } else { | 810 } else { |
| 809 assert(invariant(node, setter.isSetter, | 811 assert(setter.isSetter, |
| 810 message: "Unexpected super setter '$setter'.")); | 812 failedAt(node, "Unexpected super setter '$setter'.")); |
| 811 return new CompoundAccessSemantics( | 813 return new CompoundAccessSemantics( |
| 812 CompoundAccessKind.UNRESOLVED_SUPER_GETTER, getter, setter); | 814 CompoundAccessKind.UNRESOLVED_SUPER_GETTER, getter, setter); |
| 813 } | 815 } |
| 814 } else if (getter.isField) { | 816 } else if (getter.isField) { |
| 815 if (setter.isMalformed) { | 817 if (setter.isMalformed) { |
| 816 assert(invariant(node, getter.isFinal, | 818 assert( |
| 817 message: "Unexpected super setter '$setter' for getter '$getter.")); | 819 getter.isFinal, |
| 820 failedAt(node, |
| 821 "Unexpected super setter '$setter' for getter '$getter.")); |
| 818 return new StaticAccess.superFinalField(getter); | 822 return new StaticAccess.superFinalField(getter); |
| 819 } else if (setter.isField) { | 823 } else if (setter.isField) { |
| 820 if (getter == setter) { | 824 if (getter == setter) { |
| 821 return new StaticAccess.superField(getter); | 825 return new StaticAccess.superField(getter); |
| 822 } else { | 826 } else { |
| 823 return new CompoundAccessSemantics( | 827 return new CompoundAccessSemantics( |
| 824 CompoundAccessKind.SUPER_FIELD_FIELD, getter, setter); | 828 CompoundAccessKind.SUPER_FIELD_FIELD, getter, setter); |
| 825 } | 829 } |
| 826 } else { | 830 } else { |
| 827 // Either the field is accessible directly, or a setter shadows the | 831 // Either the field is accessible directly, or a setter shadows the |
| 828 // setter access. If there was another instance member it would shadow | 832 // setter access. If there was another instance member it would shadow |
| 829 // the field. | 833 // the field. |
| 830 assert(invariant(node, setter.isSetter, | 834 assert(setter.isSetter, |
| 831 message: "Unexpected super setter '$setter'.")); | 835 failedAt(node, "Unexpected super setter '$setter'.")); |
| 832 return new CompoundAccessSemantics( | 836 return new CompoundAccessSemantics( |
| 833 CompoundAccessKind.SUPER_FIELD_SETTER, getter, setter); | 837 CompoundAccessKind.SUPER_FIELD_SETTER, getter, setter); |
| 834 } | 838 } |
| 835 } else if (getter.isGetter) { | 839 } else if (getter.isGetter) { |
| 836 if (setter.isMalformed) { | 840 if (setter.isMalformed) { |
| 837 return new CompoundAccessSemantics( | 841 return new CompoundAccessSemantics( |
| 838 CompoundAccessKind.UNRESOLVED_SUPER_SETTER, getter, setter); | 842 CompoundAccessKind.UNRESOLVED_SUPER_SETTER, getter, setter); |
| 839 } else if (setter.isField) { | 843 } else if (setter.isField) { |
| 840 return new CompoundAccessSemantics( | 844 return new CompoundAccessSemantics( |
| 841 CompoundAccessKind.SUPER_GETTER_FIELD, getter, setter); | 845 CompoundAccessKind.SUPER_GETTER_FIELD, getter, setter); |
| 842 } else { | 846 } else { |
| 843 assert(invariant(node, setter.isSetter, | 847 assert(setter.isSetter, |
| 844 message: "Unexpected super setter '$setter'.")); | 848 failedAt(node, "Unexpected super setter '$setter'.")); |
| 845 return new CompoundAccessSemantics( | 849 return new CompoundAccessSemantics( |
| 846 CompoundAccessKind.SUPER_GETTER_SETTER, getter, setter); | 850 CompoundAccessKind.SUPER_GETTER_SETTER, getter, setter); |
| 847 } | 851 } |
| 848 } else { | 852 } else { |
| 849 assert(invariant(node, getter.isFunction, | 853 assert(getter.isFunction, |
| 850 message: "Unexpected super getter '$getter'.")); | 854 failedAt(node, "Unexpected super getter '$getter'.")); |
| 851 if (setter.isMalformed) { | 855 if (setter.isMalformed) { |
| 852 if (isIndex) { | 856 if (isIndex) { |
| 853 return new CompoundAccessSemantics( | 857 return new CompoundAccessSemantics( |
| 854 CompoundAccessKind.UNRESOLVED_SUPER_SETTER, getter, setter); | 858 CompoundAccessKind.UNRESOLVED_SUPER_SETTER, getter, setter); |
| 855 } else { | 859 } else { |
| 856 return new StaticAccess.superMethod(getter); | 860 return new StaticAccess.superMethod(getter); |
| 857 } | 861 } |
| 858 } else if (setter.isFunction) { | 862 } else if (setter.isFunction) { |
| 859 assert(invariant(node, setter.name == '[]=', | 863 assert(setter.name == '[]=', |
| 860 message: "Unexpected super setter '$setter'.")); | 864 failedAt(node, "Unexpected super setter '$setter'.")); |
| 861 assert(invariant(node, getter.name == '[]', | 865 assert(getter.name == '[]', |
| 862 message: "Unexpected super getter '$getter'.")); | 866 failedAt(node, "Unexpected super getter '$getter'.")); |
| 863 return new CompoundAccessSemantics( | 867 return new CompoundAccessSemantics( |
| 864 CompoundAccessKind.SUPER_GETTER_SETTER, getter, setter); | 868 CompoundAccessKind.SUPER_GETTER_SETTER, getter, setter); |
| 865 } else { | 869 } else { |
| 866 assert(invariant(node, setter.isSetter, | 870 assert(setter.isSetter, |
| 867 message: "Unexpected super setter '$setter'.")); | 871 failedAt(node, "Unexpected super setter '$setter'.")); |
| 868 return new CompoundAccessSemantics( | 872 return new CompoundAccessSemantics( |
| 869 CompoundAccessKind.SUPER_METHOD_SETTER, getter, setter); | 873 CompoundAccessKind.SUPER_METHOD_SETTER, getter, setter); |
| 870 } | 874 } |
| 871 } | 875 } |
| 872 } | 876 } |
| 873 | 877 |
| 874 /// Compute the [AccessSemantics] corresponding to a local access of [target]. | 878 /// Compute the [AccessSemantics] corresponding to a local access of [target]. |
| 875 AccessSemantics computeLocalAccessSemantics( | 879 AccessSemantics computeLocalAccessSemantics( |
| 876 Spannable node, LocalElement target) { | 880 Spannable node, LocalElement target) { |
| 877 if (target.isRegularParameter) { | 881 if (target.isRegularParameter) { |
| 878 if (target.isFinal || target.isConst) { | 882 if (target.isFinal || target.isConst) { |
| 879 return new StaticAccess.finalParameter(target); | 883 return new StaticAccess.finalParameter(target); |
| 880 } else { | 884 } else { |
| 881 return new StaticAccess.parameter(target); | 885 return new StaticAccess.parameter(target); |
| 882 } | 886 } |
| 883 } else if (target.isInitializingFormal) { | 887 } else if (target.isInitializingFormal) { |
| 884 return new StaticAccess.finalParameter(target); | 888 return new StaticAccess.finalParameter(target); |
| 885 } else if (target.isVariable) { | 889 } else if (target.isVariable) { |
| 886 if (target.isFinal || target.isConst) { | 890 if (target.isFinal || target.isConst) { |
| 887 return new StaticAccess.finalLocalVariable(target); | 891 return new StaticAccess.finalLocalVariable(target); |
| 888 } else { | 892 } else { |
| 889 return new StaticAccess.localVariable(target); | 893 return new StaticAccess.localVariable(target); |
| 890 } | 894 } |
| 891 } else { | 895 } else { |
| 892 assert(invariant(node, target.isFunction, | 896 assert(target.isFunction, |
| 893 message: "Unexpected local target '$target'.")); | 897 failedAt(node, "Unexpected local target '$target'.")); |
| 894 return new StaticAccess.localFunction(target); | 898 return new StaticAccess.localFunction(target); |
| 895 } | 899 } |
| 896 } | 900 } |
| 897 | 901 |
| 898 /// Compute the [AccessSemantics] corresponding to a static or toplevel access | 902 /// Compute the [AccessSemantics] corresponding to a static or toplevel access |
| 899 /// of [target]. | 903 /// of [target]. |
| 900 AccessSemantics computeStaticOrTopLevelAccessSemantics( | 904 AccessSemantics computeStaticOrTopLevelAccessSemantics( |
| 901 Spannable node, Element target) { | 905 Spannable node, Element target) { |
| 902 target = target.declaration; | 906 target = target.declaration; |
| 903 if (target.isMalformed) { | 907 if (target.isMalformed) { |
| 904 // This handles elements with parser errors. | 908 // This handles elements with parser errors. |
| 905 return new StaticAccess.unresolved(target); | 909 return new StaticAccess.unresolved(target); |
| 906 } | 910 } |
| 907 if (target.isStatic) { | 911 if (target.isStatic) { |
| 908 if (target.isGetter) { | 912 if (target.isGetter) { |
| 909 return new StaticAccess.staticGetter(target); | 913 return new StaticAccess.staticGetter(target); |
| 910 } else if (target.isSetter) { | 914 } else if (target.isSetter) { |
| 911 return new StaticAccess.staticSetter(target); | 915 return new StaticAccess.staticSetter(target); |
| 912 } else if (target.isField) { | 916 } else if (target.isField) { |
| 913 if (target.isFinal || target.isConst) { | 917 if (target.isFinal || target.isConst) { |
| 914 return new StaticAccess.finalStaticField(target); | 918 return new StaticAccess.finalStaticField(target); |
| 915 } else { | 919 } else { |
| 916 return new StaticAccess.staticField(target); | 920 return new StaticAccess.staticField(target); |
| 917 } | 921 } |
| 918 } else { | 922 } else { |
| 919 assert(invariant(node, target.isFunction, | 923 assert(target.isFunction, |
| 920 message: "Unexpected static target '$target'.")); | 924 failedAt(node, "Unexpected static target '$target'.")); |
| 921 return new StaticAccess.staticMethod(target); | 925 return new StaticAccess.staticMethod(target); |
| 922 } | 926 } |
| 923 } else { | 927 } else { |
| 924 assert(invariant(node, target.isTopLevel, | 928 assert(target.isTopLevel, |
| 925 message: "Unexpected statically resolved target '$target'.")); | 929 failedAt(node, "Unexpected statically resolved target '$target'.")); |
| 926 if (target.isGetter) { | 930 if (target.isGetter) { |
| 927 return new StaticAccess.topLevelGetter(target); | 931 return new StaticAccess.topLevelGetter(target); |
| 928 } else if (target.isSetter) { | 932 } else if (target.isSetter) { |
| 929 return new StaticAccess.topLevelSetter(target); | 933 return new StaticAccess.topLevelSetter(target); |
| 930 } else if (target.isField) { | 934 } else if (target.isField) { |
| 931 if (target.isFinal) { | 935 if (target.isFinal) { |
| 932 return new StaticAccess.finalTopLevelField(target); | 936 return new StaticAccess.finalTopLevelField(target); |
| 933 } else { | 937 } else { |
| 934 return new StaticAccess.topLevelField(target); | 938 return new StaticAccess.topLevelField(target); |
| 935 } | 939 } |
| 936 } else { | 940 } else { |
| 937 assert(invariant(node, target.isFunction, | 941 assert(target.isFunction, |
| 938 message: "Unexpected top level target '$target'.")); | 942 failedAt(node, "Unexpected top level target '$target'.")); |
| 939 return new StaticAccess.topLevelMethod(target); | 943 return new StaticAccess.topLevelMethod(target); |
| 940 } | 944 } |
| 941 } | 945 } |
| 942 } | 946 } |
| 943 | 947 |
| 944 /// Compute the [AccessSemantics] for accessing the name of [selector] on the | 948 /// Compute the [AccessSemantics] for accessing the name of [selector] on the |
| 945 /// super class. | 949 /// super class. |
| 946 /// | 950 /// |
| 947 /// If no matching super member is found and error is reported and | 951 /// If no matching super member is found and error is reported and |
| 948 /// `noSuchMethod` on `super` is registered. Furthermore, if [alternateName] | 952 /// `noSuchMethod` on `super` is registered. Furthermore, if [alternateName] |
| (...skipping 276 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1225 } | 1229 } |
| 1226 if (semantics != null) { | 1230 if (semantics != null) { |
| 1227 registry.registerSendStructure( | 1231 registry.registerSendStructure( |
| 1228 node, new UnaryStructure(semantics, operator)); | 1232 node, new UnaryStructure(semantics, operator)); |
| 1229 } | 1233 } |
| 1230 return result; | 1234 return result; |
| 1231 } | 1235 } |
| 1232 | 1236 |
| 1233 /// Handle a not expression, like `!a`. | 1237 /// Handle a not expression, like `!a`. |
| 1234 ResolutionResult handleNot(Send node, UnaryOperator operator) { | 1238 ResolutionResult handleNot(Send node, UnaryOperator operator) { |
| 1235 assert(invariant(node, operator.kind == UnaryOperatorKind.NOT)); | 1239 assert(operator.kind == UnaryOperatorKind.NOT, failedAt(node)); |
| 1236 | 1240 |
| 1237 Node expression = node.receiver; | 1241 Node expression = node.receiver; |
| 1238 ResolutionResult result = visitExpression(expression); | 1242 ResolutionResult result = visitExpression(expression); |
| 1239 registry.registerSendStructure(node, const NotStructure()); | 1243 registry.registerSendStructure(node, const NotStructure()); |
| 1240 | 1244 |
| 1241 if (result.isConstant) { | 1245 if (result.isConstant) { |
| 1242 ConstantExpression expressionConstant = result.constant; | 1246 ConstantExpression expressionConstant = result.constant; |
| 1243 if (expressionConstant.getKnownType(commonElements) == | 1247 if (expressionConstant.getKnownType(commonElements) == |
| 1244 commonElements.boolType) { | 1248 commonElements.boolType) { |
| 1245 // TODO(johnniwinther): Handle potentially invalid constant expressions. | 1249 // TODO(johnniwinther): Handle potentially invalid constant expressions. |
| (...skipping 238 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1484 node, "Unexpected binary operator '${operator}'."); | 1488 node, "Unexpected binary operator '${operator}'."); |
| 1485 break; | 1489 break; |
| 1486 } | 1490 } |
| 1487 registry.registerSendStructure(node, sendStructure); | 1491 registry.registerSendStructure(node, sendStructure); |
| 1488 } | 1492 } |
| 1489 return result; | 1493 return result; |
| 1490 } | 1494 } |
| 1491 | 1495 |
| 1492 /// Handle an invocation of an expression, like `(){}()` or `(foo)()`. | 1496 /// Handle an invocation of an expression, like `(){}()` or `(foo)()`. |
| 1493 ResolutionResult handleExpressionInvoke(Send node) { | 1497 ResolutionResult handleExpressionInvoke(Send node) { |
| 1494 assert( | 1498 assert(node.isCall, failedAt(node, "Unexpected expression: $node")); |
| 1495 invariant(node, node.isCall, message: "Unexpected expression: $node")); | |
| 1496 Node expression = node.selector; | 1499 Node expression = node.selector; |
| 1497 visitExpression(expression); | 1500 visitExpression(expression); |
| 1498 CallStructure callStructure = | 1501 CallStructure callStructure = |
| 1499 resolveArguments(node.argumentsNode).callStructure; | 1502 resolveArguments(node.argumentsNode).callStructure; |
| 1500 Selector selector = callStructure.callSelector; | 1503 Selector selector = callStructure.callSelector; |
| 1501 // TODO(23998): Remove this when all information goes through the | 1504 // TODO(23998): Remove this when all information goes through the |
| 1502 // [SendStructure]. | 1505 // [SendStructure]. |
| 1503 registry.setSelector(node, selector); | 1506 registry.setSelector(node, selector); |
| 1504 registry.registerDynamicUse(new DynamicUse(selector, null)); | 1507 registry.registerDynamicUse(new DynamicUse(selector, null)); |
| 1505 registry.registerSendStructure( | 1508 registry.registerSendStructure( |
| (...skipping 149 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1655 } else if (node.arguments.isEmpty) { | 1658 } else if (node.arguments.isEmpty) { |
| 1656 UnaryOperator operator = UnaryOperator.parse(operatorText); | 1659 UnaryOperator operator = UnaryOperator.parse(operatorText); |
| 1657 if (operator == null) { | 1660 if (operator == null) { |
| 1658 return handleUnresolvedUnary(node, operatorText); | 1661 return handleUnresolvedUnary(node, operatorText); |
| 1659 } else { | 1662 } else { |
| 1660 switch (operator.kind) { | 1663 switch (operator.kind) { |
| 1661 case UnaryOperatorKind.NOT: | 1664 case UnaryOperatorKind.NOT: |
| 1662 return handleNot(node, operator); | 1665 return handleNot(node, operator); |
| 1663 case UnaryOperatorKind.COMPLEMENT: | 1666 case UnaryOperatorKind.COMPLEMENT: |
| 1664 case UnaryOperatorKind.NEGATE: | 1667 case UnaryOperatorKind.NEGATE: |
| 1665 assert(invariant(node, operator.isUserDefinable, | 1668 assert(operator.isUserDefinable, |
| 1666 message: "Unexpected unary operator '${operator}'.")); | 1669 failedAt(node, "Unexpected unary operator '${operator}'.")); |
| 1667 return handleUserDefinableUnary(node, operator); | 1670 return handleUserDefinableUnary(node, operator); |
| 1668 } | 1671 } |
| 1669 } | 1672 } |
| 1670 } else { | 1673 } else { |
| 1671 BinaryOperator operator = BinaryOperator.parse(operatorText); | 1674 BinaryOperator operator = BinaryOperator.parse(operatorText); |
| 1672 if (operator == null) { | 1675 if (operator == null) { |
| 1673 return handleUnresolvedBinary(node, operatorText); | 1676 return handleUnresolvedBinary(node, operatorText); |
| 1674 } else { | 1677 } else { |
| 1675 switch (operator.kind) { | 1678 switch (operator.kind) { |
| 1676 case BinaryOperatorKind.LOGICAL_AND: | 1679 case BinaryOperatorKind.LOGICAL_AND: |
| (...skipping 462 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2139 return new PrefixResult(null, cls); | 2142 return new PrefixResult(null, cls); |
| 2140 } else { | 2143 } else { |
| 2141 // `C` or `C()` where 'C' is a class. | 2144 // `C` or `C()` where 'C' is a class. |
| 2142 return handleClassTypeLiteralAccess(node, name, cls); | 2145 return handleClassTypeLiteralAccess(node, name, cls); |
| 2143 } | 2146 } |
| 2144 } | 2147 } |
| 2145 | 2148 |
| 2146 /// Compute a [DeferredPrefixStructure] for [node]. | 2149 /// Compute a [DeferredPrefixStructure] for [node]. |
| 2147 ResolutionResult handleDeferredAccess( | 2150 ResolutionResult handleDeferredAccess( |
| 2148 Send node, PrefixElement prefix, ResolutionResult result) { | 2151 Send node, PrefixElement prefix, ResolutionResult result) { |
| 2149 assert(invariant(node, prefix.isDeferred, | 2152 assert( |
| 2150 message: "Prefix $prefix is not deferred.")); | 2153 prefix.isDeferred, failedAt(node, "Prefix $prefix is not deferred.")); |
| 2151 SendStructure sendStructure = registry.getSendStructure(node); | 2154 SendStructure sendStructure = registry.getSendStructure(node); |
| 2152 assert(invariant(node, sendStructure != null, | 2155 assert( |
| 2153 message: "No SendStructure for $node.")); | 2156 sendStructure != null, failedAt(node, "No SendStructure for $node.")); |
| 2154 registry.registerSendStructure( | 2157 registry.registerSendStructure( |
| 2155 node, new DeferredPrefixStructure(prefix, sendStructure)); | 2158 node, new DeferredPrefixStructure(prefix, sendStructure)); |
| 2156 if (result.isConstant) { | 2159 if (result.isConstant) { |
| 2157 ConstantExpression constant = | 2160 ConstantExpression constant = |
| 2158 new DeferredConstantExpression(result.constant, prefix); | 2161 new DeferredConstantExpression(result.constant, prefix); |
| 2159 registry.setConstant(node, constant); | 2162 registry.setConstant(node, constant); |
| 2160 result = new ConstantResult(node, constant); | 2163 result = new ConstantResult(node, constant); |
| 2161 } | 2164 } |
| 2162 return result; | 2165 return result; |
| 2163 } | 2166 } |
| (...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2290 Send node, Name name, AccessSemantics semantics) { | 2293 Send node, Name name, AccessSemantics semantics) { |
| 2291 SendStructure sendStructure; | 2294 SendStructure sendStructure; |
| 2292 Selector selector; | 2295 Selector selector; |
| 2293 if (node.isCall) { | 2296 if (node.isCall) { |
| 2294 CallStructure callStructure = | 2297 CallStructure callStructure = |
| 2295 resolveArguments(node.argumentsNode).callStructure; | 2298 resolveArguments(node.argumentsNode).callStructure; |
| 2296 selector = new Selector.call(name, callStructure); | 2299 selector = new Selector.call(name, callStructure); |
| 2297 registry.registerDynamicUse(new DynamicUse(selector, null)); | 2300 registry.registerDynamicUse(new DynamicUse(selector, null)); |
| 2298 sendStructure = new InvokeStructure(semantics, selector); | 2301 sendStructure = new InvokeStructure(semantics, selector); |
| 2299 } else { | 2302 } else { |
| 2300 assert(invariant(node, node.isPropertyAccess)); | 2303 assert(node.isPropertyAccess, failedAt(node)); |
| 2301 selector = new Selector.getter(name); | 2304 selector = new Selector.getter(name); |
| 2302 registry.registerDynamicUse(new DynamicUse(selector, null)); | 2305 registry.registerDynamicUse(new DynamicUse(selector, null)); |
| 2303 sendStructure = new GetStructure(semantics); | 2306 sendStructure = new GetStructure(semantics); |
| 2304 } | 2307 } |
| 2305 registry.registerSendStructure(node, sendStructure); | 2308 registry.registerSendStructure(node, sendStructure); |
| 2306 // TODO(23998): Remove this when all information goes through | 2309 // TODO(23998): Remove this when all information goes through |
| 2307 // the [SendStructure]. | 2310 // the [SendStructure]. |
| 2308 registry.setSelector(node, selector); | 2311 registry.setSelector(node, selector); |
| 2309 return const NoneResult(); | 2312 return const NoneResult(); |
| 2310 } | 2313 } |
| (...skipping 123 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2434 Send node, Name name, AccessSemantics semantics) { | 2437 Send node, Name name, AccessSemantics semantics) { |
| 2435 SendStructure sendStructure; | 2438 SendStructure sendStructure; |
| 2436 Selector selector; | 2439 Selector selector; |
| 2437 if (node.isCall) { | 2440 if (node.isCall) { |
| 2438 CallStructure callStructure = | 2441 CallStructure callStructure = |
| 2439 resolveArguments(node.argumentsNode).callStructure; | 2442 resolveArguments(node.argumentsNode).callStructure; |
| 2440 selector = new Selector.call(name, callStructure); | 2443 selector = new Selector.call(name, callStructure); |
| 2441 registry.registerDynamicUse(new DynamicUse(selector, null)); | 2444 registry.registerDynamicUse(new DynamicUse(selector, null)); |
| 2442 sendStructure = new InvokeStructure(semantics, selector); | 2445 sendStructure = new InvokeStructure(semantics, selector); |
| 2443 } else { | 2446 } else { |
| 2444 assert(invariant(node, node.isPropertyAccess)); | 2447 assert(node.isPropertyAccess, failedAt(node)); |
| 2445 selector = new Selector.getter(name); | 2448 selector = new Selector.getter(name); |
| 2446 registry.registerDynamicUse(new DynamicUse(selector, null)); | 2449 registry.registerDynamicUse(new DynamicUse(selector, null)); |
| 2447 sendStructure = new GetStructure(semantics); | 2450 sendStructure = new GetStructure(semantics); |
| 2448 } | 2451 } |
| 2449 // TODO(23998): Remove this when all information goes through | 2452 // TODO(23998): Remove this when all information goes through |
| 2450 // the [SendStructure]. | 2453 // the [SendStructure]. |
| 2451 registry.setSelector(node, selector); | 2454 registry.setSelector(node, selector); |
| 2452 registry.useElement(node, semantics.element); | 2455 registry.useElement(node, semantics.element); |
| 2453 registry.registerSendStructure(node, sendStructure); | 2456 registry.registerSendStructure(node, sendStructure); |
| 2454 return const NoneResult(); | 2457 return const NoneResult(); |
| (...skipping 144 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2599 semantics = new StaticAccess.finalParameter(element); | 2602 semantics = new StaticAccess.finalParameter(element); |
| 2600 } else if (element.isVariable) { | 2603 } else if (element.isVariable) { |
| 2601 if (element.isFinal || element.isConst) { | 2604 if (element.isFinal || element.isConst) { |
| 2602 error = reportAndCreateErroneousElement(node.selector, name.text, | 2605 error = reportAndCreateErroneousElement(node.selector, name.text, |
| 2603 MessageKind.UNDEFINED_STATIC_SETTER_BUT_GETTER, {'name': name}); | 2606 MessageKind.UNDEFINED_STATIC_SETTER_BUT_GETTER, {'name': name}); |
| 2604 semantics = new StaticAccess.finalLocalVariable(element); | 2607 semantics = new StaticAccess.finalLocalVariable(element); |
| 2605 } else { | 2608 } else { |
| 2606 semantics = new StaticAccess.localVariable(element); | 2609 semantics = new StaticAccess.localVariable(element); |
| 2607 } | 2610 } |
| 2608 } else { | 2611 } else { |
| 2609 assert(invariant(node, element.isFunction, | 2612 assert(element.isFunction, failedAt(node, "Unexpected local $element.")); |
| 2610 message: "Unexpected local $element.")); | |
| 2611 error = reportAndCreateErroneousElement( | 2613 error = reportAndCreateErroneousElement( |
| 2612 node.selector, name.text, MessageKind.ASSIGNING_METHOD, const {}); | 2614 node.selector, name.text, MessageKind.ASSIGNING_METHOD, const {}); |
| 2613 semantics = new StaticAccess.localFunction(element); | 2615 semantics = new StaticAccess.localFunction(element); |
| 2614 } | 2616 } |
| 2615 if (isPotentiallyMutableTarget(element)) { | 2617 if (isPotentiallyMutableTarget(element)) { |
| 2616 registry.registerPotentialMutation(element, node); | 2618 registry.registerPotentialMutation(element, node); |
| 2617 if (enclosingElement != element.enclosingElement) { | 2619 if (enclosingElement != element.enclosingElement) { |
| 2618 registry.registerPotentialMutationInClosure(element, node); | 2620 registry.registerPotentialMutationInClosure(element, node); |
| 2619 } | 2621 } |
| 2620 for (Node scope in promotionScope) { | 2622 for (Node scope in promotionScope) { |
| (...skipping 230 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2851 registry.registerFeature(Feature.THROW_NO_SUCH_METHOD); | 2853 registry.registerFeature(Feature.THROW_NO_SUCH_METHOD); |
| 2852 if (node.isComplex) { | 2854 if (node.isComplex) { |
| 2853 // `a++` or `a += b` where `a` is a function. | 2855 // `a++` or `a += b` where `a` is a function. |
| 2854 registry.registerStaticUse(new StaticUse.staticTearOff(method)); | 2856 registry.registerStaticUse(new StaticUse.staticTearOff(method)); |
| 2855 } | 2857 } |
| 2856 semantics = member.isTopLevel | 2858 semantics = member.isTopLevel |
| 2857 ? new StaticAccess.topLevelMethod(method) | 2859 ? new StaticAccess.topLevelMethod(method) |
| 2858 : new StaticAccess.staticMethod(method); | 2860 : new StaticAccess.staticMethod(method); |
| 2859 } else { | 2861 } else { |
| 2860 // `a = b`, `a++` or `a += b` where `a` is a field. | 2862 // `a = b`, `a++` or `a += b` where `a` is a field. |
| 2861 assert(invariant(node, member.isField, | 2863 assert(member.isField, failedAt(node, "Unexpected element: $member.")); |
| 2862 message: "Unexpected element: $member.")); | |
| 2863 if (node.isComplex) { | 2864 if (node.isComplex) { |
| 2864 // `a++` or `a += b` where `a` is a field. | 2865 // `a++` or `a += b` where `a` is a field. |
| 2865 registry.registerStaticUse(new StaticUse.staticGet(member)); | 2866 registry.registerStaticUse(new StaticUse.staticGet(member)); |
| 2866 } | 2867 } |
| 2867 if (member.isFinal || member.isConst) { | 2868 if (member.isFinal || member.isConst) { |
| 2868 reportAndCreateErroneousElement(node.selector, name.text, | 2869 reportAndCreateErroneousElement(node.selector, name.text, |
| 2869 MessageKind.UNDEFINED_STATIC_SETTER_BUT_GETTER, {'name': name}); | 2870 MessageKind.UNDEFINED_STATIC_SETTER_BUT_GETTER, {'name': name}); |
| 2870 registry.registerFeature(Feature.THROW_NO_SUCH_METHOD); | 2871 registry.registerFeature(Feature.THROW_NO_SUCH_METHOD); |
| 2871 semantics = member.isTopLevel | 2872 semantics = member.isTopLevel |
| 2872 ? new StaticAccess.finalTopLevelField(member) | 2873 ? new StaticAccess.finalTopLevelField(member) |
| 2873 : new StaticAccess.finalStaticField(member); | 2874 : new StaticAccess.finalStaticField(member); |
| 2874 } else { | 2875 } else { |
| 2875 registry.registerStaticUse(new StaticUse.staticSet(member)); | 2876 registry.registerStaticUse(new StaticUse.staticSet(member)); |
| 2876 semantics = member.isTopLevel | 2877 semantics = member.isTopLevel |
| 2877 ? new StaticAccess.topLevelField(member) | 2878 ? new StaticAccess.topLevelField(member) |
| 2878 : new StaticAccess.staticField(member); | 2879 : new StaticAccess.staticField(member); |
| 2879 } | 2880 } |
| 2880 } | 2881 } |
| 2881 } | 2882 } |
| 2882 return handleUpdate(node, name, semantics); | 2883 return handleUpdate(node, name, semantics); |
| 2883 } | 2884 } |
| 2884 | 2885 |
| 2885 /// Handle access to resolved [element]. | 2886 /// Handle access to resolved [element]. |
| 2886 ResolutionResult handleResolvedSend(Send node, Name name, Element element) { | 2887 ResolutionResult handleResolvedSend(Send node, Name name, Element element) { |
| 2887 if (element.isAmbiguous) { | 2888 if (element.isAmbiguous) { |
| 2888 return handleAmbiguousSend(node, name, element); | 2889 return handleAmbiguousSend(node, name, element); |
| 2889 } | 2890 } |
| 2890 if (element.isMalformed) { | 2891 if (element.isMalformed) { |
| 2891 // This handles elements with parser errors. | 2892 // This handles elements with parser errors. |
| 2892 assert(invariant(node, element is! ErroneousElement, | 2893 assert(element is! ErroneousElement, |
| 2893 message: "Unexpected erroneous element $element.")); | 2894 failedAt(node, "Unexpected erroneous element $element.")); |
| 2894 return handleErroneousAccess( | 2895 return handleErroneousAccess( |
| 2895 node, name, new StaticAccess.unresolved(element)); | 2896 node, name, new StaticAccess.unresolved(element)); |
| 2896 } | 2897 } |
| 2897 if (element.isInstanceMember) { | 2898 if (element.isInstanceMember) { |
| 2898 if (inInstanceContext) { | 2899 if (inInstanceContext) { |
| 2899 // TODO(johnniwinther): Maybe use the found [element]. | 2900 // TODO(johnniwinther): Maybe use the found [element]. |
| 2900 return handleThisPropertyAccess(node, name); | 2901 return handleThisPropertyAccess(node, name); |
| 2901 } else { | 2902 } else { |
| 2902 return handleErroneousAccess( | 2903 return handleErroneousAccess( |
| 2903 node, name, reportStaticInstanceAccess(node, name)); | 2904 node, name, reportStaticInstanceAccess(node, name)); |
| (...skipping 18 matching lines...) Expand all Loading... |
| 2922 } | 2923 } |
| 2923 | 2924 |
| 2924 /// Handle update to resolved [element]. | 2925 /// Handle update to resolved [element]. |
| 2925 ResolutionResult handleResolvedSendSet( | 2926 ResolutionResult handleResolvedSendSet( |
| 2926 SendSet node, Name name, Element element) { | 2927 SendSet node, Name name, Element element) { |
| 2927 if (element.isAmbiguous) { | 2928 if (element.isAmbiguous) { |
| 2928 return handleAmbiguousUpdate(node, name, element); | 2929 return handleAmbiguousUpdate(node, name, element); |
| 2929 } | 2930 } |
| 2930 if (element.isMalformed) { | 2931 if (element.isMalformed) { |
| 2931 // This handles elements with parser errors.. | 2932 // This handles elements with parser errors.. |
| 2932 assert(invariant(node, element is! ErroneousElement, | 2933 assert(element is! ErroneousElement, |
| 2933 message: "Unexpected erroneous element $element.")); | 2934 failedAt(node, "Unexpected erroneous element $element.")); |
| 2934 return handleUpdate(node, name, new StaticAccess.unresolved(element)); | 2935 return handleUpdate(node, name, new StaticAccess.unresolved(element)); |
| 2935 } | 2936 } |
| 2936 if (element.isInstanceMember) { | 2937 if (element.isInstanceMember) { |
| 2937 if (inInstanceContext) { | 2938 if (inInstanceContext) { |
| 2938 return handleThisPropertyUpdate(node, name, element); | 2939 return handleThisPropertyUpdate(node, name, element); |
| 2939 } else { | 2940 } else { |
| 2940 return handleUpdate(node, name, reportStaticInstanceAccess(node, name)); | 2941 return handleUpdate(node, name, reportStaticInstanceAccess(node, name)); |
| 2941 } | 2942 } |
| 2942 } | 2943 } |
| 2943 if (element.isClass) { | 2944 if (element.isClass) { |
| (...skipping 1108 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4052 MessageKind.CONST_MAP_KEY_OVERRIDES_EQUALS, {'type': keyType}); | 4053 MessageKind.CONST_MAP_KEY_OVERRIDES_EQUALS, {'type': keyType}); |
| 4053 } | 4054 } |
| 4054 } | 4055 } |
| 4055 } | 4056 } |
| 4056 | 4057 |
| 4057 void analyzeConstant(Node node, {enforceConst: true}) { | 4058 void analyzeConstant(Node node, {enforceConst: true}) { |
| 4058 ConstantExpression constant = resolver.constantCompiler | 4059 ConstantExpression constant = resolver.constantCompiler |
| 4059 .compileNode(node, registry.mapping, enforceConst: enforceConst); | 4060 .compileNode(node, registry.mapping, enforceConst: enforceConst); |
| 4060 | 4061 |
| 4061 if (constant == null) { | 4062 if (constant == null) { |
| 4062 assert(invariant(node, reporter.hasReportedError)); | 4063 assert(reporter.hasReportedError, failedAt(node)); |
| 4063 return; | 4064 return; |
| 4064 } | 4065 } |
| 4065 | 4066 |
| 4066 ConstantValue value = resolution.constants.getConstantValue(constant); | 4067 ConstantValue value = resolution.constants.getConstantValue(constant); |
| 4067 if (value.isMap) { | 4068 if (value.isMap) { |
| 4068 checkConstMapKeysDontOverrideEquals(node, value); | 4069 checkConstMapKeysDontOverrideEquals(node, value); |
| 4069 } | 4070 } |
| 4070 } | 4071 } |
| 4071 | 4072 |
| 4072 void analyzeConstantDeferred(Node node, | 4073 void analyzeConstantDeferred(Node node, |
| (...skipping 303 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4376 if (loopVariableSelector != null) { | 4377 if (loopVariableSelector != null) { |
| 4377 registry.setSelector(declaration, loopVariableSelector); | 4378 registry.setSelector(declaration, loopVariableSelector); |
| 4378 if (loopVariable == null || loopVariable.isInstanceMember) { | 4379 if (loopVariable == null || loopVariable.isInstanceMember) { |
| 4379 registry.registerDynamicUse(new DynamicUse(loopVariableSelector, null)); | 4380 registry.registerDynamicUse(new DynamicUse(loopVariableSelector, null)); |
| 4380 } else if (loopVariable.isStatic || loopVariable.isTopLevel) { | 4381 } else if (loopVariable.isStatic || loopVariable.isTopLevel) { |
| 4381 MemberElement member = loopVariable.declaration; | 4382 MemberElement member = loopVariable.declaration; |
| 4382 registry.registerStaticUse(new StaticUse.staticSet(member)); | 4383 registry.registerStaticUse(new StaticUse.staticSet(member)); |
| 4383 } | 4384 } |
| 4384 } else { | 4385 } else { |
| 4385 // The selector may only be null if we reported an error. | 4386 // The selector may only be null if we reported an error. |
| 4386 assert(invariant(declaration, reporter.hasReportedError)); | 4387 assert(reporter.hasReportedError, failedAt(declaration)); |
| 4387 } | 4388 } |
| 4388 if (loopVariable != null) { | 4389 if (loopVariable != null) { |
| 4389 // loopVariable may be null if it could not be resolved. | 4390 // loopVariable may be null if it could not be resolved. |
| 4390 registry.setForInVariable(node, loopVariable); | 4391 registry.setForInVariable(node, loopVariable); |
| 4391 } | 4392 } |
| 4392 } | 4393 } |
| 4393 | 4394 |
| 4394 visitLabel(Label node) { | 4395 visitLabel(Label node) { |
| 4395 // Labels are handled by their containing statements/cases. | 4396 // Labels are handled by their containing statements/cases. |
| 4396 } | 4397 } |
| (...skipping 140 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4537 cases = cases.tail) { | 4538 cases = cases.tail) { |
| 4538 SwitchCase switchCase = cases.head; | 4539 SwitchCase switchCase = cases.head; |
| 4539 | 4540 |
| 4540 for (Node labelOrCase in switchCase.labelsAndCases) { | 4541 for (Node labelOrCase in switchCase.labelsAndCases) { |
| 4541 CaseMatch caseMatch = labelOrCase.asCaseMatch(); | 4542 CaseMatch caseMatch = labelOrCase.asCaseMatch(); |
| 4542 if (caseMatch == null) continue; | 4543 if (caseMatch == null) continue; |
| 4543 | 4544 |
| 4544 // Analyze the constant. | 4545 // Analyze the constant. |
| 4545 ConstantExpression constant = | 4546 ConstantExpression constant = |
| 4546 registry.getConstant(caseMatch.expression); | 4547 registry.getConstant(caseMatch.expression); |
| 4547 assert(invariant(node, constant != null, | 4548 assert( |
| 4548 message: 'No constant computed for $node')); | 4549 constant != null, failedAt(node, 'No constant computed for $node')); |
| 4549 | 4550 |
| 4550 ConstantValue value = resolution.constants.getConstantValue(constant); | 4551 ConstantValue value = resolution.constants.getConstantValue(constant); |
| 4551 ResolutionDartType caseType = | 4552 ResolutionDartType caseType = |
| 4552 value.getType(commonElements); //typeOfConstant(value); | 4553 value.getType(commonElements); //typeOfConstant(value); |
| 4553 | 4554 |
| 4554 if (firstCaseType == null) { | 4555 if (firstCaseType == null) { |
| 4555 firstCase = caseMatch; | 4556 firstCase = caseMatch; |
| 4556 firstCaseType = caseType; | 4557 firstCaseType = caseType; |
| 4557 | 4558 |
| 4558 // We only report the bad type on the first class element. All others | 4559 // We only report the bad type on the first class element. All others |
| (...skipping 243 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4802 } | 4803 } |
| 4803 return const NoneResult(); | 4804 return const NoneResult(); |
| 4804 } | 4805 } |
| 4805 } | 4806 } |
| 4806 | 4807 |
| 4807 /// Looks up [name] in [scope] and unwraps the result. | 4808 /// Looks up [name] in [scope] and unwraps the result. |
| 4808 Element lookupInScope( | 4809 Element lookupInScope( |
| 4809 DiagnosticReporter reporter, Node node, Scope scope, String name) { | 4810 DiagnosticReporter reporter, Node node, Scope scope, String name) { |
| 4810 return Elements.unwrap(scope.lookup(name), reporter, node); | 4811 return Elements.unwrap(scope.lookup(name), reporter, node); |
| 4811 } | 4812 } |
| OLD | NEW |