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 |