OLD | NEW |
1 // Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2016, 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 import 'dart:collection'; | 5 import 'dart:collection'; |
6 | 6 |
7 import 'package:analyzer/dart/ast/ast.dart'; | 7 import 'package:analyzer/dart/ast/ast.dart'; |
8 import 'package:analyzer/dart/ast/standard_ast_factory.dart'; | 8 import 'package:analyzer/dart/ast/standard_ast_factory.dart'; |
9 import 'package:analyzer/dart/ast/token.dart'; | 9 import 'package:analyzer/dart/ast/token.dart'; |
10 import 'package:analyzer/dart/element/element.dart'; | 10 import 'package:analyzer/dart/element/element.dart'; |
(...skipping 799 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
810 } else { | 810 } else { |
811 // | 811 // |
812 // Example: class A inherits 2 methods named 'm'. | 812 // Example: class A inherits 2 methods named 'm'. |
813 // One has the function type '(int) -> dynamic' and one has the | 813 // One has the function type '(int) -> dynamic' and one has the |
814 // function type '(num) -> dynamic'. Since they are both a subtype | 814 // function type '(num) -> dynamic'. Since they are both a subtype |
815 // of the other, a synthetic function '(dynamic) -> dynamic' is | 815 // of the other, a synthetic function '(dynamic) -> dynamic' is |
816 // inherited. | 816 // inherited. |
817 // Tests: test_getMapOfMembersInheritedFromInterfaces_ | 817 // Tests: test_getMapOfMembersInheritedFromInterfaces_ |
818 // union_multipleSubtypes_* | 818 // union_multipleSubtypes_* |
819 // | 819 // |
| 820 // TODO(leafp): this produces (dynamic) -> dynamic even if |
| 821 // the types are equal which gives bad error messages. If |
| 822 // types are equal, we should consider using them. Even |
| 823 // better, consider using the GLB of the parameter types |
| 824 // and the LUB of the return types |
820 List<ExecutableElement> elementArrayToMerge = | 825 List<ExecutableElement> elementArrayToMerge = |
821 new List<ExecutableElement>( | 826 new List<ExecutableElement>( |
822 subtypesOfAllOtherTypesIndexes.length); | 827 subtypesOfAllOtherTypesIndexes.length); |
823 for (int i = 0; i < elementArrayToMerge.length; i++) { | 828 for (int i = 0; i < elementArrayToMerge.length; i++) { |
824 elementArrayToMerge[i] = | 829 elementArrayToMerge[i] = |
825 elements[subtypesOfAllOtherTypesIndexes[i]]; | 830 elements[subtypesOfAllOtherTypesIndexes[i]]; |
826 } | 831 } |
827 ExecutableElement mergedExecutableElement = | 832 ExecutableElement mergedExecutableElement = |
828 _computeMergedExecutableElement(elementArrayToMerge); | 833 _computeMergedExecutableElement(elementArrayToMerge); |
829 resultMap[key] = mergedExecutableElement; | 834 resultMap[key] = mergedExecutableElement; |
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
913 * function <i>f</i>, and let <i>numberOfRequiredParams</i>(<i>f</i>) denote t
he number of | 918 * function <i>f</i>, and let <i>numberOfRequiredParams</i>(<i>f</i>) denote t
he number of |
914 * required parameters of a function <i>f</i>. Furthermore, let <i>s</i> denot
e the set of all | 919 * required parameters of a function <i>f</i>. Furthermore, let <i>s</i> denot
e the set of all |
915 * named parameters of the <i>m<sub>1</sub>, …, m<sub>k</sub></i>. Then
let | 920 * named parameters of the <i>m<sub>1</sub>, …, m<sub>k</sub></i>. Then
let |
916 * * <i>h = max(numberOfPositionals(m<sub>i</sub>)),</i> | 921 * * <i>h = max(numberOfPositionals(m<sub>i</sub>)),</i> |
917 * * <i>r = min(numberOfRequiredParams(m<sub>i</sub>)), for all <i>i</i>, 1 <=
i <= k.</i> | 922 * * <i>r = min(numberOfRequiredParams(m<sub>i</sub>)), for all <i>i</i>, 1 <=
i <= k.</i> |
918 * Then <i>I</i> has a method named <i>n</i>, with <i>r</i> required parameter
s of type | 923 * Then <i>I</i> has a method named <i>n</i>, with <i>r</i> required parameter
s of type |
919 * <b>dynamic</b>, <i>h</i> positional parameters of type <b>dynamic</b>, name
d parameters | 924 * <b>dynamic</b>, <i>h</i> positional parameters of type <b>dynamic</b>, name
d parameters |
920 * <i>s</i> of type <b>dynamic</b> and return type <b>dynamic</b>. | 925 * <i>s</i> of type <b>dynamic</b> and return type <b>dynamic</b>. |
921 * | 926 * |
922 */ | 927 */ |
923 static ExecutableElement _computeMergedExecutableElement( | 928 ExecutableElement _computeMergedExecutableElement( |
924 List<ExecutableElement> elementArrayToMerge) { | 929 List<ExecutableElement> elementArrayToMerge) { |
925 int h = _getNumOfPositionalParameters(elementArrayToMerge[0]); | 930 int h = _getNumOfPositionalParameters(elementArrayToMerge[0]); |
926 int r = _getNumOfRequiredParameters(elementArrayToMerge[0]); | 931 int r = _getNumOfRequiredParameters(elementArrayToMerge[0]); |
927 Set<String> namedParametersList = new HashSet<String>(); | 932 Set<String> namedParametersList = new HashSet<String>(); |
928 for (int i = 1; i < elementArrayToMerge.length; i++) { | 933 for (int i = 1; i < elementArrayToMerge.length; i++) { |
929 ExecutableElement element = elementArrayToMerge[i]; | 934 ExecutableElement element = elementArrayToMerge[i]; |
930 int numOfPositionalParams = _getNumOfPositionalParameters(element); | 935 int numOfPositionalParams = _getNumOfPositionalParameters(element); |
931 if (h < numOfPositionalParams) { | 936 if (h < numOfPositionalParams) { |
932 h = numOfPositionalParams; | 937 h = numOfPositionalParams; |
933 } | 938 } |
(...skipping 15 matching lines...) Expand all Loading... |
949 * Used by [computeMergedExecutableElement] to actually create the | 954 * Used by [computeMergedExecutableElement] to actually create the |
950 * synthetic element. | 955 * synthetic element. |
951 * | 956 * |
952 * @param elementArrayToMerge the array used to create the synthetic element | 957 * @param elementArrayToMerge the array used to create the synthetic element |
953 * @param name the name of the method, getter or setter | 958 * @param name the name of the method, getter or setter |
954 * @param numOfRequiredParameters the number of required parameters | 959 * @param numOfRequiredParameters the number of required parameters |
955 * @param numOfPositionalParameters the number of positional parameters | 960 * @param numOfPositionalParameters the number of positional parameters |
956 * @param namedParameters the list of [String]s that are the named parameters | 961 * @param namedParameters the list of [String]s that are the named parameters |
957 * @return the created synthetic element | 962 * @return the created synthetic element |
958 */ | 963 */ |
959 static ExecutableElement _createSyntheticExecutableElement( | 964 ExecutableElement _createSyntheticExecutableElement( |
960 List<ExecutableElement> elementArrayToMerge, | 965 List<ExecutableElement> elementArrayToMerge, |
961 String name, | 966 String name, |
962 int numOfRequiredParameters, | 967 int numOfRequiredParameters, |
963 int numOfPositionalParameters, | 968 int numOfPositionalParameters, |
964 List<String> namedParameters) { | 969 List<String> namedParameters) { |
965 DynamicTypeImpl dynamicType = DynamicTypeImpl.instance; | 970 DynamicTypeImpl dynamicType = DynamicTypeImpl.instance; |
| 971 DartType bottomType = _library.context.analysisOptions.strongMode |
| 972 ? BottomTypeImpl.instance |
| 973 : dynamicType; |
966 SimpleIdentifier nameIdentifier = astFactory | 974 SimpleIdentifier nameIdentifier = astFactory |
967 .simpleIdentifier(new StringToken(TokenType.IDENTIFIER, name, 0)); | 975 .simpleIdentifier(new StringToken(TokenType.IDENTIFIER, name, 0)); |
968 ExecutableElementImpl executable; | 976 ExecutableElementImpl executable; |
969 ExecutableElement elementToMerge = elementArrayToMerge[0]; | 977 ExecutableElement elementToMerge = elementArrayToMerge[0]; |
970 if (elementToMerge is MethodElement) { | 978 if (elementToMerge is MethodElement) { |
971 MultiplyInheritedMethodElementImpl unionedMethod = | 979 MultiplyInheritedMethodElementImpl unionedMethod = |
972 new MultiplyInheritedMethodElementImpl(nameIdentifier); | 980 new MultiplyInheritedMethodElementImpl(nameIdentifier); |
973 unionedMethod.inheritedElements = elementArrayToMerge; | 981 unionedMethod.inheritedElements = elementArrayToMerge; |
974 executable = unionedMethod; | 982 executable = unionedMethod; |
975 } else if (elementToMerge is PropertyAccessorElement) { | 983 } else if (elementToMerge is PropertyAccessorElement) { |
976 MultiplyInheritedPropertyAccessorElementImpl unionedPropertyAccessor = | 984 MultiplyInheritedPropertyAccessorElementImpl unionedPropertyAccessor = |
977 new MultiplyInheritedPropertyAccessorElementImpl(nameIdentifier); | 985 new MultiplyInheritedPropertyAccessorElementImpl(nameIdentifier); |
978 unionedPropertyAccessor.getter = elementToMerge.isGetter; | 986 unionedPropertyAccessor.getter = elementToMerge.isGetter; |
979 unionedPropertyAccessor.setter = elementToMerge.isSetter; | 987 unionedPropertyAccessor.setter = elementToMerge.isSetter; |
980 unionedPropertyAccessor.inheritedElements = elementArrayToMerge; | 988 unionedPropertyAccessor.inheritedElements = elementArrayToMerge; |
981 executable = unionedPropertyAccessor; | 989 executable = unionedPropertyAccessor; |
982 } else { | 990 } else { |
983 throw new AnalysisException( | 991 throw new AnalysisException( |
984 'Invalid class of element in merge: ${elementToMerge.runtimeType}'); | 992 'Invalid class of element in merge: ${elementToMerge.runtimeType}'); |
985 } | 993 } |
986 int numOfParameters = numOfRequiredParameters + | 994 int numOfParameters = numOfRequiredParameters + |
987 numOfPositionalParameters + | 995 numOfPositionalParameters + |
988 namedParameters.length; | 996 namedParameters.length; |
989 List<ParameterElement> parameters = | 997 List<ParameterElement> parameters = |
990 new List<ParameterElement>(numOfParameters); | 998 new List<ParameterElement>(numOfParameters); |
991 int i = 0; | 999 int i = 0; |
992 for (int j = 0; j < numOfRequiredParameters; j++, i++) { | 1000 for (int j = 0; j < numOfRequiredParameters; j++, i++) { |
993 ParameterElementImpl parameter = new ParameterElementImpl("", 0); | 1001 ParameterElementImpl parameter = new ParameterElementImpl("", 0); |
994 parameter.type = dynamicType; | 1002 parameter.type = bottomType; |
995 parameter.parameterKind = ParameterKind.REQUIRED; | 1003 parameter.parameterKind = ParameterKind.REQUIRED; |
996 parameters[i] = parameter; | 1004 parameters[i] = parameter; |
997 } | 1005 } |
998 for (int k = 0; k < numOfPositionalParameters; k++, i++) { | 1006 for (int k = 0; k < numOfPositionalParameters; k++, i++) { |
999 ParameterElementImpl parameter = new ParameterElementImpl("", 0); | 1007 ParameterElementImpl parameter = new ParameterElementImpl("", 0); |
1000 parameter.type = dynamicType; | 1008 parameter.type = bottomType; |
1001 parameter.parameterKind = ParameterKind.POSITIONAL; | 1009 parameter.parameterKind = ParameterKind.POSITIONAL; |
1002 parameters[i] = parameter; | 1010 parameters[i] = parameter; |
1003 } | 1011 } |
1004 for (int m = 0; m < namedParameters.length; m++, i++) { | 1012 for (int m = 0; m < namedParameters.length; m++, i++) { |
1005 ParameterElementImpl parameter = | 1013 ParameterElementImpl parameter = |
1006 new ParameterElementImpl(namedParameters[m], 0); | 1014 new ParameterElementImpl(namedParameters[m], 0); |
1007 parameter.type = dynamicType; | 1015 parameter.type = bottomType; |
1008 parameter.parameterKind = ParameterKind.NAMED; | 1016 parameter.parameterKind = ParameterKind.NAMED; |
1009 parameters[i] = parameter; | 1017 parameters[i] = parameter; |
1010 } | 1018 } |
1011 executable.returnType = dynamicType; | 1019 executable.returnType = dynamicType; |
1012 executable.parameters = parameters; | 1020 executable.parameters = parameters; |
1013 FunctionTypeImpl methodType = new FunctionTypeImpl(executable); | 1021 FunctionTypeImpl methodType = new FunctionTypeImpl(executable); |
1014 executable.type = methodType; | 1022 executable.type = methodType; |
1015 return executable; | 1023 return executable; |
1016 } | 1024 } |
1017 | 1025 |
(...skipping 230 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1248 } | 1256 } |
1249 | 1257 |
1250 /** | 1258 /** |
1251 * Initializes [keys] and [values]. | 1259 * Initializes [keys] and [values]. |
1252 */ | 1260 */ |
1253 void _initArrays(int initialCapacity) { | 1261 void _initArrays(int initialCapacity) { |
1254 _keys = new List<String>(initialCapacity); | 1262 _keys = new List<String>(initialCapacity); |
1255 _values = new List<ExecutableElement>(initialCapacity); | 1263 _values = new List<ExecutableElement>(initialCapacity); |
1256 } | 1264 } |
1257 } | 1265 } |
OLD | NEW |