Chromium Code Reviews| Index: lib/type_algebra.dart |
| diff --git a/lib/type_algebra.dart b/lib/type_algebra.dart |
| index e93d870dc047dbab6aec93789c3467d468fba6d4..927d8c275110cf99ab7af84dc051596a79266953 100644 |
| --- a/lib/type_algebra.dart |
| +++ b/lib/type_algebra.dart |
| @@ -119,6 +119,10 @@ class FreshTypeParameters { |
| // ------------------------------------------------------------------------ |
| abstract class Substitution { |
| + const Substitution(); |
| + |
| + static const Substitution empty = _NullSubstitution.instance; |
| + |
| /// Substitutes each parameter to the type it maps to in [map]. |
| static Substitution fromMap(Map<TypeParameter, DartType> map) { |
| if (map.isEmpty) return _NullSubstitution.instance; |
| @@ -169,26 +173,41 @@ abstract class Substitution { |
| new Map<TypeParameter, DartType>.fromIterables(parameters, types)); |
| } |
| + /// Substitutes the type parameters on the class of [type] with the |
|
Kevin Millikin (Google)
2016/11/01 13:03:01
The comment is wrong here.
asgerf
2016/11/01 13:59:36
Thanks. Fixed it.
|
| + /// type arguments provided in [type]. |
| + static Substitution bottomForClass(Class class_) { |
| + if (class_.typeParameters.isEmpty) return _NullSubstitution.instance; |
| + return new _ClassBottomSubstitution(class_); |
| + } |
| + |
| + static Substitution combine(Substitution first, Substitution second) { |
|
Kevin Millikin (Google)
2016/11/01 13:03:01
It subtle that the implementation prefers first.
asgerf
2016/11/01 13:59:36
Added some documentation.
|
| + if (first == _NullSubstitution.instance) return second; |
| + if (second == _NullSubstitution.instance) return first; |
| + return new _CombinedSubstitution(first, second); |
| + } |
| + |
| DartType getSubstitute(TypeParameter parameter, bool upperBound); |
| - DartType substituteType(DartType node) { |
| - return new _TopSubstitutor(this).visit(node); |
| + DartType substituteType(DartType node, {bool contravariant: false}) { |
| + return new _TopSubstitutor(this, contravariant).visit(node); |
| } |
| Supertype substituteSupertype(Supertype node) { |
| - return new _TopSubstitutor(this).visitSupertype(node); |
| + return new _TopSubstitutor(this, false).visitSupertype(node); |
| } |
| } |
| class _NullSubstitution extends Substitution { |
| - static final _NullSubstitution instance = new _NullSubstitution(); |
| + static const _NullSubstitution instance = const _NullSubstitution(); |
| + |
| + const _NullSubstitution(); |
| DartType getSubstitute(TypeParameter parameter, bool upperBound) { |
| return new TypeParameterType(parameter); |
| } |
| @override |
| - DartType substituteType(DartType node) => node; |
| + DartType substituteType(DartType node, {bool contravariant: false}) => node; |
| @override |
| Supertype substituteSupertype(Supertype node) => node; |
| @@ -208,7 +227,11 @@ class _MapSubstitution extends Substitution { |
| class _TopSubstitutor extends _TypeSubstitutor { |
| final Substitution substitution; |
| - _TopSubstitutor(this.substitution) : super(null); |
| + _TopSubstitutor(this.substitution, bool contravariant) : super(null) { |
| + if (contravariant) { |
| + invertVariance(); |
| + } |
| + } |
| DartType lookup(TypeParameter parameter, bool upperBound) { |
| return substitution.getSubstitute(parameter, upperBound); |
| @@ -219,6 +242,30 @@ class _TopSubstitutor extends _TypeSubstitutor { |
| } |
| } |
| +class _ClassBottomSubstitution extends Substitution { |
| + final Class class_; |
| + |
| + _ClassBottomSubstitution(this.class_); |
| + |
| + DartType getSubstitute(TypeParameter parameter, bool upperBound) { |
| + if (parameter.parent == class_) { |
| + return upperBound ? const BottomType() : const DynamicType(); |
| + } |
| + return null; |
| + } |
| +} |
| + |
| +class _CombinedSubstitution extends Substitution { |
| + final Substitution first, second; |
| + |
| + _CombinedSubstitution(this.first, this.second); |
| + |
| + DartType getSubstitute(TypeParameter parameter, bool upperBound) { |
| + return first.getSubstitute(parameter, upperBound) ?? |
| + second.getSubstitute(parameter, upperBound); |
| + } |
| +} |
| + |
| class _InnerTypeSubstitutor extends _TypeSubstitutor { |
| final Map<TypeParameter, DartType> substitution = <TypeParameter, DartType>{}; |