| OLD | NEW |
| 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
| 3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 | 4 |
| 5 library dart_types; | 5 library dart_types; |
| 6 | 6 |
| 7 import 'dart:math' show min; | 7 import 'dart:math' show min; |
| 8 | 8 |
| 9 import 'common.dart'; | 9 import 'common.dart'; |
| 10 import 'common/resolution.dart' show | 10 import 'common/resolution.dart' show Resolution; |
| 11 Resolution; | |
| 12 import 'core_types.dart'; | 11 import 'core_types.dart'; |
| 13 import 'elements/modelx.dart' show | 12 import 'elements/modelx.dart' |
| 14 LibraryElementX, | 13 show LibraryElementX, TypeDeclarationElementX, TypedefElementX; |
| 15 TypeDeclarationElementX, | |
| 16 TypedefElementX; | |
| 17 import 'elements/elements.dart'; | 14 import 'elements/elements.dart'; |
| 18 import 'ordered_typeset.dart' show | 15 import 'ordered_typeset.dart' show OrderedTypeSet; |
| 19 OrderedTypeSet; | 16 import 'util/util.dart' show equalElements; |
| 20 import 'util/util.dart' show | |
| 21 equalElements; | |
| 22 | 17 |
| 23 enum TypeKind { | 18 enum TypeKind { |
| 24 FUNCTION, | 19 FUNCTION, |
| 25 INTERFACE, | 20 INTERFACE, |
| 26 STATEMENT, | 21 STATEMENT, |
| 27 TYPEDEF, | 22 TYPEDEF, |
| 28 TYPE_VARIABLE, | 23 TYPE_VARIABLE, |
| 29 MALFORMED_TYPE, | 24 MALFORMED_TYPE, |
| 30 DYNAMIC, | 25 DYNAMIC, |
| 31 VOID, | 26 VOID, |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 72 /// | 67 /// |
| 73 /// The unaliased type of a typedef'd type is the unaliased type to which its | 68 /// The unaliased type of a typedef'd type is the unaliased type to which its |
| 74 /// name is bound. The unaliased version of any other type is the type itself. | 69 /// name is bound. The unaliased version of any other type is the type itself. |
| 75 /// | 70 /// |
| 76 /// For example, the unaliased type of `typedef A Func<A,B>(B b)` is the | 71 /// For example, the unaliased type of `typedef A Func<A,B>(B b)` is the |
| 77 /// function type `(B) -> A` and the unaliased type of `Func<int,String>` | 72 /// function type `(B) -> A` and the unaliased type of `Func<int,String>` |
| 78 /// is the function type `(String) -> int`. | 73 /// is the function type `(String) -> int`. |
| 79 // TODO(johnniwinther): Maybe move this to [TypedefType]. | 74 // TODO(johnniwinther): Maybe move this to [TypedefType]. |
| 80 void computeUnaliased(Resolution resolution) {} | 75 void computeUnaliased(Resolution resolution) {} |
| 81 | 76 |
| 82 | |
| 83 /// Returns the unaliased type of this type. | 77 /// Returns the unaliased type of this type. |
| 84 /// | 78 /// |
| 85 /// The unaliased type of a typedef'd type is the unaliased type to which its | 79 /// The unaliased type of a typedef'd type is the unaliased type to which its |
| 86 /// name is bound. The unaliased version of any other type is the type itself. | 80 /// name is bound. The unaliased version of any other type is the type itself. |
| 87 /// | 81 /// |
| 88 /// For example, the unaliased type of `typedef A Func<A,B>(B b)` is the | 82 /// For example, the unaliased type of `typedef A Func<A,B>(B b)` is the |
| 89 /// function type `(B) -> A` and the unaliased type of `Func<int,String>` | 83 /// function type `(B) -> A` and the unaliased type of `Func<int,String>` |
| 90 /// is the function type `(String) -> int`. | 84 /// is the function type `(String) -> int`. |
| 91 DartType get unaliased => this; | 85 DartType get unaliased => this; |
| 92 | 86 |
| (...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 158 /// Returns a textual representation of this type as if it was the type | 152 /// Returns a textual representation of this type as if it was the type |
| 159 /// of a member named [name]. | 153 /// of a member named [name]. |
| 160 String getStringAsDeclared(String name) { | 154 String getStringAsDeclared(String name) { |
| 161 return new TypeDeclarationFormatter().format(this, name); | 155 return new TypeDeclarationFormatter().format(this, name); |
| 162 } | 156 } |
| 163 | 157 |
| 164 accept(DartTypeVisitor visitor, var argument); | 158 accept(DartTypeVisitor visitor, var argument); |
| 165 | 159 |
| 166 void visitChildren(DartTypeVisitor visitor, var argument) {} | 160 void visitChildren(DartTypeVisitor visitor, var argument) {} |
| 167 | 161 |
| 168 static void visitList(List<DartType> types, | 162 static void visitList( |
| 169 DartTypeVisitor visitor, var argument) { | 163 List<DartType> types, DartTypeVisitor visitor, var argument) { |
| 170 for (DartType type in types) { | 164 for (DartType type in types) { |
| 171 type.accept(visitor, argument); | 165 type.accept(visitor, argument); |
| 172 } | 166 } |
| 173 } | 167 } |
| 174 } | 168 } |
| 175 | 169 |
| 176 /** | 170 /** |
| 177 * Represents a type variable, that is the type parameters of a class type. | 171 * Represents a type variable, that is the type parameters of a class type. |
| 178 * | 172 * |
| 179 * For example, in [: class Array<E> { ... } :], E is a type variable. | 173 * For example, in [: class Array<E> { ... } :], E is a type variable. |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 227 f(this); | 221 f(this); |
| 228 } | 222 } |
| 229 | 223 |
| 230 accept(DartTypeVisitor visitor, var argument) { | 224 accept(DartTypeVisitor visitor, var argument) { |
| 231 return visitor.visitTypeVariableType(this, argument); | 225 return visitor.visitTypeVariableType(this, argument); |
| 232 } | 226 } |
| 233 | 227 |
| 234 int get hashCode => 17 * element.hashCode; | 228 int get hashCode => 17 * element.hashCode; |
| 235 | 229 |
| 236 bool operator ==(other) { | 230 bool operator ==(other) { |
| 237 if (other is !TypeVariableType) return false; | 231 if (other is! TypeVariableType) return false; |
| 238 return identical(other.element, element); | 232 return identical(other.element, element); |
| 239 } | 233 } |
| 240 | 234 |
| 241 String toString() => name; | 235 String toString() => name; |
| 242 } | 236 } |
| 243 | 237 |
| 244 /// Internal type representing the result of analyzing a statement. | 238 /// Internal type representing the result of analyzing a statement. |
| 245 class StatementType extends DartType { | 239 class StatementType extends DartType { |
| 246 Element get element => null; | 240 Element get element => null; |
| 247 | 241 |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 299 * where [: T :] is a type variable, in which case [declaredType] holds | 293 * where [: T :] is a type variable, in which case [declaredType] holds |
| 300 * [: dynamic :] and [: T :], respectively, or for [: X<int> :] where [: X :] | 294 * [: dynamic :] and [: T :], respectively, or for [: X<int> :] where [: X :] |
| 301 * is not resolved or does not imply a type. | 295 * is not resolved or does not imply a type. |
| 302 */ | 296 */ |
| 303 final List<DartType> typeArguments; | 297 final List<DartType> typeArguments; |
| 304 | 298 |
| 305 final int hashCode = (nextHash++) & 0x3fffffff; | 299 final int hashCode = (nextHash++) & 0x3fffffff; |
| 306 static int nextHash = 43765; | 300 static int nextHash = 43765; |
| 307 | 301 |
| 308 MalformedType(this.element, this.userProvidedBadType, | 302 MalformedType(this.element, this.userProvidedBadType, |
| 309 [this.typeArguments = null]); | 303 [this.typeArguments = null]); |
| 310 | 304 |
| 311 TypeKind get kind => TypeKind.MALFORMED_TYPE; | 305 TypeKind get kind => TypeKind.MALFORMED_TYPE; |
| 312 | 306 |
| 313 String get name => element.name; | 307 String get name => element.name; |
| 314 | 308 |
| 315 DartType subst(List<DartType> arguments, List<DartType> parameters) { | 309 DartType subst(List<DartType> arguments, List<DartType> parameters) { |
| 316 // Malformed types are not substitutable. | 310 // Malformed types are not substitutable. |
| 317 return this; | 311 return this; |
| 318 } | 312 } |
| 319 | 313 |
| (...skipping 21 matching lines...) Expand all Loading... |
| 341 sb.write(userProvidedBadType.toString()); | 335 sb.write(userProvidedBadType.toString()); |
| 342 } | 336 } |
| 343 return sb.toString(); | 337 return sb.toString(); |
| 344 } | 338 } |
| 345 } | 339 } |
| 346 | 340 |
| 347 abstract class GenericType extends DartType { | 341 abstract class GenericType extends DartType { |
| 348 final TypeDeclarationElement element; | 342 final TypeDeclarationElement element; |
| 349 final List<DartType> typeArguments; | 343 final List<DartType> typeArguments; |
| 350 | 344 |
| 351 GenericType(TypeDeclarationElement element, | 345 GenericType(TypeDeclarationElement element, this.typeArguments, |
| 352 this.typeArguments, | 346 {bool checkTypeArgumentCount: true}) |
| 353 {bool checkTypeArgumentCount: true}) | |
| 354 : this.element = element { | 347 : this.element = element { |
| 355 assert(invariant(CURRENT_ELEMENT_SPANNABLE, element != null, | 348 assert(invariant(CURRENT_ELEMENT_SPANNABLE, element != null, |
| 356 message: "Missing element for generic type.")); | 349 message: "Missing element for generic type.")); |
| 357 assert(invariant(element, () { | 350 assert(invariant(element, () { |
| 358 if (!checkTypeArgumentCount) return true; | 351 if (!checkTypeArgumentCount) return true; |
| 359 if (element is TypeDeclarationElementX) { | 352 if (element is TypeDeclarationElementX) { |
| 360 return element.thisTypeCache == null || | 353 return element.thisTypeCache == null || |
| 361 typeArguments.length == element.typeVariables.length; | 354 typeArguments.length == element.typeVariables.length; |
| 362 } | 355 } |
| 363 return true; | 356 return true; |
| 364 }, message: () => 'Invalid type argument count on ${element.thisType}. ' | 357 }, |
| 365 'Provided type arguments: $typeArguments.')); | 358 message: () => 'Invalid type argument count on ${element.thisType}. ' |
| 359 'Provided type arguments: $typeArguments.')); |
| 366 } | 360 } |
| 367 | 361 |
| 368 /// Creates a new instance of this type using the provided type arguments. | 362 /// Creates a new instance of this type using the provided type arguments. |
| 369 GenericType createInstantiation(List<DartType> newTypeArguments); | 363 GenericType createInstantiation(List<DartType> newTypeArguments); |
| 370 | 364 |
| 371 DartType subst(List<DartType> arguments, List<DartType> parameters) { | 365 DartType subst(List<DartType> arguments, List<DartType> parameters) { |
| 372 if (typeArguments.isEmpty) { | 366 if (typeArguments.isEmpty) { |
| 373 // Return fast on non-generic types. | 367 // Return fast on non-generic types. |
| 374 return this; | 368 return this; |
| 375 } | 369 } |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 415 int get hashCode { | 409 int get hashCode { |
| 416 int hash = element.hashCode; | 410 int hash = element.hashCode; |
| 417 for (DartType argument in typeArguments) { | 411 for (DartType argument in typeArguments) { |
| 418 int argumentHash = argument != null ? argument.hashCode : 0; | 412 int argumentHash = argument != null ? argument.hashCode : 0; |
| 419 hash = 17 * hash + 3 * argumentHash; | 413 hash = 17 * hash + 3 * argumentHash; |
| 420 } | 414 } |
| 421 return hash; | 415 return hash; |
| 422 } | 416 } |
| 423 | 417 |
| 424 bool operator ==(other) { | 418 bool operator ==(other) { |
| 425 if (other is !GenericType) return false; | 419 if (other is! GenericType) return false; |
| 426 return kind == other.kind | 420 return kind == other.kind && |
| 427 && element == other.element | 421 element == other.element && |
| 428 && equalElements(typeArguments, other.typeArguments); | 422 equalElements(typeArguments, other.typeArguments); |
| 429 } | 423 } |
| 430 | 424 |
| 431 /// Returns `true` if the declaration of this type has type variables. | 425 /// Returns `true` if the declaration of this type has type variables. |
| 432 bool get isGeneric => !typeArguments.isEmpty; | 426 bool get isGeneric => !typeArguments.isEmpty; |
| 433 | 427 |
| 434 bool get isRaw => typeArguments.isEmpty || identical(this, element.rawType); | 428 bool get isRaw => typeArguments.isEmpty || identical(this, element.rawType); |
| 435 | 429 |
| 436 GenericType asRaw() => element.rawType; | 430 GenericType asRaw() => element.rawType; |
| 437 | 431 |
| 438 bool get treatAsRaw { | 432 bool get treatAsRaw { |
| 439 if (isRaw) return true; | 433 if (isRaw) return true; |
| 440 for (DartType type in typeArguments) { | 434 for (DartType type in typeArguments) { |
| 441 if (!type.treatAsDynamic) return false; | 435 if (!type.treatAsDynamic) return false; |
| 442 } | 436 } |
| 443 return true; | 437 return true; |
| 444 } | 438 } |
| 445 } | 439 } |
| 446 | 440 |
| 447 class InterfaceType extends GenericType { | 441 class InterfaceType extends GenericType { |
| 448 int _hashCode; | 442 int _hashCode; |
| 449 | 443 |
| 450 InterfaceType(ClassElement element, | 444 InterfaceType(ClassElement element, |
| 451 [List<DartType> typeArguments = const <DartType>[]]) | 445 [List<DartType> typeArguments = const <DartType>[]]) |
| 452 : super(element, typeArguments) { | 446 : super(element, typeArguments) { |
| 453 assert(invariant(element, element.isDeclaration)); | 447 assert(invariant(element, element.isDeclaration)); |
| 454 } | 448 } |
| 455 | 449 |
| 456 InterfaceType.forUserProvidedBadType( | 450 InterfaceType.forUserProvidedBadType(ClassElement element, |
| 457 ClassElement element, | |
| 458 [List<DartType> typeArguments = const <DartType>[]]) | 451 [List<DartType> typeArguments = const <DartType>[]]) |
| 459 : super(element, typeArguments, checkTypeArgumentCount: false); | 452 : super(element, typeArguments, checkTypeArgumentCount: false); |
| 460 | 453 |
| 461 ClassElement get element => super.element; | 454 ClassElement get element => super.element; |
| 462 | 455 |
| 463 TypeKind get kind => TypeKind.INTERFACE; | 456 TypeKind get kind => TypeKind.INTERFACE; |
| 464 | 457 |
| 465 String get name => element.name; | 458 String get name => element.name; |
| 466 | 459 |
| 467 bool get isObject => element.isObject; | 460 bool get isObject => element.isObject; |
| 468 | 461 |
| 469 bool get isEnumType => element.isEnumClass; | 462 bool get isEnumType => element.isEnumClass; |
| 470 | 463 |
| 471 InterfaceType createInstantiation(List<DartType> newTypeArguments) { | 464 InterfaceType createInstantiation(List<DartType> newTypeArguments) { |
| 472 return new InterfaceType(element, newTypeArguments); | 465 return new InterfaceType(element, newTypeArguments); |
| 473 } | 466 } |
| 474 | 467 |
| 475 /** | 468 /** |
| 476 * Returns the type as an instance of class [other], if possible, null | 469 * Returns the type as an instance of class [other], if possible, null |
| 477 * otherwise. | 470 * otherwise. |
| 478 */ | 471 */ |
| 479 InterfaceType asInstanceOf(ClassElement other) { | 472 InterfaceType asInstanceOf(ClassElement other) { |
| 480 other = other.declaration; | 473 other = other.declaration; |
| 481 if (element == other) return this; | 474 if (element == other) return this; |
| 482 InterfaceType supertype = element.asInstanceOf(other); | 475 InterfaceType supertype = element.asInstanceOf(other); |
| 483 if (supertype != null) { | 476 if (supertype != null) { |
| 484 List<DartType> arguments = Types.substTypes(supertype.typeArguments, | 477 List<DartType> arguments = Types.substTypes( |
| 485 typeArguments, | 478 supertype.typeArguments, typeArguments, element.typeVariables); |
| 486 element.typeVariables); | |
| 487 return new InterfaceType(supertype.element, arguments); | 479 return new InterfaceType(supertype.element, arguments); |
| 488 } | 480 } |
| 489 return null; | 481 return null; |
| 490 } | 482 } |
| 491 | 483 |
| 492 MemberSignature lookupInterfaceMember(Name name) { | 484 MemberSignature lookupInterfaceMember(Name name) { |
| 493 MemberSignature member = element.lookupInterfaceMember(name); | 485 MemberSignature member = element.lookupInterfaceMember(name); |
| 494 if (member != null && isGeneric) { | 486 if (member != null && isGeneric) { |
| 495 return new InterfaceMember(this, member); | 487 return new InterfaceMember(this, member); |
| 496 } | 488 } |
| (...skipping 26 matching lines...) Expand all Loading... |
| 523 | 515 |
| 524 /** | 516 /** |
| 525 * Special subclass of [InterfaceType] used for generic interface types created | 517 * Special subclass of [InterfaceType] used for generic interface types created |
| 526 * with the wrong number of type arguments. | 518 * with the wrong number of type arguments. |
| 527 * | 519 * |
| 528 * The type uses [:dynamic:] for all it s type arguments. | 520 * The type uses [:dynamic:] for all it s type arguments. |
| 529 */ | 521 */ |
| 530 class BadInterfaceType extends InterfaceType { | 522 class BadInterfaceType extends InterfaceType { |
| 531 final InterfaceType userProvidedBadType; | 523 final InterfaceType userProvidedBadType; |
| 532 | 524 |
| 533 BadInterfaceType(ClassElement element, | 525 BadInterfaceType(ClassElement element, InterfaceType this.userProvidedBadType) |
| 534 InterfaceType this.userProvidedBadType) | |
| 535 : super(element, element.rawType.typeArguments); | 526 : super(element, element.rawType.typeArguments); |
| 536 | 527 |
| 537 String toString() { | 528 String toString() { |
| 538 return userProvidedBadType.toString(); | 529 return userProvidedBadType.toString(); |
| 539 } | 530 } |
| 540 } | 531 } |
| 541 | 532 |
| 542 | |
| 543 /** | 533 /** |
| 544 * Special subclass of [TypedefType] used for generic typedef types created | 534 * Special subclass of [TypedefType] used for generic typedef types created |
| 545 * with the wrong number of type arguments. | 535 * with the wrong number of type arguments. |
| 546 * | 536 * |
| 547 * The type uses [:dynamic:] for all it s type arguments. | 537 * The type uses [:dynamic:] for all it s type arguments. |
| 548 */ | 538 */ |
| 549 class BadTypedefType extends TypedefType { | 539 class BadTypedefType extends TypedefType { |
| 550 final TypedefType userProvidedBadType; | 540 final TypedefType userProvidedBadType; |
| 551 | 541 |
| 552 BadTypedefType(TypedefElement element, | 542 BadTypedefType(TypedefElement element, TypedefType this.userProvidedBadType) |
| 553 TypedefType this.userProvidedBadType) | |
| 554 : super(element, element.rawType.typeArguments); | 543 : super(element, element.rawType.typeArguments); |
| 555 | 544 |
| 556 String toString() { | 545 String toString() { |
| 557 return userProvidedBadType.toString(); | 546 return userProvidedBadType.toString(); |
| 558 } | 547 } |
| 559 } | 548 } |
| 560 | 549 |
| 561 class FunctionType extends DartType { | 550 class FunctionType extends DartType { |
| 562 final FunctionTypedElement element; | 551 final FunctionTypedElement element; |
| 563 final DartType returnType; | 552 final DartType returnType; |
| 564 final List<DartType> parameterTypes; | 553 final List<DartType> parameterTypes; |
| 565 final List<DartType> optionalParameterTypes; | 554 final List<DartType> optionalParameterTypes; |
| 566 | 555 |
| 567 /** | 556 /** |
| 568 * The names of the named parameters ordered lexicographically. | 557 * The names of the named parameters ordered lexicographically. |
| 569 */ | 558 */ |
| 570 final List<String> namedParameters; | 559 final List<String> namedParameters; |
| 571 | 560 |
| 572 /** | 561 /** |
| 573 * The types of the named parameters in the order corresponding to the | 562 * The types of the named parameters in the order corresponding to the |
| 574 * [namedParameters]. | 563 * [namedParameters]. |
| 575 */ | 564 */ |
| 576 final List<DartType> namedParameterTypes; | 565 final List<DartType> namedParameterTypes; |
| 577 | 566 |
| 578 factory FunctionType( | 567 factory FunctionType(FunctionTypedElement element, |
| 579 FunctionTypedElement element, | |
| 580 [DartType returnType = const DynamicType(), | 568 [DartType returnType = const DynamicType(), |
| 581 List<DartType> parameterTypes = const <DartType>[], | 569 List<DartType> parameterTypes = const <DartType>[], |
| 582 List<DartType> optionalParameterTypes = const <DartType>[], | 570 List<DartType> optionalParameterTypes = const <DartType>[], |
| 583 List<String> namedParameters = const <String>[], | 571 List<String> namedParameters = const <String>[], |
| 584 List<DartType> namedParameterTypes = const <DartType>[]]) { | 572 List<DartType> namedParameterTypes = const <DartType>[]]) { |
| 585 assert(invariant(CURRENT_ELEMENT_SPANNABLE, element != null)); | 573 assert(invariant(CURRENT_ELEMENT_SPANNABLE, element != null)); |
| 586 assert(invariant(element, element.isDeclaration)); | 574 assert(invariant(element, element.isDeclaration)); |
| 587 return new FunctionType.internal(element, | 575 return new FunctionType.internal(element, returnType, parameterTypes, |
| 588 returnType, parameterTypes, optionalParameterTypes, | 576 optionalParameterTypes, namedParameters, namedParameterTypes); |
| 589 namedParameters, namedParameterTypes); | |
| 590 } | 577 } |
| 591 | 578 |
| 592 factory FunctionType.synthesized( | 579 factory FunctionType.synthesized( |
| 593 [DartType returnType = const DynamicType(), | 580 [DartType returnType = const DynamicType(), |
| 594 List<DartType> parameterTypes = const <DartType>[], | 581 List<DartType> parameterTypes = const <DartType>[], |
| 595 List<DartType> optionalParameterTypes = const <DartType>[], | 582 List<DartType> optionalParameterTypes = const <DartType>[], |
| 596 List<String> namedParameters = const <String>[], | 583 List<String> namedParameters = const <String>[], |
| 597 List<DartType> namedParameterTypes = const <DartType>[]]) { | 584 List<DartType> namedParameterTypes = const <DartType>[]]) { |
| 598 return new FunctionType.internal(null, | 585 return new FunctionType.internal(null, returnType, parameterTypes, |
| 599 returnType, parameterTypes, optionalParameterTypes, | 586 optionalParameterTypes, namedParameters, namedParameterTypes); |
| 600 namedParameters, namedParameterTypes); | |
| 601 } | 587 } |
| 602 | 588 |
| 603 FunctionType.internal(FunctionTypedElement this.element, | 589 FunctionType.internal(FunctionTypedElement this.element, |
| 604 [DartType this.returnType = const DynamicType(), | 590 [DartType this.returnType = const DynamicType(), |
| 605 this.parameterTypes = const <DartType>[], | 591 this.parameterTypes = const <DartType>[], |
| 606 this.optionalParameterTypes = const <DartType>[], | 592 this.optionalParameterTypes = const <DartType>[], |
| 607 this.namedParameters = const <String>[], | 593 this.namedParameters = const <String>[], |
| 608 this.namedParameterTypes = const <DartType>[]]) { | 594 this.namedParameterTypes = const <DartType>[]]) { |
| 609 assert(invariant(CURRENT_ELEMENT_SPANNABLE, | 595 assert(invariant( |
| 610 element == null || element.isDeclaration)); | 596 CURRENT_ELEMENT_SPANNABLE, element == null || element.isDeclaration)); |
| 611 // Assert that optional and named parameters are not used at the same time. | 597 // Assert that optional and named parameters are not used at the same time. |
| 612 assert(optionalParameterTypes.isEmpty || namedParameterTypes.isEmpty); | 598 assert(optionalParameterTypes.isEmpty || namedParameterTypes.isEmpty); |
| 613 assert(namedParameters.length == namedParameterTypes.length); | 599 assert(namedParameters.length == namedParameterTypes.length); |
| 614 } | 600 } |
| 615 | 601 |
| 616 TypeKind get kind => TypeKind.FUNCTION; | 602 TypeKind get kind => TypeKind.FUNCTION; |
| 617 | 603 |
| 618 DartType getNamedParameterType(String name) { | 604 DartType getNamedParameterType(String name) { |
| 619 for (int i = 0; i < namedParameters.length; i++) { | 605 for (int i = 0; i < namedParameters.length; i++) { |
| 620 if (namedParameters[i] == name) { | 606 if (namedParameters[i] == name) { |
| (...skipping 12 matching lines...) Expand all Loading... |
| 633 DartType newReturnType = returnType.subst(arguments, parameters); | 619 DartType newReturnType = returnType.subst(arguments, parameters); |
| 634 bool changed = !identical(newReturnType, returnType); | 620 bool changed = !identical(newReturnType, returnType); |
| 635 List<DartType> newParameterTypes = | 621 List<DartType> newParameterTypes = |
| 636 Types.substTypes(parameterTypes, arguments, parameters); | 622 Types.substTypes(parameterTypes, arguments, parameters); |
| 637 List<DartType> newOptionalParameterTypes = | 623 List<DartType> newOptionalParameterTypes = |
| 638 Types.substTypes(optionalParameterTypes, arguments, parameters); | 624 Types.substTypes(optionalParameterTypes, arguments, parameters); |
| 639 List<DartType> newNamedParameterTypes = | 625 List<DartType> newNamedParameterTypes = |
| 640 Types.substTypes(namedParameterTypes, arguments, parameters); | 626 Types.substTypes(namedParameterTypes, arguments, parameters); |
| 641 if (!changed && | 627 if (!changed && |
| 642 (!identical(parameterTypes, newParameterTypes) || | 628 (!identical(parameterTypes, newParameterTypes) || |
| 643 !identical(optionalParameterTypes, newOptionalParameterTypes) || | 629 !identical(optionalParameterTypes, newOptionalParameterTypes) || |
| 644 !identical(namedParameterTypes, newNamedParameterTypes))) { | 630 !identical(namedParameterTypes, newNamedParameterTypes))) { |
| 645 changed = true; | 631 changed = true; |
| 646 } | 632 } |
| 647 if (changed) { | 633 if (changed) { |
| 648 // Create a new type only if necessary. | 634 // Create a new type only if necessary. |
| 649 return new FunctionType.internal(element, | 635 return new FunctionType.internal( |
| 650 newReturnType, | 636 element, |
| 651 newParameterTypes, | 637 newReturnType, |
| 652 newOptionalParameterTypes, | 638 newParameterTypes, |
| 653 namedParameters, | 639 newOptionalParameterTypes, |
| 654 newNamedParameterTypes); | 640 namedParameters, |
| 641 newNamedParameterTypes); |
| 655 } | 642 } |
| 656 return this; | 643 return this; |
| 657 } | 644 } |
| 658 | 645 |
| 659 TypeVariableType get typeVariableOccurrence { | 646 TypeVariableType get typeVariableOccurrence { |
| 660 TypeVariableType typeVariableType = returnType.typeVariableOccurrence; | 647 TypeVariableType typeVariableType = returnType.typeVariableOccurrence; |
| 661 if (typeVariableType != null) return typeVariableType; | 648 if (typeVariableType != null) return typeVariableType; |
| 662 | 649 |
| 663 typeVariableType = _findTypeVariableOccurrence(parameterTypes); | 650 typeVariableType = _findTypeVariableOccurrence(parameterTypes); |
| 664 if (typeVariableType != null) return typeVariableType; | 651 if (typeVariableType != null) return typeVariableType; |
| (...skipping 15 matching lines...) Expand all Loading... |
| 680 namedParameterTypes.forEach((DartType type) { | 667 namedParameterTypes.forEach((DartType type) { |
| 681 type.forEachTypeVariable(f); | 668 type.forEachTypeVariable(f); |
| 682 }); | 669 }); |
| 683 } | 670 } |
| 684 | 671 |
| 685 accept(DartTypeVisitor visitor, var argument) { | 672 accept(DartTypeVisitor visitor, var argument) { |
| 686 return visitor.visitFunctionType(this, argument); | 673 return visitor.visitFunctionType(this, argument); |
| 687 } | 674 } |
| 688 | 675 |
| 689 void visitChildren(DartTypeVisitor visitor, var argument) { | 676 void visitChildren(DartTypeVisitor visitor, var argument) { |
| 690 returnType.accept(visitor, argument); | 677 returnType.accept(visitor, argument); |
| 691 DartType.visitList(parameterTypes, visitor, argument); | 678 DartType.visitList(parameterTypes, visitor, argument); |
| 692 DartType.visitList(optionalParameterTypes, visitor, argument); | 679 DartType.visitList(optionalParameterTypes, visitor, argument); |
| 693 DartType.visitList(namedParameterTypes, visitor, argument); | 680 DartType.visitList(namedParameterTypes, visitor, argument); |
| 694 } | 681 } |
| 695 | 682 |
| 696 String toString() { | 683 String toString() { |
| 697 StringBuffer sb = new StringBuffer(); | 684 StringBuffer sb = new StringBuffer(); |
| 698 sb.write('('); | 685 sb.write('('); |
| 699 sb.write(parameterTypes.join(', ')); | 686 sb.write(parameterTypes.join(', ')); |
| 700 bool first = parameterTypes.isEmpty; | 687 bool first = parameterTypes.isEmpty; |
| 701 if (!optionalParameterTypes.isEmpty) { | 688 if (!optionalParameterTypes.isEmpty) { |
| 702 if (!first) { | 689 if (!first) { |
| 703 sb.write(', '); | 690 sb.write(', '); |
| 704 } | 691 } |
| 705 sb.write('['); | 692 sb.write('['); |
| 706 sb.write(optionalParameterTypes.join(', ')); | 693 sb.write(optionalParameterTypes.join(', ')); |
| 707 sb.write(']'); | 694 sb.write(']'); |
| 708 first = false; | 695 first = false; |
| 709 } | 696 } |
| 710 if (!namedParameterTypes.isEmpty) { | 697 if (!namedParameterTypes.isEmpty) { |
| 711 if (!first) { | 698 if (!first) { |
| 712 sb.write(', '); | 699 sb.write(', '); |
| 713 } | 700 } |
| 714 sb.write('{'); | 701 sb.write('{'); |
| 715 first = true; | 702 first = true; |
| 716 for (int i = 0; i < namedParameters.length; i++) { | 703 for (int i = 0; i < namedParameters.length; i++) { |
| 717 if (!first) { | 704 if (!first) { |
| 718 sb.write(', '); | 705 sb.write(', '); |
| 719 } | 706 } |
| 720 sb.write(namedParameterTypes[i]); | 707 sb.write(namedParameterTypes[i]); |
| 721 sb.write(' '); | 708 sb.write(' '); |
| 722 sb.write(namedParameters[i]); | 709 sb.write(namedParameters[i]); |
| 723 first = false; | 710 first = false; |
| 724 } | 711 } |
| 725 sb.write('}'); | 712 sb.write('}'); |
| 726 } | 713 } |
| 727 sb.write(') -> ${returnType}'); | 714 sb.write(') -> ${returnType}'); |
| 728 return sb.toString(); | 715 return sb.toString(); |
| 729 } | 716 } |
| 730 | 717 |
| 731 String get name => 'Function'; | 718 String get name => 'Function'; |
| 732 | 719 |
| 733 int computeArity() => parameterTypes.length; | 720 int computeArity() => parameterTypes.length; |
| 734 | 721 |
| 735 int get hashCode { | 722 int get hashCode { |
| 736 int hash = 3 * returnType.hashCode; | 723 int hash = 3 * returnType.hashCode; |
| 737 for (DartType parameter in parameterTypes) { | 724 for (DartType parameter in parameterTypes) { |
| 738 hash = 17 * hash + 5 * parameter.hashCode; | 725 hash = 17 * hash + 5 * parameter.hashCode; |
| 739 } | 726 } |
| 740 for (DartType parameter in optionalParameterTypes) { | 727 for (DartType parameter in optionalParameterTypes) { |
| 741 hash = 19 * hash + 7 * parameter.hashCode; | 728 hash = 19 * hash + 7 * parameter.hashCode; |
| 742 } | 729 } |
| 743 for (String name in namedParameters) { | 730 for (String name in namedParameters) { |
| 744 hash = 23 * hash + 11 * name.hashCode; | 731 hash = 23 * hash + 11 * name.hashCode; |
| 745 } | 732 } |
| 746 for (DartType parameter in namedParameterTypes) { | 733 for (DartType parameter in namedParameterTypes) { |
| 747 hash = 29 * hash + 13 * parameter.hashCode; | 734 hash = 29 * hash + 13 * parameter.hashCode; |
| 748 } | 735 } |
| 749 return hash; | 736 return hash; |
| 750 } | 737 } |
| 751 | 738 |
| 752 bool operator ==(other) { | 739 bool operator ==(other) { |
| 753 if (other is !FunctionType) return false; | 740 if (other is! FunctionType) return false; |
| 754 return returnType == other.returnType && | 741 return returnType == other.returnType && |
| 755 equalElements(parameterTypes, other.parameterTypes) && | 742 equalElements(parameterTypes, other.parameterTypes) && |
| 756 equalElements(optionalParameterTypes, other.optionalParameterTypes) && | 743 equalElements(optionalParameterTypes, other.optionalParameterTypes) && |
| 757 equalElements(namedParameters, other.namedParameters) && | 744 equalElements(namedParameters, other.namedParameters) && |
| 758 equalElements(namedParameterTypes, other.namedParameterTypes); | 745 equalElements(namedParameterTypes, other.namedParameterTypes); |
| 759 } | 746 } |
| 760 } | 747 } |
| 761 | 748 |
| 762 class TypedefType extends GenericType { | 749 class TypedefType extends GenericType { |
| 763 DartType _unaliased; | 750 DartType _unaliased; |
| 764 | 751 |
| 765 TypedefType(TypedefElement element, | 752 TypedefType(TypedefElement element, |
| 766 [List<DartType> typeArguments = const <DartType>[]]) | 753 [List<DartType> typeArguments = const <DartType>[]]) |
| 767 : super(element, typeArguments); | 754 : super(element, typeArguments); |
| 768 | 755 |
| 769 TypedefType.forUserProvidedBadType(TypedefElement element, | 756 TypedefType.forUserProvidedBadType(TypedefElement element, |
| 770 [List<DartType> typeArguments = | 757 [List<DartType> typeArguments = const <DartType>[]]) |
| 771 const <DartType>[]]) | |
| 772 : super(element, typeArguments, checkTypeArgumentCount: false); | 758 : super(element, typeArguments, checkTypeArgumentCount: false); |
| 773 | 759 |
| 774 TypedefElement get element => super.element; | 760 TypedefElement get element => super.element; |
| 775 | 761 |
| 776 TypeKind get kind => TypeKind.TYPEDEF; | 762 TypeKind get kind => TypeKind.TYPEDEF; |
| 777 | 763 |
| 778 String get name => element.name; | 764 String get name => element.name; |
| 779 | 765 |
| 780 TypedefType createInstantiation(List<DartType> newTypeArguments) { | 766 TypedefType createInstantiation(List<DartType> newTypeArguments) { |
| 781 return new TypedefType(element, newTypeArguments); | 767 return new TypedefType(element, newTypeArguments); |
| (...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 893 | 879 |
| 894 R visitDynamicType(DynamicType type, A argument) => null; | 880 R visitDynamicType(DynamicType type, A argument) => null; |
| 895 } | 881 } |
| 896 | 882 |
| 897 abstract class BaseDartTypeVisitor<R, A> extends DartTypeVisitor<R, A> { | 883 abstract class BaseDartTypeVisitor<R, A> extends DartTypeVisitor<R, A> { |
| 898 const BaseDartTypeVisitor(); | 884 const BaseDartTypeVisitor(); |
| 899 | 885 |
| 900 R visitType(DartType type, A argument); | 886 R visitType(DartType type, A argument); |
| 901 | 887 |
| 902 @override | 888 @override |
| 903 R visitVoidType(VoidType type, A argument) => | 889 R visitVoidType(VoidType type, A argument) => visitType(type, argument); |
| 904 visitType(type, argument); | |
| 905 | 890 |
| 906 @override | 891 @override |
| 907 R visitTypeVariableType(TypeVariableType type, A argument) => | 892 R visitTypeVariableType(TypeVariableType type, A argument) => |
| 908 visitType(type, argument); | 893 visitType(type, argument); |
| 909 | 894 |
| 910 @override | 895 @override |
| 911 R visitFunctionType(FunctionType type, A argument) => | 896 R visitFunctionType(FunctionType type, A argument) => |
| 912 visitType(type, argument); | 897 visitType(type, argument); |
| 913 | 898 |
| 914 @override | 899 @override |
| 915 R visitMalformedType(MalformedType type, A argument) => | 900 R visitMalformedType(MalformedType type, A argument) => |
| 916 visitType(type, argument); | 901 visitType(type, argument); |
| 917 | 902 |
| 918 @override | 903 @override |
| 919 R visitStatementType(StatementType type, A argument) => | 904 R visitStatementType(StatementType type, A argument) => |
| 920 visitType(type, argument); | 905 visitType(type, argument); |
| 921 | 906 |
| 922 R visitGenericType(GenericType type, A argument) => | 907 R visitGenericType(GenericType type, A argument) => visitType(type, argument); |
| 923 visitType(type, argument); | |
| 924 | 908 |
| 925 @override | 909 @override |
| 926 R visitInterfaceType(InterfaceType type, A argument) => | 910 R visitInterfaceType(InterfaceType type, A argument) => |
| 927 visitGenericType(type, argument); | 911 visitGenericType(type, argument); |
| 928 | 912 |
| 929 @override | 913 @override |
| 930 R visitTypedefType(TypedefType type, A argument) => | 914 R visitTypedefType(TypedefType type, A argument) => |
| 931 visitGenericType(type, argument); | 915 visitGenericType(type, argument); |
| 932 | 916 |
| 933 @override | 917 @override |
| 934 R visitDynamicType(DynamicType type, A argument) => | 918 R visitDynamicType(DynamicType type, A argument) => visitType(type, argument); |
| 935 visitType(type, argument); | |
| 936 } | 919 } |
| 937 | 920 |
| 938 /** | 921 /** |
| 939 * Abstract visitor for determining relations between types. | 922 * Abstract visitor for determining relations between types. |
| 940 */ | 923 */ |
| 941 abstract class AbstractTypeRelation | 924 abstract class AbstractTypeRelation |
| 942 extends BaseDartTypeVisitor<bool, DartType> { | 925 extends BaseDartTypeVisitor<bool, DartType> { |
| 943 final Resolution resolution; | 926 final Resolution resolution; |
| 944 | 927 |
| 945 AbstractTypeRelation(this.resolution); | 928 AbstractTypeRelation(this.resolution); |
| (...skipping 15 matching lines...) Expand all Loading... |
| 961 | 944 |
| 962 bool invalidFunctionParameterTypes(DartType t, DartType s); | 945 bool invalidFunctionParameterTypes(DartType t, DartType s); |
| 963 | 946 |
| 964 bool invalidTypeVariableBounds(DartType bound, DartType s); | 947 bool invalidTypeVariableBounds(DartType bound, DartType s); |
| 965 | 948 |
| 966 /// Handle as dynamic for both subtype and more specific relation to avoid | 949 /// Handle as dynamic for both subtype and more specific relation to avoid |
| 967 /// spurious errors from malformed types. | 950 /// spurious errors from malformed types. |
| 968 bool visitMalformedType(MalformedType t, DartType s) => true; | 951 bool visitMalformedType(MalformedType t, DartType s) => true; |
| 969 | 952 |
| 970 bool visitInterfaceType(InterfaceType t, DartType s) { | 953 bool visitInterfaceType(InterfaceType t, DartType s) { |
| 971 | |
| 972 // TODO(johnniwinther): Currently needed since literal types like int, | 954 // TODO(johnniwinther): Currently needed since literal types like int, |
| 973 // double, bool etc. might not have been resolved yet. | 955 // double, bool etc. might not have been resolved yet. |
| 974 t.element.ensureResolved(resolution); | 956 t.element.ensureResolved(resolution); |
| 975 | 957 |
| 976 bool checkTypeArguments(InterfaceType instance, InterfaceType other) { | 958 bool checkTypeArguments(InterfaceType instance, InterfaceType other) { |
| 977 List<DartType> tTypeArgs = instance.typeArguments; | 959 List<DartType> tTypeArgs = instance.typeArguments; |
| 978 List<DartType> sTypeArgs = other.typeArguments; | 960 List<DartType> sTypeArgs = other.typeArguments; |
| 979 assert(tTypeArgs.length == sTypeArgs.length); | 961 assert(tTypeArgs.length == sTypeArgs.length); |
| 980 for (int i = 0; i < tTypeArgs.length; i++) { | 962 for (int i = 0; i < tTypeArgs.length; i++) { |
| 981 if (invalidTypeArguments(tTypeArgs[i], sTypeArgs[i])) { | 963 if (invalidTypeArguments(tTypeArgs[i], sTypeArgs[i])) { |
| 982 return false; | 964 return false; |
| 983 } | 965 } |
| 984 } | 966 } |
| 985 return true; | 967 return true; |
| 986 } | 968 } |
| 987 | 969 |
| 988 if (s is InterfaceType) { | 970 if (s is InterfaceType) { |
| 989 InterfaceType instance = t.asInstanceOf(s.element); | 971 InterfaceType instance = t.asInstanceOf(s.element); |
| 990 return instance != null && checkTypeArguments(instance, s); | 972 return instance != null && checkTypeArguments(instance, s); |
| 991 } else { | 973 } else { |
| 992 return false; | 974 return false; |
| 993 } | 975 } |
| 994 } | 976 } |
| 995 | 977 |
| 996 bool visitFunctionType(FunctionType t, DartType s) { | 978 bool visitFunctionType(FunctionType t, DartType s) { |
| 997 if (s == coreTypes.functionType) { | 979 if (s == coreTypes.functionType) { |
| 998 return true; | 980 return true; |
| 999 } | 981 } |
| 1000 if (s is !FunctionType) return false; | 982 if (s is! FunctionType) return false; |
| 1001 FunctionType tf = t; | 983 FunctionType tf = t; |
| 1002 FunctionType sf = s; | 984 FunctionType sf = s; |
| 1003 if (invalidFunctionReturnTypes(tf.returnType, sf.returnType)) { | 985 if (invalidFunctionReturnTypes(tf.returnType, sf.returnType)) { |
| 1004 return false; | 986 return false; |
| 1005 } | 987 } |
| 1006 | 988 |
| 1007 // TODO(johnniwinther): Rewrite the function subtyping to be more readable | 989 // TODO(johnniwinther): Rewrite the function subtyping to be more readable |
| 1008 // but still as efficient. | 990 // but still as efficient. |
| 1009 | 991 |
| 1010 // For the comments we use the following abbreviations: | 992 // For the comments we use the following abbreviations: |
| (...skipping 18 matching lines...) Expand all Loading... |
| 1029 } | 1011 } |
| 1030 return false; | 1012 return false; |
| 1031 } | 1013 } |
| 1032 | 1014 |
| 1033 if (incompatibleParameters()) return false; | 1015 if (incompatibleParameters()) return false; |
| 1034 if (tNotEmpty) { | 1016 if (tNotEmpty) { |
| 1035 // We must have [: len(t.p) <= len(s.p) :]. | 1017 // We must have [: len(t.p) <= len(s.p) :]. |
| 1036 return false; | 1018 return false; |
| 1037 } | 1019 } |
| 1038 if (!sf.namedParameters.isEmpty) { | 1020 if (!sf.namedParameters.isEmpty) { |
| 1039 // We must have [: len(t.p) == len(s.p) :]. | 1021 // We must have [: len(t.p) == len(s.p) :]. |
| 1040 if (sNotEmpty) { | 1022 if (sNotEmpty) { |
| 1041 return false; | 1023 return false; |
| 1042 } | 1024 } |
| 1043 // Since named parameters are globally ordered we can determine the | 1025 // Since named parameters are globally ordered we can determine the |
| 1044 // subset relation with a linear search for [:sf.namedParameters:] | 1026 // subset relation with a linear search for [:sf.namedParameters:] |
| 1045 // within [:tf.namedParameters:]. | 1027 // within [:tf.namedParameters:]. |
| 1046 List<String> tNames = tf.namedParameters; | 1028 List<String> tNames = tf.namedParameters; |
| 1047 List<DartType> tTypes = tf.namedParameterTypes; | 1029 List<DartType> tTypes = tf.namedParameterTypes; |
| 1048 List<String> sNames = sf.namedParameters; | 1030 List<String> sNames = sf.namedParameters; |
| 1049 List<DartType> sTypes = sf.namedParameterTypes; | 1031 List<DartType> sTypes = sf.namedParameterTypes; |
| (...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1159 | 1141 |
| 1160 bool invalidTypeVariableBounds(DartType bound, DartType s) { | 1142 bool invalidTypeVariableBounds(DartType bound, DartType s) { |
| 1161 return !isMoreSpecific(bound, s); | 1143 return !isMoreSpecific(bound, s); |
| 1162 } | 1144 } |
| 1163 } | 1145 } |
| 1164 | 1146 |
| 1165 /** | 1147 /** |
| 1166 * Type visitor that determines the subtype relation two types. | 1148 * Type visitor that determines the subtype relation two types. |
| 1167 */ | 1149 */ |
| 1168 class SubtypeVisitor extends MoreSpecificVisitor { | 1150 class SubtypeVisitor extends MoreSpecificVisitor { |
| 1169 | |
| 1170 SubtypeVisitor(Resolution resolution) : super(resolution); | 1151 SubtypeVisitor(Resolution resolution) : super(resolution); |
| 1171 | 1152 |
| 1172 bool isSubtype(DartType t, DartType s) { | 1153 bool isSubtype(DartType t, DartType s) { |
| 1173 return t.treatAsDynamic || isMoreSpecific(t, s); | 1154 return t.treatAsDynamic || isMoreSpecific(t, s); |
| 1174 } | 1155 } |
| 1175 | 1156 |
| 1176 bool isAssignable(DartType t, DartType s) { | 1157 bool isAssignable(DartType t, DartType s) { |
| 1177 return isSubtype(t, s) || isSubtype(s, t); | 1158 return isSubtype(t, s) || isSubtype(s, t); |
| 1178 } | 1159 } |
| 1179 | 1160 |
| (...skipping 24 matching lines...) Expand all Loading... |
| 1204 } | 1185 } |
| 1205 return false; | 1186 return false; |
| 1206 } | 1187 } |
| 1207 } | 1188 } |
| 1208 | 1189 |
| 1209 /** | 1190 /** |
| 1210 * Callback used to check whether the [typeArgument] of [type] is a valid | 1191 * Callback used to check whether the [typeArgument] of [type] is a valid |
| 1211 * substitute for the bound of [typeVariable]. [bound] holds the bound against | 1192 * substitute for the bound of [typeVariable]. [bound] holds the bound against |
| 1212 * which [typeArgument] should be checked. | 1193 * which [typeArgument] should be checked. |
| 1213 */ | 1194 */ |
| 1214 typedef void CheckTypeVariableBound(GenericType type, | 1195 typedef void CheckTypeVariableBound(GenericType type, DartType typeArgument, |
| 1215 DartType typeArgument, | 1196 TypeVariableType typeVariable, DartType bound); |
| 1216 TypeVariableType typeVariable, | |
| 1217 DartType bound); | |
| 1218 | 1197 |
| 1219 /// Basic interface for the Dart type system. | 1198 /// Basic interface for the Dart type system. |
| 1220 abstract class DartTypes { | 1199 abstract class DartTypes { |
| 1221 /// The types defined in 'dart:core'. | 1200 /// The types defined in 'dart:core'. |
| 1222 CoreTypes get coreTypes; | 1201 CoreTypes get coreTypes; |
| 1223 | 1202 |
| 1224 /// Returns `true` if [t] is a subtype of [s]. | 1203 /// Returns `true` if [t] is a subtype of [s]. |
| 1225 bool isSubtype(DartType t, DartType s); | 1204 bool isSubtype(DartType t, DartType s); |
| 1226 | 1205 |
| 1227 /// Returns `true` if [t] might be a subtype of [s] for some values of | 1206 /// Returns `true` if [t] might be a subtype of [s] for some values of |
| (...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1320 // TODO(johnniwinther): Return a set of variable points in the positive | 1299 // TODO(johnniwinther): Return a set of variable points in the positive |
| 1321 // cases. | 1300 // cases. |
| 1322 return potentialSubtypeVisitor.isSubtype(t, s); | 1301 return potentialSubtypeVisitor.isSubtype(t, s); |
| 1323 } | 1302 } |
| 1324 | 1303 |
| 1325 /** | 1304 /** |
| 1326 * Checks the type arguments of [type] against the type variable bounds | 1305 * Checks the type arguments of [type] against the type variable bounds |
| 1327 * declared on [element]. Calls [checkTypeVariableBound] on each type | 1306 * declared on [element]. Calls [checkTypeVariableBound] on each type |
| 1328 * argument and bound. | 1307 * argument and bound. |
| 1329 */ | 1308 */ |
| 1330 void checkTypeVariableBounds(GenericType type, | 1309 void checkTypeVariableBounds( |
| 1331 CheckTypeVariableBound checkTypeVariableBound) { | 1310 GenericType type, CheckTypeVariableBound checkTypeVariableBound) { |
| 1332 TypeDeclarationElement element = type.element; | 1311 TypeDeclarationElement element = type.element; |
| 1333 List<DartType> typeArguments = type.typeArguments; | 1312 List<DartType> typeArguments = type.typeArguments; |
| 1334 List<DartType> typeVariables = element.typeVariables; | 1313 List<DartType> typeVariables = element.typeVariables; |
| 1335 assert(typeVariables.length == typeArguments.length); | 1314 assert(typeVariables.length == typeArguments.length); |
| 1336 for (int index = 0; index < typeArguments.length; index++) { | 1315 for (int index = 0; index < typeArguments.length; index++) { |
| 1337 TypeVariableType typeVariable = typeVariables[index]; | 1316 TypeVariableType typeVariable = typeVariables[index]; |
| 1338 DartType bound = typeVariable.element.bound.substByContext(type); | 1317 DartType bound = typeVariable.element.bound.substByContext(type); |
| 1339 DartType typeArgument = typeArguments[index]; | 1318 DartType typeArgument = typeArguments[index]; |
| 1340 checkTypeVariableBound(type, typeArgument, typeVariable, bound); | 1319 checkTypeVariableBound(type, typeArgument, typeVariable, bound); |
| 1341 } | 1320 } |
| 1342 } | 1321 } |
| 1343 | 1322 |
| 1344 /** | 1323 /** |
| 1345 * Helper method for performing substitution of a list of types. | 1324 * Helper method for performing substitution of a list of types. |
| 1346 * | 1325 * |
| 1347 * If no types are changed by the substitution, the [types] is returned | 1326 * If no types are changed by the substitution, the [types] is returned |
| 1348 * instead of a newly created list. | 1327 * instead of a newly created list. |
| 1349 */ | 1328 */ |
| 1350 static List<DartType> substTypes(List<DartType> types, | 1329 static List<DartType> substTypes(List<DartType> types, |
| 1351 List<DartType> arguments, | 1330 List<DartType> arguments, List<DartType> parameters) { |
| 1352 List<DartType> parameters) { | |
| 1353 bool changed = false; | 1331 bool changed = false; |
| 1354 List<DartType> result = new List<DartType>.generate(types.length, (index) { | 1332 List<DartType> result = new List<DartType>.generate(types.length, (index) { |
| 1355 DartType type = types[index]; | 1333 DartType type = types[index]; |
| 1356 DartType argument = type.subst(arguments, parameters); | 1334 DartType argument = type.subst(arguments, parameters); |
| 1357 if (!changed && !identical(argument, type)) { | 1335 if (!changed && !identical(argument, type)) { |
| 1358 changed = true; | 1336 changed = true; |
| 1359 } | 1337 } |
| 1360 return argument; | 1338 return argument; |
| 1361 }); | 1339 }); |
| 1362 // Use the new List only if necessary. | 1340 // Use the new List only if necessary. |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1402 return 1; | 1380 return 1; |
| 1403 } | 1381 } |
| 1404 if (a.isDynamic) { | 1382 if (a.isDynamic) { |
| 1405 // [b] is not dynamic => a < b. | 1383 // [b] is not dynamic => a < b. |
| 1406 return -1; | 1384 return -1; |
| 1407 } else if (b.isDynamic) { | 1385 } else if (b.isDynamic) { |
| 1408 // [a] is not dynamic => a > b. | 1386 // [a] is not dynamic => a > b. |
| 1409 return 1; | 1387 return 1; |
| 1410 } | 1388 } |
| 1411 bool isDefinedByDeclaration(DartType type) { | 1389 bool isDefinedByDeclaration(DartType type) { |
| 1412 return type.isInterfaceType || | 1390 return type.isInterfaceType || type.isTypedef || type.isTypeVariable; |
| 1413 type.isTypedef || | |
| 1414 type.isTypeVariable; | |
| 1415 } | 1391 } |
| 1416 | 1392 |
| 1417 if (isDefinedByDeclaration(a)) { | 1393 if (isDefinedByDeclaration(a)) { |
| 1418 if (isDefinedByDeclaration(b)) { | 1394 if (isDefinedByDeclaration(b)) { |
| 1419 int result = Elements.compareByPosition(a.element, b.element); | 1395 int result = Elements.compareByPosition(a.element, b.element); |
| 1420 if (result != 0) return result; | 1396 if (result != 0) return result; |
| 1421 if (a.isTypeVariable) { | 1397 if (a.isTypeVariable) { |
| 1422 return b.isTypeVariable | 1398 return b.isTypeVariable |
| 1423 ? 0 | 1399 ? 0 |
| 1424 : 1; // [b] is not a type variable => a > b. | 1400 : 1; // [b] is not a type variable => a > b. |
| 1425 } else { | 1401 } else { |
| 1426 if (b.isTypeVariable) { | 1402 if (b.isTypeVariable) { |
| 1427 // [a] is not a type variable => a < b. | 1403 // [a] is not a type variable => a < b. |
| 1428 return -1; | 1404 return -1; |
| 1429 } else { | 1405 } else { |
| 1430 return compareList((a as GenericType).typeArguments, | 1406 return compareList((a as GenericType).typeArguments, |
| 1431 (b as GenericType).typeArguments); | 1407 (b as GenericType).typeArguments); |
| 1432 } | 1408 } |
| 1433 } | 1409 } |
| 1434 } else { | 1410 } else { |
| 1435 // [b] is neither an interface, typedef, type variable, dynamic, | 1411 // [b] is neither an interface, typedef, type variable, dynamic, |
| 1436 // nor void => a < b. | 1412 // nor void => a < b. |
| 1437 return -1; | 1413 return -1; |
| 1438 } | 1414 } |
| 1439 } else if (isDefinedByDeclaration(b)) { | 1415 } else if (isDefinedByDeclaration(b)) { |
| 1440 // [a] is neither an interface, typedef, type variable, dynamic, | 1416 // [a] is neither an interface, typedef, type variable, dynamic, |
| 1441 // nor void => a > b. | 1417 // nor void => a > b. |
| 1442 return 1; | 1418 return 1; |
| 1443 } | 1419 } |
| 1444 if (a.isFunctionType) { | 1420 if (a.isFunctionType) { |
| 1445 if (b.isFunctionType) { | 1421 if (b.isFunctionType) { |
| 1446 FunctionType aFunc = a; | 1422 FunctionType aFunc = a; |
| 1447 FunctionType bFunc = b; | 1423 FunctionType bFunc = b; |
| 1448 int result = compare(aFunc.returnType, bFunc.returnType); | 1424 int result = compare(aFunc.returnType, bFunc.returnType); |
| 1449 if (result != 0) return result; | 1425 if (result != 0) return result; |
| 1450 result = compareList(aFunc.parameterTypes, bFunc.parameterTypes); | 1426 result = compareList(aFunc.parameterTypes, bFunc.parameterTypes); |
| 1451 if (result != 0) return result; | 1427 if (result != 0) return result; |
| 1452 result = compareList(aFunc.optionalParameterTypes, | 1428 result = compareList( |
| 1453 bFunc.optionalParameterTypes); | 1429 aFunc.optionalParameterTypes, bFunc.optionalParameterTypes); |
| 1454 if (result != 0) return result; | 1430 if (result != 0) return result; |
| 1455 // TODO(karlklose): reuse [compareList]. | 1431 // TODO(karlklose): reuse [compareList]. |
| 1456 Iterator<String> aNames = aFunc.namedParameters.iterator; | 1432 Iterator<String> aNames = aFunc.namedParameters.iterator; |
| 1457 Iterator<String> bNames = bFunc.namedParameters.iterator; | 1433 Iterator<String> bNames = bFunc.namedParameters.iterator; |
| 1458 while (aNames.moveNext() && bNames.moveNext()) { | 1434 while (aNames.moveNext() && bNames.moveNext()) { |
| 1459 int result = aNames.current.compareTo(bNames.current); | 1435 int result = aNames.current.compareTo(bNames.current); |
| 1460 if (result != 0) return result; | 1436 if (result != 0) return result; |
| 1461 } | 1437 } |
| 1462 if (aNames.moveNext()) { | 1438 if (aNames.moveNext()) { |
| 1463 // [aNames] is longer that [bNames] => a > b. | 1439 // [aNames] is longer that [bNames] => a > b. |
| 1464 return 1; | 1440 return 1; |
| 1465 } else if (bNames.moveNext()) { | 1441 } else if (bNames.moveNext()) { |
| 1466 // [bNames] is longer that [aNames] => a < b. | 1442 // [bNames] is longer that [aNames] => a < b. |
| 1467 return -1; | 1443 return -1; |
| 1468 } | 1444 } |
| 1469 return compareList(aFunc.namedParameterTypes, | 1445 return compareList( |
| 1470 bFunc.namedParameterTypes); | 1446 aFunc.namedParameterTypes, bFunc.namedParameterTypes); |
| 1471 } else { | 1447 } else { |
| 1472 // [b] is a malformed or statement type => a < b. | 1448 // [b] is a malformed or statement type => a < b. |
| 1473 return -1; | 1449 return -1; |
| 1474 } | 1450 } |
| 1475 } else if (b.isFunctionType) { | 1451 } else if (b.isFunctionType) { |
| 1476 // [b] is a malformed or statement type => a > b. | 1452 // [b] is a malformed or statement type => a > b. |
| 1477 return 1; | 1453 return 1; |
| 1478 } | 1454 } |
| 1479 if (a.kind == TypeKind.STATEMENT) { | 1455 if (a.kind == TypeKind.STATEMENT) { |
| 1480 if (b.kind == TypeKind.STATEMENT) { | 1456 if (b.kind == TypeKind.STATEMENT) { |
| 1481 return 0; | 1457 return 0; |
| 1482 } else { | 1458 } else { |
| 1483 // [b] is a malformed type => a > b. | 1459 // [b] is a malformed type => a > b. |
| 1484 return 1; | 1460 return 1; |
| 1485 } | 1461 } |
| 1486 } else if (b.kind == TypeKind.STATEMENT) { | 1462 } else if (b.kind == TypeKind.STATEMENT) { |
| 1487 // [a] is a malformed type => a < b. | 1463 // [a] is a malformed type => a < b. |
| 1488 return -1; | 1464 return -1; |
| 1489 } | 1465 } |
| 1490 assert (a.isMalformed); | 1466 assert(a.isMalformed); |
| 1491 assert (b.isMalformed); | 1467 assert(b.isMalformed); |
| 1492 // TODO(johnniwinther): Can we do this better? | 1468 // TODO(johnniwinther): Can we do this better? |
| 1493 return Elements.compareByPosition(a.element, b.element); | 1469 return Elements.compareByPosition(a.element, b.element); |
| 1494 } | 1470 } |
| 1495 | 1471 |
| 1496 static int compareList(List<DartType> a, List<DartType> b) { | 1472 static int compareList(List<DartType> a, List<DartType> b) { |
| 1497 for (int index = 0; index < min(a.length, b.length); index++) { | 1473 for (int index = 0; index < min(a.length, b.length); index++) { |
| 1498 int result = compare(a[index], b[index]); | 1474 int result = compare(a[index], b[index]); |
| 1499 if (result != 0) return result; | 1475 if (result != 0) return result; |
| 1500 } | 1476 } |
| 1501 if (a.length > b.length) { | 1477 if (a.length > b.length) { |
| 1502 return 1; | 1478 return 1; |
| 1503 } else if (a.length < b.length) { | 1479 } else if (a.length < b.length) { |
| 1504 return -1; | 1480 return -1; |
| 1505 } | 1481 } |
| 1506 return 0; | 1482 return 0; |
| 1507 } | 1483 } |
| 1508 | 1484 |
| 1509 static List<DartType> sorted(Iterable<DartType> types) { | 1485 static List<DartType> sorted(Iterable<DartType> types) { |
| 1510 return types.toList()..sort(compare); | 1486 return types.toList()..sort(compare); |
| 1511 } | 1487 } |
| 1512 | 1488 |
| 1513 /// Computes the least upper bound of two interface types [a] and [b]. | 1489 /// Computes the least upper bound of two interface types [a] and [b]. |
| 1514 InterfaceType computeLeastUpperBoundInterfaces(InterfaceType a, | 1490 InterfaceType computeLeastUpperBoundInterfaces( |
| 1515 InterfaceType b) { | 1491 InterfaceType a, InterfaceType b) { |
| 1516 | |
| 1517 /// Returns the set of supertypes of [type] at depth [depth]. | 1492 /// Returns the set of supertypes of [type] at depth [depth]. |
| 1518 Set<DartType> getSupertypesAtDepth(InterfaceType type, int depth) { | 1493 Set<DartType> getSupertypesAtDepth(InterfaceType type, int depth) { |
| 1519 OrderedTypeSet types = type.element.allSupertypesAndSelf; | 1494 OrderedTypeSet types = type.element.allSupertypesAndSelf; |
| 1520 Set<DartType> set = new Set<DartType>(); | 1495 Set<DartType> set = new Set<DartType>(); |
| 1521 types.forEach(depth, (DartType supertype) { | 1496 types.forEach(depth, (DartType supertype) { |
| 1522 set.add(supertype.substByContext(type)); | 1497 set.add(supertype.substByContext(type)); |
| 1523 }); | 1498 }); |
| 1524 return set; | 1499 return set; |
| 1525 } | 1500 } |
| 1526 | 1501 |
| 1527 ClassElement aClass = a.element; | 1502 ClassElement aClass = a.element; |
| 1528 ClassElement bClass = b.element; | 1503 ClassElement bClass = b.element; |
| 1529 int maxCommonDepth = min(aClass.hierarchyDepth, bClass.hierarchyDepth); | 1504 int maxCommonDepth = min(aClass.hierarchyDepth, bClass.hierarchyDepth); |
| 1530 for (int depth = maxCommonDepth; depth >= 0; depth--) { | 1505 for (int depth = maxCommonDepth; depth >= 0; depth--) { |
| 1531 Set<DartType> aTypeSet = getSupertypesAtDepth(a, depth); | 1506 Set<DartType> aTypeSet = getSupertypesAtDepth(a, depth); |
| 1532 Set<DartType> bTypeSet = getSupertypesAtDepth(b, depth); | 1507 Set<DartType> bTypeSet = getSupertypesAtDepth(b, depth); |
| 1533 Set<DartType> intersection = aTypeSet..retainAll(bTypeSet); | 1508 Set<DartType> intersection = aTypeSet..retainAll(bTypeSet); |
| 1534 if (intersection.length == 1) { | 1509 if (intersection.length == 1) { |
| 1535 return intersection.first; | 1510 return intersection.first; |
| 1536 } | 1511 } |
| 1537 } | 1512 } |
| 1538 | 1513 |
| 1539 reporter.internalError(CURRENT_ELEMENT_SPANNABLE, | 1514 reporter.internalError(CURRENT_ELEMENT_SPANNABLE, |
| 1540 'No least upper bound computed for $a and $b.'); | 1515 'No least upper bound computed for $a and $b.'); |
| 1541 return null; | 1516 return null; |
| 1542 } | 1517 } |
| 1543 | 1518 |
| 1544 /// Computes the least upper bound of the types in the longest prefix of [a] | 1519 /// Computes the least upper bound of the types in the longest prefix of [a] |
| 1545 /// and [b]. | 1520 /// and [b]. |
| 1546 List<DartType> computeLeastUpperBoundsTypes(List<DartType> a, | 1521 List<DartType> computeLeastUpperBoundsTypes( |
| 1547 List<DartType> b) { | 1522 List<DartType> a, List<DartType> b) { |
| 1548 if (a.isEmpty || b.isEmpty) return const <DartType>[]; | 1523 if (a.isEmpty || b.isEmpty) return const <DartType>[]; |
| 1549 int prefixLength = min(a.length, b.length); | 1524 int prefixLength = min(a.length, b.length); |
| 1550 List<DartType> types = new List<DartType>(prefixLength); | 1525 List<DartType> types = new List<DartType>(prefixLength); |
| 1551 for (int index = 0; index < prefixLength; index++) { | 1526 for (int index = 0; index < prefixLength; index++) { |
| 1552 types[index] = computeLeastUpperBound(a[index], b[index]); | 1527 types[index] = computeLeastUpperBound(a[index], b[index]); |
| 1553 } | 1528 } |
| 1554 return types; | 1529 return types; |
| 1555 } | 1530 } |
| 1556 | 1531 |
| 1557 /// Computes the least upper bound of two function types [a] and [b]. | 1532 /// Computes the least upper bound of two function types [a] and [b]. |
| 1558 /// | 1533 /// |
| 1559 /// If the required parameter count of [a] and [b] does not match, `Function` | 1534 /// If the required parameter count of [a] and [b] does not match, `Function` |
| 1560 /// is returned. | 1535 /// is returned. |
| 1561 /// | 1536 /// |
| 1562 /// Otherwise, a function type is returned whose return type and | 1537 /// Otherwise, a function type is returned whose return type and |
| 1563 /// parameter types are the least upper bound of those of [a] and [b], | 1538 /// parameter types are the least upper bound of those of [a] and [b], |
| 1564 /// respectively. In addition, the optional parameters are the least upper | 1539 /// respectively. In addition, the optional parameters are the least upper |
| 1565 /// bound of the longest common prefix of the optional parameters of [a] and | 1540 /// bound of the longest common prefix of the optional parameters of [a] and |
| 1566 /// [b], and the named parameters are the least upper bound of those common to | 1541 /// [b], and the named parameters are the least upper bound of those common to |
| 1567 /// [a] and [b]. | 1542 /// [a] and [b]. |
| 1568 DartType computeLeastUpperBoundFunctionTypes(FunctionType a, | 1543 DartType computeLeastUpperBoundFunctionTypes(FunctionType a, FunctionType b) { |
| 1569 FunctionType b) { | |
| 1570 if (a.parameterTypes.length != b.parameterTypes.length) { | 1544 if (a.parameterTypes.length != b.parameterTypes.length) { |
| 1571 return coreTypes.functionType; | 1545 return coreTypes.functionType; |
| 1572 } | 1546 } |
| 1573 DartType returnType = computeLeastUpperBound(a.returnType, b.returnType); | 1547 DartType returnType = computeLeastUpperBound(a.returnType, b.returnType); |
| 1574 List<DartType> parameterTypes = | 1548 List<DartType> parameterTypes = |
| 1575 computeLeastUpperBoundsTypes(a.parameterTypes, b.parameterTypes); | 1549 computeLeastUpperBoundsTypes(a.parameterTypes, b.parameterTypes); |
| 1576 List<DartType> optionalParameterTypes = | 1550 List<DartType> optionalParameterTypes = computeLeastUpperBoundsTypes( |
| 1577 computeLeastUpperBoundsTypes(a.optionalParameterTypes, | 1551 a.optionalParameterTypes, b.optionalParameterTypes); |
| 1578 b.optionalParameterTypes); | |
| 1579 List<String> namedParameters = <String>[]; | 1552 List<String> namedParameters = <String>[]; |
| 1580 List<String> aNamedParameters = a.namedParameters; | 1553 List<String> aNamedParameters = a.namedParameters; |
| 1581 List<String> bNamedParameters = b.namedParameters; | 1554 List<String> bNamedParameters = b.namedParameters; |
| 1582 List<DartType> namedParameterTypes = <DartType>[]; | 1555 List<DartType> namedParameterTypes = <DartType>[]; |
| 1583 List<DartType> aNamedParameterTypes = a.namedParameterTypes; | 1556 List<DartType> aNamedParameterTypes = a.namedParameterTypes; |
| 1584 List<DartType> bNamedParameterTypes = b.namedParameterTypes; | 1557 List<DartType> bNamedParameterTypes = b.namedParameterTypes; |
| 1585 int aIndex = 0; | 1558 int aIndex = 0; |
| 1586 int bIndex = 0; | 1559 int bIndex = 0; |
| 1587 while (aIndex < aNamedParameters.length && | 1560 while ( |
| 1588 bIndex < bNamedParameters.length) { | 1561 aIndex < aNamedParameters.length && bIndex < bNamedParameters.length) { |
| 1589 String aNamedParameter = aNamedParameters[aIndex]; | 1562 String aNamedParameter = aNamedParameters[aIndex]; |
| 1590 String bNamedParameter = bNamedParameters[bIndex]; | 1563 String bNamedParameter = bNamedParameters[bIndex]; |
| 1591 int result = aNamedParameter.compareTo(bNamedParameter); | 1564 int result = aNamedParameter.compareTo(bNamedParameter); |
| 1592 if (result == 0) { | 1565 if (result == 0) { |
| 1593 namedParameters.add(aNamedParameter); | 1566 namedParameters.add(aNamedParameter); |
| 1594 namedParameterTypes.add(computeLeastUpperBound( | 1567 namedParameterTypes.add(computeLeastUpperBound( |
| 1595 aNamedParameterTypes[aIndex], bNamedParameterTypes[bIndex])); | 1568 aNamedParameterTypes[aIndex], bNamedParameterTypes[bIndex])); |
| 1596 } | 1569 } |
| 1597 if (result <= 0) { | 1570 if (result <= 0) { |
| 1598 aIndex++; | 1571 aIndex++; |
| 1599 } | 1572 } |
| 1600 if (result >= 0) { | 1573 if (result >= 0) { |
| 1601 bIndex++; | 1574 bIndex++; |
| 1602 } | 1575 } |
| 1603 } | 1576 } |
| 1604 return new FunctionType.synthesized( | 1577 return new FunctionType.synthesized(returnType, parameterTypes, |
| 1605 returnType, | 1578 optionalParameterTypes, namedParameters, namedParameterTypes); |
| 1606 parameterTypes, optionalParameterTypes, | |
| 1607 namedParameters, namedParameterTypes); | |
| 1608 } | 1579 } |
| 1609 | 1580 |
| 1610 /// Computes the least upper bound of two types of which at least one is a | 1581 /// Computes the least upper bound of two types of which at least one is a |
| 1611 /// type variable. The least upper bound of a type variable is defined in | 1582 /// type variable. The least upper bound of a type variable is defined in |
| 1612 /// terms of its bound, but to ensure reflexivity we need to check for common | 1583 /// terms of its bound, but to ensure reflexivity we need to check for common |
| 1613 /// bounds transitively. | 1584 /// bounds transitively. |
| 1614 DartType computeLeastUpperBoundTypeVariableTypes(DartType a, | 1585 DartType computeLeastUpperBoundTypeVariableTypes(DartType a, DartType b) { |
| 1615 DartType b) { | |
| 1616 Set<DartType> typeVariableBounds = new Set<DartType>(); | 1586 Set<DartType> typeVariableBounds = new Set<DartType>(); |
| 1617 while (a.isTypeVariable) { | 1587 while (a.isTypeVariable) { |
| 1618 if (a == b) return a; | 1588 if (a == b) return a; |
| 1619 typeVariableBounds.add(a); | 1589 typeVariableBounds.add(a); |
| 1620 TypeVariableElement element = a.element; | 1590 TypeVariableElement element = a.element; |
| 1621 a = element.bound; | 1591 a = element.bound; |
| 1622 } | 1592 } |
| 1623 while (b.isTypeVariable) { | 1593 while (b.isTypeVariable) { |
| 1624 if (typeVariableBounds.contains(b)) return b; | 1594 if (typeVariableBounds.contains(b)) return b; |
| 1625 TypeVariableElement element = b.element; | 1595 TypeVariableElement element = b.element; |
| (...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1681 /// | 1651 /// |
| 1682 /// unaliasedBound(Foo) = Foo | 1652 /// unaliasedBound(Foo) = Foo |
| 1683 /// unaliasedBound(Bar) = Bar | 1653 /// unaliasedBound(Bar) = Bar |
| 1684 /// unaliasedBound(Unresolved) = `dynamic` | 1654 /// unaliasedBound(Unresolved) = `dynamic` |
| 1685 /// unaliasedBound(Baz) = ()->dynamic | 1655 /// unaliasedBound(Baz) = ()->dynamic |
| 1686 /// unaliasedBound(T) = Bar | 1656 /// unaliasedBound(T) = Bar |
| 1687 /// unaliasedBound(S) = unaliasedBound(T) = Bar | 1657 /// unaliasedBound(S) = unaliasedBound(T) = Bar |
| 1688 /// unaliasedBound(U) = unaliasedBound(Baz) = ()->dynamic | 1658 /// unaliasedBound(U) = unaliasedBound(Baz) = ()->dynamic |
| 1689 /// unaliasedBound(X) = unaliasedBound(Y) = `Object` | 1659 /// unaliasedBound(X) = unaliasedBound(Y) = `Object` |
| 1690 /// | 1660 /// |
| 1691 static DartType computeUnaliasedBound( | 1661 static DartType computeUnaliasedBound(Resolution resolution, DartType type) { |
| 1692 Resolution resolution, | |
| 1693 DartType type) { | |
| 1694 DartType originalType = type; | 1662 DartType originalType = type; |
| 1695 while (type.isTypeVariable) { | 1663 while (type.isTypeVariable) { |
| 1696 TypeVariableType variable = type; | 1664 TypeVariableType variable = type; |
| 1697 type = variable.element.bound; | 1665 type = variable.element.bound; |
| 1698 if (type == originalType) { | 1666 if (type == originalType) { |
| 1699 type = resolution.coreTypes.objectType; | 1667 type = resolution.coreTypes.objectType; |
| 1700 } | 1668 } |
| 1701 } | 1669 } |
| 1702 if (type.isMalformed) { | 1670 if (type.isMalformed) { |
| 1703 return const DynamicType(); | 1671 return const DynamicType(); |
| (...skipping 23 matching lines...) Expand all Loading... |
| 1727 /// interfaceType(Baz) = interfaceType(()->dynamic) = Function | 1695 /// interfaceType(Baz) = interfaceType(()->dynamic) = Function |
| 1728 /// interfaceType(T) = interfaceType(Bar) = Bar | 1696 /// interfaceType(T) = interfaceType(Bar) = Bar |
| 1729 /// interfaceType(S) = interfaceType(T) = interfaceType(Bar) = Bar | 1697 /// interfaceType(S) = interfaceType(T) = interfaceType(Bar) = Bar |
| 1730 /// interfaceType(U) = interfaceType(Baz) | 1698 /// interfaceType(U) = interfaceType(Baz) |
| 1731 /// = intefaceType(()->dynamic) = Function | 1699 /// = intefaceType(()->dynamic) = Function |
| 1732 /// | 1700 /// |
| 1733 /// When typechecking `o.foo` the interface type of the static type of `o` is | 1701 /// When typechecking `o.foo` the interface type of the static type of `o` is |
| 1734 /// used to lookup the existence and type of `foo`. | 1702 /// used to lookup the existence and type of `foo`. |
| 1735 /// | 1703 /// |
| 1736 static InterfaceType computeInterfaceType( | 1704 static InterfaceType computeInterfaceType( |
| 1737 Resolution resolution, | 1705 Resolution resolution, DartType type) { |
| 1738 DartType type) { | |
| 1739 type = computeUnaliasedBound(resolution, type); | 1706 type = computeUnaliasedBound(resolution, type); |
| 1740 if (type.treatAsDynamic) { | 1707 if (type.treatAsDynamic) { |
| 1741 return null; | 1708 return null; |
| 1742 } | 1709 } |
| 1743 if (type.isFunctionType) { | 1710 if (type.isFunctionType) { |
| 1744 type = resolution.coreTypes.functionType; | 1711 type = resolution.coreTypes.functionType; |
| 1745 } | 1712 } |
| 1746 assert(invariant(NO_LOCATION_SPANNABLE, type.isInterfaceType, | 1713 assert(invariant(NO_LOCATION_SPANNABLE, type.isInterfaceType, |
| 1747 message: "unexpected type kind ${type.kind}.")); | 1714 message: "unexpected type kind ${type.kind}.")); |
| 1748 return type; | 1715 return type; |
| (...skipping 27 matching lines...) Expand all Loading... |
| 1776 final Types types; | 1743 final Types types; |
| 1777 Map<TypeVariableType, DartType> constraintMap; | 1744 Map<TypeVariableType, DartType> constraintMap; |
| 1778 | 1745 |
| 1779 MoreSpecificSubtypeVisitor(this.types); | 1746 MoreSpecificSubtypeVisitor(this.types); |
| 1780 | 1747 |
| 1781 /// Compute an instance of [element] which is more specific than [supertype]. | 1748 /// Compute an instance of [element] which is more specific than [supertype]. |
| 1782 /// If no instance is found, `null` is returned. | 1749 /// If no instance is found, `null` is returned. |
| 1783 /// | 1750 /// |
| 1784 /// Note that this computation is a heuristic. It does not find a suggestion | 1751 /// Note that this computation is a heuristic. It does not find a suggestion |
| 1785 /// in all possible cases. | 1752 /// in all possible cases. |
| 1786 InterfaceType computeMoreSpecific(ClassElement element, | 1753 InterfaceType computeMoreSpecific( |
| 1787 InterfaceType supertype) { | 1754 ClassElement element, InterfaceType supertype) { |
| 1788 InterfaceType supertypeInstance = | 1755 InterfaceType supertypeInstance = |
| 1789 element.thisType.asInstanceOf(supertype.element); | 1756 element.thisType.asInstanceOf(supertype.element); |
| 1790 if (supertypeInstance == null) return null; | 1757 if (supertypeInstance == null) return null; |
| 1791 | 1758 |
| 1792 constraintMap = new Map<TypeVariableType, DartType>(); | 1759 constraintMap = new Map<TypeVariableType, DartType>(); |
| 1793 element.typeVariables.forEach((TypeVariableType typeVariable) { | 1760 element.typeVariables.forEach((TypeVariableType typeVariable) { |
| 1794 constraintMap[typeVariable] = const DynamicType(); | 1761 constraintMap[typeVariable] = const DynamicType(); |
| 1795 }); | 1762 }); |
| 1796 if (supertypeInstance.accept(this, supertype)) { | 1763 if (supertypeInstance.accept(this, supertype)) { |
| 1797 List<DartType> variables = element.typeVariables; | 1764 List<DartType> variables = element.typeVariables; |
| (...skipping 10 matching lines...) Expand all Loading... |
| 1808 | 1775 |
| 1809 bool visitTypes(List<DartType> a, List<DartType> b) { | 1776 bool visitTypes(List<DartType> a, List<DartType> b) { |
| 1810 int prefixLength = min(a.length, b.length); | 1777 int prefixLength = min(a.length, b.length); |
| 1811 for (int index = 0; index < prefixLength; index++) { | 1778 for (int index = 0; index < prefixLength; index++) { |
| 1812 if (!a[index].accept(this, b[index])) return false; | 1779 if (!a[index].accept(this, b[index])) return false; |
| 1813 } | 1780 } |
| 1814 return prefixLength == a.length && a.length == b.length; | 1781 return prefixLength == a.length && a.length == b.length; |
| 1815 } | 1782 } |
| 1816 | 1783 |
| 1817 bool visitTypeVariableType(TypeVariableType type, DartType argument) { | 1784 bool visitTypeVariableType(TypeVariableType type, DartType argument) { |
| 1818 DartType constraint = | 1785 DartType constraint = types.getMostSpecific(constraintMap[type], argument); |
| 1819 types.getMostSpecific(constraintMap[type], argument); | |
| 1820 constraintMap[type] = constraint; | 1786 constraintMap[type] = constraint; |
| 1821 return constraint != null; | 1787 return constraint != null; |
| 1822 } | 1788 } |
| 1823 | 1789 |
| 1824 bool visitFunctionType(FunctionType type, DartType argument) { | 1790 bool visitFunctionType(FunctionType type, DartType argument) { |
| 1825 if (argument is FunctionType) { | 1791 if (argument is FunctionType) { |
| 1826 if (type.parameterTypes.length != | 1792 if (type.parameterTypes.length != argument.parameterTypes.length) { |
| 1827 argument.parameterTypes.length) { | |
| 1828 return false; | 1793 return false; |
| 1829 } | 1794 } |
| 1830 if (type.optionalParameterTypes.length != | 1795 if (type.optionalParameterTypes.length != |
| 1831 argument.optionalParameterTypes.length) { | 1796 argument.optionalParameterTypes.length) { |
| 1832 return false; | 1797 return false; |
| 1833 } | 1798 } |
| 1834 if (type.namedParameters != argument.namedParameters) { | 1799 if (type.namedParameters != argument.namedParameters) { |
| 1835 return false; | 1800 return false; |
| 1836 } | 1801 } |
| 1837 | 1802 |
| 1838 if (!type.returnType.accept(this, argument.returnType)) return false; | 1803 if (!type.returnType.accept(this, argument.returnType)) return false; |
| 1839 if (visitTypes(type.parameterTypes, argument.parameterTypes)) { | 1804 if (visitTypes(type.parameterTypes, argument.parameterTypes)) { |
| 1840 return false; | 1805 return false; |
| 1841 } | 1806 } |
| 1842 if (visitTypes(type.optionalParameterTypes, | 1807 if (visitTypes( |
| 1843 argument.optionalParameterTypes)) { | 1808 type.optionalParameterTypes, argument.optionalParameterTypes)) { |
| 1844 return false; | 1809 return false; |
| 1845 } | 1810 } |
| 1846 return visitTypes(type.namedParameterTypes, argument.namedParameterTypes); | 1811 return visitTypes(type.namedParameterTypes, argument.namedParameterTypes); |
| 1847 } | 1812 } |
| 1848 return false; | 1813 return false; |
| 1849 } | 1814 } |
| 1850 | 1815 |
| 1851 bool visitGenericType(GenericType type, DartType argument) { | 1816 bool visitGenericType(GenericType type, DartType argument) { |
| 1852 if (argument is GenericType) { | 1817 if (argument is GenericType) { |
| 1853 if (type.element != argument.element) return false; | 1818 if (type.element != argument.element) return false; |
| (...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1957 sb.write(', '); | 1922 sb.write(', '); |
| 1958 } | 1923 } |
| 1959 namedParameterTypes[index].accept(this, namedParameters[index]); | 1924 namedParameterTypes[index].accept(this, namedParameters[index]); |
| 1960 needsComma = true; | 1925 needsComma = true; |
| 1961 } | 1926 } |
| 1962 sb.write('}'); | 1927 sb.write('}'); |
| 1963 } | 1928 } |
| 1964 sb.write(')'); | 1929 sb.write(')'); |
| 1965 } | 1930 } |
| 1966 } | 1931 } |
| 1967 | |
| OLD | NEW |