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

Side by Side Diff: sdk/lib/_internal/compiler/implementation/typechecker.dart

Issue 11413219: Canonicalize raw type (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Updated cf. comment Created 8 years 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 | Annotate | Revision Log
OLDNEW
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 part of dart2js; 5 part of dart2js;
6 6
7 class TypeCheckerTask extends CompilerTask { 7 class TypeCheckerTask extends CompilerTask {
8 TypeCheckerTask(Compiler compiler) : super(compiler); 8 TypeCheckerTask(Compiler compiler) : super(compiler);
9 String get name => "Type checker"; 9 String get name => "Type checker";
10 10
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after
80 * 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.
81 * 81 *
82 * 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
83 * function type [: (B) -> A :] and the unaliased type of 83 * function type [: (B) -> A :] and the unaliased type of
84 * [: Func<int,String> :] is the function type [: (String) -> int :]. 84 * [: Func<int,String> :] is the function type [: (String) -> int :].
85 */ 85 */
86 DartType unalias(Compiler compiler); 86 DartType unalias(Compiler compiler);
87 87
88 bool operator ==(other); 88 bool operator ==(other);
89 89
90 /**
91 * Is [: true :] if this type has no explict type arguments.
92 */
93 bool get isRaw => true;
94
90 DartType asRaw() => this; 95 DartType asRaw() => this;
91 } 96 }
92 97
93 /** 98 /**
94 * Represents a type variable, that is the type parameters of a class type. 99 * Represents a type variable, that is the type parameters of a class type.
95 * 100 *
96 * For example, in [: class Array<E> { ... } :], E is a type variable. 101 * For example, in [: class Array<E> { ... } :], E is a type variable.
97 * 102 *
98 * Each class should have its own unique type variables, one for each type 103 * Each class should have its own unique type variables, one for each type
99 * parameter. A class with type parameters is said to be parameterized or 104 * parameter. A class with type parameters is said to be parameterized or
(...skipping 157 matching lines...) Expand 10 before | Expand all | Expand 10 after
257 DartType unalias(Compiler compiler) => this; 262 DartType unalias(Compiler compiler) => this;
258 263
259 int get hashCode => 1733; 264 int get hashCode => 1733;
260 265
261 bool operator ==(other) => other is MalformedType; 266 bool operator ==(other) => other is MalformedType;
262 267
263 String toString() => name.slowToString(); 268 String toString() => name.slowToString();
264 } 269 }
265 270
266 class InterfaceType extends DartType { 271 class InterfaceType extends DartType {
267 final Element element; 272 final ClassElement element;
268 final Link<DartType> typeArguments; 273 final Link<DartType> typeArguments;
269 274
270 InterfaceType(this.element, 275 InterfaceType(this.element,
271 [this.typeArguments = const Link<DartType>()]) { 276 [this.typeArguments = const Link<DartType>()]) {
272 assert(invariant(element, element.isDeclaration)); 277 assert(invariant(element, element.isDeclaration));
273 } 278 }
274 279
275 TypeKind get kind => TypeKind.INTERFACE; 280 TypeKind get kind => TypeKind.INTERFACE;
276 281
277 SourceString get name => element.name; 282 SourceString get name => element.name;
(...skipping 15 matching lines...) Expand all
293 return new InterfaceType(element, newTypeArguments); 298 return new InterfaceType(element, newTypeArguments);
294 } 299 }
295 return this; 300 return this;
296 } 301 }
297 302
298 DartType unalias(Compiler compiler) => this; 303 DartType unalias(Compiler compiler) => this;
299 304
300 String toString() { 305 String toString() {
301 StringBuffer sb = new StringBuffer(); 306 StringBuffer sb = new StringBuffer();
302 sb.add(name.slowToString()); 307 sb.add(name.slowToString());
303 if (!typeArguments.isEmpty) { 308 if (!isRaw) {
304 sb.add('<'); 309 sb.add('<');
305 typeArguments.printOn(sb, ', '); 310 typeArguments.printOn(sb, ', ');
306 sb.add('>'); 311 sb.add('>');
307 } 312 }
308 return sb.toString(); 313 return sb.toString();
309 } 314 }
310 315
311 int get hashCode { 316 int get hashCode {
312 int hash = element.hashCode; 317 int hash = element.hashCode;
313 for (Link<DartType> arguments = this.typeArguments; 318 for (Link<DartType> arguments = this.typeArguments;
314 !arguments.isEmpty; 319 !arguments.isEmpty;
315 arguments = arguments.tail) { 320 arguments = arguments.tail) {
316 int argumentHash = arguments.head != null ? arguments.head.hashCode : 0; 321 int argumentHash = arguments.head != null ? arguments.head.hashCode : 0;
317 hash = 17 * hash + 3 * argumentHash; 322 hash = 17 * hash + 3 * argumentHash;
318 } 323 }
319 return hash; 324 return hash;
320 } 325 }
321 326
322 bool operator ==(other) { 327 bool operator ==(other) {
323 if (other is !InterfaceType) return false; 328 if (other is !InterfaceType) return false;
324 if (!identical(element, other.element)) return false; 329 if (!identical(element, other.element)) return false;
325 return typeArguments == other.typeArguments; 330 return typeArguments == other.typeArguments;
326 } 331 }
327 332
328 InterfaceType asRaw() { 333 bool get isRaw => typeArguments.isEmpty || identical(this, element.rawType);
329 if (typeArguments.isEmpty) return this; 334
330 return new InterfaceType(element); 335 InterfaceType asRaw() => element.rawType;
331 }
332 } 336 }
333 337
334 class FunctionType extends DartType { 338 class FunctionType extends DartType {
335 final Element element; 339 final Element element;
336 DartType returnType; 340 DartType returnType;
337 Link<DartType> parameterTypes; 341 Link<DartType> parameterTypes;
338 342
339 FunctionType(DartType this.returnType, Link<DartType> this.parameterTypes, 343 FunctionType(DartType this.returnType, Link<DartType> this.parameterTypes,
340 Element this.element) { 344 Element this.element) {
341 assert(element == null || invariant(element, element.isDeclaration)); 345 assert(element == null || invariant(element, element.isDeclaration));
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after
438 DartType unalias(Compiler compiler) { 442 DartType unalias(Compiler compiler) {
439 // TODO(ahe): This should be [ensureResolved]. 443 // TODO(ahe): This should be [ensureResolved].
440 compiler.resolveTypedef(element); 444 compiler.resolveTypedef(element);
441 // TODO(johnniwinther): Perform substitution on the unaliased type. 445 // TODO(johnniwinther): Perform substitution on the unaliased type.
442 return element.alias.unalias(compiler); 446 return element.alias.unalias(compiler);
443 } 447 }
444 448
445 String toString() { 449 String toString() {
446 StringBuffer sb = new StringBuffer(); 450 StringBuffer sb = new StringBuffer();
447 sb.add(name.slowToString()); 451 sb.add(name.slowToString());
448 if (!typeArguments.isEmpty) { 452 if (!isRaw) {
449 sb.add('<'); 453 sb.add('<');
450 typeArguments.printOn(sb, ', '); 454 typeArguments.printOn(sb, ', ');
451 sb.add('>'); 455 sb.add('>');
452 } 456 }
453 return sb.toString(); 457 return sb.toString();
454 } 458 }
455 459
456 int get hashCode => 17 * element.hashCode; 460 int get hashCode => 17 * element.hashCode;
457 461
458 bool operator ==(other) { 462 bool operator ==(other) {
459 if (other is !TypedefType) return false; 463 if (other is !TypedefType) return false;
460 if (!identical(element, other.element)) return false; 464 if (!identical(element, other.element)) return false;
461 return typeArguments == other.typeArguments; 465 return typeArguments == other.typeArguments;
462 } 466 }
467
468 bool get isRaw => typeArguments.isEmpty || identical(this, element.rawType);
469
470 TypedefType asRaw() => element.rawType;
463 } 471 }
464 472
465 /** 473 /**
466 * Special type to hold the [dynamic] type. Used for correctly returning 474 * Special type to hold the [dynamic] type. Used for correctly returning
467 * 'dynamic' on [toString]. 475 * 'dynamic' on [toString].
468 */ 476 */
469 class DynamicType extends InterfaceType { 477 class DynamicType extends InterfaceType {
470 DynamicType(ClassElement element) : super(element); 478 DynamicType(ClassElement element) : super(element);
471 479
472 String toString() => 'dynamic'; 480 String toString() => 'dynamic';
473 } 481 }
474 482
475 483
476 class Types { 484 class Types {
477 final Compiler compiler; 485 final Compiler compiler;
478 // TODO(karlklose): should we have a class Void? 486 // TODO(karlklose): should we have a class Void?
479 final VoidType voidType; 487 final VoidType voidType;
480 final InterfaceType dynamicType; 488 final DynamicType dynamicType;
481 489
482 Types(Compiler compiler, ClassElement dynamicElement) 490 Types(Compiler compiler, ClassElement dynamicElement)
483 : this.with(compiler, dynamicElement, 491 : this.with(compiler, dynamicElement,
484 new LibraryElement(new Script(null, null))); 492 new LibraryElement(new Script(null, null)));
485 493
486 Types.with(Compiler this.compiler, 494 Types.with(Compiler this.compiler,
487 ClassElement dynamicElement, 495 ClassElement dynamicElement,
488 LibraryElement library) 496 LibraryElement library)
489 : voidType = new VoidType(new VoidElement(library)), 497 : voidType = new VoidType(new VoidElement(library)),
490 dynamicType = new DynamicType(dynamicElement) { 498 dynamicType = new DynamicType(dynamicElement) {
491 dynamicElement.type = dynamicType; 499 dynamicElement.rawType = dynamicElement.thisType = dynamicType;
492 } 500 }
493 501
494 /** Returns true if t is a subtype of s */ 502 /** Returns true if t is a subtype of s */
495 bool isSubtype(DartType t, DartType s) { 503 bool isSubtype(DartType t, DartType s) {
496 if (identical(t, s) || 504 if (identical(t, s) ||
497 identical(t, dynamicType) || 505 identical(t, dynamicType) ||
498 identical(s, dynamicType) || 506 identical(s, dynamicType) ||
499 identical(s.element, compiler.objectClass) || 507 identical(s.element, compiler.objectClass) ||
500 identical(t.element, compiler.nullClass)) { 508 identical(t.element, compiler.nullClass)) {
501 return true; 509 return true;
502 } 510 }
503 t = t.unalias(compiler); 511 t = t.unalias(compiler);
504 s = s.unalias(compiler); 512 s = s.unalias(compiler);
505 513
506 if (t is VoidType) { 514 if (t is VoidType) {
507 return false; 515 return false;
508 } else if (t is MalformedType) { 516 } else if (t is MalformedType || s is MalformedType) {
517 // TODO(johnniwinther): Malformed types should be treated as dynamic and
518 // thus return true here.
509 return false; 519 return false;
510 } else if (t is InterfaceType) { 520 } else if (t is InterfaceType) {
511 if (s is !InterfaceType) return false; 521 if (s is !InterfaceType) return false;
512 ClassElement tc = t.element; 522 ClassElement tc = t.element;
513 if (identical(tc, s.element)) return true; 523 if (identical(tc, s.element)) return true;
514 for (Link<DartType> supertypes = tc.allSupertypes; 524 for (Link<DartType> supertypes = tc.allSupertypes;
515 supertypes != null && !supertypes.isEmpty; 525 supertypes != null && !supertypes.isEmpty;
516 supertypes = supertypes.tail) { 526 supertypes = supertypes.tail) {
517 DartType supertype = supertypes.head; 527 DartType supertype = supertypes.head;
518 if (identical(supertype.element, s.element)) return true; 528 if (identical(supertype.element, s.element)) return true;
(...skipping 699 matching lines...) Expand 10 before | Expand all | Expand 10 after
1218 } 1228 }
1219 1229
1220 DartType visitStringNode(StringNode node) { 1230 DartType visitStringNode(StringNode node) {
1221 compiler.unimplemented('visitNode', node: node); 1231 compiler.unimplemented('visitNode', node: node);
1222 } 1232 }
1223 1233
1224 DartType visitLibraryDependency(LibraryDependency node) { 1234 DartType visitLibraryDependency(LibraryDependency node) {
1225 compiler.unimplemented('visitNode', node: node); 1235 compiler.unimplemented('visitNode', node: node);
1226 } 1236 }
1227 } 1237 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698