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 |