Chromium Code Reviews| Index: sdk/lib/_internal/compiler/implementation/elements/elements.dart | 
| diff --git a/sdk/lib/_internal/compiler/implementation/elements/elements.dart b/sdk/lib/_internal/compiler/implementation/elements/elements.dart | 
| index b521f1b1641f1725c6f7ef13ab99f1c4d089f6bf..44112048363739ad1362a00875ddf5e40cb3c253 100644 | 
| --- a/sdk/lib/_internal/compiler/implementation/elements/elements.dart | 
| +++ b/sdk/lib/_internal/compiler/implementation/elements/elements.dart | 
| @@ -838,6 +838,19 @@ class PrefixElement extends Element { | 
| class TypedefElement extends Element implements TypeDeclarationElement { | 
| Typedef cachedNode; | 
| TypedefType cachedType; | 
| + | 
| + /** | 
| + * Canonicalize raw version of [cachedType]. | 
| + * | 
| + * See [ClassElement.rawType] for motivation. | 
| + * | 
| + * The [rawType] is computed together with [cachedType] in [computeType]. | 
| + */ | 
| + TypedefType rawType; | 
| + | 
| + /** | 
| + * The type annotation which defines this typedef. | 
| + */ | 
| DartType alias; | 
| bool isResolved = false; | 
| @@ -862,6 +875,16 @@ class TypedefElement extends Element implements TypeDeclarationElement { | 
| Link<DartType> parameters = | 
| TypeDeclarationElement.createTypeVariables(this, node.typeParameters); | 
| cachedType = new TypedefType(this, parameters); | 
| + if (parameters.isEmpty) { | 
| + rawType = cachedType; | 
| + } else { | 
| + var dynamicParameters = const Link<DartType>(); | 
| + parameters.forEach((_) { | 
| + dynamicParameters = | 
| + dynamicParameters.prepend(compiler.types.dynamicType); | 
| + }); | 
| + rawType = new TypedefType(this, dynamicParameters); | 
| + } | 
| compiler.resolveTypedef(this); | 
| return cachedType; | 
| } | 
| @@ -1383,7 +1406,36 @@ abstract class TypeDeclarationElement implements Element { | 
| abstract class ClassElement extends ScopeContainerElement | 
| implements TypeDeclarationElement { | 
| final int id; | 
| - InterfaceType type; | 
| + /** | 
| + * The type of [:this:] for this class declaration. | 
| + * | 
| + * The type of [:this:] is the interface type based on this element in which | 
| + * the type arguments are the declared type variables. For instance, | 
| + * [:List<E>:] for [:List:] and [:Map<K,V>:] for [:Map:]. | 
| + * | 
| + * This type is computed in [computeType]. | 
| + */ | 
| + InterfaceType thisType; | 
| + | 
| + /** | 
| + * The raw type for this class declaration. | 
| + * | 
| + * The raw type is the interface type base on this element in which the type | 
| + * arguments are all [dynamic]. For instance [:List<dynamic>:] for [:List:] | 
| + * and [:Map<dynamic,dynamic>:] for [:Map:]. For non-generic classes [rawType] | 
| + * is the same as [thisType]. | 
| + * | 
| + * The [rawType] field is a canonicalization of the raw type and should be | 
| + * used to distinguish explicit and implicit uses of the [dynamic] | 
| + * type arguments. For instance should [:List:] be the [rawType] of the | 
| + * [:List:] class element whereas [:List<dynamic>:] should be its own | 
| + * instantiation of [InterfaceType] with [:dynamic:] as type argument. Using | 
| + * this distinction, we can print the raw type with type arguments only when | 
| + * the input source has used explicit type arguments. | 
| + * | 
| + * This type is computed together with [thisType] in [computeType]. | 
| 
 
ahe
2012/11/29 10:09:08
Awesome comments.
 
 | 
| + */ | 
| + InterfaceType rawType; | 
| DartType supertype; | 
| DartType defaultClass; | 
| Link<DartType> interfaces; | 
| @@ -1409,18 +1461,29 @@ abstract class ClassElement extends ScopeContainerElement | 
| ClassNode parseNode(Compiler compiler); | 
| InterfaceType computeType(compiler) { | 
| - if (type == null) { | 
| + if (thisType == null) { | 
| if (origin == null) { | 
| ClassNode node = parseNode(compiler); | 
| Link<DartType> parameters = | 
| TypeDeclarationElement.createTypeVariables(this, | 
| node.typeParameters); | 
| - type = new InterfaceType(this, parameters); | 
| + thisType = new InterfaceType(this, parameters); | 
| + if (parameters.isEmpty) { | 
| + rawType = thisType; | 
| + } else { | 
| + var dynamicParameters = const Link<DartType>(); | 
| + parameters.forEach((_) { | 
| + dynamicParameters = | 
| + dynamicParameters.prepend(compiler.types.dynamicType); | 
| + }); | 
| 
 
ahe
2012/11/29 10:09:08
Code duplication detected. This loop can be shared
 
 | 
| + rawType = new InterfaceType(this, dynamicParameters); | 
| + } | 
| } else { | 
| - type = origin.computeType(compiler); | 
| + thisType = origin.computeType(compiler); | 
| + rawType = origin.rawType; | 
| } | 
| } | 
| - return type; | 
| + return thisType; | 
| } | 
| bool get isPatched => patch != null; | 
| @@ -1435,7 +1498,7 @@ abstract class ClassElement extends ScopeContainerElement | 
| bool isObject(Compiler compiler) => | 
| identical(declaration, compiler.objectClass); | 
| - Link<DartType> get typeVariables => type.typeArguments; | 
| + Link<DartType> get typeVariables => thisType.typeArguments; | 
| ClassElement ensureResolved(Compiler compiler) { | 
| if (resolutionState == STATE_NOT_STARTED) { | 
| @@ -1729,10 +1792,6 @@ abstract class ClassElement extends ScopeContainerElement | 
| Scope buildScope() => new ClassScope(enclosingElement.buildScope(), this); | 
| - Link<DartType> get allSupertypesAndSelf { | 
| - return allSupertypes.prepend(new InterfaceType(this)); | 
| - } | 
| - | 
| String toString() { | 
| if (origin != null) { | 
| return 'patch ${super.toString()}'; |