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

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

Issue 137863002: Issue 8742. Preserve leading line comments during java2dart translation. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Test for block-style comment translation. Created 6 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 // This code was auto-generated, is not intended to be edited, and is subject to 5 // This code was auto-generated, is not intended to be edited, and is subject to
6 // significant change. Please see the README file for more information. 6 // significant change. Please see the README file for more information.
7 7
8 library engine.element; 8 library engine.element;
9 9
10 import 'dart:collection'; 10 import 'dart:collection';
(...skipping 1971 matching lines...) Expand 10 before | Expand all | Expand 10 after
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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 }
OLDNEW
« no previous file with comments | « pkg/analyzer/lib/src/generated/constant.dart ('k') | pkg/analyzer/lib/src/generated/engine.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698