| OLD | NEW |
| 1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2014, 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 analyzer.src.generated.resolver; | 5 library analyzer.src.generated.resolver; |
| 6 | 6 |
| 7 import 'dart:collection'; | 7 import 'dart:collection'; |
| 8 | 8 |
| 9 import 'package:analyzer/dart/ast/ast.dart'; | 9 import 'package:analyzer/dart/ast/ast.dart'; |
| 10 import 'package:analyzer/dart/ast/token.dart'; | 10 import 'package:analyzer/dart/ast/token.dart'; |
| (...skipping 4825 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4836 class InheritanceManager { | 4836 class InheritanceManager { |
| 4837 /** | 4837 /** |
| 4838 * The [LibraryElement] that is managed by this manager. | 4838 * The [LibraryElement] that is managed by this manager. |
| 4839 */ | 4839 */ |
| 4840 LibraryElement _library; | 4840 LibraryElement _library; |
| 4841 | 4841 |
| 4842 /** | 4842 /** |
| 4843 * This is a mapping between each [ClassElement] and a map between the [String
] member | 4843 * This is a mapping between each [ClassElement] and a map between the [String
] member |
| 4844 * names and the associated [ExecutableElement] in the mixin and superclass ch
ain. | 4844 * names and the associated [ExecutableElement] in the mixin and superclass ch
ain. |
| 4845 */ | 4845 */ |
| 4846 HashMap<ClassElement, MemberMap> _classLookup; | 4846 Map<ClassElement, Map<String, ExecutableElement>> _classLookup; |
| 4847 | 4847 |
| 4848 /** | 4848 /** |
| 4849 * This is a mapping between each [ClassElement] and a map between the [String
] member | 4849 * This is a mapping between each [ClassElement] and a map between the [String
] member |
| 4850 * names and the associated [ExecutableElement] in the interface set. | 4850 * names and the associated [ExecutableElement] in the interface set. |
| 4851 */ | 4851 */ |
| 4852 HashMap<ClassElement, MemberMap> _interfaceLookup; | 4852 Map<ClassElement, Map<String, ExecutableElement>> _interfaceLookup; |
| 4853 | 4853 |
| 4854 /** | 4854 /** |
| 4855 * A map between each visited [ClassElement] and the set of [AnalysisError]s f
ound on | 4855 * A map between each visited [ClassElement] and the set of [AnalysisError]s f
ound on |
| 4856 * the class element. | 4856 * the class element. |
| 4857 */ | 4857 */ |
| 4858 HashMap<ClassElement, HashSet<AnalysisError>> _errorsInClassElement = | 4858 Map<ClassElement, Set<AnalysisError>> _errorsInClassElement = |
| 4859 new HashMap<ClassElement, HashSet<AnalysisError>>(); | 4859 new HashMap<ClassElement, Set<AnalysisError>>(); |
| 4860 | 4860 |
| 4861 /** | 4861 /** |
| 4862 * Initialize a newly created inheritance manager. | 4862 * Initialize a newly created inheritance manager. |
| 4863 * | 4863 * |
| 4864 * @param library the library element context that the inheritance mappings ar
e being generated | 4864 * @param library the library element context that the inheritance mappings ar
e being generated |
| 4865 */ | 4865 */ |
| 4866 InheritanceManager(LibraryElement library) { | 4866 InheritanceManager(LibraryElement library) { |
| 4867 this._library = library; | 4867 this._library = library; |
| 4868 _classLookup = new HashMap<ClassElement, MemberMap>(); | 4868 _classLookup = new HashMap<ClassElement, Map<String, ExecutableElement>>(); |
| 4869 _interfaceLookup = new HashMap<ClassElement, MemberMap>(); | 4869 _interfaceLookup = new HashMap<ClassElement, Map<String, ExecutableElement>>
(); |
| 4870 } | 4870 } |
| 4871 | 4871 |
| 4872 /** | 4872 /** |
| 4873 * Set the new library element context. | 4873 * Set the new library element context. |
| 4874 * | 4874 * |
| 4875 * @param library the new library element | 4875 * @param library the new library element |
| 4876 */ | 4876 */ |
| 4877 void set libraryElement(LibraryElement library) { | 4877 void set libraryElement(LibraryElement library) { |
| 4878 this._library = library; | 4878 this._library = library; |
| 4879 } | 4879 } |
| 4880 | 4880 |
| 4881 /** | 4881 /** |
| 4882 * Return the set of [AnalysisError]s found on the passed [ClassElement], or | 4882 * Return the set of [AnalysisError]s found on the passed [ClassElement], or |
| 4883 * `null` if there are none. | 4883 * `null` if there are none. |
| 4884 * | 4884 * |
| 4885 * @param classElt the class element to query | 4885 * @param classElt the class element to query |
| 4886 * @return the set of [AnalysisError]s found on the passed [ClassElement], or | 4886 * @return the set of [AnalysisError]s found on the passed [ClassElement], or |
| 4887 * `null` if there are none | 4887 * `null` if there are none |
| 4888 */ | 4888 */ |
| 4889 HashSet<AnalysisError> getErrors(ClassElement classElt) => | 4889 Set<AnalysisError> getErrors(ClassElement classElt) => |
| 4890 _errorsInClassElement[classElt]; | 4890 _errorsInClassElement[classElt]; |
| 4891 | 4891 |
| 4892 /** | 4892 /** |
| 4893 * Get and return a mapping between the set of all string names of the members
inherited from the | 4893 * Get and return a mapping between the set of all string names of the members
inherited from the |
| 4894 * passed [ClassElement] superclass hierarchy, and the associated [ExecutableE
lement]. | 4894 * passed [ClassElement] superclass hierarchy, and the associated [ExecutableE
lement]. |
| 4895 * | 4895 * |
| 4896 * @param classElt the class element to query | 4896 * @param classElt the class element to query |
| 4897 * @return a mapping between the set of all members inherited from the passed
[ClassElement] | 4897 * @return a mapping between the set of all members inherited from the passed
[ClassElement] |
| 4898 * superclass hierarchy, and the associated [ExecutableElement] | 4898 * superclass hierarchy, and the associated [ExecutableElement] |
| 4899 */ | 4899 */ |
| 4900 @deprecated |
| 4900 MemberMap getMapOfMembersInheritedFromClasses(ClassElement classElt) => | 4901 MemberMap getMapOfMembersInheritedFromClasses(ClassElement classElt) => |
| 4901 _computeClassChainLookupMap(classElt, new HashSet<ClassElement>()); | 4902 new MemberMap.fromMap(_computeClassChainLookupMap(classElt, new HashSet<Cl
assElement>())); |
| 4902 | 4903 |
| 4903 /** | 4904 /** |
| 4904 * Get and return a mapping between the set of all string names of the members
inherited from the | 4905 * Get and return a mapping between the set of all string names of the members
inherited from the |
| 4905 * passed [ClassElement] interface hierarchy, and the associated [ExecutableEl
ement]. | 4906 * passed [ClassElement] interface hierarchy, and the associated [ExecutableEl
ement]. |
| 4906 * | 4907 * |
| 4907 * @param classElt the class element to query | 4908 * @param classElt the class element to query |
| 4908 * @return a mapping between the set of all string names of the members inheri
ted from the passed | 4909 * @return a mapping between the set of all string names of the members inheri
ted from the passed |
| 4909 * [ClassElement] interface hierarchy, and the associated [ExecutableE
lement]. | 4910 * [ClassElement] interface hierarchy, and the associated [ExecutableE
lement]. |
| 4910 */ | 4911 */ |
| 4912 @deprecated |
| 4911 MemberMap getMapOfMembersInheritedFromInterfaces(ClassElement classElt) => | 4913 MemberMap getMapOfMembersInheritedFromInterfaces(ClassElement classElt) => |
| 4914 new MemberMap.fromMap(_computeInterfaceLookupMap(classElt, new HashSet<Cla
ssElement>())); |
| 4915 |
| 4916 /** |
| 4917 * Return a table mapping the string names of the members inherited from the |
| 4918 * passed [ClassElement]'s superclass hierarchy, and the associated executable |
| 4919 * element. |
| 4920 */ |
| 4921 Map<String, ExecutableElement> getMembersInheritedFromClasses(ClassElement cla
ssElt) => |
| 4922 _computeClassChainLookupMap(classElt, new HashSet<ClassElement>()); |
| 4923 |
| 4924 /** |
| 4925 * Return a table mapping the string names of the members inherited from the |
| 4926 * passed [ClassElement]'s interface hierarchy, and the associated executable |
| 4927 * element. |
| 4928 */ |
| 4929 Map<String, ExecutableElement> getMembersInheritedFromInterfaces(ClassElement
classElt) => |
| 4912 _computeInterfaceLookupMap(classElt, new HashSet<ClassElement>()); | 4930 _computeInterfaceLookupMap(classElt, new HashSet<ClassElement>()); |
| 4913 | 4931 |
| 4914 /** | 4932 /** |
| 4915 * Given some [ClassElement] and some member name, this returns the | 4933 * Given some [ClassElement] and some member name, this returns the |
| 4916 * [ExecutableElement] that the class inherits from the mixins, | 4934 * [ExecutableElement] that the class inherits from the mixins, |
| 4917 * superclasses or interfaces, that has the member name, if no member is inher
ited `null` is | 4935 * superclasses or interfaces, that has the member name, if no member is inher
ited `null` is |
| 4918 * returned. | 4936 * returned. |
| 4919 * | 4937 * |
| 4920 * @param classElt the class element to query | 4938 * @param classElt the class element to query |
| 4921 * @param memberName the name of the executable element to find and return | 4939 * @param memberName the name of the executable element to find and return |
| 4922 * @return the inherited executable element with the member name, or `null` if
no such | 4940 * @return the inherited executable element with the member name, or `null` if
no such |
| 4923 * member exists | 4941 * member exists |
| 4924 */ | 4942 */ |
| 4925 ExecutableElement lookupInheritance( | 4943 ExecutableElement lookupInheritance( |
| 4926 ClassElement classElt, String memberName) { | 4944 ClassElement classElt, String memberName) { |
| 4927 if (memberName == null || memberName.isEmpty) { | 4945 if (memberName == null || memberName.isEmpty) { |
| 4928 return null; | 4946 return null; |
| 4929 } | 4947 } |
| 4930 ExecutableElement executable = | 4948 ExecutableElement executable = |
| 4931 _computeClassChainLookupMap(classElt, new HashSet<ClassElement>()) | 4949 _computeClassChainLookupMap(classElt, new HashSet<ClassElement>()) |
| 4932 .get(memberName); | 4950 [memberName]; |
| 4933 if (executable == null) { | 4951 if (executable == null) { |
| 4934 return _computeInterfaceLookupMap(classElt, new HashSet<ClassElement>()) | 4952 return _computeInterfaceLookupMap(classElt, new HashSet<ClassElement>()) |
| 4935 .get(memberName); | 4953 [memberName]; |
| 4936 } | 4954 } |
| 4937 return executable; | 4955 return executable; |
| 4938 } | 4956 } |
| 4939 | 4957 |
| 4940 /** | 4958 /** |
| 4941 * Given some [ClassElement] and some member name, this returns the | 4959 * Given some [ClassElement] and some member name, this returns the |
| 4942 * [ExecutableElement] that the class either declares itself, or | 4960 * [ExecutableElement] that the class either declares itself, or |
| 4943 * inherits, that has the member name, if no member is inherited `null` is ret
urned. | 4961 * inherits, that has the member name, if no member is inherited `null` is ret
urned. |
| 4944 * | 4962 * |
| 4945 * @param classElt the class element to query | 4963 * @param classElt the class element to query |
| (...skipping 18 matching lines...) Expand all Loading... |
| 4964 * @param classElt the class to query | 4982 * @param classElt the class to query |
| 4965 * @param memberName the name of the class member to query | 4983 * @param memberName the name of the class member to query |
| 4966 * @return a list of overridden methods | 4984 * @return a list of overridden methods |
| 4967 */ | 4985 */ |
| 4968 List<ExecutableElement> lookupOverrides( | 4986 List<ExecutableElement> lookupOverrides( |
| 4969 ClassElement classElt, String memberName) { | 4987 ClassElement classElt, String memberName) { |
| 4970 List<ExecutableElement> result = new List<ExecutableElement>(); | 4988 List<ExecutableElement> result = new List<ExecutableElement>(); |
| 4971 if (memberName == null || memberName.isEmpty) { | 4989 if (memberName == null || memberName.isEmpty) { |
| 4972 return result; | 4990 return result; |
| 4973 } | 4991 } |
| 4974 List<MemberMap> interfaceMaps = | 4992 List<Map<String, ExecutableElement>> interfaceMaps = |
| 4975 _gatherInterfaceLookupMaps(classElt, new HashSet<ClassElement>()); | 4993 _gatherInterfaceLookupMaps(classElt, new HashSet<ClassElement>()); |
| 4976 if (interfaceMaps != null) { | 4994 if (interfaceMaps != null) { |
| 4977 for (MemberMap interfaceMap in interfaceMaps) { | 4995 for (Map<String, ExecutableElement> interfaceMap in interfaceMaps) { |
| 4978 ExecutableElement overriddenElement = interfaceMap.get(memberName); | 4996 ExecutableElement overriddenElement = interfaceMap[memberName]; |
| 4979 if (overriddenElement != null) { | 4997 if (overriddenElement != null) { |
| 4980 if (overriddenElement is MultiplyInheritedExecutableElement) { | 4998 if (overriddenElement is MultiplyInheritedExecutableElement) { |
| 4981 MultiplyInheritedExecutableElement multiplyInheritedElement = | 4999 MultiplyInheritedExecutableElement multiplyInheritedElement = |
| 4982 overriddenElement; | 5000 overriddenElement; |
| 4983 for (ExecutableElement element | 5001 for (ExecutableElement element |
| 4984 in multiplyInheritedElement.inheritedElements) { | 5002 in multiplyInheritedElement.inheritedElements) { |
| 4985 result.add(element); | 5003 result.add(element); |
| 4986 } | 5004 } |
| 4987 } else { | 5005 } else { |
| 4988 result.add(overriddenElement); | 5006 result.add(overriddenElement); |
| (...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5039 * Compute and return a mapping between the set of all string names of the mem
bers inherited from | 5057 * Compute and return a mapping between the set of all string names of the mem
bers inherited from |
| 5040 * the passed [ClassElement] superclass hierarchy, and the associated | 5058 * the passed [ClassElement] superclass hierarchy, and the associated |
| 5041 * [ExecutableElement]. | 5059 * [ExecutableElement]. |
| 5042 * | 5060 * |
| 5043 * @param classElt the class element to query | 5061 * @param classElt the class element to query |
| 5044 * @param visitedClasses a set of visited classes passed back into this method
when it calls | 5062 * @param visitedClasses a set of visited classes passed back into this method
when it calls |
| 5045 * itself recursively | 5063 * itself recursively |
| 5046 * @return a mapping between the set of all string names of the members inheri
ted from the passed | 5064 * @return a mapping between the set of all string names of the members inheri
ted from the passed |
| 5047 * [ClassElement] superclass hierarchy, and the associated [Executable
Element] | 5065 * [ClassElement] superclass hierarchy, and the associated [Executable
Element] |
| 5048 */ | 5066 */ |
| 5049 MemberMap _computeClassChainLookupMap( | 5067 Map<String, ExecutableElement> _computeClassChainLookupMap( |
| 5050 ClassElement classElt, HashSet<ClassElement> visitedClasses) { | 5068 ClassElement classElt, Set<ClassElement> visitedClasses) { |
| 5051 MemberMap resultMap = _classLookup[classElt]; | 5069 Map<String, ExecutableElement> resultMap = _classLookup[classElt]; |
| 5052 if (resultMap != null) { | 5070 if (resultMap != null) { |
| 5053 return resultMap; | 5071 return resultMap; |
| 5054 } else { | 5072 } else { |
| 5055 resultMap = new MemberMap(); | 5073 resultMap = new Map<String, ExecutableElement>(); |
| 5056 } | 5074 } |
| 5057 ClassElement superclassElt = null; | 5075 ClassElement superclassElt = null; |
| 5058 InterfaceType supertype = classElt.supertype; | 5076 InterfaceType supertype = classElt.supertype; |
| 5059 if (supertype != null) { | 5077 if (supertype != null) { |
| 5060 superclassElt = supertype.element; | 5078 superclassElt = supertype.element; |
| 5061 } else { | 5079 } else { |
| 5062 // classElt is Object | 5080 // classElt is Object |
| 5063 _classLookup[classElt] = resultMap; | 5081 _classLookup[classElt] = resultMap; |
| 5064 return resultMap; | 5082 return resultMap; |
| 5065 } | 5083 } |
| 5066 if (superclassElt != null) { | 5084 if (superclassElt != null) { |
| 5067 if (!visitedClasses.contains(superclassElt)) { | 5085 if (!visitedClasses.contains(superclassElt)) { |
| 5068 visitedClasses.add(superclassElt); | 5086 visitedClasses.add(superclassElt); |
| 5069 try { | 5087 try { |
| 5070 resultMap = new MemberMap.from( | 5088 resultMap = new Map<String, ExecutableElement>.from( |
| 5071 _computeClassChainLookupMap(superclassElt, visitedClasses)); | 5089 _computeClassChainLookupMap(superclassElt, visitedClasses)); |
| 5072 // | 5090 // |
| 5073 // Substitute the super types down the hierarchy. | 5091 // Substitute the super types down the hierarchy. |
| 5074 // | 5092 // |
| 5075 _substituteTypeParametersDownHierarchy(supertype, resultMap); | 5093 _substituteTypeParametersDownHierarchy(supertype, resultMap); |
| 5076 // | 5094 // |
| 5077 // Include the members from the superclass in the resultMap. | 5095 // Include the members from the superclass in the resultMap. |
| 5078 // | 5096 // |
| 5079 _recordMapWithClassMembers(resultMap, supertype, false); | 5097 _recordMapWithClassMembers(resultMap, supertype, false); |
| 5080 } finally { | 5098 } finally { |
| (...skipping 12 matching lines...) Expand all Loading... |
| 5093 // multiple mixins, visit them in the order listed so that methods in later | 5111 // multiple mixins, visit them in the order listed so that methods in later |
| 5094 // mixins will overwrite identically-named methods in earlier mixins. | 5112 // mixins will overwrite identically-named methods in earlier mixins. |
| 5095 // | 5113 // |
| 5096 List<InterfaceType> mixins = classElt.mixins; | 5114 List<InterfaceType> mixins = classElt.mixins; |
| 5097 for (InterfaceType mixin in mixins) { | 5115 for (InterfaceType mixin in mixins) { |
| 5098 ClassElement mixinElement = mixin.element; | 5116 ClassElement mixinElement = mixin.element; |
| 5099 if (mixinElement != null) { | 5117 if (mixinElement != null) { |
| 5100 if (!visitedClasses.contains(mixinElement)) { | 5118 if (!visitedClasses.contains(mixinElement)) { |
| 5101 visitedClasses.add(mixinElement); | 5119 visitedClasses.add(mixinElement); |
| 5102 try { | 5120 try { |
| 5103 MemberMap map = new MemberMap.from( | 5121 Map<String, ExecutableElement> map = new Map<String, ExecutableEleme
nt>.from( |
| 5104 _computeClassChainLookupMap(mixinElement, visitedClasses)); | 5122 _computeClassChainLookupMap(mixinElement, visitedClasses)); |
| 5105 // | 5123 // |
| 5106 // Substitute the super types down the hierarchy. | 5124 // Substitute the super types down the hierarchy. |
| 5107 // | 5125 // |
| 5108 _substituteTypeParametersDownHierarchy(mixin, map); | 5126 _substituteTypeParametersDownHierarchy(mixin, map); |
| 5109 // | 5127 // |
| 5110 // Include the members from the superclass in the resultMap. | 5128 // Include the members from the superclass in the resultMap. |
| 5111 // | 5129 // |
| 5112 _recordMapWithClassMembers(map, mixin, false); | 5130 _recordMapWithClassMembers(map, mixin, false); |
| 5113 // | 5131 // |
| 5114 // Add the members from map into result map. | 5132 // Add the members from map into result map. |
| 5115 // | 5133 // |
| 5116 for (int j = 0; j < map.size; j++) { | 5134 for (String memberName in map.keys) { |
| 5117 String key = map.getKey(j); | 5135 ExecutableElement value = map[memberName]; |
| 5118 ExecutableElement value = map.getValue(j); | 5136 ClassElement definingClass = value |
| 5119 if (key != null) { | 5137 .getAncestor((Element element) => element is ClassElement); |
| 5120 ClassElement definingClass = value | 5138 if (!definingClass.type.isObject) { |
| 5121 .getAncestor((Element element) => element is ClassElement); | 5139 ExecutableElement existingValue = resultMap[memberName]; |
| 5122 if (!definingClass.type.isObject) { | 5140 if (existingValue == null || |
| 5123 ExecutableElement existingValue = resultMap.get(key); | 5141 (existingValue != null && !_isAbstract(value))) { |
| 5124 if (existingValue == null || | 5142 resultMap[memberName] = value; |
| 5125 (existingValue != null && !_isAbstract(value))) { | |
| 5126 resultMap.put(key, value); | |
| 5127 } | |
| 5128 } | 5143 } |
| 5129 } | 5144 } |
| 5130 } | 5145 } |
| 5131 } finally { | 5146 } finally { |
| 5132 visitedClasses.remove(mixinElement); | 5147 visitedClasses.remove(mixinElement); |
| 5133 } | 5148 } |
| 5134 } else { | 5149 } else { |
| 5135 // This case happens only when the superclass was previously visited | 5150 // This case happens only when the superclass was previously visited |
| 5136 // and not in the lookup, meaning this is meant to shorten the compute | 5151 // and not in the lookup, meaning this is meant to shorten the compute |
| 5137 // for recursive cases. | 5152 // for recursive cases. |
| (...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5212 * Compute and return a mapping between the set of all string names of the mem
bers inherited from | 5227 * Compute and return a mapping between the set of all string names of the mem
bers inherited from |
| 5213 * the passed [ClassElement] interface hierarchy, and the associated | 5228 * the passed [ClassElement] interface hierarchy, and the associated |
| 5214 * [ExecutableElement]. | 5229 * [ExecutableElement]. |
| 5215 * | 5230 * |
| 5216 * @param classElt the class element to query | 5231 * @param classElt the class element to query |
| 5217 * @param visitedInterfaces a set of visited classes passed back into this met
hod when it calls | 5232 * @param visitedInterfaces a set of visited classes passed back into this met
hod when it calls |
| 5218 * itself recursively | 5233 * itself recursively |
| 5219 * @return a mapping between the set of all string names of the members inheri
ted from the passed | 5234 * @return a mapping between the set of all string names of the members inheri
ted from the passed |
| 5220 * [ClassElement] interface hierarchy, and the associated [ExecutableE
lement] | 5235 * [ClassElement] interface hierarchy, and the associated [ExecutableE
lement] |
| 5221 */ | 5236 */ |
| 5222 MemberMap _computeInterfaceLookupMap( | 5237 Map<String, ExecutableElement> _computeInterfaceLookupMap( |
| 5223 ClassElement classElt, HashSet<ClassElement> visitedInterfaces) { | 5238 ClassElement classElt, HashSet<ClassElement> visitedInterfaces) { |
| 5224 MemberMap resultMap = _interfaceLookup[classElt]; | 5239 Map<String, ExecutableElement> resultMap = _interfaceLookup[classElt]; |
| 5225 if (resultMap != null) { | 5240 if (resultMap != null) { |
| 5226 return resultMap; | 5241 return resultMap; |
| 5227 } | 5242 } |
| 5228 List<MemberMap> lookupMaps = | 5243 List<Map<String, ExecutableElement>> lookupMaps = |
| 5229 _gatherInterfaceLookupMaps(classElt, visitedInterfaces); | 5244 _gatherInterfaceLookupMaps(classElt, visitedInterfaces); |
| 5230 if (lookupMaps == null) { | 5245 if (lookupMaps == null) { |
| 5231 resultMap = new MemberMap(); | 5246 resultMap = new Map<String, ExecutableElement>(); |
| 5232 } else { | 5247 } else { |
| 5233 HashMap<String, List<ExecutableElement>> unionMap = | 5248 HashMap<String, List<ExecutableElement>> unionMap = |
| 5234 _unionInterfaceLookupMaps(lookupMaps); | 5249 _unionInterfaceLookupMaps(lookupMaps); |
| 5235 resultMap = _resolveInheritanceLookup(classElt, unionMap); | 5250 resultMap = _resolveInheritanceLookup(classElt, unionMap); |
| 5236 } | 5251 } |
| 5237 _interfaceLookup[classElt] = resultMap; | 5252 _interfaceLookup[classElt] = resultMap; |
| 5238 return resultMap; | 5253 return resultMap; |
| 5239 } | 5254 } |
| 5240 | 5255 |
| 5241 /** | 5256 /** |
| 5242 * Collect a list of interface lookup maps whose elements correspond to all of
the classes | 5257 * Collect a list of interface lookup maps whose elements correspond to all of
the classes |
| 5243 * directly above [classElt] in the class hierarchy (the direct superclass if
any, all | 5258 * directly above [classElt] in the class hierarchy (the direct superclass if
any, all |
| 5244 * mixins, and all direct superinterfaces). Each item in the list is the inter
face lookup map | 5259 * mixins, and all direct superinterfaces). Each item in the list is the inter
face lookup map |
| 5245 * returned by [computeInterfaceLookupMap] for the corresponding super, except
with type | 5260 * returned by [computeInterfaceLookupMap] for the corresponding super, except
with type |
| 5246 * parameters appropriately substituted. | 5261 * parameters appropriately substituted. |
| 5247 * | 5262 * |
| 5248 * @param classElt the class element to query | 5263 * @param classElt the class element to query |
| 5249 * @param visitedInterfaces a set of visited classes passed back into this met
hod when it calls | 5264 * @param visitedInterfaces a set of visited classes passed back into this met
hod when it calls |
| 5250 * itself recursively | 5265 * itself recursively |
| 5251 * @return `null` if there was a problem (such as a loop in the class hierarch
y) or if there | 5266 * @return `null` if there was a problem (such as a loop in the class hierarch
y) or if there |
| 5252 * are no classes above this one in the class hierarchy. Otherwise, a
list of interface | 5267 * are no classes above this one in the class hierarchy. Otherwise, a
list of interface |
| 5253 * lookup maps. | 5268 * lookup maps. |
| 5254 */ | 5269 */ |
| 5255 List<MemberMap> _gatherInterfaceLookupMaps( | 5270 List<Map<String, ExecutableElement>> _gatherInterfaceLookupMaps( |
| 5256 ClassElement classElt, HashSet<ClassElement> visitedInterfaces) { | 5271 ClassElement classElt, HashSet<ClassElement> visitedInterfaces) { |
| 5257 InterfaceType supertype = classElt.supertype; | 5272 InterfaceType supertype = classElt.supertype; |
| 5258 ClassElement superclassElement = | 5273 ClassElement superclassElement = |
| 5259 supertype != null ? supertype.element : null; | 5274 supertype != null ? supertype.element : null; |
| 5260 List<InterfaceType> mixins = classElt.mixins; | 5275 List<InterfaceType> mixins = classElt.mixins; |
| 5261 List<InterfaceType> interfaces = classElt.interfaces; | 5276 List<InterfaceType> interfaces = classElt.interfaces; |
| 5262 // Recursively collect the list of mappings from all of the interface types | 5277 // Recursively collect the list of mappings from all of the interface types |
| 5263 List<MemberMap> lookupMaps = new List<MemberMap>(); | 5278 List<Map<String, ExecutableElement>> lookupMaps = new List<Map<String, Execu
tableElement>>(); |
| 5264 // | 5279 // |
| 5265 // Superclass element | 5280 // Superclass element |
| 5266 // | 5281 // |
| 5267 if (superclassElement != null) { | 5282 if (superclassElement != null) { |
| 5268 if (!visitedInterfaces.contains(superclassElement)) { | 5283 if (!visitedInterfaces.contains(superclassElement)) { |
| 5269 try { | 5284 try { |
| 5270 visitedInterfaces.add(superclassElement); | 5285 visitedInterfaces.add(superclassElement); |
| 5271 // | 5286 // |
| 5272 // Recursively compute the map for the super type. | 5287 // Recursively compute the map for the super type. |
| 5273 // | 5288 // |
| 5274 MemberMap map = | 5289 Map<String, ExecutableElement> map = |
| 5275 _computeInterfaceLookupMap(superclassElement, visitedInterfaces); | 5290 _computeInterfaceLookupMap(superclassElement, visitedInterfaces); |
| 5276 map = new MemberMap.from(map); | 5291 map = new Map<String, ExecutableElement>.from(map); |
| 5277 // | 5292 // |
| 5278 // Substitute the super type down the hierarchy. | 5293 // Substitute the super type down the hierarchy. |
| 5279 // | 5294 // |
| 5280 _substituteTypeParametersDownHierarchy(supertype, map); | 5295 _substituteTypeParametersDownHierarchy(supertype, map); |
| 5281 // | 5296 // |
| 5282 // Add any members from the super type into the map as well. | 5297 // Add any members from the super type into the map as well. |
| 5283 // | 5298 // |
| 5284 _recordMapWithClassMembers(map, supertype, true); | 5299 _recordMapWithClassMembers(map, supertype, true); |
| 5285 lookupMaps.add(map); | 5300 lookupMaps.add(map); |
| 5286 } finally { | 5301 } finally { |
| 5287 visitedInterfaces.remove(superclassElement); | 5302 visitedInterfaces.remove(superclassElement); |
| 5288 } | 5303 } |
| 5289 } else { | 5304 } else { |
| 5290 return null; | 5305 return null; |
| 5291 } | 5306 } |
| 5292 } | 5307 } |
| 5293 // | 5308 // |
| 5294 // Mixin elements | 5309 // Mixin elements |
| 5295 // | 5310 // |
| 5296 for (int i = mixins.length - 1; i >= 0; i--) { | 5311 for (int i = mixins.length - 1; i >= 0; i--) { |
| 5297 InterfaceType mixinType = mixins[i]; | 5312 InterfaceType mixinType = mixins[i]; |
| 5298 ClassElement mixinElement = mixinType.element; | 5313 ClassElement mixinElement = mixinType.element; |
| 5299 if (mixinElement != null) { | 5314 if (mixinElement != null) { |
| 5300 if (!visitedInterfaces.contains(mixinElement)) { | 5315 if (!visitedInterfaces.contains(mixinElement)) { |
| 5301 try { | 5316 try { |
| 5302 visitedInterfaces.add(mixinElement); | 5317 visitedInterfaces.add(mixinElement); |
| 5303 // | 5318 // |
| 5304 // Recursively compute the map for the mixin. | 5319 // Recursively compute the map for the mixin. |
| 5305 // | 5320 // |
| 5306 MemberMap map = | 5321 Map<String, ExecutableElement> map = |
| 5307 _computeInterfaceLookupMap(mixinElement, visitedInterfaces); | 5322 _computeInterfaceLookupMap(mixinElement, visitedInterfaces); |
| 5308 map = new MemberMap.from(map); | 5323 map = new Map<String, ExecutableElement>.from(map); |
| 5309 // | 5324 // |
| 5310 // Substitute the mixin type down the hierarchy. | 5325 // Substitute the mixin type down the hierarchy. |
| 5311 // | 5326 // |
| 5312 _substituteTypeParametersDownHierarchy(mixinType, map); | 5327 _substituteTypeParametersDownHierarchy(mixinType, map); |
| 5313 // | 5328 // |
| 5314 // Add any members from the mixin type into the map as well. | 5329 // Add any members from the mixin type into the map as well. |
| 5315 // | 5330 // |
| 5316 _recordMapWithClassMembers(map, mixinType, true); | 5331 _recordMapWithClassMembers(map, mixinType, true); |
| 5317 lookupMaps.add(map); | 5332 lookupMaps.add(map); |
| 5318 } finally { | 5333 } finally { |
| 5319 visitedInterfaces.remove(mixinElement); | 5334 visitedInterfaces.remove(mixinElement); |
| 5320 } | 5335 } |
| 5321 } else { | 5336 } else { |
| 5322 return null; | 5337 return null; |
| 5323 } | 5338 } |
| 5324 } | 5339 } |
| 5325 } | 5340 } |
| 5326 // | 5341 // |
| 5327 // Interface elements | 5342 // Interface elements |
| 5328 // | 5343 // |
| 5329 for (InterfaceType interfaceType in interfaces) { | 5344 for (InterfaceType interfaceType in interfaces) { |
| 5330 ClassElement interfaceElement = interfaceType.element; | 5345 ClassElement interfaceElement = interfaceType.element; |
| 5331 if (interfaceElement != null) { | 5346 if (interfaceElement != null) { |
| 5332 if (!visitedInterfaces.contains(interfaceElement)) { | 5347 if (!visitedInterfaces.contains(interfaceElement)) { |
| 5333 try { | 5348 try { |
| 5334 visitedInterfaces.add(interfaceElement); | 5349 visitedInterfaces.add(interfaceElement); |
| 5335 // | 5350 // |
| 5336 // Recursively compute the map for the interfaces. | 5351 // Recursively compute the map for the interfaces. |
| 5337 // | 5352 // |
| 5338 MemberMap map = | 5353 Map<String, ExecutableElement> map = |
| 5339 _computeInterfaceLookupMap(interfaceElement, visitedInterfaces); | 5354 _computeInterfaceLookupMap(interfaceElement, visitedInterfaces); |
| 5340 map = new MemberMap.from(map); | 5355 map = new Map<String, ExecutableElement>.from(map); |
| 5341 // | 5356 // |
| 5342 // Substitute the supertypes down the hierarchy | 5357 // Substitute the supertypes down the hierarchy |
| 5343 // | 5358 // |
| 5344 _substituteTypeParametersDownHierarchy(interfaceType, map); | 5359 _substituteTypeParametersDownHierarchy(interfaceType, map); |
| 5345 // | 5360 // |
| 5346 // And add any members from the interface into the map as well. | 5361 // And add any members from the interface into the map as well. |
| 5347 // | 5362 // |
| 5348 _recordMapWithClassMembers(map, interfaceType, true); | 5363 _recordMapWithClassMembers(map, interfaceType, true); |
| 5349 lookupMaps.add(map); | 5364 lookupMaps.add(map); |
| 5350 } finally { | 5365 } finally { |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5394 /** | 5409 /** |
| 5395 * Record the passed map with the set of all members (methods, getters and set
ters) in the type | 5410 * Record the passed map with the set of all members (methods, getters and set
ters) in the type |
| 5396 * into the passed map. | 5411 * into the passed map. |
| 5397 * | 5412 * |
| 5398 * @param map some non-`null` map to put the methods and accessors from the pa
ssed | 5413 * @param map some non-`null` map to put the methods and accessors from the pa
ssed |
| 5399 * [ClassElement] into | 5414 * [ClassElement] into |
| 5400 * @param type the type that will be recorded into the passed map | 5415 * @param type the type that will be recorded into the passed map |
| 5401 * @param doIncludeAbstract `true` if abstract members will be put into the ma
p | 5416 * @param doIncludeAbstract `true` if abstract members will be put into the ma
p |
| 5402 */ | 5417 */ |
| 5403 void _recordMapWithClassMembers( | 5418 void _recordMapWithClassMembers( |
| 5404 MemberMap map, InterfaceType type, bool doIncludeAbstract) { | 5419 Map<String, ExecutableElement> map, InterfaceType type, bool doIncludeAbst
ract) { |
| 5405 List<MethodElement> methods = type.methods; | 5420 List<MethodElement> methods = type.methods; |
| 5406 for (MethodElement method in methods) { | 5421 for (MethodElement method in methods) { |
| 5407 if (method.isAccessibleIn(_library) && | 5422 if (method.isAccessibleIn(_library) && |
| 5408 !method.isStatic && | 5423 !method.isStatic && |
| 5409 (doIncludeAbstract || !method.isAbstract)) { | 5424 (doIncludeAbstract || !method.isAbstract)) { |
| 5410 map.put(method.name, method); | 5425 map[method.name] = method; |
| 5411 } | 5426 } |
| 5412 } | 5427 } |
| 5413 List<PropertyAccessorElement> accessors = type.accessors; | 5428 List<PropertyAccessorElement> accessors = type.accessors; |
| 5414 for (PropertyAccessorElement accessor in accessors) { | 5429 for (PropertyAccessorElement accessor in accessors) { |
| 5415 if (accessor.isAccessibleIn(_library) && | 5430 if (accessor.isAccessibleIn(_library) && |
| 5416 !accessor.isStatic && | 5431 !accessor.isStatic && |
| 5417 (doIncludeAbstract || !accessor.isAbstract)) { | 5432 (doIncludeAbstract || !accessor.isAbstract)) { |
| 5418 map.put(accessor.name, accessor); | 5433 map[accessor.name] = accessor; |
| 5419 } | 5434 } |
| 5420 } | 5435 } |
| 5421 } | 5436 } |
| 5422 | 5437 |
| 5423 /** | 5438 /** |
| 5424 * This method is used to report errors on when they are found computing inher
itance information. | 5439 * This method is used to report errors on when they are found computing inher
itance information. |
| 5425 * See [ErrorVerifier.checkForInconsistentMethodInheritance] to see where thes
e generated | 5440 * See [ErrorVerifier.checkForInconsistentMethodInheritance] to see where thes
e generated |
| 5426 * error codes are reported back into the analysis engine. | 5441 * error codes are reported back into the analysis engine. |
| 5427 * | 5442 * |
| 5428 * @param classElt the location of the source for which the exception occurred | 5443 * @param classElt the location of the source for which the exception occurred |
| (...skipping 18 matching lines...) Expand all Loading... |
| 5447 * apply the appropriate inheritance rules to determine those methods inherite
d by or overridden | 5462 * apply the appropriate inheritance rules to determine those methods inherite
d by or overridden |
| 5448 * by [classElt]. Also report static warnings | 5463 * by [classElt]. Also report static warnings |
| 5449 * [StaticTypeWarningCode.INCONSISTENT_METHOD_INHERITANCE] and | 5464 * [StaticTypeWarningCode.INCONSISTENT_METHOD_INHERITANCE] and |
| 5450 * [StaticWarningCode.INCONSISTENT_METHOD_INHERITANCE_GETTER_AND_METHOD] if ap
propriate. | 5465 * [StaticWarningCode.INCONSISTENT_METHOD_INHERITANCE_GETTER_AND_METHOD] if ap
propriate. |
| 5451 * | 5466 * |
| 5452 * @param classElt the class element to query. | 5467 * @param classElt the class element to query. |
| 5453 * @param unionMap a mapping from method name to the set of unique (in terms o
f signature) methods | 5468 * @param unionMap a mapping from method name to the set of unique (in terms o
f signature) methods |
| 5454 * defined in superclasses of [classElt]. | 5469 * defined in superclasses of [classElt]. |
| 5455 * @return the inheritance lookup map for [classElt]. | 5470 * @return the inheritance lookup map for [classElt]. |
| 5456 */ | 5471 */ |
| 5457 MemberMap _resolveInheritanceLookup(ClassElement classElt, | 5472 Map<String, ExecutableElement> _resolveInheritanceLookup(ClassElement classElt
, |
| 5458 HashMap<String, List<ExecutableElement>> unionMap) { | 5473 Map<String, List<ExecutableElement>> unionMap) { |
| 5459 MemberMap resultMap = new MemberMap(); | 5474 Map<String, ExecutableElement> resultMap = new Map<String, ExecutableElement
>(); |
| 5460 unionMap.forEach((String key, List<ExecutableElement> list) { | 5475 unionMap.forEach((String key, List<ExecutableElement> list) { |
| 5461 int numOfEltsWithMatchingNames = list.length; | 5476 int numOfEltsWithMatchingNames = list.length; |
| 5462 if (numOfEltsWithMatchingNames == 1) { | 5477 if (numOfEltsWithMatchingNames == 1) { |
| 5463 // | 5478 // |
| 5464 // Example: class A inherits only 1 method named 'm'. | 5479 // Example: class A inherits only 1 method named 'm'. |
| 5465 // Since it is the only such method, it is inherited. | 5480 // Since it is the only such method, it is inherited. |
| 5466 // Another example: class A inherits 2 methods named 'm' from 2 | 5481 // Another example: class A inherits 2 methods named 'm' from 2 |
| 5467 // different interfaces, but they both have the same signature, so it is | 5482 // different interfaces, but they both have the same signature, so it is |
| 5468 // the method inherited. | 5483 // the method inherited. |
| 5469 // | 5484 // |
| 5470 resultMap.put(key, list[0]); | 5485 resultMap[key] = list[0]; |
| 5471 } else { | 5486 } else { |
| 5472 // | 5487 // |
| 5473 // Then numOfEltsWithMatchingNames > 1, check for the warning cases. | 5488 // Then numOfEltsWithMatchingNames > 1, check for the warning cases. |
| 5474 // | 5489 // |
| 5475 bool allMethods = true; | 5490 bool allMethods = true; |
| 5476 bool allSetters = true; | 5491 bool allSetters = true; |
| 5477 bool allGetters = true; | 5492 bool allGetters = true; |
| 5478 for (ExecutableElement executableElement in list) { | 5493 for (ExecutableElement executableElement in list) { |
| 5479 if (executableElement is PropertyAccessorElement) { | 5494 if (executableElement is PropertyAccessorElement) { |
| 5480 allMethods = false; | 5495 allMethods = false; |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5532 // | 5547 // |
| 5533 if (subtypesOfAllOtherTypesIndexes.length == 1) { | 5548 if (subtypesOfAllOtherTypesIndexes.length == 1) { |
| 5534 // | 5549 // |
| 5535 // Example: class A inherited only 2 method named 'm'. | 5550 // Example: class A inherited only 2 method named 'm'. |
| 5536 // One has the function type '() -> dynamic' and one has the | 5551 // One has the function type '() -> dynamic' and one has the |
| 5537 // function type '([int]) -> dynamic'. Since the second method is a | 5552 // function type '([int]) -> dynamic'. Since the second method is a |
| 5538 // subtype of all the others, it is the inherited method. | 5553 // subtype of all the others, it is the inherited method. |
| 5539 // Tests: InheritanceManagerTest. | 5554 // Tests: InheritanceManagerTest. |
| 5540 // test_getMapOfMembersInheritedFromInterfaces_union_oneSubtype_* | 5555 // test_getMapOfMembersInheritedFromInterfaces_union_oneSubtype_* |
| 5541 // | 5556 // |
| 5542 resultMap.put(key, elements[subtypesOfAllOtherTypesIndexes[0]]); | 5557 resultMap[key] = elements[subtypesOfAllOtherTypesIndexes[0]]; |
| 5543 } else { | 5558 } else { |
| 5544 if (subtypesOfAllOtherTypesIndexes.isEmpty) { | 5559 if (subtypesOfAllOtherTypesIndexes.isEmpty) { |
| 5545 // | 5560 // |
| 5546 // Determine if the current class has a method or accessor with | 5561 // Determine if the current class has a method or accessor with |
| 5547 // the member name, if it does then then this class does not | 5562 // the member name, if it does then then this class does not |
| 5548 // "inherit" from any of the supertypes. See issue 16134. | 5563 // "inherit" from any of the supertypes. See issue 16134. |
| 5549 // | 5564 // |
| 5550 bool classHasMember = false; | 5565 bool classHasMember = false; |
| 5551 if (allMethods) { | 5566 if (allMethods) { |
| 5552 classHasMember = classElt.getMethod(key) != null; | 5567 classHasMember = classElt.getMethod(key) != null; |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5586 // | 5601 // |
| 5587 List<ExecutableElement> elementArrayToMerge = | 5602 List<ExecutableElement> elementArrayToMerge = |
| 5588 new List<ExecutableElement>( | 5603 new List<ExecutableElement>( |
| 5589 subtypesOfAllOtherTypesIndexes.length); | 5604 subtypesOfAllOtherTypesIndexes.length); |
| 5590 for (int i = 0; i < elementArrayToMerge.length; i++) { | 5605 for (int i = 0; i < elementArrayToMerge.length; i++) { |
| 5591 elementArrayToMerge[i] = | 5606 elementArrayToMerge[i] = |
| 5592 elements[subtypesOfAllOtherTypesIndexes[i]]; | 5607 elements[subtypesOfAllOtherTypesIndexes[i]]; |
| 5593 } | 5608 } |
| 5594 ExecutableElement mergedExecutableElement = | 5609 ExecutableElement mergedExecutableElement = |
| 5595 _computeMergedExecutableElement(elementArrayToMerge); | 5610 _computeMergedExecutableElement(elementArrayToMerge); |
| 5596 resultMap.put(key, mergedExecutableElement); | 5611 resultMap[key] = mergedExecutableElement; |
| 5597 } | 5612 } |
| 5598 } | 5613 } |
| 5599 } else { | 5614 } else { |
| 5600 _reportError( | 5615 _reportError( |
| 5601 classElt, | 5616 classElt, |
| 5602 classElt.nameOffset, | 5617 classElt.nameOffset, |
| 5603 classElt.nameLength, | 5618 classElt.nameLength, |
| 5604 StaticWarningCode | 5619 StaticWarningCode |
| 5605 .INCONSISTENT_METHOD_INHERITANCE_GETTER_AND_METHOD, | 5620 .INCONSISTENT_METHOD_INHERITANCE_GETTER_AND_METHOD, |
| 5606 [key]); | 5621 [key]); |
| 5607 } | 5622 } |
| 5608 } | 5623 } |
| 5609 }); | 5624 }); |
| 5610 return resultMap; | 5625 return resultMap; |
| 5611 } | 5626 } |
| 5612 | 5627 |
| 5613 /** | 5628 /** |
| 5614 * Loop through all of the members in some [MemberMap], performing type parame
ter | 5629 * Loop through all of the members in the given [map], performing type |
| 5615 * substitutions using a passed supertype. | 5630 * parameter substitutions using a passed [supertype]. |
| 5616 * | |
| 5617 * @param superType the supertype to substitute into the members of the [Membe
rMap] | |
| 5618 * @param map the MemberMap to perform the substitutions on | |
| 5619 */ | 5631 */ |
| 5620 void _substituteTypeParametersDownHierarchy( | 5632 void _substituteTypeParametersDownHierarchy( |
| 5621 InterfaceType superType, MemberMap map) { | 5633 InterfaceType superType, Map<String, ExecutableElement> map) { |
| 5622 for (int i = 0; i < map.size; i++) { | 5634 for (String memberName in map.keys) { |
| 5623 ExecutableElement executableElement = map.getValue(i); | 5635 ExecutableElement executableElement = map[memberName]; |
| 5624 if (executableElement is MethodMember) { | 5636 if (executableElement is MethodMember) { |
| 5625 executableElement = | 5637 executableElement = |
| 5626 MethodMember.from(executableElement as MethodMember, superType); | 5638 MethodMember.from(executableElement as MethodMember, superType); |
| 5627 map.setValue(i, executableElement); | 5639 map[memberName] = executableElement; |
| 5628 } else if (executableElement is PropertyAccessorMember) { | 5640 } else if (executableElement is PropertyAccessorMember) { |
| 5629 executableElement = PropertyAccessorMember.from( | 5641 executableElement = PropertyAccessorMember.from( |
| 5630 executableElement as PropertyAccessorMember, superType); | 5642 executableElement as PropertyAccessorMember, superType); |
| 5631 map.setValue(i, executableElement); | 5643 map[memberName] = executableElement; |
| 5632 } | 5644 } |
| 5633 } | 5645 } |
| 5634 } | 5646 } |
| 5635 | 5647 |
| 5636 /** | 5648 /** |
| 5637 * Union all of the [lookupMaps] together into a single map, grouping the Exec
utableElements | 5649 * Union all of the [lookupMaps] together into a single map, grouping the Exec
utableElements |
| 5638 * into a list where none of the elements are equal where equality is determin
ed by having equal | 5650 * into a list where none of the elements are equal where equality is determin
ed by having equal |
| 5639 * function types. (We also take note too of the kind of the element: ()->int
and () -> int may | 5651 * function types. (We also take note too of the kind of the element: ()->int
and () -> int may |
| 5640 * not be equal if one is a getter and the other is a method.) | 5652 * not be equal if one is a getter and the other is a method.) |
| 5641 * | 5653 * |
| 5642 * @param lookupMaps the maps to be unioned together. | 5654 * @param lookupMaps the maps to be unioned together. |
| 5643 * @return the resulting union map. | 5655 * @return the resulting union map. |
| 5644 */ | 5656 */ |
| 5645 HashMap<String, List<ExecutableElement>> _unionInterfaceLookupMaps( | 5657 HashMap<String, List<ExecutableElement>> _unionInterfaceLookupMaps( |
| 5646 List<MemberMap> lookupMaps) { | 5658 List<Map<String, ExecutableElement>> lookupMaps) { |
| 5647 HashMap<String, List<ExecutableElement>> unionMap = | 5659 HashMap<String, List<ExecutableElement>> unionMap = |
| 5648 new HashMap<String, List<ExecutableElement>>(); | 5660 new HashMap<String, List<ExecutableElement>>(); |
| 5649 for (MemberMap lookupMap in lookupMaps) { | 5661 for (Map<String, ExecutableElement> lookupMap in lookupMaps) { |
| 5650 int lookupMapSize = lookupMap.size; | 5662 for (String memberName in lookupMap.keys) { |
| 5651 for (int i = 0; i < lookupMapSize; i++) { | |
| 5652 // Get the string key, if null, break. | |
| 5653 String key = lookupMap.getKey(i); | |
| 5654 if (key == null) { | |
| 5655 break; | |
| 5656 } | |
| 5657 // Get the list value out of the unionMap | 5663 // Get the list value out of the unionMap |
| 5658 List<ExecutableElement> list = unionMap[key]; | 5664 List<ExecutableElement> list = unionMap[memberName]; |
| 5659 // If we haven't created such a map for this key yet, do create it and | 5665 // If we haven't created such a map for this key yet, do create it and |
| 5660 // put the list entry into the unionMap. | 5666 // put the list entry into the unionMap. |
| 5661 if (list == null) { | 5667 if (list == null) { |
| 5662 list = new List<ExecutableElement>(); | 5668 list = new List<ExecutableElement>(); |
| 5663 unionMap[key] = list; | 5669 unionMap[memberName] = list; |
| 5664 } | 5670 } |
| 5665 // Fetch the entry out of this lookupMap | 5671 // Fetch the entry out of this lookupMap |
| 5666 ExecutableElement newExecutableElementEntry = lookupMap.getValue(i); | 5672 ExecutableElement newExecutableElementEntry = lookupMap[memberName]; |
| 5667 if (list.isEmpty) { | 5673 if (list.isEmpty) { |
| 5668 // If the list is empty, just the new value | 5674 // If the list is empty, just the new value |
| 5669 list.add(newExecutableElementEntry); | 5675 list.add(newExecutableElementEntry); |
| 5670 } else { | 5676 } else { |
| 5671 // Otherwise, only add the newExecutableElementEntry if it isn't | 5677 // Otherwise, only add the newExecutableElementEntry if it isn't |
| 5672 // already in the list, this covers situation where a class inherits | 5678 // already in the list, this covers situation where a class inherits |
| 5673 // two methods (or two getters) that are identical. | 5679 // two methods (or two getters) that are identical. |
| 5674 bool alreadyInList = false; | 5680 bool alreadyInList = false; |
| 5675 bool isMethod1 = newExecutableElementEntry is MethodElement; | 5681 bool isMethod1 = newExecutableElementEntry is MethodElement; |
| 5676 for (ExecutableElement executableElementInList in list) { | 5682 for (ExecutableElement executableElementInList in list) { |
| (...skipping 211 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5888 INIT_IN_INITIALIZERS | 5894 INIT_IN_INITIALIZERS |
| 5889 ]; | 5895 ]; |
| 5890 | 5896 |
| 5891 const INIT_STATE(String name, int ordinal) : super(name, ordinal); | 5897 const INIT_STATE(String name, int ordinal) : super(name, ordinal); |
| 5892 } | 5898 } |
| 5893 | 5899 |
| 5894 /** | 5900 /** |
| 5895 * This class is used to replace uses of `HashMap<String, ExecutableElement>` | 5901 * This class is used to replace uses of `HashMap<String, ExecutableElement>` |
| 5896 * which are not as performant as this class. | 5902 * which are not as performant as this class. |
| 5897 */ | 5903 */ |
| 5904 @deprecated |
| 5898 class MemberMap { | 5905 class MemberMap { |
| 5899 /** | 5906 /** |
| 5900 * The current size of this map. | 5907 * The current size of this map. |
| 5901 */ | 5908 */ |
| 5902 int _size = 0; | 5909 int _size = 0; |
| 5903 | 5910 |
| 5904 /** | 5911 /** |
| 5905 * The array of keys. | 5912 * The array of keys. |
| 5906 */ | 5913 */ |
| 5907 List<String> _keys; | 5914 List<String> _keys; |
| (...skipping 18 matching lines...) Expand all Loading... |
| 5926 MemberMap.from(MemberMap memberMap) { | 5933 MemberMap.from(MemberMap memberMap) { |
| 5927 _initArrays(memberMap._size + 5); | 5934 _initArrays(memberMap._size + 5); |
| 5928 for (int i = 0; i < memberMap._size; i++) { | 5935 for (int i = 0; i < memberMap._size; i++) { |
| 5929 _keys[i] = memberMap._keys[i]; | 5936 _keys[i] = memberMap._keys[i]; |
| 5930 _values[i] = memberMap._values[i]; | 5937 _values[i] = memberMap._values[i]; |
| 5931 } | 5938 } |
| 5932 _size = memberMap._size; | 5939 _size = memberMap._size; |
| 5933 } | 5940 } |
| 5934 | 5941 |
| 5935 /** | 5942 /** |
| 5943 * Initialize a newly created member map to contain the same members as the |
| 5944 * given [map]. |
| 5945 */ |
| 5946 MemberMap.fromMap(Map<String, ExecutableElement> map) { |
| 5947 _size = map.length; |
| 5948 _initArrays(_size + 5); |
| 5949 int index = 0; |
| 5950 map.forEach((String memberName, ExecutableElement element) { |
| 5951 _keys[index] = memberName; |
| 5952 _values[index] = element; |
| 5953 index++; |
| 5954 }); |
| 5955 } |
| 5956 |
| 5957 /** |
| 5936 * The size of the map. | 5958 * The size of the map. |
| 5937 * | 5959 * |
| 5938 * @return the size of the map. | 5960 * @return the size of the map. |
| 5939 */ | 5961 */ |
| 5940 int get size => _size; | 5962 int get size => _size; |
| 5941 | 5963 |
| 5942 /** | 5964 /** |
| 5943 * Given some key, return the ExecutableElement value from the map, if the key
does not exist in | 5965 * Given some key, return the ExecutableElement value from the map, if the key
does not exist in |
| 5944 * the map, `null` is returned. | 5966 * the map, `null` is returned. |
| 5945 * | 5967 * |
| (...skipping 6003 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 11949 nonFields.add(node); | 11971 nonFields.add(node); |
| 11950 return null; | 11972 return null; |
| 11951 } | 11973 } |
| 11952 | 11974 |
| 11953 @override | 11975 @override |
| 11954 Object visitNode(AstNode node) => node.accept(TypeResolverVisitor_this); | 11976 Object visitNode(AstNode node) => node.accept(TypeResolverVisitor_this); |
| 11955 | 11977 |
| 11956 @override | 11978 @override |
| 11957 Object visitWithClause(WithClause node) => null; | 11979 Object visitWithClause(WithClause node) => null; |
| 11958 } | 11980 } |
| OLD | NEW |