Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(228)

Side by Side Diff: pkg/analyzer/lib/src/generated/element.dart

Issue 1179343004: Refactor least upper bound computation; support bottom correctly. (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: Created 5 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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 // This code was auto-generated, is not intended to be edited, and is subject to 5 // This code was auto-generated, is not intended to be edited, and is subject to
6 // significant change. Please see the README file for more information. 6 // significant change. Please see the README file for more information.
7 7
8 library engine.element; 8 library engine.element;
9 9
10 import 'dart:collection'; 10 import 'dart:collection';
(...skipping 2031 matching lines...) Expand 10 before | Expand all | Expand 10 after
2042 2042
2043 /** 2043 /**
2044 * Return the name of this type, or `null` if the type does not have a name, 2044 * Return the name of this type, or `null` if the type does not have a name,
2045 * such as when the type represents the type of an unnamed function. 2045 * such as when the type represents the type of an unnamed function.
2046 */ 2046 */
2047 String get name; 2047 String get name;
2048 2048
2049 /** 2049 /**
2050 * Return the least upper bound of this type and the given [type], or `null` 2050 * Return the least upper bound of this type and the given [type], or `null`
2051 * if there is no least upper bound. 2051 * if there is no least upper bound.
2052 *
2053 * Deprecated, since it is impossible to implement the correct algorithm
2054 * without access to a [TypeProvider]. Please use
2055 * [TypeSystem.getLeastUpperBound] instead.
2052 */ 2056 */
2057 @deprecated
2053 DartType getLeastUpperBound(DartType type); 2058 DartType getLeastUpperBound(DartType type);
2054 2059
2055 /** 2060 /**
2056 * Return `true` if this type is assignable to the given [type]. A type 2061 * Return `true` if this type is assignable to the given [type]. A type
2057 * <i>T</i> may be assigned to a type <i>S</i>, written <i>T</i> &hArr; 2062 * <i>T</i> may be assigned to a type <i>S</i>, written <i>T</i> &hArr;
2058 * <i>S</i>, iff either <i>T</i> <: <i>S</i> or <i>S</i> <: <i>T</i>. 2063 * <i>S</i>, iff either <i>T</i> <: <i>S</i> or <i>S</i> <: <i>T</i>.
2059 */ 2064 */
2060 bool isAssignableTo(DartType type); 2065 bool isAssignableTo(DartType type);
2061 2066
2062 /** 2067 /**
(...skipping 3185 matching lines...) Expand 10 before | Expand all | Expand 10 after
5248 newType.typeArguments = 5253 newType.typeArguments =
5249 TypeImpl.substitute(typeArguments, argumentTypes, parameterTypes); 5254 TypeImpl.substitute(typeArguments, argumentTypes, parameterTypes);
5250 return newType; 5255 return newType;
5251 } 5256 }
5252 5257
5253 @override 5258 @override
5254 FunctionTypeImpl substitute3(List<DartType> argumentTypes) => 5259 FunctionTypeImpl substitute3(List<DartType> argumentTypes) =>
5255 substitute2(argumentTypes, typeArguments); 5260 substitute2(argumentTypes, typeArguments);
5256 5261
5257 /** 5262 /**
5263 * Compute the least upper bound of types [f] and [g], both of which are
5264 * known to be function types.
5265 *
5266 * In the event that f and g have different numbers of required parameters,
5267 * `null` is returned, in which case the least upper bound is the interface
5268 * type `Function`.
5269 */
5270 static FunctionType computeLeastUpperBound(FunctionType f, FunctionType g) {
5271 // TODO(paulberry): implement this.
5272 return null;
5273 }
5274
5275 /**
5258 * Return `true` if all of the name/type pairs in the first map ([firstTypes]) 5276 * Return `true` if all of the name/type pairs in the first map ([firstTypes])
5259 * are equal to the corresponding name/type pairs in the second map 5277 * are equal to the corresponding name/type pairs in the second map
5260 * ([secondTypes]). The maps are expected to iterate over their entries in the 5278 * ([secondTypes]). The maps are expected to iterate over their entries in the
5261 * same order in which those entries were added to the map. 5279 * same order in which those entries were added to the map.
5262 */ 5280 */
5263 static bool _equals( 5281 static bool _equals(
5264 Map<String, DartType> firstTypes, Map<String, DartType> secondTypes) { 5282 Map<String, DartType> firstTypes, Map<String, DartType> secondTypes) {
5265 if (secondTypes.length != firstTypes.length) { 5283 if (secondTypes.length != firstTypes.length) {
5266 return false; 5284 return false;
5267 } 5285 }
(...skipping 535 matching lines...) Expand 10 before | Expand all | Expand 10 after
5803 * set of superinterfaces of <i>I<i>, let <i>S<sub>J</sub></i> be the set of 5821 * set of superinterfaces of <i>I<i>, let <i>S<sub>J</sub></i> be the set of
5804 * superinterfaces of <i>J</i> and let <i>S = (I &cup; S<sub>I</sub>) &cap; 5822 * superinterfaces of <i>J</i> and let <i>S = (I &cup; S<sub>I</sub>) &cap;
5805 * (J &cup; S<sub>J</sub>)</i>. Furthermore, we define <i>S<sub>n</sub> = 5823 * (J &cup; S<sub>J</sub>)</i>. Furthermore, we define <i>S<sub>n</sub> =
5806 * {T | T &isin; S &and; depth(T) = n}</i> for any finite <i>n</i>, where 5824 * {T | T &isin; S &and; depth(T) = n}</i> for any finite <i>n</i>, where
5807 * <i>depth(T)</i> is the number of steps in the longest inheritance path from 5825 * <i>depth(T)</i> is the number of steps in the longest inheritance path from
5808 * <i>T</i> to <i>Object</i>. Let <i>q</i> be the largest number such that 5826 * <i>T</i> to <i>Object</i>. Let <i>q</i> be the largest number such that
5809 * <i>S<sub>q</sub></i> has cardinality one. The least upper bound of <i>I</i> 5827 * <i>S<sub>q</sub></i> has cardinality one. The least upper bound of <i>I</i>
5810 * and <i>J</i> is the sole element of <i>S<sub>q</sub></i>. 5828 * and <i>J</i> is the sole element of <i>S<sub>q</sub></i>.
5811 */ 5829 */
5812 @override 5830 @override
5831 @deprecated
5813 DartType getLeastUpperBound(DartType type); 5832 DartType getLeastUpperBound(DartType type);
5814 5833
5815 /** 5834 /**
5816 * Return the element representing the method with the given [name] that is 5835 * Return the element representing the method with the given [name] that is
5817 * declared in this class, or `null` if this class does not declare a method 5836 * declared in this class, or `null` if this class does not declare a method
5818 * with the given name. 5837 * with the given name.
5819 */ 5838 */
5820 MethodElement getMethod(String name); 5839 MethodElement getMethod(String name);
5821 5840
5822 /** 5841 /**
(...skipping 184 matching lines...) Expand 10 before | Expand all | Expand 10 after
6007 /** 6026 /**
6008 * Returns a "smart" version of the "least upper bound" of the given types. 6027 * Returns a "smart" version of the "least upper bound" of the given types.
6009 * 6028 *
6010 * If these types have the same element and differ only in terms of the type 6029 * If these types have the same element and differ only in terms of the type
6011 * arguments, attempts to find a compatible set of type arguments. 6030 * arguments, attempts to find a compatible set of type arguments.
6012 * 6031 *
6013 * Otherwise, calls [DartType.getLeastUpperBound]. 6032 * Otherwise, calls [DartType.getLeastUpperBound].
6014 */ 6033 */
6015 static InterfaceType getSmartLeastUpperBound( 6034 static InterfaceType getSmartLeastUpperBound(
6016 InterfaceType first, InterfaceType second) { 6035 InterfaceType first, InterfaceType second) {
6036 // TODO(paulberry): this needs to be deprecated and replaced with a method
6037 // in [TypeSystem], since it relies on the deprecated functionality of
6038 // [DartType.getLeastUpperBound].
6017 if (first.element == second.element) { 6039 if (first.element == second.element) {
6018 return _leastUpperBound(first, second); 6040 return _leastUpperBound(first, second);
6019 } 6041 }
6020 return first.getLeastUpperBound(second); 6042 return first.getLeastUpperBound(second);
6021 } 6043 }
6022 6044
6023 /** 6045 /**
6024 * Return the "least upper bound" of the given types under the assumption that 6046 * Return the "least upper bound" of the given types under the assumption that
6025 * the types have the same element and differ only in terms of the type 6047 * the types have the same element and differ only in terms of the type
6026 * arguments. 6048 * arguments.
(...skipping 256 matching lines...) Expand 10 before | Expand all | Expand 10 after
6283 } 6305 }
6284 buffer.write(">"); 6306 buffer.write(">");
6285 } 6307 }
6286 } 6308 }
6287 6309
6288 @override 6310 @override
6289 PropertyAccessorElement getGetter(String getterName) => PropertyAccessorMember 6311 PropertyAccessorElement getGetter(String getterName) => PropertyAccessorMember
6290 .from((element as ClassElementImpl).getGetter(getterName), this); 6312 .from((element as ClassElementImpl).getGetter(getterName), this);
6291 6313
6292 @override 6314 @override
6315 @deprecated
6293 DartType getLeastUpperBound(DartType type) { 6316 DartType getLeastUpperBound(DartType type) {
6294 // quick check for self 6317 // quick check for self
6295 if (identical(type, this)) { 6318 if (identical(type, this)) {
6296 return this; 6319 return this;
6297 } 6320 }
6298 // dynamic 6321 // dynamic
6299 DartType dynamicType = DynamicTypeImpl.instance; 6322 DartType dynamicType = DynamicTypeImpl.instance;
6300 if (identical(this, dynamicType) || identical(type, dynamicType)) { 6323 if (identical(this, dynamicType) || identical(type, dynamicType)) {
6301 return dynamicType; 6324 return dynamicType;
6302 } 6325 }
6303 // TODO (jwren) opportunity here for a better, faster algorithm if this 6326 // TODO (jwren) opportunity here for a better, faster algorithm if this
6304 // turns out to be a bottle-neck 6327 // turns out to be a bottle-neck
6305 if (type is! InterfaceType) { 6328 if (type is! InterfaceType) {
6306 return null; 6329 return null;
6307 } 6330 }
6308 // new names to match up with the spec 6331 return computeLeastUpperBound(this, type);
6309 InterfaceType i = this;
6310 InterfaceType j = type as InterfaceType;
6311 // compute set of supertypes
6312 Set<InterfaceType> si = computeSuperinterfaceSet(i);
6313 Set<InterfaceType> sj = computeSuperinterfaceSet(j);
6314 // union si with i and sj with j
6315 si.add(i);
6316 sj.add(j);
6317 // compute intersection, reference as set 's'
6318 List<InterfaceType> s = _intersection(si, sj);
6319 // for each element in Set s, compute the largest inheritance path to Object
6320 List<int> depths = new List<int>.filled(s.length, 0);
6321 int maxDepth = 0;
6322 for (int n = 0; n < s.length; n++) {
6323 depths[n] = computeLongestInheritancePathToObject(s[n]);
6324 if (depths[n] > maxDepth) {
6325 maxDepth = depths[n];
6326 }
6327 }
6328 // ensure that the currently computed maxDepth is unique,
6329 // otherwise, decrement and test for uniqueness again
6330 for (; maxDepth >= 0; maxDepth--) {
6331 int indexOfLeastUpperBound = -1;
6332 int numberOfTypesAtMaxDepth = 0;
6333 for (int m = 0; m < depths.length; m++) {
6334 if (depths[m] == maxDepth) {
6335 numberOfTypesAtMaxDepth++;
6336 indexOfLeastUpperBound = m;
6337 }
6338 }
6339 if (numberOfTypesAtMaxDepth == 1) {
6340 return s[indexOfLeastUpperBound];
6341 }
6342 }
6343 // illegal state, log and return null- Object at maxDepth == 0 should always
6344 // return itself as the least upper bound.
6345 // TODO (jwren) log the error state
6346 return null;
6347 } 6332 }
6348 6333
6349 @override 6334 @override
6350 MethodElement getMethod(String methodName) => MethodMember.from( 6335 MethodElement getMethod(String methodName) => MethodMember.from(
6351 (element as ClassElementImpl).getMethod(methodName), this); 6336 (element as ClassElementImpl).getMethod(methodName), this);
6352 6337
6353 @override 6338 @override
6354 PropertyAccessorElement getSetter(String setterName) => PropertyAccessorMember 6339 PropertyAccessorElement getSetter(String setterName) => PropertyAccessorMember
6355 .from((element as ClassElementImpl).getSetter(setterName), this); 6340 .from((element as ClassElementImpl).getSetter(setterName), this);
6356 6341
(...skipping 326 matching lines...) Expand 10 before | Expand all | Expand 10 after
6683 InterfaceTypeImpl newType = new InterfaceTypeImpl(element, prune); 6668 InterfaceTypeImpl newType = new InterfaceTypeImpl(element, prune);
6684 newType.typeArguments = newTypeArguments; 6669 newType.typeArguments = newTypeArguments;
6685 return newType; 6670 return newType;
6686 } 6671 }
6687 6672
6688 @override 6673 @override
6689 InterfaceTypeImpl substitute4(List<DartType> argumentTypes) => 6674 InterfaceTypeImpl substitute4(List<DartType> argumentTypes) =>
6690 substitute2(argumentTypes, typeArguments); 6675 substitute2(argumentTypes, typeArguments);
6691 6676
6692 /** 6677 /**
6678 * Compute the least upper bound of types [i] and [j], both of which are
6679 * known to be interface types.
6680 *
6681 * In the event that the algorithm fails (which might occur due to a bug in
6682 * the analyzer), `null` is returned.
6683 */
6684 static InterfaceType computeLeastUpperBound(
6685 InterfaceType i, InterfaceType j) {
6686 // compute set of supertypes
6687 Set<InterfaceType> si = computeSuperinterfaceSet(i);
6688 Set<InterfaceType> sj = computeSuperinterfaceSet(j);
6689 // union si with i and sj with j
6690 si.add(i);
6691 sj.add(j);
6692 // compute intersection, reference as set 's'
6693 List<InterfaceType> s = _intersection(si, sj);
6694 // for each element in Set s, compute the largest inheritance path to Object
6695 List<int> depths = new List<int>.filled(s.length, 0);
6696 int maxDepth = 0;
6697 for (int n = 0; n < s.length; n++) {
6698 depths[n] = computeLongestInheritancePathToObject(s[n]);
6699 if (depths[n] > maxDepth) {
6700 maxDepth = depths[n];
6701 }
6702 }
6703 // ensure that the currently computed maxDepth is unique,
6704 // otherwise, decrement and test for uniqueness again
6705 for (; maxDepth >= 0; maxDepth--) {
6706 int indexOfLeastUpperBound = -1;
6707 int numberOfTypesAtMaxDepth = 0;
6708 for (int m = 0; m < depths.length; m++) {
6709 if (depths[m] == maxDepth) {
6710 numberOfTypesAtMaxDepth++;
6711 indexOfLeastUpperBound = m;
6712 }
6713 }
6714 if (numberOfTypesAtMaxDepth == 1) {
6715 return s[indexOfLeastUpperBound];
6716 }
6717 }
6718 // Should be impossible--there should always be exactly one type with the
6719 // maximum depth.
6720 assert(false);
6721 return null;
6722 }
6723
6724 /**
6693 * Return the length of the longest inheritance path from the given [type] to 6725 * Return the length of the longest inheritance path from the given [type] to
6694 * Object. 6726 * Object.
6695 * 6727 *
6696 * See [InterfaceType.getLeastUpperBound]. 6728 * See [computeLeastUpperBound].
6697 */ 6729 */
6698 static int computeLongestInheritancePathToObject(InterfaceType type) => 6730 static int computeLongestInheritancePathToObject(InterfaceType type) =>
6699 _computeLongestInheritancePathToObject( 6731 _computeLongestInheritancePathToObject(
6700 type, 0, new HashSet<ClassElement>()); 6732 type, 0, new HashSet<ClassElement>());
6701 6733
6702 /** 6734 /**
6703 * Returns the set of all superinterfaces of the given [type]. 6735 * Returns the set of all superinterfaces of the given [type].
6704 * 6736 *
6705 * See [getLeastUpperBound]. 6737 * See [computeLeastUpperBound].
6706 */ 6738 */
6707 static Set<InterfaceType> computeSuperinterfaceSet(InterfaceType type) => 6739 static Set<InterfaceType> computeSuperinterfaceSet(InterfaceType type) =>
6708 _computeSuperinterfaceSet(type, new HashSet<InterfaceType>()); 6740 _computeSuperinterfaceSet(type, new HashSet<InterfaceType>());
6709 6741
6710 /** 6742 /**
6711 * Return the length of the longest inheritance path from a subtype of the 6743 * Return the length of the longest inheritance path from a subtype of the
6712 * given [type] to Object, where the given [depth] is the length of the 6744 * given [type] to Object, where the given [depth] is the length of the
6713 * longest path from the subtype to this type. The set of [visitedTypes] is 6745 * longest path from the subtype to this type. The set of [visitedTypes] is
6714 * used to prevent infinite recursion in the case of a cyclic type structure. 6746 * used to prevent infinite recursion in the case of a cyclic type structure.
6715 * 6747 *
6716 * See [computeLongestInheritancePathToObject], and [getLeastUpperBound]. 6748 * See [computeLongestInheritancePathToObject], and [computeLeastUpperBound].
6717 */ 6749 */
6718 static int _computeLongestInheritancePathToObject( 6750 static int _computeLongestInheritancePathToObject(
6719 InterfaceType type, int depth, HashSet<ClassElement> visitedTypes) { 6751 InterfaceType type, int depth, HashSet<ClassElement> visitedTypes) {
6720 ClassElement classElement = type.element; 6752 ClassElement classElement = type.element;
6721 // Object case 6753 // Object case
6722 if (classElement.supertype == null || visitedTypes.contains(classElement)) { 6754 if (classElement.supertype == null || visitedTypes.contains(classElement)) {
6723 return depth; 6755 return depth;
6724 } 6756 }
6725 int longestPath = 1; 6757 int longestPath = 1;
6726 try { 6758 try {
(...skipping 23 matching lines...) Expand all
6750 } finally { 6782 } finally {
6751 visitedTypes.remove(classElement); 6783 visitedTypes.remove(classElement);
6752 } 6784 }
6753 return longestPath; 6785 return longestPath;
6754 } 6786 }
6755 6787
6756 /** 6788 /**
6757 * Add all of the superinterfaces of the given [type] to the given [set]. 6789 * Add all of the superinterfaces of the given [type] to the given [set].
6758 * Return the [set] as a convenience. 6790 * Return the [set] as a convenience.
6759 * 6791 *
6760 * See [computeSuperinterfaceSet], and [getLeastUpperBound]. 6792 * See [computeSuperinterfaceSet], and [computeLeastUpperBound].
6761 */ 6793 */
6762 static Set<InterfaceType> _computeSuperinterfaceSet( 6794 static Set<InterfaceType> _computeSuperinterfaceSet(
6763 InterfaceType type, HashSet<InterfaceType> set) { 6795 InterfaceType type, HashSet<InterfaceType> set) {
6764 Element element = type.element; 6796 Element element = type.element;
6765 if (element != null) { 6797 if (element != null) {
6766 List<InterfaceType> superinterfaces = type.interfaces; 6798 List<InterfaceType> superinterfaces = type.interfaces;
6767 for (InterfaceType superinterface in superinterfaces) { 6799 for (InterfaceType superinterface in superinterfaces) {
6768 if (set.add(superinterface)) { 6800 if (set.add(superinterface)) {
6769 _computeSuperinterfaceSet(superinterface, set); 6801 _computeSuperinterfaceSet(superinterface, set);
6770 } 6802 }
(...skipping 3673 matching lines...) Expand 10 before | Expand all | Expand 10 after
10444 10476
10445 @override 10477 @override
10446 void visitElement(Element element) { 10478 void visitElement(Element element) {
10447 int offset = element.nameOffset; 10479 int offset = element.nameOffset;
10448 if (offset != -1) { 10480 if (offset != -1) {
10449 map[offset] = element; 10481 map[offset] = element;
10450 } 10482 }
10451 super.visitElement(element); 10483 super.visitElement(element);
10452 } 10484 }
10453 } 10485 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698