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

Side by Side Diff: lib/type_algebra.dart

Issue 2465893002: Add strong mode type checking pass. (Closed)
Patch Set: Merge with master and remove visitBlockExpression Created 4 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « lib/ast.dart ('k') | lib/type_checker.dart » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 101 matching lines...) Expand 10 before | Expand all | Expand 10 after
112 Supertype substituteSuper(Supertype type) { 112 Supertype substituteSuper(Supertype type) {
113 return substitution.substituteSupertype(type); 113 return substitution.substituteSupertype(type);
114 } 114 }
115 } 115 }
116 116
117 // ------------------------------------------------------------------------ 117 // ------------------------------------------------------------------------
118 // IMPLEMENTATION 118 // IMPLEMENTATION
119 // ------------------------------------------------------------------------ 119 // ------------------------------------------------------------------------
120 120
121 abstract class Substitution { 121 abstract class Substitution {
122 const Substitution();
123
124 static const Substitution empty = _NullSubstitution.instance;
125
122 /// Substitutes each parameter to the type it maps to in [map]. 126 /// Substitutes each parameter to the type it maps to in [map].
123 static Substitution fromMap(Map<TypeParameter, DartType> map) { 127 static Substitution fromMap(Map<TypeParameter, DartType> map) {
124 if (map.isEmpty) return _NullSubstitution.instance; 128 if (map.isEmpty) return _NullSubstitution.instance;
125 return new _MapSubstitution(map, map); 129 return new _MapSubstitution(map, map);
126 } 130 }
127 131
128 /// Substitutes all occurrences of the given type parameters with the 132 /// Substitutes all occurrences of the given type parameters with the
129 /// corresponding upper or lower bound, depending on the variance of the 133 /// corresponding upper or lower bound, depending on the variance of the
130 /// context where it occurs. 134 /// context where it occurs.
131 /// 135 ///
(...skipping 30 matching lines...) Expand all
162 static Substitution fromPairs( 166 static Substitution fromPairs(
163 List<TypeParameter> parameters, List<DartType> types) { 167 List<TypeParameter> parameters, List<DartType> types) {
164 // TODO(asgerf): Investigate if it is more efficient to implement 168 // TODO(asgerf): Investigate if it is more efficient to implement
165 // substitution based on parallel pairwise lists instead of Maps. 169 // substitution based on parallel pairwise lists instead of Maps.
166 assert(parameters.length == types.length); 170 assert(parameters.length == types.length);
167 if (parameters.isEmpty) return _NullSubstitution.instance; 171 if (parameters.isEmpty) return _NullSubstitution.instance;
168 return fromMap( 172 return fromMap(
169 new Map<TypeParameter, DartType>.fromIterables(parameters, types)); 173 new Map<TypeParameter, DartType>.fromIterables(parameters, types));
170 } 174 }
171 175
176 /// Substitutes the type parameters on the class with bottom or dynamic,
177 /// depending on the covariance of its use.
178 static Substitution bottomForClass(Class class_) {
179 if (class_.typeParameters.isEmpty) return _NullSubstitution.instance;
180 return new _ClassBottomSubstitution(class_);
181 }
182
183 /// Substitutes both variables from [first] and [second], favoring those from
184 /// [first] if they overlap.
185 ///
186 /// Neither substitution is applied to the results of the other, so this does
187 /// *not* correspond to a sequence of two subsitutions. For example, combining
188 /// `{T -> List<G>}` with `{G -> String}` does not correspond to
189 /// `{T -> List<String>}` because the result from substituting `T` is not
190 /// searched for occurences of `G`.
191 static Substitution combine(Substitution first, Substitution second) {
192 if (first == _NullSubstitution.instance) return second;
193 if (second == _NullSubstitution.instance) return first;
194 return new _CombinedSubstitution(first, second);
195 }
196
172 DartType getSubstitute(TypeParameter parameter, bool upperBound); 197 DartType getSubstitute(TypeParameter parameter, bool upperBound);
173 198
174 DartType substituteType(DartType node) { 199 DartType substituteType(DartType node, {bool contravariant: false}) {
175 return new _TopSubstitutor(this).visit(node); 200 return new _TopSubstitutor(this, contravariant).visit(node);
176 } 201 }
177 202
178 Supertype substituteSupertype(Supertype node) { 203 Supertype substituteSupertype(Supertype node) {
179 return new _TopSubstitutor(this).visitSupertype(node); 204 return new _TopSubstitutor(this, false).visitSupertype(node);
180 } 205 }
181 } 206 }
182 207
183 class _NullSubstitution extends Substitution { 208 class _NullSubstitution extends Substitution {
184 static final _NullSubstitution instance = new _NullSubstitution(); 209 static const _NullSubstitution instance = const _NullSubstitution();
210
211 const _NullSubstitution();
185 212
186 DartType getSubstitute(TypeParameter parameter, bool upperBound) { 213 DartType getSubstitute(TypeParameter parameter, bool upperBound) {
187 return new TypeParameterType(parameter); 214 return new TypeParameterType(parameter);
188 } 215 }
189 216
190 @override 217 @override
191 DartType substituteType(DartType node) => node; 218 DartType substituteType(DartType node, {bool contravariant: false}) => node;
192 219
193 @override 220 @override
194 Supertype substituteSupertype(Supertype node) => node; 221 Supertype substituteSupertype(Supertype node) => node;
195 } 222 }
196 223
197 class _MapSubstitution extends Substitution { 224 class _MapSubstitution extends Substitution {
198 final Map<TypeParameter, DartType> upper; 225 final Map<TypeParameter, DartType> upper;
199 final Map<TypeParameter, DartType> lower; 226 final Map<TypeParameter, DartType> lower;
200 227
201 _MapSubstitution(this.upper, this.lower); 228 _MapSubstitution(this.upper, this.lower);
202 229
203 DartType getSubstitute(TypeParameter parameter, bool upperBound) { 230 DartType getSubstitute(TypeParameter parameter, bool upperBound) {
204 return upperBound ? upper[parameter] : lower[parameter]; 231 return upperBound ? upper[parameter] : lower[parameter];
205 } 232 }
206 } 233 }
207 234
208 class _TopSubstitutor extends _TypeSubstitutor { 235 class _TopSubstitutor extends _TypeSubstitutor {
209 final Substitution substitution; 236 final Substitution substitution;
210 237
211 _TopSubstitutor(this.substitution) : super(null); 238 _TopSubstitutor(this.substitution, bool contravariant) : super(null) {
239 if (contravariant) {
240 invertVariance();
241 }
242 }
212 243
213 DartType lookup(TypeParameter parameter, bool upperBound) { 244 DartType lookup(TypeParameter parameter, bool upperBound) {
214 return substitution.getSubstitute(parameter, upperBound); 245 return substitution.getSubstitute(parameter, upperBound);
215 } 246 }
216 247
217 TypeParameter freshTypeParameter(TypeParameter node) { 248 TypeParameter freshTypeParameter(TypeParameter node) {
218 throw 'Create a fresh environment first'; 249 throw 'Create a fresh environment first';
219 } 250 }
220 } 251 }
221 252
253 class _ClassBottomSubstitution extends Substitution {
254 final Class class_;
255
256 _ClassBottomSubstitution(this.class_);
257
258 DartType getSubstitute(TypeParameter parameter, bool upperBound) {
259 if (parameter.parent == class_) {
260 return upperBound ? const BottomType() : const DynamicType();
261 }
262 return null;
263 }
264 }
265
266 class _CombinedSubstitution extends Substitution {
267 final Substitution first, second;
268
269 _CombinedSubstitution(this.first, this.second);
270
271 DartType getSubstitute(TypeParameter parameter, bool upperBound) {
272 return first.getSubstitute(parameter, upperBound) ??
273 second.getSubstitute(parameter, upperBound);
274 }
275 }
276
222 class _InnerTypeSubstitutor extends _TypeSubstitutor { 277 class _InnerTypeSubstitutor extends _TypeSubstitutor {
223 final Map<TypeParameter, DartType> substitution = <TypeParameter, DartType>{}; 278 final Map<TypeParameter, DartType> substitution = <TypeParameter, DartType>{};
224 279
225 _InnerTypeSubstitutor(_TypeSubstitutor outer) : super(outer); 280 _InnerTypeSubstitutor(_TypeSubstitutor outer) : super(outer);
226 281
227 DartType lookup(TypeParameter parameter, bool upperBound) { 282 DartType lookup(TypeParameter parameter, bool upperBound) {
228 return substitution[parameter]; 283 return substitution[parameter];
229 } 284 }
230 285
231 TypeParameter freshTypeParameter(TypeParameter node) { 286 TypeParameter freshTypeParameter(TypeParameter node) {
(...skipping 344 matching lines...) Expand 10 before | Expand all | Expand 10 after
576 } 631 }
577 632
578 Map<dynamic/*=K*/, dynamic/*=W*/ > _mapValues/*<K,V,W>*/( 633 Map<dynamic/*=K*/, dynamic/*=W*/ > _mapValues/*<K,V,W>*/(
579 Map<dynamic/*=K*/, dynamic/*=V*/ > map, dynamic/*=W*/ fn(dynamic/*=V*/)) { 634 Map<dynamic/*=K*/, dynamic/*=V*/ > map, dynamic/*=W*/ fn(dynamic/*=V*/)) {
580 Map<dynamic/*=K*/, dynamic/*=W*/ > result = {}; 635 Map<dynamic/*=K*/, dynamic/*=W*/ > result = {};
581 map.forEach((key, value) { 636 map.forEach((key, value) {
582 result[key] = fn(value); 637 result[key] = fn(value);
583 }); 638 });
584 return result; 639 return result;
585 } 640 }
OLDNEW
« no previous file with comments | « lib/ast.dart ('k') | lib/type_checker.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698