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()}'; |