| OLD | NEW |
| 1 // Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2016, 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 library kernel.type_algebra; | 4 library kernel.type_algebra; |
| 5 | 5 |
| 6 import 'ast.dart'; | 6 import 'ast.dart'; |
| 7 | 7 |
| 8 /// Returns a type where all occurrences of the given type parameters have been | 8 /// Returns a type where all occurrences of the given type parameters have been |
| 9 /// replaced with the corresponding types. | 9 /// replaced with the corresponding types. |
| 10 /// | 10 /// |
| (...skipping 307 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 318 } | 318 } |
| 319 | 319 |
| 320 Supertype visitSupertype(Supertype node) { | 320 Supertype visitSupertype(Supertype node) { |
| 321 if (node.typeArguments.isEmpty) return node; | 321 if (node.typeArguments.isEmpty) return node; |
| 322 int before = useCounter; | 322 int before = useCounter; |
| 323 var typeArguments = node.typeArguments.map(visit).toList(); | 323 var typeArguments = node.typeArguments.map(visit).toList(); |
| 324 if (useCounter == before) return node; | 324 if (useCounter == before) return node; |
| 325 return new Supertype(node.classNode, typeArguments); | 325 return new Supertype(node.classNode, typeArguments); |
| 326 } | 326 } |
| 327 | 327 |
| 328 NamedType visitNamedType(NamedType node) { |
| 329 int before = useCounter; |
| 330 var type = visit(node.type); |
| 331 if (useCounter == before) return node; |
| 332 return new NamedType(node.name, type); |
| 333 } |
| 334 |
| 328 DartType visit(DartType node) => node.accept(this); | 335 DartType visit(DartType node) => node.accept(this); |
| 329 | 336 |
| 330 DartType visitInvalidType(InvalidType node) => node; | 337 DartType visitInvalidType(InvalidType node) => node; |
| 331 DartType visitDynamicType(DynamicType node) => node; | 338 DartType visitDynamicType(DynamicType node) => node; |
| 332 DartType visitVoidType(VoidType node) => node; | 339 DartType visitVoidType(VoidType node) => node; |
| 333 DartType visitBottomType(BottomType node) => node; | 340 DartType visitBottomType(BottomType node) => node; |
| 334 | 341 |
| 335 DartType visitInterfaceType(InterfaceType node) { | 342 DartType visitInterfaceType(InterfaceType node) { |
| 336 if (node.typeArguments.isEmpty) return node; | 343 if (node.typeArguments.isEmpty) return node; |
| 337 int before = useCounter; | 344 int before = useCounter; |
| (...skipping 23 matching lines...) Expand all Loading... |
| 361 // environment has been used inside the function. | 368 // environment has been used inside the function. |
| 362 var inner = node.typeParameters.isEmpty ? this : newInnerEnvironment(); | 369 var inner = node.typeParameters.isEmpty ? this : newInnerEnvironment(); |
| 363 int before = this.useCounter; | 370 int before = this.useCounter; |
| 364 // Invert the variance when translating parameters. | 371 // Invert the variance when translating parameters. |
| 365 inner.invertVariance(); | 372 inner.invertVariance(); |
| 366 var typeParameters = inner.freshTypeParameters(node.typeParameters); | 373 var typeParameters = inner.freshTypeParameters(node.typeParameters); |
| 367 var positionalParameters = node.positionalParameters.isEmpty | 374 var positionalParameters = node.positionalParameters.isEmpty |
| 368 ? const <DartType>[] | 375 ? const <DartType>[] |
| 369 : node.positionalParameters.map(inner.visit).toList(); | 376 : node.positionalParameters.map(inner.visit).toList(); |
| 370 var namedParameters = node.namedParameters.isEmpty | 377 var namedParameters = node.namedParameters.isEmpty |
| 371 ? const <String, DartType>{} | 378 ? const <NamedType>[] |
| 372 : _mapValues(node.namedParameters, inner.visit); | 379 : node.namedParameters.map(inner.visitNamedType).toList(); |
| 373 inner.invertVariance(); | 380 inner.invertVariance(); |
| 374 var returnType = inner.visit(node.returnType); | 381 var returnType = inner.visit(node.returnType); |
| 375 if (this.useCounter == before) return node; | 382 if (this.useCounter == before) return node; |
| 376 return new FunctionType(positionalParameters, returnType, | 383 return new FunctionType(positionalParameters, returnType, |
| 377 namedParameters: namedParameters, | 384 namedParameters: namedParameters, |
| 378 typeParameters: typeParameters, | 385 typeParameters: typeParameters, |
| 379 requiredParameterCount: node.requiredParameterCount); | 386 requiredParameterCount: node.requiredParameterCount); |
| 380 } | 387 } |
| 381 | 388 |
| 382 void bumpCountersUntil(_TypeSubstitutor target) { | 389 void bumpCountersUntil(_TypeSubstitutor target) { |
| (...skipping 162 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 545 for (int i = 0; i < type1.typeParameters.length; ++i) { | 552 for (int i = 0; i < type1.typeParameters.length; ++i) { |
| 546 var left = substitute(type1.typeParameters[i].bound, leftInstance); | 553 var left = substitute(type1.typeParameters[i].bound, leftInstance); |
| 547 var right = substitute(type2.typeParameters[i].bound, rightInstance); | 554 var right = substitute(type2.typeParameters[i].bound, rightInstance); |
| 548 if (!_unify(left, right)) return false; | 555 if (!_unify(left, right)) return false; |
| 549 } | 556 } |
| 550 for (int i = 0; i < type1.positionalParameters.length; ++i) { | 557 for (int i = 0; i < type1.positionalParameters.length; ++i) { |
| 551 var left = substitute(type1.positionalParameters[i], leftInstance); | 558 var left = substitute(type1.positionalParameters[i], leftInstance); |
| 552 var right = substitute(type2.positionalParameters[i], rightInstance); | 559 var right = substitute(type2.positionalParameters[i], rightInstance); |
| 553 if (!_unify(left, right)) return false; | 560 if (!_unify(left, right)) return false; |
| 554 } | 561 } |
| 555 for (var name in type1.namedParameters.keys) { | 562 for (int i = 0; i < type1.namedParameters.length; ++i) { |
| 556 var right = type2.namedParameters[name]; | 563 if (type1.namedParameters[i].name != type2.namedParameters[i].name) { |
| 557 if (right == null) return _fail(); | 564 return false; |
| 558 right = substitute(right, rightInstance); | 565 } |
| 559 var left = substitute(type1.namedParameters[name], leftInstance); | 566 var left = substitute(type1.namedParameters[i].type, leftInstance); |
| 567 var right = substitute(type2.namedParameters[i].type, rightInstance); |
| 560 if (!_unify(left, right)) return false; | 568 if (!_unify(left, right)) return false; |
| 561 } | 569 } |
| 562 var leftReturn = substitute(type1.returnType, leftInstance); | 570 var leftReturn = substitute(type1.returnType, leftInstance); |
| 563 var rightReturn = substitute(type2.returnType, rightInstance); | 571 var rightReturn = substitute(type2.returnType, rightInstance); |
| 564 if (!_unify(leftReturn, rightReturn)) return false; | 572 if (!_unify(leftReturn, rightReturn)) return false; |
| 565 return true; | 573 return true; |
| 566 } | 574 } |
| 567 if (type1 is TypeParameterType && | 575 if (type1 is TypeParameterType && |
| 568 type2 is TypeParameterType && | 576 type2 is TypeParameterType && |
| 569 type1.parameter == type2.parameter) { | 577 type1.parameter == type2.parameter) { |
| (...skipping 28 matching lines...) Expand all Loading... |
| 598 } | 606 } |
| 599 } | 607 } |
| 600 | 608 |
| 601 class _OccurrenceVisitor extends DartTypeVisitor<bool> { | 609 class _OccurrenceVisitor extends DartTypeVisitor<bool> { |
| 602 final Set<TypeParameter> variables; | 610 final Set<TypeParameter> variables; |
| 603 | 611 |
| 604 _OccurrenceVisitor(this.variables); | 612 _OccurrenceVisitor(this.variables); |
| 605 | 613 |
| 606 bool visit(DartType node) => node.accept(this); | 614 bool visit(DartType node) => node.accept(this); |
| 607 | 615 |
| 616 bool visitNamedType(NamedType node) { |
| 617 return visit(node.type); |
| 618 } |
| 619 |
| 608 bool visitInvalidType(InvalidType node) => false; | 620 bool visitInvalidType(InvalidType node) => false; |
| 609 bool visitDynamicType(DynamicType node) => false; | 621 bool visitDynamicType(DynamicType node) => false; |
| 610 bool visitVoidType(VoidType node) => false; | 622 bool visitVoidType(VoidType node) => false; |
| 611 | 623 |
| 612 bool visitInterfaceType(InterfaceType node) { | 624 bool visitInterfaceType(InterfaceType node) { |
| 613 return node.typeArguments.any(visit); | 625 return node.typeArguments.any(visit); |
| 614 } | 626 } |
| 615 | 627 |
| 616 bool visitFunctionType(FunctionType node) { | 628 bool visitFunctionType(FunctionType node) { |
| 617 return node.typeParameters.any(handleTypeParameter) || | 629 return node.typeParameters.any(handleTypeParameter) || |
| 618 node.positionalParameters.any(visit) || | 630 node.positionalParameters.any(visit) || |
| 619 node.namedParameters.values.any(visit) || | 631 node.namedParameters.any(visitNamedType) || |
| 620 visit(node.returnType); | 632 visit(node.returnType); |
| 621 } | 633 } |
| 622 | 634 |
| 623 bool visitTypeParameterType(TypeParameterType node) { | 635 bool visitTypeParameterType(TypeParameterType node) { |
| 624 return variables == null || variables.contains(node.parameter); | 636 return variables == null || variables.contains(node.parameter); |
| 625 } | 637 } |
| 626 | 638 |
| 627 bool handleTypeParameter(TypeParameter node) { | 639 bool handleTypeParameter(TypeParameter node) { |
| 628 assert(!variables.contains(node)); | 640 assert(!variables.contains(node)); |
| 629 return node.bound.accept(this); | 641 return node.bound.accept(this); |
| 630 } | 642 } |
| 631 } | 643 } |
| 632 | 644 |
| 633 Map<dynamic/*=K*/, dynamic/*=W*/ > _mapValues/*<K,V,W>*/( | 645 Map<dynamic/*=K*/, dynamic/*=W*/ > _mapValues/*<K,V,W>*/( |
| 634 Map<dynamic/*=K*/, dynamic/*=V*/ > map, dynamic/*=W*/ fn(dynamic/*=V*/)) { | 646 Map<dynamic/*=K*/, dynamic/*=V*/ > map, dynamic/*=W*/ fn(dynamic/*=V*/)) { |
| 635 Map<dynamic/*=K*/, dynamic/*=W*/ > result = {}; | 647 Map<dynamic/*=K*/, dynamic/*=W*/ > result = {}; |
| 636 map.forEach((key, value) { | 648 map.forEach((key, value) { |
| 637 result[key] = fn(value); | 649 result[key] = fn(value); |
| 638 }); | 650 }); |
| 639 return result; | 651 return result; |
| 640 } | 652 } |
| OLD | NEW |