| 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 // 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 1971 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1982 * `=>!` - Treat the DOM attribute value as an expression. Set up a one time w
atch on expression. | 1982 * `=>!` - Treat the DOM attribute value as an expression. Set up a one time w
atch on expression. |
| 1983 * Once the expression turns not null it will no longer update. (cost: 1 watch
es until not null, | 1983 * Once the expression turns not null it will no longer update. (cost: 1 watch
es until not null, |
| 1984 * then 0 watches) | 1984 * then 0 watches) |
| 1985 */ | 1985 */ |
| 1986 static final AngularPropertyKind ONE_WAY_ONE_TIME = new AngularPropertyKind('O
NE_WAY_ONE_TIME', 3); | 1986 static final AngularPropertyKind ONE_WAY_ONE_TIME = new AngularPropertyKind('O
NE_WAY_ONE_TIME', 3); |
| 1987 | 1987 |
| 1988 /** | 1988 /** |
| 1989 * `<=>` - Treat the DOM attribute value as an expression. Set up a watch on b
oth outside as well | 1989 * `<=>` - Treat the DOM attribute value as an expression. Set up a watch on b
oth outside as well |
| 1990 * as component scope to keep the source and destination in sync. (cost: 2 wat
ches) | 1990 * as component scope to keep the source and destination in sync. (cost: 2 wat
ches) |
| 1991 */ | 1991 */ |
| 1992 static final AngularPropertyKind TWO_WAY = new AngularPropertyKind('TWO_WAY',
4); | 1992 static final AngularPropertyKind TWO_WAY = new AngularPropertyKind_TWO_WAY('TW
O_WAY', 4); |
| 1993 | 1993 |
| 1994 static final List<AngularPropertyKind> values = [ATTR, CALLBACK, ONE_WAY, ONE_
WAY_ONE_TIME, TWO_WAY]; | 1994 static final List<AngularPropertyKind> values = [ATTR, CALLBACK, ONE_WAY, ONE_
WAY_ONE_TIME, TWO_WAY]; |
| 1995 | 1995 |
| 1996 /** |
| 1997 * Returns `true` if property of this kind calls field getter. |
| 1998 */ |
| 1999 bool callsGetter() => false; |
| 2000 |
| 2001 /** |
| 2002 * Returns `true` if property of this kind calls field setter. |
| 2003 */ |
| 2004 bool callsSetter() => true; |
| 2005 |
| 1996 AngularPropertyKind(String name, int ordinal) : super(name, ordinal); | 2006 AngularPropertyKind(String name, int ordinal) : super(name, ordinal); |
| 1997 } | 2007 } |
| 1998 | 2008 |
| 2009 class AngularPropertyKind_TWO_WAY extends AngularPropertyKind { |
| 2010 AngularPropertyKind_TWO_WAY(String name, int ordinal) : super(name, ordinal); |
| 2011 |
| 2012 bool callsGetter() => true; |
| 2013 } |
| 2014 |
| 1999 /** | 2015 /** |
| 2000 * [AngularSelectorElement] is used to decide when Angular object should be appl
ied. | 2016 * [AngularSelectorElement] is used to decide when Angular object should be appl
ied. |
| 2001 * | 2017 * |
| 2002 * This class is an [Element] to support renaming component tag names, which are
identifiers | 2018 * This class is an [Element] to support renaming component tag names, which are
identifiers |
| 2003 * in selectors. | 2019 * in selectors. |
| 2004 */ | 2020 */ |
| 2005 abstract class AngularSelectorElement implements AngularElement { | 2021 abstract class AngularSelectorElement implements AngularElement { |
| 2006 /** | 2022 /** |
| 2007 * Checks if the given [XmlTagNode] matches this selector. | 2023 * Checks if the given [XmlTagNode] matches this selector. |
| 2008 * | 2024 * |
| (...skipping 479 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2488 | 2504 |
| 2489 List<PropertyAccessorElement> get accessors => _accessors; | 2505 List<PropertyAccessorElement> get accessors => _accessors; |
| 2490 | 2506 |
| 2491 List<InterfaceType> get allSupertypes { | 2507 List<InterfaceType> get allSupertypes { |
| 2492 List<InterfaceType> list = new List<InterfaceType>(); | 2508 List<InterfaceType> list = new List<InterfaceType>(); |
| 2493 collectAllSupertypes(list); | 2509 collectAllSupertypes(list); |
| 2494 return new List.from(list); | 2510 return new List.from(list); |
| 2495 } | 2511 } |
| 2496 | 2512 |
| 2497 ElementImpl getChild(String identifier) { | 2513 ElementImpl getChild(String identifier) { |
| 2514 // |
| 2515 // The casts in this method are safe because the set methods would have thro
wn a CCE if any of |
| 2516 // the elements in the arrays were not of the expected types. |
| 2517 // |
| 2498 for (PropertyAccessorElement accessor in _accessors) { | 2518 for (PropertyAccessorElement accessor in _accessors) { |
| 2499 if ((accessor as PropertyAccessorElementImpl).identifier == identifier) { | 2519 if ((accessor as PropertyAccessorElementImpl).identifier == identifier) { |
| 2500 return accessor as PropertyAccessorElementImpl; | 2520 return accessor as PropertyAccessorElementImpl; |
| 2501 } | 2521 } |
| 2502 } | 2522 } |
| 2503 for (ConstructorElement constructor in _constructors) { | 2523 for (ConstructorElement constructor in _constructors) { |
| 2504 if ((constructor as ConstructorElementImpl).identifier == identifier) { | 2524 if ((constructor as ConstructorElementImpl).identifier == identifier) { |
| 2505 return constructor as ConstructorElementImpl; | 2525 return constructor as ConstructorElementImpl; |
| 2506 } | 2526 } |
| 2507 } | 2527 } |
| (...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2564 if (elementName != null && elementName == name) { | 2584 if (elementName != null && elementName == name) { |
| 2565 return element; | 2585 return element; |
| 2566 } | 2586 } |
| 2567 } | 2587 } |
| 2568 return null; | 2588 return null; |
| 2569 } | 2589 } |
| 2570 | 2590 |
| 2571 ClassDeclaration get node => getNode2(ClassDeclaration); | 2591 ClassDeclaration get node => getNode2(ClassDeclaration); |
| 2572 | 2592 |
| 2573 PropertyAccessorElement getSetter(String setterName) { | 2593 PropertyAccessorElement getSetter(String setterName) { |
| 2594 // TODO (jwren) revisit- should we append '=' here or require clients to inc
lude it? |
| 2595 // Do we need the check for isSetter below? |
| 2574 if (!setterName.endsWith("=")) { | 2596 if (!setterName.endsWith("=")) { |
| 2575 setterName += '='; | 2597 setterName += '='; |
| 2576 } | 2598 } |
| 2577 for (PropertyAccessorElement accessor in _accessors) { | 2599 for (PropertyAccessorElement accessor in _accessors) { |
| 2578 if (accessor.isSetter && accessor.name == setterName) { | 2600 if (accessor.isSetter && accessor.name == setterName) { |
| 2579 return accessor; | 2601 return accessor; |
| 2580 } | 2602 } |
| 2581 } | 2603 } |
| 2582 return null; | 2604 return null; |
| 2583 } | 2605 } |
| (...skipping 12 matching lines...) Expand all Loading... |
| 2596 return null; | 2618 return null; |
| 2597 } | 2619 } |
| 2598 | 2620 |
| 2599 bool hasNonFinalField() { | 2621 bool hasNonFinalField() { |
| 2600 List<ClassElement> classesToVisit = new List<ClassElement>(); | 2622 List<ClassElement> classesToVisit = new List<ClassElement>(); |
| 2601 Set<ClassElement> visitedClasses = new Set<ClassElement>(); | 2623 Set<ClassElement> visitedClasses = new Set<ClassElement>(); |
| 2602 classesToVisit.add(this); | 2624 classesToVisit.add(this); |
| 2603 while (!classesToVisit.isEmpty) { | 2625 while (!classesToVisit.isEmpty) { |
| 2604 ClassElement currentElement = classesToVisit.removeAt(0); | 2626 ClassElement currentElement = classesToVisit.removeAt(0); |
| 2605 if (visitedClasses.add(currentElement)) { | 2627 if (visitedClasses.add(currentElement)) { |
| 2628 // check fields |
| 2606 for (FieldElement field in currentElement.fields) { | 2629 for (FieldElement field in currentElement.fields) { |
| 2607 if (!field.isFinal && !field.isConst && !field.isStatic && !field.isSy
nthetic) { | 2630 if (!field.isFinal && !field.isConst && !field.isStatic && !field.isSy
nthetic) { |
| 2608 return true; | 2631 return true; |
| 2609 } | 2632 } |
| 2610 } | 2633 } |
| 2634 // check mixins |
| 2611 for (InterfaceType mixinType in currentElement.mixins) { | 2635 for (InterfaceType mixinType in currentElement.mixins) { |
| 2612 ClassElement mixinElement = mixinType.element; | 2636 ClassElement mixinElement = mixinType.element; |
| 2613 classesToVisit.add(mixinElement); | 2637 classesToVisit.add(mixinElement); |
| 2614 } | 2638 } |
| 2639 // check super |
| 2615 InterfaceType supertype = currentElement.supertype; | 2640 InterfaceType supertype = currentElement.supertype; |
| 2616 if (supertype != null) { | 2641 if (supertype != null) { |
| 2617 ClassElement superElement = supertype.element; | 2642 ClassElement superElement = supertype.element; |
| 2618 if (superElement != null) { | 2643 if (superElement != null) { |
| 2619 classesToVisit.add(superElement); | 2644 classesToVisit.add(superElement); |
| 2620 } | 2645 } |
| 2621 } | 2646 } |
| 2622 } | 2647 } |
| 2623 } | 2648 } |
| 2649 // not found |
| 2624 return false; | 2650 return false; |
| 2625 } | 2651 } |
| 2626 | 2652 |
| 2627 bool hasReferenceToSuper() => hasModifier(Modifier.REFERENCES_SUPER); | 2653 bool hasReferenceToSuper() => hasModifier(Modifier.REFERENCES_SUPER); |
| 2628 | 2654 |
| 2629 bool get isAbstract => hasModifier(Modifier.ABSTRACT); | 2655 bool get isAbstract => hasModifier(Modifier.ABSTRACT); |
| 2630 | 2656 |
| 2631 bool get isProxy { | 2657 bool get isProxy { |
| 2632 for (ElementAnnotation annotation in metadata) { | 2658 for (ElementAnnotation annotation in metadata) { |
| 2633 if (annotation.isProxy) { | 2659 if (annotation.isProxy) { |
| (...skipping 317 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2951 */ | 2977 */ |
| 2952 CompilationUnitElementImpl(String name) : super.con2(name, -1); | 2978 CompilationUnitElementImpl(String name) : super.con2(name, -1); |
| 2953 | 2979 |
| 2954 accept(ElementVisitor visitor) => visitor.visitCompilationUnitElement(this); | 2980 accept(ElementVisitor visitor) => visitor.visitCompilationUnitElement(this); |
| 2955 | 2981 |
| 2956 bool operator ==(Object object) => object != null && runtimeType == object.run
timeType && source == (object as CompilationUnitElementImpl).source; | 2982 bool operator ==(Object object) => object != null && runtimeType == object.run
timeType && source == (object as CompilationUnitElementImpl).source; |
| 2957 | 2983 |
| 2958 List<PropertyAccessorElement> get accessors => _accessors; | 2984 List<PropertyAccessorElement> get accessors => _accessors; |
| 2959 | 2985 |
| 2960 ElementImpl getChild(String identifier) { | 2986 ElementImpl getChild(String identifier) { |
| 2987 // |
| 2988 // The casts in this method are safe because the set methods would have thro
wn a CCE if any of |
| 2989 // the elements in the arrays were not of the expected types. |
| 2990 // |
| 2961 for (PropertyAccessorElement accessor in _accessors) { | 2991 for (PropertyAccessorElement accessor in _accessors) { |
| 2962 if ((accessor as PropertyAccessorElementImpl).identifier == identifier) { | 2992 if ((accessor as PropertyAccessorElementImpl).identifier == identifier) { |
| 2963 return accessor as PropertyAccessorElementImpl; | 2993 return accessor as PropertyAccessorElementImpl; |
| 2964 } | 2994 } |
| 2965 } | 2995 } |
| 2966 for (VariableElement variable in _variables) { | 2996 for (VariableElement variable in _variables) { |
| 2967 if ((variable as VariableElementImpl).identifier == identifier) { | 2997 if ((variable as VariableElementImpl).identifier == identifier) { |
| 2968 return variable as VariableElementImpl; | 2998 return variable as VariableElementImpl; |
| 2969 } | 2999 } |
| 2970 } | 3000 } |
| (...skipping 249 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3220 | 3250 |
| 3221 ClassElement get enclosingElement => super.enclosingElement as ClassElement; | 3251 ClassElement get enclosingElement => super.enclosingElement as ClassElement; |
| 3222 | 3252 |
| 3223 ElementKind get kind => ElementKind.CONSTRUCTOR; | 3253 ElementKind get kind => ElementKind.CONSTRUCTOR; |
| 3224 | 3254 |
| 3225 ConstructorDeclaration get node => getNode2(ConstructorDeclaration); | 3255 ConstructorDeclaration get node => getNode2(ConstructorDeclaration); |
| 3226 | 3256 |
| 3227 bool get isConst => hasModifier(Modifier.CONST); | 3257 bool get isConst => hasModifier(Modifier.CONST); |
| 3228 | 3258 |
| 3229 bool get isDefaultConstructor { | 3259 bool get isDefaultConstructor { |
| 3260 // unnamed |
| 3230 String name = this.name; | 3261 String name = this.name; |
| 3231 if (name != null && name.length != 0) { | 3262 if (name != null && name.length != 0) { |
| 3232 return false; | 3263 return false; |
| 3233 } | 3264 } |
| 3265 // no required parameters |
| 3234 for (ParameterElement parameter in parameters) { | 3266 for (ParameterElement parameter in parameters) { |
| 3235 if (identical(parameter.parameterKind, ParameterKind.REQUIRED)) { | 3267 if (identical(parameter.parameterKind, ParameterKind.REQUIRED)) { |
| 3236 return false; | 3268 return false; |
| 3237 } | 3269 } |
| 3238 } | 3270 } |
| 3271 // OK, can be used as default constructor |
| 3239 return true; | 3272 return true; |
| 3240 } | 3273 } |
| 3241 | 3274 |
| 3242 bool get isFactory => hasModifier(Modifier.FACTORY); | 3275 bool get isFactory => hasModifier(Modifier.FACTORY); |
| 3243 | 3276 |
| 3244 bool get isStatic => false; | 3277 bool get isStatic => false; |
| 3245 | 3278 |
| 3246 /** | 3279 /** |
| 3247 * Set whether this constructor represents a 'const' constructor to the given
value. | 3280 * Set whether this constructor represents a 'const' constructor to the given
value. |
| 3248 * | 3281 * |
| (...skipping 311 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3560 Source get source { | 3593 Source get source { |
| 3561 if (_enclosingElement == null) { | 3594 if (_enclosingElement == null) { |
| 3562 return null; | 3595 return null; |
| 3563 } | 3596 } |
| 3564 return _enclosingElement.source; | 3597 return _enclosingElement.source; |
| 3565 } | 3598 } |
| 3566 | 3599 |
| 3567 CompilationUnit get unit => context.resolveCompilationUnit(source, library); | 3600 CompilationUnit get unit => context.resolveCompilationUnit(source, library); |
| 3568 | 3601 |
| 3569 int get hashCode { | 3602 int get hashCode { |
| 3603 // TODO: We might want to re-visit this optimization in the future. |
| 3604 // We cache the hash code value as this is a very frequently called method. |
| 3570 if (_cachedHashCode == 0) { | 3605 if (_cachedHashCode == 0) { |
| 3571 _cachedHashCode = location.hashCode; | 3606 _cachedHashCode = location.hashCode; |
| 3572 } | 3607 } |
| 3573 return _cachedHashCode; | 3608 return _cachedHashCode; |
| 3574 } | 3609 } |
| 3575 | 3610 |
| 3576 bool isAccessibleIn(LibraryElement library) { | 3611 bool isAccessibleIn(LibraryElement library) { |
| 3577 if (Identifier.isPrivateName(_name)) { | 3612 if (Identifier.isPrivateName(_name)) { |
| 3578 return library == this.library; | 3613 return library == this.library; |
| 3579 } | 3614 } |
| (...skipping 297 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3877 | 3912 |
| 3878 /** | 3913 /** |
| 3879 * Return `true` if the given components, when interpreted to be encoded sourc
es with a | 3914 * Return `true` if the given components, when interpreted to be encoded sourc
es with a |
| 3880 * leading source type indicator, are equal when the source type's are ignored
. | 3915 * leading source type indicator, are equal when the source type's are ignored
. |
| 3881 * | 3916 * |
| 3882 * @param left the left component being compared | 3917 * @param left the left component being compared |
| 3883 * @param right the right component being compared | 3918 * @param right the right component being compared |
| 3884 * @return `true` if the given components are equal when the source type's are
ignored | 3919 * @return `true` if the given components are equal when the source type's are
ignored |
| 3885 */ | 3920 */ |
| 3886 bool equalSourceComponents(String left, String right) { | 3921 bool equalSourceComponents(String left, String right) { |
| 3922 // TODO(brianwilkerson) This method can go away when sources no longer have
a URI kind. |
| 3887 if (left == null) { | 3923 if (left == null) { |
| 3888 return right == null; | 3924 return right == null; |
| 3889 } else if (right == null) { | 3925 } else if (right == null) { |
| 3890 return false; | 3926 return false; |
| 3891 } | 3927 } |
| 3892 int leftLength = left.length; | 3928 int leftLength = left.length; |
| 3893 int rightLength = right.length; | 3929 int rightLength = right.length; |
| 3894 if (leftLength != rightLength) { | 3930 if (leftLength != rightLength) { |
| 3895 return false; | 3931 return false; |
| 3896 } else if (leftLength <= 1 || rightLength <= 1) { | 3932 } else if (leftLength <= 1 || rightLength <= 1) { |
| 3897 return left == right; | 3933 return left == right; |
| 3898 } | 3934 } |
| 3899 return javaStringRegionMatches(left, 1, right, 1, leftLength - 1); | 3935 return javaStringRegionMatches(left, 1, right, 1, leftLength - 1); |
| 3900 } | 3936 } |
| 3901 | 3937 |
| 3902 /** | 3938 /** |
| 3903 * Return the hash code of the given encoded source component, ignoring the so
urce type indicator. | 3939 * Return the hash code of the given encoded source component, ignoring the so
urce type indicator. |
| 3904 * | 3940 * |
| 3905 * @param sourceComponent the component to compute a hash code | 3941 * @param sourceComponent the component to compute a hash code |
| 3906 * @return the hash code of the given encoded source component | 3942 * @return the hash code of the given encoded source component |
| 3907 */ | 3943 */ |
| 3908 int hashSourceComponent(String sourceComponent) { | 3944 int hashSourceComponent(String sourceComponent) { |
| 3945 // TODO(brianwilkerson) This method can go away when sources no longer have
a URI kind. |
| 3909 if (sourceComponent.length <= 1) { | 3946 if (sourceComponent.length <= 1) { |
| 3910 return sourceComponent.hashCode; | 3947 return sourceComponent.hashCode; |
| 3911 } | 3948 } |
| 3912 return sourceComponent.substring(1).hashCode; | 3949 return sourceComponent.substring(1).hashCode; |
| 3913 } | 3950 } |
| 3914 } | 3951 } |
| 3915 | 3952 |
| 3916 /** | 3953 /** |
| 3917 * The class `ElementPair` is a pair of [Element]s. [Object#equals] and | 3954 * The class `ElementPair` is a pair of [Element]s. [Object#equals] and |
| 3918 * [Object#hashCode] so this class can be used in hashed data structures. | 3955 * [Object#hashCode] so this class can be used in hashed data structures. |
| (...skipping 886 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4805 /** | 4842 /** |
| 4806 * Determine if the given library is up to date with respect to the given time
stamp. | 4843 * Determine if the given library is up to date with respect to the given time
stamp. |
| 4807 * | 4844 * |
| 4808 * @param library the library to process | 4845 * @param library the library to process |
| 4809 * @param timeStamp the time stamp to check against | 4846 * @param timeStamp the time stamp to check against |
| 4810 * @param visitedLibraries the set of visited libraries | 4847 * @param visitedLibraries the set of visited libraries |
| 4811 */ | 4848 */ |
| 4812 static bool isUpToDate(LibraryElement library, int timeStamp, Set<LibraryEleme
nt> visitedLibraries) { | 4849 static bool isUpToDate(LibraryElement library, int timeStamp, Set<LibraryEleme
nt> visitedLibraries) { |
| 4813 if (!visitedLibraries.contains(library)) { | 4850 if (!visitedLibraries.contains(library)) { |
| 4814 visitedLibraries.add(library); | 4851 visitedLibraries.add(library); |
| 4852 // Check the defining compilation unit. |
| 4815 if (timeStamp < library.definingCompilationUnit.source.modificationStamp)
{ | 4853 if (timeStamp < library.definingCompilationUnit.source.modificationStamp)
{ |
| 4816 return false; | 4854 return false; |
| 4817 } | 4855 } |
| 4856 // Check the parted compilation units. |
| 4818 for (CompilationUnitElement element in library.parts) { | 4857 for (CompilationUnitElement element in library.parts) { |
| 4819 if (timeStamp < element.source.modificationStamp) { | 4858 if (timeStamp < element.source.modificationStamp) { |
| 4820 return false; | 4859 return false; |
| 4821 } | 4860 } |
| 4822 } | 4861 } |
| 4862 // Check the imported libraries. |
| 4823 for (LibraryElement importedLibrary in library.importedLibraries) { | 4863 for (LibraryElement importedLibrary in library.importedLibraries) { |
| 4824 if (!isUpToDate(importedLibrary, timeStamp, visitedLibraries)) { | 4864 if (!isUpToDate(importedLibrary, timeStamp, visitedLibraries)) { |
| 4825 return false; | 4865 return false; |
| 4826 } | 4866 } |
| 4827 } | 4867 } |
| 4868 // Check the exported libraries. |
| 4828 for (LibraryElement exportedLibrary in library.exportedLibraries) { | 4869 for (LibraryElement exportedLibrary in library.exportedLibraries) { |
| 4829 if (!isUpToDate(exportedLibrary, timeStamp, visitedLibraries)) { | 4870 if (!isUpToDate(exportedLibrary, timeStamp, visitedLibraries)) { |
| 4830 return false; | 4871 return false; |
| 4831 } | 4872 } |
| 4832 } | 4873 } |
| 4833 } | 4874 } |
| 4834 return true; | 4875 return true; |
| 4835 } | 4876 } |
| 4836 | 4877 |
| 4837 /** | 4878 /** |
| (...skipping 204 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5042 safelyVisitChildren(_imports, visitor); | 5083 safelyVisitChildren(_imports, visitor); |
| 5043 safelyVisitChildren(_parts, visitor); | 5084 safelyVisitChildren(_parts, visitor); |
| 5044 } | 5085 } |
| 5045 | 5086 |
| 5046 String get identifier => _definingCompilationUnit.source.encoding; | 5087 String get identifier => _definingCompilationUnit.source.encoding; |
| 5047 | 5088 |
| 5048 /** | 5089 /** |
| 5049 * Recursively fills set of visible libraries for [getVisibleElementsLibraries
]. | 5090 * Recursively fills set of visible libraries for [getVisibleElementsLibraries
]. |
| 5050 */ | 5091 */ |
| 5051 void addVisibleLibraries(Set<LibraryElement> visibleLibraries, bool includeExp
orts) { | 5092 void addVisibleLibraries(Set<LibraryElement> visibleLibraries, bool includeExp
orts) { |
| 5093 // maybe already processed |
| 5052 if (!visibleLibraries.add(this)) { | 5094 if (!visibleLibraries.add(this)) { |
| 5053 return; | 5095 return; |
| 5054 } | 5096 } |
| 5097 // add imported libraries |
| 5055 for (ImportElement importElement in _imports) { | 5098 for (ImportElement importElement in _imports) { |
| 5056 LibraryElement importedLibrary = importElement.importedLibrary; | 5099 LibraryElement importedLibrary = importElement.importedLibrary; |
| 5057 if (importedLibrary != null) { | 5100 if (importedLibrary != null) { |
| 5058 (importedLibrary as LibraryElementImpl).addVisibleLibraries(visibleLibra
ries, true); | 5101 (importedLibrary as LibraryElementImpl).addVisibleLibraries(visibleLibra
ries, true); |
| 5059 } | 5102 } |
| 5060 } | 5103 } |
| 5104 // add exported libraries |
| 5061 if (includeExports) { | 5105 if (includeExports) { |
| 5062 for (ExportElement exportElement in _exports) { | 5106 for (ExportElement exportElement in _exports) { |
| 5063 LibraryElement exportedLibrary = exportElement.exportedLibrary; | 5107 LibraryElement exportedLibrary = exportElement.exportedLibrary; |
| 5064 if (exportedLibrary != null) { | 5108 if (exportedLibrary != null) { |
| 5065 (exportedLibrary as LibraryElementImpl).addVisibleLibraries(visibleLib
raries, true); | 5109 (exportedLibrary as LibraryElementImpl).addVisibleLibraries(visibleLib
raries, true); |
| 5066 } | 5110 } |
| 5067 } | 5111 } |
| 5068 } | 5112 } |
| 5069 } | 5113 } |
| 5070 | 5114 |
| (...skipping 1409 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6480 * @param definingType the type defining the parameters and arguments to be us
ed in the | 6524 * @param definingType the type defining the parameters and arguments to be us
ed in the |
| 6481 * substitution | 6525 * substitution |
| 6482 * @return the constructor element that will return the correctly substituted
types | 6526 * @return the constructor element that will return the correctly substituted
types |
| 6483 */ | 6527 */ |
| 6484 static ConstructorElement from(ConstructorElement baseConstructor, InterfaceTy
pe definingType) { | 6528 static ConstructorElement from(ConstructorElement baseConstructor, InterfaceTy
pe definingType) { |
| 6485 if (baseConstructor == null || definingType.typeArguments.length == 0) { | 6529 if (baseConstructor == null || definingType.typeArguments.length == 0) { |
| 6486 return baseConstructor; | 6530 return baseConstructor; |
| 6487 } | 6531 } |
| 6488 FunctionType baseType = baseConstructor.type; | 6532 FunctionType baseType = baseConstructor.type; |
| 6489 if (baseType == null) { | 6533 if (baseType == null) { |
| 6534 // TODO(brianwilkerson) We need to understand when this can happen. |
| 6490 return baseConstructor; | 6535 return baseConstructor; |
| 6491 } | 6536 } |
| 6492 List<Type2> argumentTypes = definingType.typeArguments; | 6537 List<Type2> argumentTypes = definingType.typeArguments; |
| 6493 List<Type2> parameterTypes = definingType.element.type.typeArguments; | 6538 List<Type2> parameterTypes = definingType.element.type.typeArguments; |
| 6494 FunctionType substitutedType = baseType.substitute2(argumentTypes, parameter
Types); | 6539 FunctionType substitutedType = baseType.substitute2(argumentTypes, parameter
Types); |
| 6495 if (baseType == substitutedType) { | 6540 if (baseType == substitutedType) { |
| 6496 return baseConstructor; | 6541 return baseConstructor; |
| 6497 } | 6542 } |
| 6543 // TODO(brianwilkerson) Consider caching the substituted type in the instanc
e. It would use more |
| 6544 // memory but speed up some operations. We need to see how often the type is
being re-computed. |
| 6498 return new ConstructorMember(baseConstructor, definingType); | 6545 return new ConstructorMember(baseConstructor, definingType); |
| 6499 } | 6546 } |
| 6500 | 6547 |
| 6501 /** | 6548 /** |
| 6502 * Initialize a newly created element to represent a constructor of the given
parameterized type. | 6549 * Initialize a newly created element to represent a constructor of the given
parameterized type. |
| 6503 * | 6550 * |
| 6504 * @param baseElement the element on which the parameterized element was creat
ed | 6551 * @param baseElement the element on which the parameterized element was creat
ed |
| 6505 * @param definingType the type in which the element is defined | 6552 * @param definingType the type in which the element is defined |
| 6506 */ | 6553 */ |
| 6507 ConstructorMember(ConstructorElement baseElement, InterfaceType definingType)
: super(baseElement, definingType); | 6554 ConstructorMember(ConstructorElement baseElement, InterfaceType definingType)
: super(baseElement, definingType); |
| (...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6563 * parameterized type. | 6610 * parameterized type. |
| 6564 * | 6611 * |
| 6565 * @param baseElement the element on which the parameterized element was creat
ed | 6612 * @param baseElement the element on which the parameterized element was creat
ed |
| 6566 * @param definingType the type in which the element is defined | 6613 * @param definingType the type in which the element is defined |
| 6567 */ | 6614 */ |
| 6568 ExecutableMember(ExecutableElement baseElement, InterfaceType definingType) :
super(baseElement, definingType); | 6615 ExecutableMember(ExecutableElement baseElement, InterfaceType definingType) :
super(baseElement, definingType); |
| 6569 | 6616 |
| 6570 ExecutableElement get baseElement => super.baseElement as ExecutableElement; | 6617 ExecutableElement get baseElement => super.baseElement as ExecutableElement; |
| 6571 | 6618 |
| 6572 List<FunctionElement> get functions { | 6619 List<FunctionElement> get functions { |
| 6620 // |
| 6621 // Elements within this element should have type parameters substituted, jus
t like this element. |
| 6622 // |
| 6573 throw new UnsupportedOperationException(); | 6623 throw new UnsupportedOperationException(); |
| 6574 } | 6624 } |
| 6575 | 6625 |
| 6576 List<LabelElement> get labels => baseElement.labels; | 6626 List<LabelElement> get labels => baseElement.labels; |
| 6577 | 6627 |
| 6578 List<LocalVariableElement> get localVariables { | 6628 List<LocalVariableElement> get localVariables { |
| 6629 // |
| 6630 // Elements within this element should have type parameters substituted, jus
t like this element. |
| 6631 // |
| 6579 throw new UnsupportedOperationException(); | 6632 throw new UnsupportedOperationException(); |
| 6580 } | 6633 } |
| 6581 | 6634 |
| 6582 List<ParameterElement> get parameters { | 6635 List<ParameterElement> get parameters { |
| 6583 List<ParameterElement> baseParameters = baseElement.parameters; | 6636 List<ParameterElement> baseParameters = baseElement.parameters; |
| 6584 int parameterCount = baseParameters.length; | 6637 int parameterCount = baseParameters.length; |
| 6585 if (parameterCount == 0) { | 6638 if (parameterCount == 0) { |
| 6586 return baseParameters; | 6639 return baseParameters; |
| 6587 } | 6640 } |
| 6588 List<ParameterElement> parameterizedParameters = new List<ParameterElement>(
parameterCount); | 6641 List<ParameterElement> parameterizedParameters = new List<ParameterElement>(
parameterCount); |
| 6589 for (int i = 0; i < parameterCount; i++) { | 6642 for (int i = 0; i < parameterCount; i++) { |
| 6590 parameterizedParameters[i] = ParameterMember.from(baseParameters[i], defin
ingType); | 6643 parameterizedParameters[i] = ParameterMember.from(baseParameters[i], defin
ingType); |
| 6591 } | 6644 } |
| 6592 return parameterizedParameters; | 6645 return parameterizedParameters; |
| 6593 } | 6646 } |
| 6594 | 6647 |
| 6595 Type2 get returnType => substituteFor(baseElement.returnType); | 6648 Type2 get returnType => substituteFor(baseElement.returnType); |
| 6596 | 6649 |
| 6597 FunctionType get type => substituteFor(baseElement.type); | 6650 FunctionType get type => substituteFor(baseElement.type); |
| 6598 | 6651 |
| 6599 bool get isOperator => baseElement.isOperator; | 6652 bool get isOperator => baseElement.isOperator; |
| 6600 | 6653 |
| 6601 bool get isStatic => baseElement.isStatic; | 6654 bool get isStatic => baseElement.isStatic; |
| 6602 | 6655 |
| 6603 void visitChildren(ElementVisitor visitor) { | 6656 void visitChildren(ElementVisitor visitor) { |
| 6657 // TODO(brianwilkerson) We need to finish implementing the accessors used be
low so that we can |
| 6658 // safely invoke them. |
| 6604 super.visitChildren(visitor); | 6659 super.visitChildren(visitor); |
| 6605 safelyVisitChildren(baseElement.functions, visitor); | 6660 safelyVisitChildren(baseElement.functions, visitor); |
| 6606 safelyVisitChildren(labels, visitor); | 6661 safelyVisitChildren(labels, visitor); |
| 6607 safelyVisitChildren(baseElement.localVariables, visitor); | 6662 safelyVisitChildren(baseElement.localVariables, visitor); |
| 6608 safelyVisitChildren(parameters, visitor); | 6663 safelyVisitChildren(parameters, visitor); |
| 6609 } | 6664 } |
| 6610 } | 6665 } |
| 6611 | 6666 |
| 6612 /** | 6667 /** |
| 6613 * Instances of the class `FieldFormalParameterMember` represent a parameter ele
ment defined | 6668 * Instances of the class `FieldFormalParameterMember` represent a parameter ele
ment defined |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6650 Type2 baseType = baseField.type; | 6705 Type2 baseType = baseField.type; |
| 6651 if (baseType == null) { | 6706 if (baseType == null) { |
| 6652 return baseField; | 6707 return baseField; |
| 6653 } | 6708 } |
| 6654 List<Type2> argumentTypes = definingType.typeArguments; | 6709 List<Type2> argumentTypes = definingType.typeArguments; |
| 6655 List<Type2> parameterTypes = definingType.element.type.typeArguments; | 6710 List<Type2> parameterTypes = definingType.element.type.typeArguments; |
| 6656 Type2 substitutedType = baseType.substitute2(argumentTypes, parameterTypes); | 6711 Type2 substitutedType = baseType.substitute2(argumentTypes, parameterTypes); |
| 6657 if (baseType == substitutedType) { | 6712 if (baseType == substitutedType) { |
| 6658 return baseField; | 6713 return baseField; |
| 6659 } | 6714 } |
| 6715 // TODO(brianwilkerson) Consider caching the substituted type in the instanc
e. It would use more |
| 6716 // memory but speed up some operations. We need to see how often the type is
being re-computed. |
| 6660 return new FieldMember(baseField, definingType); | 6717 return new FieldMember(baseField, definingType); |
| 6661 } | 6718 } |
| 6662 | 6719 |
| 6663 /** | 6720 /** |
| 6664 * Initialize a newly created element to represent a field of the given parame
terized type. | 6721 * Initialize a newly created element to represent a field of the given parame
terized type. |
| 6665 * | 6722 * |
| 6666 * @param baseElement the element on which the parameterized element was creat
ed | 6723 * @param baseElement the element on which the parameterized element was creat
ed |
| 6667 * @param definingType the type in which the element is defined | 6724 * @param definingType the type in which the element is defined |
| 6668 */ | 6725 */ |
| 6669 FieldMember(FieldElement baseElement, InterfaceType definingType) : super(base
Element, definingType); | 6726 FieldMember(FieldElement baseElement, InterfaceType definingType) : super(base
Element, definingType); |
| (...skipping 168 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6838 if (baseMethod == null || definingType.typeArguments.length == 0) { | 6895 if (baseMethod == null || definingType.typeArguments.length == 0) { |
| 6839 return baseMethod; | 6896 return baseMethod; |
| 6840 } | 6897 } |
| 6841 FunctionType baseType = baseMethod.type; | 6898 FunctionType baseType = baseMethod.type; |
| 6842 List<Type2> argumentTypes = definingType.typeArguments; | 6899 List<Type2> argumentTypes = definingType.typeArguments; |
| 6843 List<Type2> parameterTypes = definingType.element.type.typeArguments; | 6900 List<Type2> parameterTypes = definingType.element.type.typeArguments; |
| 6844 FunctionType substitutedType = baseType.substitute2(argumentTypes, parameter
Types); | 6901 FunctionType substitutedType = baseType.substitute2(argumentTypes, parameter
Types); |
| 6845 if (baseType == substitutedType) { | 6902 if (baseType == substitutedType) { |
| 6846 return baseMethod; | 6903 return baseMethod; |
| 6847 } | 6904 } |
| 6905 // TODO(brianwilkerson) Consider caching the substituted type in the instanc
e. It would use more |
| 6906 // memory but speed up some operations. We need to see how often the type is
being re-computed. |
| 6848 return new MethodMember(baseMethod, definingType); | 6907 return new MethodMember(baseMethod, definingType); |
| 6849 } | 6908 } |
| 6850 | 6909 |
| 6851 /** | 6910 /** |
| 6852 * Initialize a newly created element to represent a method of the given param
eterized type. | 6911 * Initialize a newly created element to represent a method of the given param
eterized type. |
| 6853 * | 6912 * |
| 6854 * @param baseElement the element on which the parameterized element was creat
ed | 6913 * @param baseElement the element on which the parameterized element was creat
ed |
| 6855 * @param definingType the type in which the element is defined | 6914 * @param definingType the type in which the element is defined |
| 6856 */ | 6915 */ |
| 6857 MethodMember(MethodElement baseElement, InterfaceType definingType) : super(ba
seElement, definingType); | 6916 MethodMember(MethodElement baseElement, InterfaceType definingType) : super(ba
seElement, definingType); |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6904 * | 6963 * |
| 6905 * @param baseParameter the base parameter for which a member might be created | 6964 * @param baseParameter the base parameter for which a member might be created |
| 6906 * @param definingType the type defining the parameters and arguments to be us
ed in the | 6965 * @param definingType the type defining the parameters and arguments to be us
ed in the |
| 6907 * substitution | 6966 * substitution |
| 6908 * @return the parameter element that will return the correctly substituted ty
pes | 6967 * @return the parameter element that will return the correctly substituted ty
pes |
| 6909 */ | 6968 */ |
| 6910 static ParameterElement from(ParameterElement baseParameter, ParameterizedType
definingType) { | 6969 static ParameterElement from(ParameterElement baseParameter, ParameterizedType
definingType) { |
| 6911 if (baseParameter == null || definingType.typeArguments.length == 0) { | 6970 if (baseParameter == null || definingType.typeArguments.length == 0) { |
| 6912 return baseParameter; | 6971 return baseParameter; |
| 6913 } | 6972 } |
| 6973 // Check if parameter type depends on defining type type arguments. |
| 6974 // It is possible that we did not resolve field formal parameter yet, so ski
p this check for it. |
| 6914 bool isFieldFormal = baseParameter is FieldFormalParameterElement; | 6975 bool isFieldFormal = baseParameter is FieldFormalParameterElement; |
| 6915 if (!isFieldFormal) { | 6976 if (!isFieldFormal) { |
| 6916 Type2 baseType = baseParameter.type; | 6977 Type2 baseType = baseParameter.type; |
| 6917 List<Type2> argumentTypes = definingType.typeArguments; | 6978 List<Type2> argumentTypes = definingType.typeArguments; |
| 6918 List<Type2> parameterTypes = TypeParameterTypeImpl.getTypes(definingType.t
ypeParameters); | 6979 List<Type2> parameterTypes = TypeParameterTypeImpl.getTypes(definingType.t
ypeParameters); |
| 6919 Type2 substitutedType = baseType.substitute2(argumentTypes, parameterTypes
); | 6980 Type2 substitutedType = baseType.substitute2(argumentTypes, parameterTypes
); |
| 6920 if (baseType == substitutedType) { | 6981 if (baseType == substitutedType) { |
| 6921 return baseParameter; | 6982 return baseParameter; |
| 6922 } | 6983 } |
| 6923 } | 6984 } |
| 6985 // TODO(brianwilkerson) Consider caching the substituted type in the instanc
e. It would use more |
| 6986 // memory but speed up some operations. We need to see how often the type is
being re-computed. |
| 6924 if (isFieldFormal) { | 6987 if (isFieldFormal) { |
| 6925 return new FieldFormalParameterMember(baseParameter as FieldFormalParamete
rElement, definingType); | 6988 return new FieldFormalParameterMember(baseParameter as FieldFormalParamete
rElement, definingType); |
| 6926 } | 6989 } |
| 6927 return new ParameterMember(baseParameter, definingType); | 6990 return new ParameterMember(baseParameter, definingType); |
| 6928 } | 6991 } |
| 6929 | 6992 |
| 6930 /** | 6993 /** |
| 6931 * Initialize a newly created element to represent a parameter of the given pa
rameterized type. | 6994 * Initialize a newly created element to represent a parameter of the given pa
rameterized type. |
| 6932 * | 6995 * |
| 6933 * @param baseElement the element on which the parameterized element was creat
ed | 6996 * @param baseElement the element on which the parameterized element was creat
ed |
| (...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7027 if (baseAccessor == null || definingType.typeArguments.length == 0) { | 7090 if (baseAccessor == null || definingType.typeArguments.length == 0) { |
| 7028 return baseAccessor; | 7091 return baseAccessor; |
| 7029 } | 7092 } |
| 7030 FunctionType baseType = baseAccessor.type; | 7093 FunctionType baseType = baseAccessor.type; |
| 7031 List<Type2> argumentTypes = definingType.typeArguments; | 7094 List<Type2> argumentTypes = definingType.typeArguments; |
| 7032 List<Type2> parameterTypes = definingType.element.type.typeArguments; | 7095 List<Type2> parameterTypes = definingType.element.type.typeArguments; |
| 7033 FunctionType substitutedType = baseType.substitute2(argumentTypes, parameter
Types); | 7096 FunctionType substitutedType = baseType.substitute2(argumentTypes, parameter
Types); |
| 7034 if (baseType == substitutedType) { | 7097 if (baseType == substitutedType) { |
| 7035 return baseAccessor; | 7098 return baseAccessor; |
| 7036 } | 7099 } |
| 7100 // TODO(brianwilkerson) Consider caching the substituted type in the instanc
e. It would use more |
| 7101 // memory but speed up some operations. We need to see how often the type is
being re-computed. |
| 7037 return new PropertyAccessorMember(baseAccessor, definingType); | 7102 return new PropertyAccessorMember(baseAccessor, definingType); |
| 7038 } | 7103 } |
| 7039 | 7104 |
| 7040 /** | 7105 /** |
| 7041 * Initialize a newly created element to represent a property accessor of the
given parameterized | 7106 * Initialize a newly created element to represent a property accessor of the
given parameterized |
| 7042 * type. | 7107 * type. |
| 7043 * | 7108 * |
| 7044 * @param baseElement the element on which the parameterized element was creat
ed | 7109 * @param baseElement the element on which the parameterized element was creat
ed |
| 7045 * @param definingType the type in which the element is defined | 7110 * @param definingType the type in which the element is defined |
| 7046 */ | 7111 */ |
| (...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7113 * parameterized type. | 7178 * parameterized type. |
| 7114 * | 7179 * |
| 7115 * @param baseElement the element on which the parameterized element was creat
ed | 7180 * @param baseElement the element on which the parameterized element was creat
ed |
| 7116 * @param definingType the type in which the element is defined | 7181 * @param definingType the type in which the element is defined |
| 7117 */ | 7182 */ |
| 7118 VariableMember(VariableElement baseElement, ParameterizedType definingType) :
super(baseElement, definingType); | 7183 VariableMember(VariableElement baseElement, ParameterizedType definingType) :
super(baseElement, definingType); |
| 7119 | 7184 |
| 7120 VariableElement get baseElement => super.baseElement as VariableElement; | 7185 VariableElement get baseElement => super.baseElement as VariableElement; |
| 7121 | 7186 |
| 7122 FunctionElement get initializer { | 7187 FunctionElement get initializer { |
| 7188 // |
| 7189 // Elements within this element should have type parameters substituted, jus
t like this element. |
| 7190 // |
| 7123 throw new UnsupportedOperationException(); | 7191 throw new UnsupportedOperationException(); |
| 7124 } | 7192 } |
| 7125 | 7193 |
| 7126 VariableDeclaration get node => baseElement.node; | 7194 VariableDeclaration get node => baseElement.node; |
| 7127 | 7195 |
| 7128 Type2 get type => substituteFor(baseElement.type); | 7196 Type2 get type => substituteFor(baseElement.type); |
| 7129 | 7197 |
| 7130 bool get isConst => baseElement.isConst; | 7198 bool get isConst => baseElement.isConst; |
| 7131 | 7199 |
| 7132 bool get isFinal => baseElement.isFinal; | 7200 bool get isFinal => baseElement.isFinal; |
| 7133 | 7201 |
| 7134 void visitChildren(ElementVisitor visitor) { | 7202 void visitChildren(ElementVisitor visitor) { |
| 7203 // TODO(brianwilkerson) We need to finish implementing the accessors used be
low so that we can |
| 7204 // safely invoke them. |
| 7135 super.visitChildren(visitor); | 7205 super.visitChildren(visitor); |
| 7136 safelyVisitChild(baseElement.initializer, visitor); | 7206 safelyVisitChild(baseElement.initializer, visitor); |
| 7137 } | 7207 } |
| 7138 } | 7208 } |
| 7139 | 7209 |
| 7140 /** | 7210 /** |
| 7141 * The unique instance of the class `BottomTypeImpl` implements the type `bottom
`. | 7211 * The unique instance of the class `BottomTypeImpl` implements the type `bottom
`. |
| 7142 * | 7212 * |
| 7143 * @coverage dart.engine.type | 7213 * @coverage dart.engine.type |
| 7144 */ | 7214 */ |
| (...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7216 if (parameterTypes[i] == this) { | 7286 if (parameterTypes[i] == this) { |
| 7217 return argumentTypes[i]; | 7287 return argumentTypes[i]; |
| 7218 } | 7288 } |
| 7219 } | 7289 } |
| 7220 return this; | 7290 return this; |
| 7221 } | 7291 } |
| 7222 | 7292 |
| 7223 bool internalEquals(Object object, Set<ElementPair> visitedElementPairs) => id
entical(object, this); | 7293 bool internalEquals(Object object, Set<ElementPair> visitedElementPairs) => id
entical(object, this); |
| 7224 | 7294 |
| 7225 bool internalIsMoreSpecificThan(Type2 type, bool withDynamic, Set<TypeImpl_Typ
ePair> visitedTypePairs) { | 7295 bool internalIsMoreSpecificThan(Type2 type, bool withDynamic, Set<TypeImpl_Typ
ePair> visitedTypePairs) { |
| 7296 // T is S |
| 7226 if (identical(this, type)) { | 7297 if (identical(this, type)) { |
| 7227 return true; | 7298 return true; |
| 7228 } | 7299 } |
| 7300 // else |
| 7229 return withDynamic; | 7301 return withDynamic; |
| 7230 } | 7302 } |
| 7231 | 7303 |
| 7232 bool internalIsSubtypeOf(Type2 type, Set<TypeImpl_TypePair> visitedTypePairs)
=> true; | 7304 bool internalIsSubtypeOf(Type2 type, Set<TypeImpl_TypePair> visitedTypePairs)
=> true; |
| 7233 } | 7305 } |
| 7234 | 7306 |
| 7235 /** | 7307 /** |
| 7236 * Instances of the class `FunctionTypeImpl` defines the behavior common to obje
cts | 7308 * Instances of the class `FunctionTypeImpl` defines the behavior common to obje
cts |
| 7237 * representing the type of a function, method, constructor, getter, or setter. | 7309 * representing the type of a function, method, constructor, getter, or setter. |
| 7238 * | 7310 * |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7285 * | 7357 * |
| 7286 * @param element the element representing the declaration of the function typ
e | 7358 * @param element the element representing the declaration of the function typ
e |
| 7287 */ | 7359 */ |
| 7288 FunctionTypeImpl.con2(FunctionTypeAliasElement element) : super(element, eleme
nt == null ? null : element.name); | 7360 FunctionTypeImpl.con2(FunctionTypeAliasElement element) : super(element, eleme
nt == null ? null : element.name); |
| 7289 | 7361 |
| 7290 bool operator ==(Object object) => internalEquals(object, new Set<ElementPair>
()); | 7362 bool operator ==(Object object) => internalEquals(object, new Set<ElementPair>
()); |
| 7291 | 7363 |
| 7292 String get displayName { | 7364 String get displayName { |
| 7293 String name = this.name; | 7365 String name = this.name; |
| 7294 if (name == null || name.length == 0) { | 7366 if (name == null || name.length == 0) { |
| 7367 // TODO(brianwilkerson) Determine whether function types should ever have
an empty name. |
| 7295 List<Type2> normalParameterTypes = this.normalParameterTypes; | 7368 List<Type2> normalParameterTypes = this.normalParameterTypes; |
| 7296 List<Type2> optionalParameterTypes = this.optionalParameterTypes; | 7369 List<Type2> optionalParameterTypes = this.optionalParameterTypes; |
| 7297 Map<String, Type2> namedParameterTypes = this.namedParameterTypes; | 7370 Map<String, Type2> namedParameterTypes = this.namedParameterTypes; |
| 7298 Type2 returnType = this.returnType; | 7371 Type2 returnType = this.returnType; |
| 7299 JavaStringBuilder builder = new JavaStringBuilder(); | 7372 JavaStringBuilder builder = new JavaStringBuilder(); |
| 7300 builder.append("("); | 7373 builder.append("("); |
| 7301 bool needsComma = false; | 7374 bool needsComma = false; |
| 7302 if (normalParameterTypes.length > 0) { | 7375 if (normalParameterTypes.length > 0) { |
| 7303 for (Type2 type in normalParameterTypes) { | 7376 for (Type2 type in normalParameterTypes) { |
| 7304 if (needsComma) { | 7377 if (needsComma) { |
| (...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7397 for (ParameterElement parameter in parameters) { | 7470 for (ParameterElement parameter in parameters) { |
| 7398 if (identical(parameter.parameterKind, ParameterKind.POSITIONAL)) { | 7471 if (identical(parameter.parameterKind, ParameterKind.POSITIONAL)) { |
| 7399 types.add(parameter.type.substitute2(typeArguments, typeParameters)); | 7472 types.add(parameter.type.substitute2(typeArguments, typeParameters)); |
| 7400 } | 7473 } |
| 7401 } | 7474 } |
| 7402 return new List.from(types); | 7475 return new List.from(types); |
| 7403 } | 7476 } |
| 7404 | 7477 |
| 7405 List<ParameterElement> get parameters { | 7478 List<ParameterElement> get parameters { |
| 7406 List<ParameterElement> baseParameters = this.baseParameters; | 7479 List<ParameterElement> baseParameters = this.baseParameters; |
| 7480 // no parameters, quick return |
| 7407 int parameterCount = baseParameters.length; | 7481 int parameterCount = baseParameters.length; |
| 7408 if (parameterCount == 0) { | 7482 if (parameterCount == 0) { |
| 7409 return baseParameters; | 7483 return baseParameters; |
| 7410 } | 7484 } |
| 7485 // create specialized parameters |
| 7411 List<ParameterElement> specializedParameters = new List<ParameterElement>(pa
rameterCount); | 7486 List<ParameterElement> specializedParameters = new List<ParameterElement>(pa
rameterCount); |
| 7412 for (int i = 0; i < parameterCount; i++) { | 7487 for (int i = 0; i < parameterCount; i++) { |
| 7413 specializedParameters[i] = ParameterMember.from(baseParameters[i], this); | 7488 specializedParameters[i] = ParameterMember.from(baseParameters[i], this); |
| 7414 } | 7489 } |
| 7415 return specializedParameters; | 7490 return specializedParameters; |
| 7416 } | 7491 } |
| 7417 | 7492 |
| 7418 Type2 get returnType { | 7493 Type2 get returnType { |
| 7419 Type2 baseReturnType = this.baseReturnType; | 7494 Type2 baseReturnType = this.baseReturnType; |
| 7420 if (baseReturnType == null) { | 7495 if (baseReturnType == null) { |
| 7496 // TODO(brianwilkerson) This is a patch. The return type should never be n
ull and we need to |
| 7497 // understand why it is and fix it. |
| 7421 return DynamicTypeImpl.instance; | 7498 return DynamicTypeImpl.instance; |
| 7422 } | 7499 } |
| 7423 return baseReturnType.substitute2(typeArguments, TypeParameterTypeImpl.getTy
pes(typeParameters)); | 7500 return baseReturnType.substitute2(typeArguments, TypeParameterTypeImpl.getTy
pes(typeParameters)); |
| 7424 } | 7501 } |
| 7425 | 7502 |
| 7426 List<TypeParameterElement> get typeParameters { | 7503 List<TypeParameterElement> get typeParameters { |
| 7427 Element element = this.element; | 7504 Element element = this.element; |
| 7428 if (element is FunctionTypeAliasElement) { | 7505 if (element is FunctionTypeAliasElement) { |
| 7429 return element.typeParameters; | 7506 return element.typeParameters; |
| 7430 } | 7507 } |
| 7431 ClassElement definingClass = element.getAncestor(ClassElement); | 7508 ClassElement definingClass = element.getAncestor(ClassElement); |
| 7432 if (definingClass != null) { | 7509 if (definingClass != null) { |
| 7433 return definingClass.typeParameters; | 7510 return definingClass.typeParameters; |
| 7434 } | 7511 } |
| 7435 return TypeParameterElementImpl.EMPTY_ARRAY; | 7512 return TypeParameterElementImpl.EMPTY_ARRAY; |
| 7436 } | 7513 } |
| 7437 | 7514 |
| 7438 int get hashCode { | 7515 int get hashCode { |
| 7439 if (element == null) { | 7516 if (element == null) { |
| 7440 return 0; | 7517 return 0; |
| 7441 } | 7518 } |
| 7519 // Reference the arrays of parameters |
| 7442 List<Type2> normalParameterTypes = this.normalParameterTypes; | 7520 List<Type2> normalParameterTypes = this.normalParameterTypes; |
| 7443 List<Type2> optionalParameterTypes = this.optionalParameterTypes; | 7521 List<Type2> optionalParameterTypes = this.optionalParameterTypes; |
| 7444 Iterable<Type2> namedParameterTypes = this.namedParameterTypes.values; | 7522 Iterable<Type2> namedParameterTypes = this.namedParameterTypes.values; |
| 7523 // Generate the hashCode |
| 7445 int hashCode = returnType.hashCode; | 7524 int hashCode = returnType.hashCode; |
| 7446 for (int i = 0; i < normalParameterTypes.length; i++) { | 7525 for (int i = 0; i < normalParameterTypes.length; i++) { |
| 7447 hashCode = (hashCode << 1) + normalParameterTypes[i].hashCode; | 7526 hashCode = (hashCode << 1) + normalParameterTypes[i].hashCode; |
| 7448 } | 7527 } |
| 7449 for (int i = 0; i < optionalParameterTypes.length; i++) { | 7528 for (int i = 0; i < optionalParameterTypes.length; i++) { |
| 7450 hashCode = (hashCode << 1) + optionalParameterTypes[i].hashCode; | 7529 hashCode = (hashCode << 1) + optionalParameterTypes[i].hashCode; |
| 7451 } | 7530 } |
| 7452 for (Type2 type in namedParameterTypes) { | 7531 for (Type2 type in namedParameterTypes) { |
| 7453 hashCode = (hashCode << 1) + type.hashCode; | 7532 hashCode = (hashCode << 1) + type.hashCode; |
| 7454 } | 7533 } |
| 7455 return hashCode; | 7534 return hashCode; |
| 7456 } | 7535 } |
| 7457 | 7536 |
| 7458 bool internalIsMoreSpecificThan(Type2 type, bool withDynamic, Set<TypeImpl_Typ
ePair> visitedTypePairs) { | 7537 bool internalIsMoreSpecificThan(Type2 type, bool withDynamic, Set<TypeImpl_Typ
ePair> visitedTypePairs) { |
| 7538 // trivial base cases |
| 7459 if (type == null) { | 7539 if (type == null) { |
| 7460 return false; | 7540 return false; |
| 7461 } else if (identical(this, type) || type.isDynamic || type.isDartCoreFunctio
n || type.isObject) { | 7541 } else if (identical(this, type) || type.isDynamic || type.isDartCoreFunctio
n || type.isObject) { |
| 7462 return true; | 7542 return true; |
| 7463 } else if (type is! FunctionType) { | 7543 } else if (type is! FunctionType) { |
| 7464 return false; | 7544 return false; |
| 7465 } else if (this == type) { | 7545 } else if (this == type) { |
| 7466 return true; | 7546 return true; |
| 7467 } | 7547 } |
| 7468 FunctionType t = this; | 7548 FunctionType t = this; |
| 7469 FunctionType s = type as FunctionType; | 7549 FunctionType s = type as FunctionType; |
| 7470 List<Type2> tTypes = t.normalParameterTypes; | 7550 List<Type2> tTypes = t.normalParameterTypes; |
| 7471 List<Type2> tOpTypes = t.optionalParameterTypes; | 7551 List<Type2> tOpTypes = t.optionalParameterTypes; |
| 7472 List<Type2> sTypes = s.normalParameterTypes; | 7552 List<Type2> sTypes = s.normalParameterTypes; |
| 7473 List<Type2> sOpTypes = s.optionalParameterTypes; | 7553 List<Type2> sOpTypes = s.optionalParameterTypes; |
| 7554 // If one function has positional and the other has named parameters, return
false. |
| 7474 if ((sOpTypes.length > 0 && t.namedParameterTypes.length > 0) || (tOpTypes.l
ength > 0 && s.namedParameterTypes.length > 0)) { | 7555 if ((sOpTypes.length > 0 && t.namedParameterTypes.length > 0) || (tOpTypes.l
ength > 0 && s.namedParameterTypes.length > 0)) { |
| 7475 return false; | 7556 return false; |
| 7476 } | 7557 } |
| 7558 // named parameters case |
| 7477 if (t.namedParameterTypes.length > 0) { | 7559 if (t.namedParameterTypes.length > 0) { |
| 7560 // check that the number of required parameters are equal, and check that
every t_i is |
| 7561 // more specific than every s_i |
| 7478 if (t.normalParameterTypes.length != s.normalParameterTypes.length) { | 7562 if (t.normalParameterTypes.length != s.normalParameterTypes.length) { |
| 7479 return false; | 7563 return false; |
| 7480 } else if (t.normalParameterTypes.length > 0) { | 7564 } else if (t.normalParameterTypes.length > 0) { |
| 7481 for (int i = 0; i < tTypes.length; i++) { | 7565 for (int i = 0; i < tTypes.length; i++) { |
| 7482 if (!(tTypes[i] as TypeImpl).isMoreSpecificThan3(sTypes[i], withDynami
c, visitedTypePairs)) { | 7566 if (!(tTypes[i] as TypeImpl).isMoreSpecificThan3(sTypes[i], withDynami
c, visitedTypePairs)) { |
| 7483 return false; | 7567 return false; |
| 7484 } | 7568 } |
| 7485 } | 7569 } |
| 7486 } | 7570 } |
| 7487 Map<String, Type2> namedTypesT = t.namedParameterTypes; | 7571 Map<String, Type2> namedTypesT = t.namedParameterTypes; |
| 7488 Map<String, Type2> namedTypesS = s.namedParameterTypes; | 7572 Map<String, Type2> namedTypesS = s.namedParameterTypes; |
| 7573 // if k >= m is false, return false: the passed function type has more nam
ed parameter types than this |
| 7489 if (namedTypesT.length < namedTypesS.length) { | 7574 if (namedTypesT.length < namedTypesS.length) { |
| 7490 return false; | 7575 return false; |
| 7491 } | 7576 } |
| 7577 // Loop through each element in S verifying that T has a matching paramete
r name and that the |
| 7578 // corresponding type is more specific then the type in S. |
| 7492 JavaIterator<MapEntry<String, Type2>> iteratorS = new JavaIterator(getMapE
ntrySet(namedTypesS)); | 7579 JavaIterator<MapEntry<String, Type2>> iteratorS = new JavaIterator(getMapE
ntrySet(namedTypesS)); |
| 7493 while (iteratorS.hasNext) { | 7580 while (iteratorS.hasNext) { |
| 7494 MapEntry<String, Type2> entryS = iteratorS.next(); | 7581 MapEntry<String, Type2> entryS = iteratorS.next(); |
| 7495 Type2 typeT = namedTypesT[entryS.getKey()]; | 7582 Type2 typeT = namedTypesT[entryS.getKey()]; |
| 7496 if (typeT == null) { | 7583 if (typeT == null) { |
| 7497 return false; | 7584 return false; |
| 7498 } | 7585 } |
| 7499 if (!(typeT as TypeImpl).isMoreSpecificThan3(entryS.getValue(), withDyna
mic, visitedTypePairs)) { | 7586 if (!(typeT as TypeImpl).isMoreSpecificThan3(entryS.getValue(), withDyna
mic, visitedTypePairs)) { |
| 7500 return false; | 7587 return false; |
| 7501 } | 7588 } |
| 7502 } | 7589 } |
| 7503 } else if (s.namedParameterTypes.length > 0) { | 7590 } else if (s.namedParameterTypes.length > 0) { |
| 7504 return false; | 7591 return false; |
| 7505 } else { | 7592 } else { |
| 7593 // positional parameter case |
| 7506 int tArgLength = tTypes.length + tOpTypes.length; | 7594 int tArgLength = tTypes.length + tOpTypes.length; |
| 7507 int sArgLength = sTypes.length + sOpTypes.length; | 7595 int sArgLength = sTypes.length + sOpTypes.length; |
| 7596 // Check that the total number of parameters in t is greater than or equal
to the number of |
| 7597 // parameters in s and that the number of required parameters in s is grea
ter than or equal to |
| 7598 // the number of required parameters in t. |
| 7508 if (tArgLength < sArgLength || sTypes.length < tTypes.length) { | 7599 if (tArgLength < sArgLength || sTypes.length < tTypes.length) { |
| 7509 return false; | 7600 return false; |
| 7510 } | 7601 } |
| 7511 if (tOpTypes.length == 0 && sOpTypes.length == 0) { | 7602 if (tOpTypes.length == 0 && sOpTypes.length == 0) { |
| 7603 // No positional arguments, don't copy contents to new array |
| 7512 for (int i = 0; i < sTypes.length; i++) { | 7604 for (int i = 0; i < sTypes.length; i++) { |
| 7513 if (!(tTypes[i] as TypeImpl).isMoreSpecificThan3(sTypes[i], withDynami
c, visitedTypePairs)) { | 7605 if (!(tTypes[i] as TypeImpl).isMoreSpecificThan3(sTypes[i], withDynami
c, visitedTypePairs)) { |
| 7514 return false; | 7606 return false; |
| 7515 } | 7607 } |
| 7516 } | 7608 } |
| 7517 } else { | 7609 } else { |
| 7610 // Else, we do have positional parameters, copy required and positional
parameter types into |
| 7611 // arrays to do the compare (for loop below). |
| 7518 List<Type2> tAllTypes = new List<Type2>(sArgLength); | 7612 List<Type2> tAllTypes = new List<Type2>(sArgLength); |
| 7519 for (int i = 0; i < tTypes.length; i++) { | 7613 for (int i = 0; i < tTypes.length; i++) { |
| 7520 tAllTypes[i] = tTypes[i]; | 7614 tAllTypes[i] = tTypes[i]; |
| 7521 } | 7615 } |
| 7522 for (int i = tTypes.length, j = 0; i < sArgLength; i++, j++) { | 7616 for (int i = tTypes.length, j = 0; i < sArgLength; i++, j++) { |
| 7523 tAllTypes[i] = tOpTypes[j]; | 7617 tAllTypes[i] = tOpTypes[j]; |
| 7524 } | 7618 } |
| 7525 List<Type2> sAllTypes = new List<Type2>(sArgLength); | 7619 List<Type2> sAllTypes = new List<Type2>(sArgLength); |
| 7526 for (int i = 0; i < sTypes.length; i++) { | 7620 for (int i = 0; i < sTypes.length; i++) { |
| 7527 sAllTypes[i] = sTypes[i]; | 7621 sAllTypes[i] = sTypes[i]; |
| (...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7630 } else { | 7724 } else { |
| 7631 return (element as FunctionTypeAliasElement).parameters; | 7725 return (element as FunctionTypeAliasElement).parameters; |
| 7632 } | 7726 } |
| 7633 } | 7727 } |
| 7634 | 7728 |
| 7635 bool internalEquals(Object object, Set<ElementPair> visitedElementPairs) { | 7729 bool internalEquals(Object object, Set<ElementPair> visitedElementPairs) { |
| 7636 if (object is! FunctionTypeImpl) { | 7730 if (object is! FunctionTypeImpl) { |
| 7637 return false; | 7731 return false; |
| 7638 } | 7732 } |
| 7639 FunctionTypeImpl otherType = object as FunctionTypeImpl; | 7733 FunctionTypeImpl otherType = object as FunctionTypeImpl; |
| 7734 // If the visitedTypePairs already has the pair (this, type), use the elemen
ts to determine equality |
| 7640 ElementPair elementPair = new ElementPair(element, otherType.element); | 7735 ElementPair elementPair = new ElementPair(element, otherType.element); |
| 7641 if (!visitedElementPairs.add(elementPair)) { | 7736 if (!visitedElementPairs.add(elementPair)) { |
| 7642 return elementPair.firstElt == elementPair.secondElt; | 7737 return elementPair.firstElt == elementPair.secondElt; |
| 7643 } | 7738 } |
| 7739 // Compute the result |
| 7644 bool result = TypeImpl.equalArrays(normalParameterTypes, otherType.normalPar
ameterTypes, visitedElementPairs) && TypeImpl.equalArrays(optionalParameterTypes
, otherType.optionalParameterTypes, visitedElementPairs) && equals2(namedParamet
erTypes, otherType.namedParameterTypes, visitedElementPairs) && (returnType as T
ypeImpl).internalEquals(otherType.returnType, visitedElementPairs); | 7740 bool result = TypeImpl.equalArrays(normalParameterTypes, otherType.normalPar
ameterTypes, visitedElementPairs) && TypeImpl.equalArrays(optionalParameterTypes
, otherType.optionalParameterTypes, visitedElementPairs) && equals2(namedParamet
erTypes, otherType.namedParameterTypes, visitedElementPairs) && (returnType as T
ypeImpl).internalEquals(otherType.returnType, visitedElementPairs); |
| 7741 // Remove the pair from our visited pairs list |
| 7645 visitedElementPairs.remove(elementPair); | 7742 visitedElementPairs.remove(elementPair); |
| 7743 // Return the result |
| 7646 return result; | 7744 return result; |
| 7647 } | 7745 } |
| 7648 | 7746 |
| 7649 bool internalIsSubtypeOf(Type2 type, Set<TypeImpl_TypePair> visitedTypePairs)
{ | 7747 bool internalIsSubtypeOf(Type2 type, Set<TypeImpl_TypePair> visitedTypePairs)
{ |
| 7748 // trivial base cases |
| 7650 if (type == null) { | 7749 if (type == null) { |
| 7651 return false; | 7750 return false; |
| 7652 } else if (identical(this, type) || type.isDynamic || type.isDartCoreFunctio
n || type.isObject) { | 7751 } else if (identical(this, type) || type.isDynamic || type.isDartCoreFunctio
n || type.isObject) { |
| 7653 return true; | 7752 return true; |
| 7654 } else if (type is! FunctionType) { | 7753 } else if (type is! FunctionType) { |
| 7655 return false; | 7754 return false; |
| 7656 } else if (this == type) { | 7755 } else if (this == type) { |
| 7657 return true; | 7756 return true; |
| 7658 } | 7757 } |
| 7659 FunctionType t = this; | 7758 FunctionType t = this; |
| 7660 FunctionType s = type as FunctionType; | 7759 FunctionType s = type as FunctionType; |
| 7661 List<Type2> tTypes = t.normalParameterTypes; | 7760 List<Type2> tTypes = t.normalParameterTypes; |
| 7662 List<Type2> tOpTypes = t.optionalParameterTypes; | 7761 List<Type2> tOpTypes = t.optionalParameterTypes; |
| 7663 List<Type2> sTypes = s.normalParameterTypes; | 7762 List<Type2> sTypes = s.normalParameterTypes; |
| 7664 List<Type2> sOpTypes = s.optionalParameterTypes; | 7763 List<Type2> sOpTypes = s.optionalParameterTypes; |
| 7764 // If one function has positional and the other has named parameters, return
false. |
| 7665 if ((sOpTypes.length > 0 && t.namedParameterTypes.length > 0) || (tOpTypes.l
ength > 0 && s.namedParameterTypes.length > 0)) { | 7765 if ((sOpTypes.length > 0 && t.namedParameterTypes.length > 0) || (tOpTypes.l
ength > 0 && s.namedParameterTypes.length > 0)) { |
| 7666 return false; | 7766 return false; |
| 7667 } | 7767 } |
| 7768 // named parameters case |
| 7668 if (t.namedParameterTypes.length > 0) { | 7769 if (t.namedParameterTypes.length > 0) { |
| 7770 // check that the number of required parameters are equal, and check that
every t_i is |
| 7771 // assignable to every s_i |
| 7669 if (t.normalParameterTypes.length != s.normalParameterTypes.length) { | 7772 if (t.normalParameterTypes.length != s.normalParameterTypes.length) { |
| 7670 return false; | 7773 return false; |
| 7671 } else if (t.normalParameterTypes.length > 0) { | 7774 } else if (t.normalParameterTypes.length > 0) { |
| 7672 for (int i = 0; i < tTypes.length; i++) { | 7775 for (int i = 0; i < tTypes.length; i++) { |
| 7673 if (!(tTypes[i] as TypeImpl).isAssignableTo2(sTypes[i], visitedTypePai
rs)) { | 7776 if (!(tTypes[i] as TypeImpl).isAssignableTo2(sTypes[i], visitedTypePai
rs)) { |
| 7674 return false; | 7777 return false; |
| 7675 } | 7778 } |
| 7676 } | 7779 } |
| 7677 } | 7780 } |
| 7678 Map<String, Type2> namedTypesT = t.namedParameterTypes; | 7781 Map<String, Type2> namedTypesT = t.namedParameterTypes; |
| 7679 Map<String, Type2> namedTypesS = s.namedParameterTypes; | 7782 Map<String, Type2> namedTypesS = s.namedParameterTypes; |
| 7783 // if k >= m is false, return false: the passed function type has more nam
ed parameter types than this |
| 7680 if (namedTypesT.length < namedTypesS.length) { | 7784 if (namedTypesT.length < namedTypesS.length) { |
| 7681 return false; | 7785 return false; |
| 7682 } | 7786 } |
| 7787 // Loop through each element in S verifying that T has a matching paramete
r name and that the |
| 7788 // corresponding type is assignable to the type in S. |
| 7683 JavaIterator<MapEntry<String, Type2>> iteratorS = new JavaIterator(getMapE
ntrySet(namedTypesS)); | 7789 JavaIterator<MapEntry<String, Type2>> iteratorS = new JavaIterator(getMapE
ntrySet(namedTypesS)); |
| 7684 while (iteratorS.hasNext) { | 7790 while (iteratorS.hasNext) { |
| 7685 MapEntry<String, Type2> entryS = iteratorS.next(); | 7791 MapEntry<String, Type2> entryS = iteratorS.next(); |
| 7686 Type2 typeT = namedTypesT[entryS.getKey()]; | 7792 Type2 typeT = namedTypesT[entryS.getKey()]; |
| 7687 if (typeT == null) { | 7793 if (typeT == null) { |
| 7688 return false; | 7794 return false; |
| 7689 } | 7795 } |
| 7690 if (!(typeT as TypeImpl).isAssignableTo2(entryS.getValue(), visitedTypeP
airs)) { | 7796 if (!(typeT as TypeImpl).isAssignableTo2(entryS.getValue(), visitedTypeP
airs)) { |
| 7691 return false; | 7797 return false; |
| 7692 } | 7798 } |
| 7693 } | 7799 } |
| 7694 } else if (s.namedParameterTypes.length > 0) { | 7800 } else if (s.namedParameterTypes.length > 0) { |
| 7695 return false; | 7801 return false; |
| 7696 } else { | 7802 } else { |
| 7803 // positional parameter case |
| 7697 int tArgLength = tTypes.length + tOpTypes.length; | 7804 int tArgLength = tTypes.length + tOpTypes.length; |
| 7698 int sArgLength = sTypes.length + sOpTypes.length; | 7805 int sArgLength = sTypes.length + sOpTypes.length; |
| 7806 // Check that the total number of parameters in t is greater than or equal
to the number of |
| 7807 // parameters in s and that the number of required parameters in s is grea
ter than or equal to |
| 7808 // the number of required parameters in t. |
| 7699 if (tArgLength < sArgLength || sTypes.length < tTypes.length) { | 7809 if (tArgLength < sArgLength || sTypes.length < tTypes.length) { |
| 7700 return false; | 7810 return false; |
| 7701 } | 7811 } |
| 7702 if (tOpTypes.length == 0 && sOpTypes.length == 0) { | 7812 if (tOpTypes.length == 0 && sOpTypes.length == 0) { |
| 7813 // No positional arguments, don't copy contents to new array |
| 7703 for (int i = 0; i < sTypes.length; i++) { | 7814 for (int i = 0; i < sTypes.length; i++) { |
| 7704 if (!(tTypes[i] as TypeImpl).isAssignableTo2(sTypes[i], visitedTypePai
rs)) { | 7815 if (!(tTypes[i] as TypeImpl).isAssignableTo2(sTypes[i], visitedTypePai
rs)) { |
| 7705 return false; | 7816 return false; |
| 7706 } | 7817 } |
| 7707 } | 7818 } |
| 7708 } else { | 7819 } else { |
| 7820 // Else, we do have positional parameters, copy required and positional
parameter types into |
| 7821 // arrays to do the compare (for loop below). |
| 7709 List<Type2> tAllTypes = new List<Type2>(sArgLength); | 7822 List<Type2> tAllTypes = new List<Type2>(sArgLength); |
| 7710 for (int i = 0; i < tTypes.length; i++) { | 7823 for (int i = 0; i < tTypes.length; i++) { |
| 7711 tAllTypes[i] = tTypes[i]; | 7824 tAllTypes[i] = tTypes[i]; |
| 7712 } | 7825 } |
| 7713 for (int i = tTypes.length, j = 0; i < sArgLength; i++, j++) { | 7826 for (int i = tTypes.length, j = 0; i < sArgLength; i++, j++) { |
| 7714 tAllTypes[i] = tOpTypes[j]; | 7827 tAllTypes[i] = tOpTypes[j]; |
| 7715 } | 7828 } |
| 7716 List<Type2> sAllTypes = new List<Type2>(sArgLength); | 7829 List<Type2> sAllTypes = new List<Type2>(sArgLength); |
| 7717 for (int i = 0; i < sTypes.length; i++) { | 7830 for (int i = 0; i < sTypes.length; i++) { |
| 7718 sAllTypes[i] = sTypes[i]; | 7831 sAllTypes[i] = sTypes[i]; |
| (...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7787 * @param type the [Type] to compute the longest inheritance path of from the
passed | 7900 * @param type the [Type] to compute the longest inheritance path of from the
passed |
| 7788 * [Type] to Object | 7901 * [Type] to Object |
| 7789 * @param depth a field used recursively | 7902 * @param depth a field used recursively |
| 7790 * @param visitedClasses the classes that have already been visited | 7903 * @param visitedClasses the classes that have already been visited |
| 7791 * @return the computed longest inheritance path to Object | 7904 * @return the computed longest inheritance path to Object |
| 7792 * @see #computeLongestInheritancePathToObject(Type) | 7905 * @see #computeLongestInheritancePathToObject(Type) |
| 7793 * @see #getLeastUpperBound(Type) | 7906 * @see #getLeastUpperBound(Type) |
| 7794 */ | 7907 */ |
| 7795 static int computeLongestInheritancePathToObject2(InterfaceType type, int dept
h, Set<ClassElement> visitedClasses) { | 7908 static int computeLongestInheritancePathToObject2(InterfaceType type, int dept
h, Set<ClassElement> visitedClasses) { |
| 7796 ClassElement classElement = type.element; | 7909 ClassElement classElement = type.element; |
| 7910 // Object case |
| 7797 if (classElement.supertype == null || visitedClasses.contains(classElement))
{ | 7911 if (classElement.supertype == null || visitedClasses.contains(classElement))
{ |
| 7798 return depth; | 7912 return depth; |
| 7799 } | 7913 } |
| 7800 int longestPath = 1; | 7914 int longestPath = 1; |
| 7801 try { | 7915 try { |
| 7802 visitedClasses.add(classElement); | 7916 visitedClasses.add(classElement); |
| 7803 List<InterfaceType> superinterfaces = classElement.interfaces; | 7917 List<InterfaceType> superinterfaces = classElement.interfaces; |
| 7804 int pathLength; | 7918 int pathLength; |
| 7805 if (superinterfaces.length > 0) { | 7919 if (superinterfaces.length > 0) { |
| 7920 // loop through each of the superinterfaces recursively calling this met
hod and keeping track |
| 7921 // of the longest path to return |
| 7806 for (InterfaceType superinterface in superinterfaces) { | 7922 for (InterfaceType superinterface in superinterfaces) { |
| 7807 pathLength = computeLongestInheritancePathToObject2(superinterface, de
pth + 1, visitedClasses); | 7923 pathLength = computeLongestInheritancePathToObject2(superinterface, de
pth + 1, visitedClasses); |
| 7808 if (pathLength > longestPath) { | 7924 if (pathLength > longestPath) { |
| 7809 longestPath = pathLength; | 7925 longestPath = pathLength; |
| 7810 } | 7926 } |
| 7811 } | 7927 } |
| 7812 } | 7928 } |
| 7929 // finally, perform this same check on the super type |
| 7930 // TODO(brianwilkerson) Does this also need to add in the number of mixin
classes? |
| 7813 InterfaceType supertype = classElement.supertype; | 7931 InterfaceType supertype = classElement.supertype; |
| 7814 pathLength = computeLongestInheritancePathToObject2(supertype, depth + 1,
visitedClasses); | 7932 pathLength = computeLongestInheritancePathToObject2(supertype, depth + 1,
visitedClasses); |
| 7815 if (pathLength > longestPath) { | 7933 if (pathLength > longestPath) { |
| 7816 longestPath = pathLength; | 7934 longestPath = pathLength; |
| 7817 } | 7935 } |
| 7818 } finally { | 7936 } finally { |
| 7819 visitedClasses.remove(classElement); | 7937 visitedClasses.remove(classElement); |
| 7820 } | 7938 } |
| 7821 return longestPath; | 7939 return longestPath; |
| 7822 } | 7940 } |
| (...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7892 return firstType; | 8010 return firstType; |
| 7893 } | 8011 } |
| 7894 List<Type2> firstArguments = firstType.typeArguments; | 8012 List<Type2> firstArguments = firstType.typeArguments; |
| 7895 List<Type2> secondArguments = secondType.typeArguments; | 8013 List<Type2> secondArguments = secondType.typeArguments; |
| 7896 int argumentCount = firstArguments.length; | 8014 int argumentCount = firstArguments.length; |
| 7897 if (argumentCount == 0) { | 8015 if (argumentCount == 0) { |
| 7898 return firstType; | 8016 return firstType; |
| 7899 } | 8017 } |
| 7900 List<Type2> lubArguments = new List<Type2>(argumentCount); | 8018 List<Type2> lubArguments = new List<Type2>(argumentCount); |
| 7901 for (int i = 0; i < argumentCount; i++) { | 8019 for (int i = 0; i < argumentCount; i++) { |
| 8020 // |
| 8021 // Ideally we would take the least upper bound of the two argument types,
but this can cause |
| 8022 // an infinite recursion (such as when finding the least upper bound of St
ring and num). |
| 8023 // |
| 7902 if (firstArguments[i] == secondArguments[i]) { | 8024 if (firstArguments[i] == secondArguments[i]) { |
| 7903 lubArguments[i] = firstArguments[i]; | 8025 lubArguments[i] = firstArguments[i]; |
| 7904 } | 8026 } |
| 7905 if (lubArguments[i] == null) { | 8027 if (lubArguments[i] == null) { |
| 7906 lubArguments[i] = DynamicTypeImpl.instance; | 8028 lubArguments[i] = DynamicTypeImpl.instance; |
| 7907 } | 8029 } |
| 7908 } | 8030 } |
| 7909 InterfaceTypeImpl lub = new InterfaceTypeImpl.con1(firstType.element); | 8031 InterfaceTypeImpl lub = new InterfaceTypeImpl.con1(firstType.element); |
| 7910 lub.typeArguments = lubArguments; | 8032 lub.typeArguments = lubArguments; |
| 7911 return lub; | 8033 return lub; |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7945 String get displayName { | 8067 String get displayName { |
| 7946 String name = this.name; | 8068 String name = this.name; |
| 7947 List<Type2> typeArguments = this.typeArguments; | 8069 List<Type2> typeArguments = this.typeArguments; |
| 7948 bool allDynamic = true; | 8070 bool allDynamic = true; |
| 7949 for (Type2 type in typeArguments) { | 8071 for (Type2 type in typeArguments) { |
| 7950 if (type != null && !type.isDynamic) { | 8072 if (type != null && !type.isDynamic) { |
| 7951 allDynamic = false; | 8073 allDynamic = false; |
| 7952 break; | 8074 break; |
| 7953 } | 8075 } |
| 7954 } | 8076 } |
| 8077 // If there is at least one non-dynamic type, then list them out |
| 7955 if (!allDynamic) { | 8078 if (!allDynamic) { |
| 7956 JavaStringBuilder builder = new JavaStringBuilder(); | 8079 JavaStringBuilder builder = new JavaStringBuilder(); |
| 7957 builder.append(name); | 8080 builder.append(name); |
| 7958 builder.append("<"); | 8081 builder.append("<"); |
| 7959 for (int i = 0; i < typeArguments.length; i++) { | 8082 for (int i = 0; i < typeArguments.length; i++) { |
| 7960 if (i != 0) { | 8083 if (i != 0) { |
| 7961 builder.append(", "); | 8084 builder.append(", "); |
| 7962 } | 8085 } |
| 7963 Type2 typeArg = typeArguments[i]; | 8086 Type2 typeArg = typeArguments[i]; |
| 7964 builder.append(typeArg.displayName); | 8087 builder.append(typeArg.displayName); |
| (...skipping 18 matching lines...) Expand all Loading... |
| 7983 } | 8106 } |
| 7984 int count = interfaces.length; | 8107 int count = interfaces.length; |
| 7985 List<InterfaceType> typedInterfaces = new List<InterfaceType>(count); | 8108 List<InterfaceType> typedInterfaces = new List<InterfaceType>(count); |
| 7986 for (int i = 0; i < count; i++) { | 8109 for (int i = 0; i < count; i++) { |
| 7987 typedInterfaces[i] = interfaces[i].substitute2(typeArguments, parameterTyp
es); | 8110 typedInterfaces[i] = interfaces[i].substitute2(typeArguments, parameterTyp
es); |
| 7988 } | 8111 } |
| 7989 return typedInterfaces; | 8112 return typedInterfaces; |
| 7990 } | 8113 } |
| 7991 | 8114 |
| 7992 Type2 getLeastUpperBound(Type2 type) { | 8115 Type2 getLeastUpperBound(Type2 type) { |
| 8116 // quick check for self |
| 7993 if (identical(type, this)) { | 8117 if (identical(type, this)) { |
| 7994 return this; | 8118 return this; |
| 7995 } | 8119 } |
| 8120 // dynamic |
| 7996 Type2 dynamicType = DynamicTypeImpl.instance; | 8121 Type2 dynamicType = DynamicTypeImpl.instance; |
| 7997 if (identical(this, dynamicType) || identical(type, dynamicType)) { | 8122 if (identical(this, dynamicType) || identical(type, dynamicType)) { |
| 7998 return dynamicType; | 8123 return dynamicType; |
| 7999 } | 8124 } |
| 8125 // TODO (jwren) opportunity here for a better, faster algorithm if this turn
s out to be a bottle-neck |
| 8000 if (type is! InterfaceType) { | 8126 if (type is! InterfaceType) { |
| 8001 return null; | 8127 return null; |
| 8002 } | 8128 } |
| 8129 // new names to match up with the spec |
| 8003 InterfaceType i = this; | 8130 InterfaceType i = this; |
| 8004 InterfaceType j = type as InterfaceType; | 8131 InterfaceType j = type as InterfaceType; |
| 8132 // compute set of supertypes |
| 8005 Set<InterfaceType> si = computeSuperinterfaceSet(i); | 8133 Set<InterfaceType> si = computeSuperinterfaceSet(i); |
| 8006 Set<InterfaceType> sj = computeSuperinterfaceSet(j); | 8134 Set<InterfaceType> sj = computeSuperinterfaceSet(j); |
| 8135 // union si with i and sj with j |
| 8007 si.add(i); | 8136 si.add(i); |
| 8008 sj.add(j); | 8137 sj.add(j); |
| 8138 // compute intersection, reference as set 's' |
| 8009 List<InterfaceType> s = intersection(si, sj); | 8139 List<InterfaceType> s = intersection(si, sj); |
| 8140 // for each element in Set s, compute the largest inheritance path to Object |
| 8010 List<int> depths = new List<int>.filled(s.length, 0); | 8141 List<int> depths = new List<int>.filled(s.length, 0); |
| 8011 int maxDepth = 0; | 8142 int maxDepth = 0; |
| 8012 for (int n = 0; n < s.length; n++) { | 8143 for (int n = 0; n < s.length; n++) { |
| 8013 depths[n] = computeLongestInheritancePathToObject(s[n]); | 8144 depths[n] = computeLongestInheritancePathToObject(s[n]); |
| 8014 if (depths[n] > maxDepth) { | 8145 if (depths[n] > maxDepth) { |
| 8015 maxDepth = depths[n]; | 8146 maxDepth = depths[n]; |
| 8016 } | 8147 } |
| 8017 } | 8148 } |
| 8149 // ensure that the currently computed maxDepth is unique, |
| 8150 // otherwise, decrement and test for uniqueness again |
| 8018 for (; maxDepth >= 0; maxDepth--) { | 8151 for (; maxDepth >= 0; maxDepth--) { |
| 8019 int indexOfLeastUpperBound = -1; | 8152 int indexOfLeastUpperBound = -1; |
| 8020 int numberOfTypesAtMaxDepth = 0; | 8153 int numberOfTypesAtMaxDepth = 0; |
| 8021 for (int m = 0; m < depths.length; m++) { | 8154 for (int m = 0; m < depths.length; m++) { |
| 8022 if (depths[m] == maxDepth) { | 8155 if (depths[m] == maxDepth) { |
| 8023 numberOfTypesAtMaxDepth++; | 8156 numberOfTypesAtMaxDepth++; |
| 8024 indexOfLeastUpperBound = m; | 8157 indexOfLeastUpperBound = m; |
| 8025 } | 8158 } |
| 8026 } | 8159 } |
| 8027 if (numberOfTypesAtMaxDepth == 1) { | 8160 if (numberOfTypesAtMaxDepth == 1) { |
| 8028 return s[indexOfLeastUpperBound]; | 8161 return s[indexOfLeastUpperBound]; |
| 8029 } | 8162 } |
| 8030 } | 8163 } |
| 8164 // illegal state, log and return null- Object at maxDepth == 0 should always
return itself as |
| 8165 // the least upper bound. |
| 8166 // TODO (jwren) log the error state |
| 8031 return null; | 8167 return null; |
| 8032 } | 8168 } |
| 8033 | 8169 |
| 8034 MethodElement getMethod(String methodName) => MethodMember.from((element as Cl
assElementImpl).getMethod(methodName), this); | 8170 MethodElement getMethod(String methodName) => MethodMember.from((element as Cl
assElementImpl).getMethod(methodName), this); |
| 8035 | 8171 |
| 8036 List<MethodElement> get methods { | 8172 List<MethodElement> get methods { |
| 8037 List<MethodElement> methods = element.methods; | 8173 List<MethodElement> methods = element.methods; |
| 8038 List<MethodElement> members = new List<MethodElement>(methods.length); | 8174 List<MethodElement> members = new List<MethodElement>(methods.length); |
| 8039 for (int i = 0; i < methods.length; i++) { | 8175 for (int i = 0; i < methods.length; i++) { |
| 8040 members[i] = MethodMember.from(methods[i], this); | 8176 members[i] = MethodMember.from(methods[i], this); |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 8085 return false; | 8221 return false; |
| 8086 } | 8222 } |
| 8087 return element.name == "Function" && element.library.isDartCore; | 8223 return element.name == "Function" && element.library.isDartCore; |
| 8088 } | 8224 } |
| 8089 | 8225 |
| 8090 bool isDirectSupertypeOf(InterfaceType type) { | 8226 bool isDirectSupertypeOf(InterfaceType type) { |
| 8091 InterfaceType i = this; | 8227 InterfaceType i = this; |
| 8092 InterfaceType j = type; | 8228 InterfaceType j = type; |
| 8093 ClassElement jElement = j.element; | 8229 ClassElement jElement = j.element; |
| 8094 InterfaceType supertype = jElement.supertype; | 8230 InterfaceType supertype = jElement.supertype; |
| 8231 // |
| 8232 // If J has no direct supertype then it is Object, and Object has no direct
supertypes. |
| 8233 // |
| 8095 if (supertype == null) { | 8234 if (supertype == null) { |
| 8096 return false; | 8235 return false; |
| 8097 } | 8236 } |
| 8237 // |
| 8238 // I is listed in the extends clause of J. |
| 8239 // |
| 8098 List<Type2> jArgs = j.typeArguments; | 8240 List<Type2> jArgs = j.typeArguments; |
| 8099 List<Type2> jVars = jElement.type.typeArguments; | 8241 List<Type2> jVars = jElement.type.typeArguments; |
| 8100 supertype = supertype.substitute2(jArgs, jVars); | 8242 supertype = supertype.substitute2(jArgs, jVars); |
| 8101 if (supertype == i) { | 8243 if (supertype == i) { |
| 8102 return true; | 8244 return true; |
| 8103 } | 8245 } |
| 8246 // |
| 8247 // I is listed in the implements clause of J. |
| 8248 // |
| 8104 for (InterfaceType interfaceType in jElement.interfaces) { | 8249 for (InterfaceType interfaceType in jElement.interfaces) { |
| 8105 interfaceType = interfaceType.substitute2(jArgs, jVars); | 8250 interfaceType = interfaceType.substitute2(jArgs, jVars); |
| 8106 if (interfaceType == i) { | 8251 if (interfaceType == i) { |
| 8107 return true; | 8252 return true; |
| 8108 } | 8253 } |
| 8109 } | 8254 } |
| 8255 // |
| 8256 // I is listed in the with clause of J. |
| 8257 // |
| 8110 for (InterfaceType mixinType in jElement.mixins) { | 8258 for (InterfaceType mixinType in jElement.mixins) { |
| 8111 mixinType = mixinType.substitute2(jArgs, jVars); | 8259 mixinType = mixinType.substitute2(jArgs, jVars); |
| 8112 if (mixinType == i) { | 8260 if (mixinType == i) { |
| 8113 return true; | 8261 return true; |
| 8114 } | 8262 } |
| 8115 } | 8263 } |
| 8264 // |
| 8265 // J is a mixin application of the mixin of I. |
| 8266 // |
| 8267 // TODO(brianwilkerson) Determine whether this needs to be implemented or wh
ether it is covered |
| 8268 // by the case above. |
| 8116 return false; | 8269 return false; |
| 8117 } | 8270 } |
| 8118 | 8271 |
| 8119 bool get isObject => element.supertype == null; | 8272 bool get isObject => element.supertype == null; |
| 8120 | 8273 |
| 8121 ConstructorElement lookUpConstructor(String constructorName, LibraryElement li
brary) { | 8274 ConstructorElement lookUpConstructor(String constructorName, LibraryElement li
brary) { |
| 8275 // prepare base ConstructorElement |
| 8122 ConstructorElement constructorElement; | 8276 ConstructorElement constructorElement; |
| 8123 if (constructorName == null) { | 8277 if (constructorName == null) { |
| 8124 constructorElement = element.unnamedConstructor; | 8278 constructorElement = element.unnamedConstructor; |
| 8125 } else { | 8279 } else { |
| 8126 constructorElement = element.getNamedConstructor(constructorName); | 8280 constructorElement = element.getNamedConstructor(constructorName); |
| 8127 } | 8281 } |
| 8282 // not found or not accessible |
| 8128 if (constructorElement == null || !constructorElement.isAccessibleIn(library
)) { | 8283 if (constructorElement == null || !constructorElement.isAccessibleIn(library
)) { |
| 8129 return null; | 8284 return null; |
| 8130 } | 8285 } |
| 8286 // return member |
| 8131 return ConstructorMember.from(constructorElement, this); | 8287 return ConstructorMember.from(constructorElement, this); |
| 8132 } | 8288 } |
| 8133 | 8289 |
| 8134 PropertyAccessorElement lookUpGetter(String getterName, LibraryElement library
) { | 8290 PropertyAccessorElement lookUpGetter(String getterName, LibraryElement library
) { |
| 8135 PropertyAccessorElement element = getGetter(getterName); | 8291 PropertyAccessorElement element = getGetter(getterName); |
| 8136 if (element != null && element.isAccessibleIn(library)) { | 8292 if (element != null && element.isAccessibleIn(library)) { |
| 8137 return element; | 8293 return element; |
| 8138 } | 8294 } |
| 8139 return lookUpGetterInSuperclass(getterName, library); | 8295 return lookUpGetterInSuperclass(getterName, library); |
| 8140 } | 8296 } |
| (...skipping 133 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 8274 | 8430 |
| 8275 bool internalEquals(Object object, Set<ElementPair> visitedElementPairs) { | 8431 bool internalEquals(Object object, Set<ElementPair> visitedElementPairs) { |
| 8276 if (object is! InterfaceTypeImpl) { | 8432 if (object is! InterfaceTypeImpl) { |
| 8277 return false; | 8433 return false; |
| 8278 } | 8434 } |
| 8279 InterfaceTypeImpl otherType = object as InterfaceTypeImpl; | 8435 InterfaceTypeImpl otherType = object as InterfaceTypeImpl; |
| 8280 return (element == otherType.element) && TypeImpl.equalArrays(typeArguments,
otherType.typeArguments, visitedElementPairs); | 8436 return (element == otherType.element) && TypeImpl.equalArrays(typeArguments,
otherType.typeArguments, visitedElementPairs); |
| 8281 } | 8437 } |
| 8282 | 8438 |
| 8283 bool internalIsMoreSpecificThan(Type2 type, bool withDynamic, Set<TypeImpl_Typ
ePair> visitedTypePairs) { | 8439 bool internalIsMoreSpecificThan(Type2 type, bool withDynamic, Set<TypeImpl_Typ
ePair> visitedTypePairs) { |
| 8440 // |
| 8441 // S is dynamic. |
| 8442 // The test to determine whether S is dynamic is done here because dynamic i
s not an instance of |
| 8443 // InterfaceType. |
| 8444 // |
| 8284 if (identical(type, DynamicTypeImpl.instance)) { | 8445 if (identical(type, DynamicTypeImpl.instance)) { |
| 8285 return true; | 8446 return true; |
| 8286 } else if (type is! InterfaceType) { | 8447 } else if (type is! InterfaceType) { |
| 8287 return false; | 8448 return false; |
| 8288 } | 8449 } |
| 8289 return isMoreSpecificThan2(type as InterfaceType, new Set<ClassElement>(), w
ithDynamic, visitedTypePairs); | 8450 return isMoreSpecificThan2(type as InterfaceType, new Set<ClassElement>(), w
ithDynamic, visitedTypePairs); |
| 8290 } | 8451 } |
| 8291 | 8452 |
| 8292 bool internalIsSubtypeOf(Type2 type, Set<TypeImpl_TypePair> visitedTypePairs)
{ | 8453 bool internalIsSubtypeOf(Type2 type, Set<TypeImpl_TypePair> visitedTypePairs)
{ |
| 8454 // |
| 8455 // T is a subtype of S, written T <: S, iff [bottom/dynamic]T << S |
| 8456 // |
| 8293 if (identical(type, DynamicTypeImpl.instance)) { | 8457 if (identical(type, DynamicTypeImpl.instance)) { |
| 8294 return true; | 8458 return true; |
| 8295 } else if (type is TypeParameterType) { | 8459 } else if (type is TypeParameterType) { |
| 8296 return true; | 8460 return true; |
| 8297 } else if (type is FunctionType) { | 8461 } else if (type is FunctionType) { |
| 8298 ClassElement element = this.element; | 8462 ClassElement element = this.element; |
| 8299 MethodElement callMethod = element.lookUpMethod("call", element.library); | 8463 MethodElement callMethod = element.lookUpMethod("call", element.library); |
| 8300 if (callMethod != null) { | 8464 if (callMethod != null) { |
| 8301 return callMethod.type.isSubtypeOf(type); | 8465 return callMethod.type.isSubtypeOf(type); |
| 8302 } | 8466 } |
| 8303 return false; | 8467 return false; |
| 8304 } else if (type is! InterfaceType) { | 8468 } else if (type is! InterfaceType) { |
| 8305 return false; | 8469 return false; |
| 8306 } else if (this == type) { | 8470 } else if (this == type) { |
| 8307 return true; | 8471 return true; |
| 8308 } | 8472 } |
| 8309 return isSubtypeOf2(type as InterfaceType, new Set<ClassElement>(), visitedT
ypePairs); | 8473 return isSubtypeOf2(type as InterfaceType, new Set<ClassElement>(), visitedT
ypePairs); |
| 8310 } | 8474 } |
| 8311 | 8475 |
| 8312 bool isMoreSpecificThan2(InterfaceType s, Set<ClassElement> visitedClasses, bo
ol withDynamic, Set<TypeImpl_TypePair> visitedTypePairs) { | 8476 bool isMoreSpecificThan2(InterfaceType s, Set<ClassElement> visitedClasses, bo
ol withDynamic, Set<TypeImpl_TypePair> visitedTypePairs) { |
| 8477 // |
| 8478 // A type T is more specific than a type S, written T << S, if one of the f
ollowing conditions |
| 8479 // is met: |
| 8480 // |
| 8481 // Reflexivity: T is S. |
| 8482 // |
| 8313 if (this == s) { | 8483 if (this == s) { |
| 8314 return true; | 8484 return true; |
| 8315 } | 8485 } |
| 8486 // |
| 8487 // T is bottom. (This case is handled by the class BottomTypeImpl.) |
| 8488 // |
| 8489 // Direct supertype: S is a direct supertype of T. |
| 8490 // |
| 8316 if (s.isDirectSupertypeOf(this)) { | 8491 if (s.isDirectSupertypeOf(this)) { |
| 8317 return true; | 8492 return true; |
| 8318 } | 8493 } |
| 8494 // |
| 8495 // Covariance: T is of the form I<T1, ..., Tn> and S is of the form I<S1, ..
., Sn> and Ti << Si, 1 <= i <= n. |
| 8496 // |
| 8319 ClassElement tElement = this.element; | 8497 ClassElement tElement = this.element; |
| 8320 ClassElement sElement = s.element; | 8498 ClassElement sElement = s.element; |
| 8321 if (tElement == sElement) { | 8499 if (tElement == sElement) { |
| 8322 List<Type2> tArguments = typeArguments; | 8500 List<Type2> tArguments = typeArguments; |
| 8323 List<Type2> sArguments = s.typeArguments; | 8501 List<Type2> sArguments = s.typeArguments; |
| 8324 if (tArguments.length != sArguments.length) { | 8502 if (tArguments.length != sArguments.length) { |
| 8325 return false; | 8503 return false; |
| 8326 } | 8504 } |
| 8327 for (int i = 0; i < tArguments.length; i++) { | 8505 for (int i = 0; i < tArguments.length; i++) { |
| 8328 if (!(tArguments[i] as TypeImpl).isMoreSpecificThan3(sArguments[i], with
Dynamic, visitedTypePairs)) { | 8506 if (!(tArguments[i] as TypeImpl).isMoreSpecificThan3(sArguments[i], with
Dynamic, visitedTypePairs)) { |
| 8329 return false; | 8507 return false; |
| 8330 } | 8508 } |
| 8331 } | 8509 } |
| 8332 return true; | 8510 return true; |
| 8333 } | 8511 } |
| 8512 // |
| 8513 // Transitivity: T << U and U << S. |
| 8514 // |
| 8515 // First check for infinite loops |
| 8334 ClassElement element = this.element; | 8516 ClassElement element = this.element; |
| 8335 if (element == null || visitedClasses.contains(element)) { | 8517 if (element == null || visitedClasses.contains(element)) { |
| 8336 return false; | 8518 return false; |
| 8337 } | 8519 } |
| 8338 visitedClasses.add(element); | 8520 visitedClasses.add(element); |
| 8521 // Iterate over all of the types U that are more specific than T because the
y are direct |
| 8522 // supertypes of T and return true if any of them are more specific than S. |
| 8339 InterfaceType supertype = superclass; | 8523 InterfaceType supertype = superclass; |
| 8340 if (supertype != null && (supertype as InterfaceTypeImpl).isMoreSpecificThan
2(s, visitedClasses, withDynamic, visitedTypePairs)) { | 8524 if (supertype != null && (supertype as InterfaceTypeImpl).isMoreSpecificThan
2(s, visitedClasses, withDynamic, visitedTypePairs)) { |
| 8341 return true; | 8525 return true; |
| 8342 } | 8526 } |
| 8343 for (InterfaceType interfaceType in interfaces) { | 8527 for (InterfaceType interfaceType in interfaces) { |
| 8344 if ((interfaceType as InterfaceTypeImpl).isMoreSpecificThan2(s, visitedCla
sses, withDynamic, visitedTypePairs)) { | 8528 if ((interfaceType as InterfaceTypeImpl).isMoreSpecificThan2(s, visitedCla
sses, withDynamic, visitedTypePairs)) { |
| 8345 return true; | 8529 return true; |
| 8346 } | 8530 } |
| 8347 } | 8531 } |
| 8348 for (InterfaceType mixinType in mixins) { | 8532 for (InterfaceType mixinType in mixins) { |
| 8349 if ((mixinType as InterfaceTypeImpl).isMoreSpecificThan2(s, visitedClasses
, withDynamic, visitedTypePairs)) { | 8533 if ((mixinType as InterfaceTypeImpl).isMoreSpecificThan2(s, visitedClasses
, withDynamic, visitedTypePairs)) { |
| 8350 return true; | 8534 return true; |
| 8351 } | 8535 } |
| 8352 } | 8536 } |
| 8353 return false; | 8537 return false; |
| 8354 } | 8538 } |
| 8355 | 8539 |
| 8356 bool isSubtypeOf2(InterfaceType type, Set<ClassElement> visitedClasses, Set<Ty
peImpl_TypePair> visitedTypePairs) { | 8540 bool isSubtypeOf2(InterfaceType type, Set<ClassElement> visitedClasses, Set<Ty
peImpl_TypePair> visitedTypePairs) { |
| 8357 InterfaceType typeT = this; | 8541 InterfaceType typeT = this; |
| 8358 InterfaceType typeS = type; | 8542 InterfaceType typeS = type; |
| 8359 ClassElement elementT = element; | 8543 ClassElement elementT = element; |
| 8360 if (elementT == null || visitedClasses.contains(elementT)) { | 8544 if (elementT == null || visitedClasses.contains(elementT)) { |
| 8361 return false; | 8545 return false; |
| 8362 } | 8546 } |
| 8363 visitedClasses.add(elementT); | 8547 visitedClasses.add(elementT); |
| 8364 if (typeT == typeS) { | 8548 if (typeT == typeS) { |
| 8365 return true; | 8549 return true; |
| 8366 } else if (elementT == typeS.element) { | 8550 } else if (elementT == typeS.element) { |
| 8551 // For each of the type arguments return true if all type args from T is a
subtype of all |
| 8552 // types from S. |
| 8367 List<Type2> typeTArgs = typeT.typeArguments; | 8553 List<Type2> typeTArgs = typeT.typeArguments; |
| 8368 List<Type2> typeSArgs = typeS.typeArguments; | 8554 List<Type2> typeSArgs = typeS.typeArguments; |
| 8369 if (typeTArgs.length != typeSArgs.length) { | 8555 if (typeTArgs.length != typeSArgs.length) { |
| 8556 // This case covers the case where two objects are being compared that h
ave a different |
| 8557 // number of parameterized types. |
| 8370 return false; | 8558 return false; |
| 8371 } | 8559 } |
| 8372 for (int i = 0; i < typeTArgs.length; i++) { | 8560 for (int i = 0; i < typeTArgs.length; i++) { |
| 8561 // Recursively call isSubtypeOf the type arguments and return false if t
he T argument is not |
| 8562 // a subtype of the S argument. |
| 8373 if (!(typeTArgs[i] as TypeImpl).isSubtypeOf3(typeSArgs[i], visitedTypePa
irs)) { | 8563 if (!(typeTArgs[i] as TypeImpl).isSubtypeOf3(typeSArgs[i], visitedTypePa
irs)) { |
| 8374 return false; | 8564 return false; |
| 8375 } | 8565 } |
| 8376 } | 8566 } |
| 8377 return true; | 8567 return true; |
| 8378 } else if (typeS.isDartCoreFunction && elementT.getMethod("call") != null) { | 8568 } else if (typeS.isDartCoreFunction && elementT.getMethod("call") != null) { |
| 8379 return true; | 8569 return true; |
| 8380 } | 8570 } |
| 8381 InterfaceType supertype = superclass; | 8571 InterfaceType supertype = superclass; |
| 8572 // The type is Object, return false. |
| 8382 if (supertype != null && (supertype as InterfaceTypeImpl).isSubtypeOf2(typeS
, visitedClasses, visitedTypePairs)) { | 8573 if (supertype != null && (supertype as InterfaceTypeImpl).isSubtypeOf2(typeS
, visitedClasses, visitedTypePairs)) { |
| 8383 return true; | 8574 return true; |
| 8384 } | 8575 } |
| 8385 List<InterfaceType> interfaceTypes = interfaces; | 8576 List<InterfaceType> interfaceTypes = interfaces; |
| 8386 for (InterfaceType interfaceType in interfaceTypes) { | 8577 for (InterfaceType interfaceType in interfaceTypes) { |
| 8387 if ((interfaceType as InterfaceTypeImpl).isSubtypeOf2(typeS, visitedClasse
s, visitedTypePairs)) { | 8578 if ((interfaceType as InterfaceTypeImpl).isSubtypeOf2(typeS, visitedClasse
s, visitedTypePairs)) { |
| 8388 return true; | 8579 return true; |
| 8389 } | 8580 } |
| 8390 } | 8581 } |
| 8391 List<InterfaceType> mixinTypes = mixins; | 8582 List<InterfaceType> mixinTypes = mixins; |
| (...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 8501 * The given set of pairs of types (T1, T2), where each pair indicates that we
invoked this method | 8692 * The given set of pairs of types (T1, T2), where each pair indicates that we
invoked this method |
| 8502 * because we are in the process of answering the question of whether T1 is a
subtype of T2, is | 8693 * because we are in the process of answering the question of whether T1 is a
subtype of T2, is |
| 8503 * used to prevent infinite loops. | 8694 * used to prevent infinite loops. |
| 8504 * | 8695 * |
| 8505 * @param type the type being compared with this type | 8696 * @param type the type being compared with this type |
| 8506 * @param withDynamic `true` if "dynamic" should be considered as a subtype of
any type | 8697 * @param withDynamic `true` if "dynamic" should be considered as a subtype of
any type |
| 8507 * @param visitedPairs the set of pairs of types used to prevent infinite loop
s | 8698 * @param visitedPairs the set of pairs of types used to prevent infinite loop
s |
| 8508 * @return `true` if this type is more specific than the given type | 8699 * @return `true` if this type is more specific than the given type |
| 8509 */ | 8700 */ |
| 8510 bool isMoreSpecificThan3(Type2 type, bool withDynamic, Set<TypeImpl_TypePair>
visitedTypePairs) { | 8701 bool isMoreSpecificThan3(Type2 type, bool withDynamic, Set<TypeImpl_TypePair>
visitedTypePairs) { |
| 8702 // If the visitedTypePairs already has the pair (this, type), return false |
| 8511 TypeImpl_TypePair typePair = new TypeImpl_TypePair(this, type); | 8703 TypeImpl_TypePair typePair = new TypeImpl_TypePair(this, type); |
| 8512 if (!visitedTypePairs.add(typePair)) { | 8704 if (!visitedTypePairs.add(typePair)) { |
| 8513 return false; | 8705 return false; |
| 8514 } | 8706 } |
| 8515 bool result = internalIsMoreSpecificThan(type, withDynamic, visitedTypePairs
); | 8707 bool result = internalIsMoreSpecificThan(type, withDynamic, visitedTypePairs
); |
| 8516 visitedTypePairs.remove(typePair); | 8708 visitedTypePairs.remove(typePair); |
| 8517 return result; | 8709 return result; |
| 8518 } | 8710 } |
| 8519 | 8711 |
| 8520 bool get isObject => false; | 8712 bool get isObject => false; |
| 8521 | 8713 |
| 8522 bool isSubtypeOf(Type2 type) => isSubtypeOf3(type, new Set<TypeImpl_TypePair>(
)); | 8714 bool isSubtypeOf(Type2 type) => isSubtypeOf3(type, new Set<TypeImpl_TypePair>(
)); |
| 8523 | 8715 |
| 8524 /** | 8716 /** |
| 8525 * Return `true` if this type is a subtype of the given type. | 8717 * Return `true` if this type is a subtype of the given type. |
| 8526 * | 8718 * |
| 8527 * The given set of pairs of types (T1, T2), where each pair indicates that we
invoked this method | 8719 * The given set of pairs of types (T1, T2), where each pair indicates that we
invoked this method |
| 8528 * because we are in the process of answering the question of whether T1 is a
subtype of T2, is | 8720 * because we are in the process of answering the question of whether T1 is a
subtype of T2, is |
| 8529 * used to prevent infinite loops. | 8721 * used to prevent infinite loops. |
| 8530 * | 8722 * |
| 8531 * @param type the type being compared with this type | 8723 * @param type the type being compared with this type |
| 8532 * @param visitedPairs the set of pairs of types used to prevent infinite loop
s | 8724 * @param visitedPairs the set of pairs of types used to prevent infinite loop
s |
| 8533 * @return `true` if this type is a subtype of the given type | 8725 * @return `true` if this type is a subtype of the given type |
| 8534 */ | 8726 */ |
| 8535 bool isSubtypeOf3(Type2 type, Set<TypeImpl_TypePair> visitedTypePairs) { | 8727 bool isSubtypeOf3(Type2 type, Set<TypeImpl_TypePair> visitedTypePairs) { |
| 8728 // If the visitedTypePairs already has the pair (this, type), return false |
| 8536 TypeImpl_TypePair typePair = new TypeImpl_TypePair(this, type); | 8729 TypeImpl_TypePair typePair = new TypeImpl_TypePair(this, type); |
| 8537 if (!visitedTypePairs.add(typePair)) { | 8730 if (!visitedTypePairs.add(typePair)) { |
| 8538 return false; | 8731 return false; |
| 8539 } | 8732 } |
| 8540 bool result = internalIsSubtypeOf(type, visitedTypePairs); | 8733 bool result = internalIsSubtypeOf(type, visitedTypePairs); |
| 8541 visitedTypePairs.remove(typePair); | 8734 visitedTypePairs.remove(typePair); |
| 8542 return result; | 8735 return result; |
| 8543 } | 8736 } |
| 8544 | 8737 |
| 8545 bool isSupertypeOf(Type2 type) => type.isSubtypeOf(this); | 8738 bool isSupertypeOf(Type2 type) => type.isSubtypeOf(this); |
| (...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 8658 if (parameterTypes[i] == this) { | 8851 if (parameterTypes[i] == this) { |
| 8659 return argumentTypes[i]; | 8852 return argumentTypes[i]; |
| 8660 } | 8853 } |
| 8661 } | 8854 } |
| 8662 return this; | 8855 return this; |
| 8663 } | 8856 } |
| 8664 | 8857 |
| 8665 bool internalEquals(Object object, Set<ElementPair> visitedElementPairs) => th
is == object; | 8858 bool internalEquals(Object object, Set<ElementPair> visitedElementPairs) => th
is == object; |
| 8666 | 8859 |
| 8667 bool internalIsMoreSpecificThan(Type2 s, bool withDynamic, Set<TypeImpl_TypePa
ir> visitedTypePairs) { | 8860 bool internalIsMoreSpecificThan(Type2 s, bool withDynamic, Set<TypeImpl_TypePa
ir> visitedTypePairs) { |
| 8861 // |
| 8862 // A type T is more specific than a type S, written T << S, if one of the f
ollowing conditions |
| 8863 // is met: |
| 8864 // |
| 8865 // Reflexivity: T is S. |
| 8866 // |
| 8668 if (this == s) { | 8867 if (this == s) { |
| 8669 return true; | 8868 return true; |
| 8670 } | 8869 } |
| 8870 // S is bottom. |
| 8871 // |
| 8671 if (s.isBottom) { | 8872 if (s.isBottom) { |
| 8672 return true; | 8873 return true; |
| 8673 } | 8874 } |
| 8875 // S is dynamic. |
| 8876 // |
| 8674 if (s.isDynamic) { | 8877 if (s.isDynamic) { |
| 8675 return true; | 8878 return true; |
| 8676 } | 8879 } |
| 8677 return isMoreSpecificThan4(s, new Set<Type2>(), withDynamic, visitedTypePair
s); | 8880 return isMoreSpecificThan4(s, new Set<Type2>(), withDynamic, visitedTypePair
s); |
| 8678 } | 8881 } |
| 8679 | 8882 |
| 8680 bool internalIsSubtypeOf(Type2 type, Set<TypeImpl_TypePair> visitedTypePairs)
=> isMoreSpecificThan3(type, true, new Set<TypeImpl_TypePair>()); | 8883 bool internalIsSubtypeOf(Type2 type, Set<TypeImpl_TypePair> visitedTypePairs)
=> isMoreSpecificThan3(type, true, new Set<TypeImpl_TypePair>()); |
| 8681 | 8884 |
| 8682 bool isMoreSpecificThan4(Type2 s, Set<Type2> visitedTypes, bool withDynamic, S
et<TypeImpl_TypePair> visitedTypePairs) { | 8885 bool isMoreSpecificThan4(Type2 s, Set<Type2> visitedTypes, bool withDynamic, S
et<TypeImpl_TypePair> visitedTypePairs) { |
| 8886 // T is a type parameter and S is the upper bound of T. |
| 8887 // |
| 8683 Type2 bound = element.bound; | 8888 Type2 bound = element.bound; |
| 8684 if (s == bound) { | 8889 if (s == bound) { |
| 8685 return true; | 8890 return true; |
| 8686 } | 8891 } |
| 8892 // T is a type parameter and S is Object. |
| 8893 // |
| 8687 if (s.isObject) { | 8894 if (s.isObject) { |
| 8688 return true; | 8895 return true; |
| 8689 } | 8896 } |
| 8897 // We need upper bound to continue. |
| 8690 if (bound == null) { | 8898 if (bound == null) { |
| 8691 return false; | 8899 return false; |
| 8692 } | 8900 } |
| 8901 // |
| 8902 // Transitivity: T << U and U << S. |
| 8903 // |
| 8693 if (bound is TypeParameterTypeImpl) { | 8904 if (bound is TypeParameterTypeImpl) { |
| 8694 TypeParameterTypeImpl boundTypeParameter = bound; | 8905 TypeParameterTypeImpl boundTypeParameter = bound; |
| 8906 // First check for infinite loops |
| 8695 if (visitedTypes.contains(bound)) { | 8907 if (visitedTypes.contains(bound)) { |
| 8696 return false; | 8908 return false; |
| 8697 } | 8909 } |
| 8698 visitedTypes.add(bound); | 8910 visitedTypes.add(bound); |
| 8911 // Then check upper bound. |
| 8699 return boundTypeParameter.isMoreSpecificThan4(s, visitedTypes, withDynamic
, visitedTypePairs); | 8912 return boundTypeParameter.isMoreSpecificThan4(s, visitedTypes, withDynamic
, visitedTypePairs); |
| 8700 } | 8913 } |
| 8914 // Check interface type. |
| 8701 return (bound as TypeImpl).isMoreSpecificThan3(s, withDynamic, visitedTypePa
irs); | 8915 return (bound as TypeImpl).isMoreSpecificThan3(s, withDynamic, visitedTypePa
irs); |
| 8702 } | 8916 } |
| 8703 } | 8917 } |
| 8704 | 8918 |
| 8705 /** | 8919 /** |
| 8706 * The unique instance of the class `VoidTypeImpl` implements the type `void`. | 8920 * The unique instance of the class `VoidTypeImpl` implements the type `void`. |
| 8707 * | 8921 * |
| 8708 * @coverage dart.engine.type | 8922 * @coverage dart.engine.type |
| 8709 */ | 8923 */ |
| 8710 class VoidTypeImpl extends TypeImpl implements VoidType { | 8924 class VoidTypeImpl extends TypeImpl implements VoidType { |
| (...skipping 638 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 9349 | 9563 |
| 9350 /** | 9564 /** |
| 9351 * The interface `VoidType` defines the behavior of the unique object representi
ng the type | 9565 * The interface `VoidType` defines the behavior of the unique object representi
ng the type |
| 9352 * `void`. | 9566 * `void`. |
| 9353 * | 9567 * |
| 9354 * @coverage dart.engine.type | 9568 * @coverage dart.engine.type |
| 9355 */ | 9569 */ |
| 9356 abstract class VoidType implements Type2 { | 9570 abstract class VoidType implements Type2 { |
| 9357 VoidType substitute2(List<Type2> argumentTypes, List<Type2> parameterTypes); | 9571 VoidType substitute2(List<Type2> argumentTypes, List<Type2> parameterTypes); |
| 9358 } | 9572 } |
| OLD | NEW |