Chromium Code Reviews| Index: frog/type.dart |
| diff --git a/frog/type.dart b/frog/type.dart |
| index 4d8b1377c43ceb393c590fa1665ad95680af0a43..ca8a1a2ff8d9c85bd2bfb80979cc5ed14b4b13dd 100644 |
| --- a/frog/type.dart |
| +++ b/frog/type.dart |
| @@ -41,7 +41,9 @@ class Type implements Named, Hashable { |
| Member getMember(String name) => null; |
| abstract MethodMember getConstructor(String name); |
| abstract MethodMember getFactory(Type type, String name); |
| - |
| + abstract Type getOrMakeConcreteType(List<Type> typeArgs); |
| + abstract Map<String, MethodMember> get constructors(); |
| + abstract addDirectSubtype(Type type); |
|
jimhug
2011/11/10 15:47:21
Another of those cool vs. weird things - but I'm a
|
| abstract bool get isClass(); |
| abstract Library get library(); |
| @@ -83,10 +85,14 @@ class Type implements Named, Hashable { |
| set jsname(String name) => _jsname = name; |
| + Map<String, Member> get members() => null; |
| + Definition get definition() => null; |
| + FactoryMap get factories() => null; |
| + |
| // TODO(jmesserly): should try using a const list instead of null to represent |
| // the absence of type parameters. |
| Collection<Type> get typeArgsInOrder() => null; |
| - Type get genericType() => this; |
| + DefinedType get genericType() => this; |
| // TODO(jmesserly): what should these do for ParameterType? |
| List<Type> get interfaces() => null; |
| @@ -304,6 +310,9 @@ class ParameterType extends Type { |
| ParameterType(String name, this.typeParameter): super(name); |
| + Map<String, MethodMember> get constructors() => |
| + world.internalError('no constructors on type parameters yet'); |
| + |
| MethodMember getCallMethod() => extendsType.getCallMethod(); |
| void genMethod(Member method) { |
| @@ -322,10 +331,18 @@ class ParameterType extends Type { |
| world.internalError('no constructors on type parameters yet'); |
| } |
| + Type getOrMakeConcreteType(List<Type> typeArgs) { |
| + world.internalError('no concrete types of type parameters yet', span); |
| + } |
| + |
| Type resolveTypeParams(ConcreteType inType) { |
| return inType.typeArguments[name]; |
| } |
| + addDirectSubtype(Type type) { |
| + world.internalError('no subtypes of type parameters yet', span); |
| + } |
| + |
| resolve(Type inType) { |
| if (typeParameter.extendsType != null) { |
| extendsType = inType.resolveType(typeParameter.extendsType, true); |
| @@ -338,7 +355,7 @@ class ParameterType extends Type { |
| /** A concrete version of a generic type. */ |
| class ConcreteType extends Type { |
| - final Type genericType; |
| + final DefinedType genericType; |
| Map<String, Type> typeArguments; |
| List<Type> _interfaces; |
| List<Type> typeArgsInOrder; |
| @@ -724,13 +741,14 @@ class DefinedType extends Type { |
| resolve() { |
| if (definition is TypeDefinition) { |
| + TypeDefinition typeDef = definition; |
|
jimhug
2011/11/10 15:47:21
Can we at least add a TODO here? TODO: Fix the co
|
| if (isClass) { |
| - if (definition.extendsTypes != null && definition.extendsTypes.length > 0) { |
| - if (definition.extendsTypes.length > 1) { |
| + if (typeDef.extendsTypes != null && typeDef.extendsTypes.length > 0) { |
| + if (typeDef.extendsTypes.length > 1) { |
| world.error('more than one base class', |
| - definition.extendsTypes[1].span); |
| + typeDef.extendsTypes[1].span); |
| } |
| - var extendsTypeRef = definition.extendsTypes[0]; |
| + var extendsTypeRef = typeDef.extendsTypes[0]; |
| if (extendsTypeRef is GenericTypeReference) { |
| // If we are extending a generic type first resolve against the |
| // base type, then the full generic type. This makes circular |
| @@ -741,7 +759,7 @@ class DefinedType extends Type { |
| parent = resolveType(extendsTypeRef, true); |
| if (!parent.isClass) { |
| world.error('class may not extend an interface - use implements', |
| - definition.extendsTypes[0].span); |
| + typeDef.extendsTypes[0].span); |
| } |
| parent.addDirectSubtype(this); |
| if (_cycleInClassExtends()) { |
| @@ -754,31 +772,29 @@ class DefinedType extends Type { |
| parent = world.objectType; |
| } |
| } |
| - this.interfaces = _resolveInterfaces(definition.implementsTypes); |
| - if (definition.factoryType != null) { |
| + this.interfaces = _resolveInterfaces(typeDef.implementsTypes); |
| + if (typeDef.factoryType != null) { |
| world.error('factory not allowed on classes', |
| - definition.factoryType.span); |
| + typeDef.factoryType.span); |
| } |
| } else { |
| - if (definition.implementsTypes != null && |
| - definition.implementsTypes.length > 0) { |
| + if (typeDef.implementsTypes != null && |
| + typeDef.implementsTypes.length > 0) { |
| world.error('implements not allowed on interfaces (use extends)', |
| - definition.implementsTypes[0].span); |
| + typeDef.implementsTypes[0].span); |
| } |
| - this.interfaces = _resolveInterfaces(definition.extendsTypes); |
| + this.interfaces = _resolveInterfaces(typeDef.extendsTypes); |
| final res = _cycleInInterfaceExtends(); |
| if (res >= 0) { |
| world.error('interface "$name" has a cycle in its inheritance chain', |
| - definition.extendsTypes[res].span); |
| + typeDef.extendsTypes[res].span); |
| } |
| - if (definition.factoryType != null) { |
| - factory_ = resolveType(definition.factoryType, true); |
| + if (typeDef.factoryType != null) { |
| + factory_ = resolveType(typeDef.factoryType, true); |
| if (factory_ == null) { |
| // TODO(jimhug): Appropriate warning levels; |
| - world.info( |
| - 'unresolved factory: ${definition.factoryType.name.name}', |
| - definition.factoryType.name.span); |
| + world.warning('unresolved factory', typeDef.factoryType.span); |
| } |
| } |
| } |
| @@ -935,7 +951,9 @@ class DefinedType extends Type { |
| inits = [new CallExpression(new SuperExpression(span), [], span)]; |
| } |
| - var c = new FunctionDefinition(null, null, definition.name, [], |
| + |
| + TypeDefinition typeDef = definition; |
| + var c = new FunctionDefinition(null, null, typeDef.name, [], |
| inits, body, span); |
| addMethod(null, c); |
| constructors[''].resolve(this); |
| @@ -1070,59 +1088,62 @@ class DefinedType extends Type { |
| // same message twice. |
| if (node is NameTypeReference) { |
| + NameTypeReference typeRef = node; |
| String name; |
| - if (node.names != null) { |
| - name = node.names.last().name; |
| + if (typeRef.names != null) { |
| + name = typeRef.names.last().name; |
| } else { |
| - name = node.name.name; |
| + name = typeRef.name.name; |
| } |
| if (typeParameters != null) { |
| for (var tp in typeParameters) { |
| if (tp.name == name) { |
| - node.type = tp; |
| + typeRef.type = tp; |
| } |
| } |
| } |
| - if (node.type == null) { |
| - node.type = library.findType(node); |
| + if (typeRef.type == null) { |
| + typeRef.type = library.findType(typeRef); |
| } |
| - if (node.type == null) { |
| - var message = 'can not find type ${_getDottedName(node)}'; |
| + if (typeRef.type == null) { |
| + var message = 'can not find type ${_getDottedName(typeRef)}'; |
| if (typeErrors) { |
| - world.error(message, node.span); |
| - node.type = world.objectType; |
| + world.error(message, typeRef.span); |
| + typeRef.type = world.objectType; |
| } else { |
| - world.warning(message, node.span); |
| - node.type = world.varType; |
| + world.warning(message, typeRef.span); |
| + typeRef.type = world.varType; |
| } |
| } |
| } else if (node is GenericTypeReference) { |
| + GenericTypeReference typeRef = node; |
| // TODO(jimhug): Expand the handling of typeErrors to generics and funcs |
| - var baseType = resolveType(node.baseType, typeErrors); |
| + var baseType = resolveType(typeRef.baseType, typeErrors); |
| if (!baseType.isGeneric) { |
| - world.error('${baseType.name} is not generic', node.span); |
| + world.error('${baseType.name} is not generic', typeRef.span); |
| return null; |
| } |
| - if (node.typeArguments.length != baseType.typeParameters.length) { |
| - world.error('wrong number of type arguments', node.span); |
| + if (typeRef.typeArguments.length != baseType.typeParameters.length) { |
| + world.error('wrong number of type arguments', typeRef.span); |
| return null; |
| } |
| var typeArgs = []; |
| - for (int i=0; i < node.typeArguments.length; i++) { |
| + for (int i=0; i < typeRef.typeArguments.length; i++) { |
| var extendsType = baseType.typeParameters[i].extendsType; |
| - var typeArg = resolveType(node.typeArguments[i], typeErrors); |
| + var typeArg = resolveType(typeRef.typeArguments[i], typeErrors); |
| typeArgs.add(typeArg); |
| if (extendsType != null && typeArg is! ParameterType) { |
| typeArg.ensureSubtypeOf(extendsType, |
| - node.typeArguments[i].span, typeErrors); |
| + typeRef.typeArguments[i].span, typeErrors); |
| } |
| } |
| - node.type = baseType.getOrMakeConcreteType(typeArgs); |
| + typeRef.type = baseType.getOrMakeConcreteType(typeArgs); |
| } else if (node is FunctionTypeReference) { |
| + FunctionTypeReference typeRef = node; |
| var name = ''; |
| - if (node.func.name != null) name = node.func.name.name; |
| - node.type = library.getOrAddFunctionType(name, node.func, this); |
| + if (typeRef.func.name != null) name = typeRef.func.name.name; |
| + typeRef.type = library.getOrAddFunctionType(name, typeRef.func, this); |
| } else { |
| world.internalError('unknown type reference', node.span); |
| } |