Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
| 3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 | 4 |
| 5 library elements; | 5 library elements; |
| 6 | 6 |
| 7 import '../common.dart'; | 7 import '../common.dart'; |
| 8 import '../common/resolution.dart' show Resolution; | 8 import '../common/resolution.dart' show Resolution; |
| 9 import '../compiler.dart' show Compiler; | 9 import '../compiler.dart' show Compiler; |
| 10 import '../constants/constructors.dart'; | 10 import '../constants/constructors.dart'; |
| 11 import '../constants/expressions.dart'; | 11 import '../constants/expressions.dart'; |
| 12 import '../core_types.dart' show CommonElements; | 12 import '../core_types.dart' show CommonElements; |
| 13 import '../ordered_typeset.dart' show OrderedTypeSet; | 13 import '../ordered_typeset.dart' show OrderedTypeSet; |
| 14 import '../resolution/scope.dart' show Scope; | 14 import '../resolution/scope.dart' show Scope; |
| 15 import '../resolution/tree_elements.dart' show TreeElements; | 15 import '../resolution/tree_elements.dart' show TreeElements; |
| 16 import '../script.dart'; | 16 import '../script.dart'; |
| 17 import '../tokens/token.dart' | 17 import '../tokens/token.dart' |
| 18 show Token, isUserDefinableOperator, isMinusOperator; | 18 show Token, isUserDefinableOperator, isMinusOperator; |
| 19 import '../tree/tree.dart'; | 19 import '../tree/tree.dart'; |
| 20 import '../universe/call_structure.dart'; | |
| 20 import '../util/characters.dart' show $_; | 21 import '../util/characters.dart' show $_; |
| 21 import '../util/util.dart'; | 22 import '../util/util.dart'; |
| 22 import '../world.dart' show ClosedWorld; | 23 import '../world.dart' show ClosedWorld; |
| 23 import 'entities.dart'; | 24 import 'entities.dart'; |
| 24 import 'resolution_types.dart'; | 25 import 'resolution_types.dart'; |
| 25 import 'visitor.dart' show ElementVisitor; | 26 import 'visitor.dart' show ElementVisitor; |
| 26 | 27 |
| 27 part 'names.dart'; | 28 part 'names.dart'; |
| 28 | 29 |
| 29 const int STATE_NOT_STARTED = 0; | 30 const int STATE_NOT_STARTED = 0; |
| (...skipping 782 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 812 | 813 |
| 813 static bool isUnusedLabel(LabeledStatement node, TreeElements elements) { | 814 static bool isUnusedLabel(LabeledStatement node, TreeElements elements) { |
| 814 Node body = node.statement; | 815 Node body = node.statement; |
| 815 JumpTarget element = elements.getTargetDefinition(body); | 816 JumpTarget element = elements.getTargetDefinition(body); |
| 816 // Labeled statements with no element on the body have no breaks. | 817 // Labeled statements with no element on the body have no breaks. |
| 817 // A different target statement only happens if the body is itself | 818 // A different target statement only happens if the body is itself |
| 818 // a break or continue for a different target. In that case, this | 819 // a break or continue for a different target. In that case, this |
| 819 // label is also always unused. | 820 // label is also always unused. |
| 820 return element == null || element.statement != body; | 821 return element == null || element.statement != body; |
| 821 } | 822 } |
| 823 | |
| 824 /** | |
| 825 * Returns a `List` with the evaluated arguments in the normalized order. | |
| 826 * | |
| 827 * [compileDefaultValue] is a function that returns a compiled constant | |
| 828 * of an optional argument that is not in [compiledArguments]. | |
| 829 * | |
| 830 * Precondition: `this.applies(element, world)`. | |
|
Siggi Cherem (dart-lang)
2017/01/13 17:11:07
what is `this` in this static context?
Johnni Winther
2017/01/18 11:02:51
Old invariant. Changed to `callStructure.signature
| |
| 831 * | |
| 832 * Invariant: [element] must be the implementation element. | |
| 833 */ | |
| 834 static List<T> makeArgumentsList<T>( | |
| 835 CallStructure callStructure, | |
| 836 Link<Node> arguments, | |
| 837 FunctionElement element, | |
| 838 T compileArgument(Node argument), | |
| 839 T compileDefaultValue(ParameterElement element)) { | |
| 840 assert(invariant(element, element.isImplementation)); | |
| 841 List<T> result = <T>[]; | |
| 842 | |
| 843 FunctionSignature parameters = element.functionSignature; | |
| 844 parameters.forEachRequiredParameter((ParameterElement element) { | |
| 845 result.add(compileArgument(arguments.head)); | |
| 846 arguments = arguments.tail; | |
| 847 }); | |
| 848 | |
| 849 if (!parameters.optionalParametersAreNamed) { | |
| 850 parameters.forEachOptionalParameter((ParameterElement element) { | |
| 851 if (!arguments.isEmpty) { | |
| 852 result.add(compileArgument(arguments.head)); | |
| 853 arguments = arguments.tail; | |
| 854 } else { | |
| 855 result.add(compileDefaultValue(element)); | |
| 856 } | |
| 857 }); | |
| 858 } else { | |
| 859 // Visit named arguments and add them into a temporary list. | |
| 860 List compiledNamedArguments = []; | |
| 861 for (; !arguments.isEmpty; arguments = arguments.tail) { | |
| 862 NamedArgument namedArgument = arguments.head; | |
| 863 compiledNamedArguments.add(compileArgument(namedArgument.expression)); | |
| 864 } | |
| 865 // Iterate over the optional parameters of the signature, and try to | |
| 866 // find them in [compiledNamedArguments]. If found, we use the | |
| 867 // value in the temporary list, otherwise the default value. | |
| 868 parameters.orderedOptionalParameters.forEach((ParameterElement element) { | |
| 869 int foundIndex = callStructure.namedArguments.indexOf(element.name); | |
| 870 if (foundIndex != -1) { | |
| 871 result.add(compiledNamedArguments[foundIndex]); | |
| 872 } else { | |
| 873 result.add(compileDefaultValue(element)); | |
| 874 } | |
| 875 }); | |
| 876 } | |
| 877 return result; | |
| 878 } | |
| 879 | |
| 880 /** | |
| 881 * Fills [list] with the arguments in the order expected by | |
| 882 * [callee], and where [caller] is a synthesized element | |
| 883 * | |
| 884 * [compileArgument] is a function that returns a compiled version | |
| 885 * of a parameter of [callee]. | |
| 886 * | |
| 887 * [compileConstant] is a function that returns a compiled constant | |
| 888 * of an optional argument that is not in the parameters of [callee]. | |
| 889 * | |
| 890 * Returns [:true:] if the signature of the [caller] matches the | |
| 891 * signature of the [callee], [:false:] otherwise. | |
| 892 */ | |
| 893 static bool addForwardingElementArgumentsToList<T>( | |
| 894 ConstructorElement caller, | |
| 895 List<T> list, | |
| 896 ConstructorElement callee, | |
| 897 T compileArgument(ParameterElement element), | |
| 898 T compileConstant(ParameterElement element)) { | |
| 899 assert(invariant(caller, !callee.isMalformed, | |
| 900 message: "Cannot compute arguments to malformed constructor: " | |
| 901 "$caller calling $callee.")); | |
| 902 | |
| 903 FunctionSignature signature = caller.functionSignature; | |
| 904 Map<Node, ParameterElement> mapping = <Node, ParameterElement>{}; | |
| 905 | |
| 906 // TODO(ngeoffray): This is a hack that fakes up AST nodes, so | |
| 907 // that we can call [addArgumentsToList]. | |
| 908 Link<Node> computeCallNodesFromParameters() { | |
| 909 LinkBuilder<Node> builder = new LinkBuilder<Node>(); | |
| 910 signature.forEachRequiredParameter((ParameterElement element) { | |
| 911 Node node = element.node; | |
| 912 mapping[node] = element; | |
| 913 builder.addLast(node); | |
| 914 }); | |
| 915 if (signature.optionalParametersAreNamed) { | |
| 916 signature.forEachOptionalParameter((ParameterElement element) { | |
| 917 mapping[element.initializer] = element; | |
| 918 builder.addLast(new NamedArgument(null, null, element.initializer)); | |
| 919 }); | |
| 920 } else { | |
| 921 signature.forEachOptionalParameter((ParameterElement element) { | |
| 922 Node node = element.node; | |
| 923 mapping[node] = element; | |
| 924 builder.addLast(node); | |
| 925 }); | |
| 926 } | |
| 927 return builder.toLink(); | |
| 928 } | |
| 929 | |
| 930 /*T*/ internalCompileArgument(Node node) { | |
| 931 return compileArgument(mapping[node]); | |
| 932 } | |
| 933 | |
| 934 Link<Node> nodes = computeCallNodesFromParameters(); | |
| 935 | |
| 936 // Synthesize a structure for the call. | |
| 937 // TODO(ngeoffray): Should the resolver do it instead? | |
| 938 CallStructure callStructure = new CallStructure( | |
| 939 signature.parameterCount, signature.type.namedParameters); | |
| 940 if (!callStructure.signatureApplies(signature.type)) { | |
| 941 return false; | |
| 942 } | |
| 943 list.addAll(makeArgumentsList<T>(callStructure, nodes, callee, | |
| 944 internalCompileArgument, compileConstant)); | |
| 945 | |
| 946 return true; | |
| 947 } | |
| 822 } | 948 } |
| 823 | 949 |
| 824 /// An element representing an erroneous resolution. | 950 /// An element representing an erroneous resolution. |
| 825 /// | 951 /// |
| 826 /// An [ErroneousElement] is used instead of `null` to provide additional | 952 /// An [ErroneousElement] is used instead of `null` to provide additional |
| 827 /// information about the error that caused the element to be unresolvable | 953 /// information about the error that caused the element to be unresolvable |
| 828 /// or otherwise invalid. | 954 /// or otherwise invalid. |
| 829 /// | 955 /// |
| 830 /// Accessing any field or calling any method defined on [ErroneousElement] | 956 /// Accessing any field or calling any method defined on [ErroneousElement] |
| 831 /// except [isError] will currently throw an exception. (This might | 957 /// except [isError] will currently throw an exception. (This might |
| (...skipping 1086 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1918 /// by a field. | 2044 /// by a field. |
| 1919 bool get isDeclaredByField; | 2045 bool get isDeclaredByField; |
| 1920 | 2046 |
| 1921 /// Returns `true` if this member is abstract. | 2047 /// Returns `true` if this member is abstract. |
| 1922 bool get isAbstract; | 2048 bool get isAbstract; |
| 1923 | 2049 |
| 1924 /// If abstract, [implementation] points to the overridden concrete member, | 2050 /// If abstract, [implementation] points to the overridden concrete member, |
| 1925 /// if any. Otherwise [implementation] points to the member itself. | 2051 /// if any. Otherwise [implementation] points to the member itself. |
| 1926 Member get implementation; | 2052 Member get implementation; |
| 1927 } | 2053 } |
| OLD | NEW |