[Nice-commit] Nice/src/bossa/syntax TypeIdent.java,1.29,1.30 MonotypeConstructor.java,1.33,1.34 Meth
Brought to you by:
bonniot
Update of /cvsroot/nice/Nice/src/bossa/syntax In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv29266/src/bossa/syntax Modified Files: TypeIdent.java MonotypeConstructor.java MethodContainer.java EnumDefinition.java ClassDefinition.java AbstractInterface.java Log Message: Allow subclasses to have less type parameters than their parent, by instantiation of some of their type parameters. Index: TypeIdent.java =================================================================== RCS file: /cvsroot/nice/Nice/src/bossa/syntax/TypeIdent.java,v retrieving revision 1.29 retrieving revision 1.30 diff -C2 -d -r1.29 -r1.30 *** TypeIdent.java 30 Jul 2004 19:08:45 -0000 1.29 --- TypeIdent.java 12 Aug 2004 23:21:41 -0000 1.30 *************** *** 91,94 **** --- 91,99 ---- } catch(mlsub.typing.BadSizeEx e){ + // See if this is a class with default type parameters + mlsub.typing.Monotype type = ClassDefinition.toType(tc); + if (type != null) + return type; + throw User.error(this, name + Util.has(e.expected, "type parameter", e.actual)); Index: ClassDefinition.java =================================================================== RCS file: /cvsroot/nice/Nice/src/bossa/syntax/ClassDefinition.java,v retrieving revision 1.107 retrieving revision 1.108 diff -C2 -d -r1.107 -r1.108 *** ClassDefinition.java 30 Jul 2004 19:08:45 -0000 1.107 --- ClassDefinition.java 12 Aug 2004 23:21:41 -0000 1.108 *************** *** 15,18 **** --- 15,19 ---- import bossa.util.*; import mlsub.typing.*; + import mlsub.typing.Monotype; import gnu.bytecode.*; *************** *** 49,52 **** --- 50,65 ---- this.extensions = extensions; + // Find out the real variance of the interface + int arity = getVariance(extensions); + if (arity == -1) + arity = getVariance(implementations); + if (arity == -1) + arity = getVariance(abstractions); + + if (arity == -1 || arity <= typeParametersVariances.size()) + this.variance = makeVariance(typeParametersVariances); + else + this.variance = Variance.make(new int[arity]); + this.createTC(); associatedInterface = new mlsub.typing.Interface(variance, tc); *************** *** 141,150 **** } ! public static ! Class makeClass(LocatedString name, ! boolean isFinal, boolean isAbstract, Constraint typeParameters, List typeParametersVariances, ! TypeIdent superClassIdent, List implementations, List abstractions ) --- 154,163 ---- } ! public static ! Class makeClass(LocatedString name, ! boolean isFinal, boolean isAbstract, Constraint typeParameters, List typeParametersVariances, ! MonotypeConstructor superClassIdent, List implementations, List abstractions ) *************** *** 157,165 **** public static class Class extends ClassDefinition { ! Class(LocatedString name, ! boolean isFinal, boolean isAbstract, Constraint typeParameters, List typeParametersVariances, ! TypeIdent superClassIdent, List implementations, List abstractions ) --- 170,178 ---- public static class Class extends ClassDefinition { ! Class(LocatedString name, ! boolean isFinal, boolean isAbstract, Constraint typeParameters, List typeParametersVariances, ! MonotypeConstructor superClassIdent, List implementations, List abstractions ) *************** *** 170,176 **** this.isFinal = isFinal; this.isAbstract = isAbstract; ! this.superClassIdent = superClassIdent; this.createTC(); if (isFinal) --- 183,201 ---- this.isFinal = isFinal; this.isAbstract = isAbstract; ! this.superClassIdent = superClassIdent; + // Find out the real variance of the interface + int arity = getVariance(superClassIdent); + if (arity == -1) + arity = getVariance(implementations); + if (arity == -1) + arity = getVariance(abstractions); + + if (arity == -1 || arity <= typeParametersVariances.size()) + this.variance = makeVariance(typeParametersVariances); + else + this.variance = Variance.make(new int[arity]); + this.createTC(); if (isFinal) *************** *** 238,244 **** void resolveClass() { if (superClassIdent != null) { ! superClass = superClassIdent.resolveToTC(typeScope); if (superClass.isMinimal()) --- 263,271 ---- void resolveClass() { + Monotype[] params = null; if (superClassIdent != null) { ! params = resolveParent(superClassIdent, getLocalScope()); ! superClass = superClassIdent.tc.resolveToTC(typeScope); if (superClass.isMinimal()) *************** *** 247,251 **** if (TypeConstructors.isInterface(superClass)) User.error(superClassIdent, ! superClass + " is an interface, so " + name + " may only implement it"); --- 274,278 ---- if (TypeConstructors.isInterface(superClass)) User.error(superClassIdent, ! superClass + " is an interface, so " + name + " may only implement it"); *************** *** 258,261 **** --- 285,290 ---- d.resolve(); + useParent(d, params); + if(d.getImplementation() instanceof PrimitiveType && ! (this.getImplementation() instanceof PrimitiveType)) *************** *** 301,305 **** } ! TypeIdent superClassIdent; TypeConstructor superClass; protected boolean isFinal; --- 330,334 ---- } ! MonotypeConstructor superClassIdent; TypeConstructor superClass; protected boolean isFinal; *************** *** 325,333 **** ) { ! super(name, Node.upper, typeParameters, typeParametersVariances); this.implementations = implementations; this.abstractions = abstractions; } ! protected List /* of Interface */ implementations, --- 354,362 ---- ) { ! super(name, Node.upper, typeParameters); this.implementations = implementations; this.abstractions = abstractions; } ! protected List /* of Interface */ implementations, *************** *** 426,435 **** private static Map tcToClassDef; public static void reset() { tcToClassDef = new HashMap(); } ! public static final ClassDefinition get(TypeConstructor tc) { return (ClassDefinition) tcToClassDef.get(tc); } ! /**************************************************************** * Selectors --- 455,469 ---- private static Map tcToClassDef; public static void reset() { tcToClassDef = new HashMap(); } ! public static final ClassDefinition get(TypeConstructor tc) { return (ClassDefinition) tcToClassDef.get(tc); } ! ! public static final ClassDefinition get(mlsub.typing.Interface itf) ! { ! return ClassDefinition.get(itf.associatedTC()); ! } ! /**************************************************************** * Selectors *************** *** 495,502 **** status = RESOLVING; ! try { - super.resolve(); resolveClass(); } finally --- 529,541 ---- status = RESOLVING; ! try { resolveClass(); + + super.resolve(); + + // This needs to be after super.resolve(), so that the constraint is + // resolved + implementation.resolveClass(); } finally *************** *** 509,514 **** { this.resolveInterfaces(implementations); ! abs = TypeIdent.resolveToItf(typeScope, abstractions); ! implementations = abstractions = null; --- 548,553 ---- { this.resolveInterfaces(implementations); ! abs = AbstractInterface.resolve(typeScope, abstractions); ! implementations = abstractions = null; *************** *** 523,527 **** createContext(); - implementation.resolveClass(); } --- 562,565 ---- *************** *** 538,546 **** for (Iterator i = names.iterator(); i.hasNext();) { ! TypeIdent name = (TypeIdent) i.next(); TypeSymbol s = name.resolvePreferablyToItf(typeScope); ! if (s instanceof mlsub.typing.Interface) ! interfaces.add(s); else { --- 576,593 ---- for (Iterator i = names.iterator(); i.hasNext();) { ! MonotypeConstructor parent = (MonotypeConstructor) i.next(); ! Monotype[] params = resolveParent(parent, getLocalScope()); ! ! TypeIdent name = parent.tc; TypeSymbol s = name.resolvePreferablyToItf(typeScope); ! if (s instanceof mlsub.typing.Interface) ! { ! interfaces.add(s); ! ! ClassDefinition def = ClassDefinition.get((mlsub.typing.Interface) s); ! if (def != null) ! useParent(def, params); ! } else { *************** *** 561,564 **** --- 608,619 ---- } + Monotype[] resolveParent(MonotypeConstructor parent, TypeScope typeScope) + { + if (parent.parameters == null) + return null; + + return bossa.syntax.Monotype.resolve(typeScope, parent.parameters.content); + } + void resolveBody() { *************** *** 637,640 **** --- 692,844 ---- } + /** + Returns a monotype based on this tc, provided that the class + requires no type parameter because it specializes its parent. + */ + static Monotype toType(TypeConstructor tc) + { + ClassDefinition def = ClassDefinition.get(tc); + if (def == null) + return null; + + if (def.parentParams == null) + return null; + + // Look for missing type parameters + int missing = 0; + for (int i = 0; i < def.parentParams.length; i++) + if (def.parentParams[i] == null) + missing++; + + if (missing == 0) + return new mlsub.typing.MonotypeConstructor(tc, def.parentParams); + + return null; + } + + /** + Returns a monotype based on this tc, provided that the class + requires exactly these type parameters because it specializes its parent. + */ + static Monotype toType(TypeConstructor tc, Monotype[] sourceParams) + { + ClassDefinition def = ClassDefinition.get(tc); + if (def == null) + return null; + + if (def.parentParams == null) + return null; + + Monotype[] fullParams = new Monotype[def.parentParams.length]; + + int used = 0; + for (int i = 0; i < fullParams.length; i++) + if (def.parentParams[i] == null) + { + fullParams[i] = sourceParams[def.parentTypeParameterMap[i]]; + used++; + } + else + fullParams[i] = def.parentParams[i]; + + if (used < sourceParams.length) + return null; + + return new mlsub.typing.MonotypeConstructor(tc, fullParams); + } + + private Monotype[] parentParams; + private int[] parentTypeParameterMap; + + MethodContainer.Constraint specialize(MethodContainer.Constraint our, + MethodContainer.Constraint parent, + Monotype[] params) + { + if (parent == null) + return null; + + if (params == null) + return our; + + this.parentParams = params; + this.parentTypeParameterMap = new int[params.length]; + + List binders = new ArrayList(); + List atoms = new ArrayList(); + Monotype[] typeParameters = new Monotype[params.length]; + + if (our != null) + { + binders.addAll(Arrays.asList(our.getBinderArray())); + atoms.addAll(our.getAtoms()); + } + + for (int i = 0; i < params.length; i++) + { + if (params[i] instanceof MonotypeVar) + { + typeParameters[i] = params[i]; + parentTypeParameterMap[i] = find(params[i], our.typeParameters); + parentParams[i] = null; + continue; + } + + MonotypeVar mvar = new MonotypeVar("D" + i); + binders.add(mvar); + typeParameters[i] = mvar; + + bossa.syntax.Monotype var = bossa.syntax.Monotype.create(mvar); + atoms.add(new MonotypeLeqCst(bossa.syntax.Monotype.create(params[i]), var)); + atoms.add(new MonotypeLeqCst(var, bossa.syntax.Monotype.create(params[i]))); + } + + return new MethodContainer.Constraint + ((TypeSymbol[]) binders.toArray(new TypeSymbol[binders.size()]), + atoms, + typeParameters, + this.location()); + } + + private int find(Object o, Object[] array) + { + for (int i = 0; ; i++) + if (array[i] == o) + return i; + } + + int getVariance(List parents) + { + if (parents == null) + return -1; + + int res; + + for (Iterator i = parents.iterator(); i.hasNext();) + { + res = getVariance((MonotypeConstructor) i.next()); + if (res != -1) + return res; + } + + return -1; + } + + int getVariance(MonotypeConstructor parent) + { + if (parent == null || parent.parameters.content == null) + return -1; + + // Assume non-variance + return parent.parameters.content.length; + } + + void useParent(MethodContainer parent, Monotype[] params) + { + if (parentParams == null) + classConstraint = + specialize(this.classConstraint, parent.classConstraint, params); + + } + /**************************************************************** * Class hierarchy Index: EnumDefinition.java =================================================================== RCS file: /cvsroot/nice/Nice/src/bossa/syntax/EnumDefinition.java,v retrieving revision 1.12 retrieving revision 1.13 diff -C2 -d -r1.12 -r1.13 *** EnumDefinition.java 4 Aug 2004 18:36:08 -0000 1.12 --- EnumDefinition.java 12 Aug 2004 23:21:41 -0000 1.13 *************** *** 34,38 **** classDef = ClassDefinition.makeClass (name,true,false, null, new ArrayList(0), ! new TypeIdent(new LocatedString("nice.lang.Enum",name.location())), interfaces,null); NiceClass impl = new NiceClass(classDef); --- 34,38 ---- classDef = ClassDefinition.makeClass (name,true,false, null, new ArrayList(0), ! new MonotypeConstructor(new TypeIdent(new LocatedString("nice.lang.Enum",name.location())), null, this.location()), interfaces,null); NiceClass impl = new NiceClass(classDef); Index: MethodContainer.java =================================================================== RCS file: /cvsroot/nice/Nice/src/bossa/syntax/MethodContainer.java,v retrieving revision 1.16 retrieving revision 1.17 diff -C2 -d -r1.16 -r1.17 *** MethodContainer.java 16 Jul 2004 10:01:33 -0000 1.16 --- MethodContainer.java 12 Aug 2004 23:21:41 -0000 1.17 *************** *** 33,48 **** public abstract class MethodContainer extends Definition { ! MethodContainer (LocatedString name, int propagate, ! MethodContainer.Constraint classConstraint, ! List variance) { super(name, propagate); this.name.prepend(module.getName() + "."); - - this.variance = makeVariance(variance); this.classConstraint = classConstraint; } /** The name of this method container without package qualification. */ String getSimpleName() --- 33,53 ---- public abstract class MethodContainer extends Definition { ! MethodContainer (LocatedString name, int propagate, ! MethodContainer.Constraint classConstraint) { super(name, propagate); this.name.prepend(module.getName() + "."); this.classConstraint = classConstraint; } + MethodContainer (LocatedString name, int propagate, + MethodContainer.Constraint classConstraint, + List variance) + { + this(name, propagate, classConstraint); + this.variance = makeVariance(variance); + } + /** The name of this method container without package qualification. */ String getSimpleName() *************** *** 56,60 **** abstract mlsub.typing.TypeSymbol getTypeSymbol(); ! private static Variance makeVariance(java.util.List typeParametersVariances) { int[] variances = new int[typeParametersVariances.size()]; --- 61,65 ---- abstract mlsub.typing.TypeSymbol getTypeSymbol(); ! static Variance makeVariance(java.util.List typeParametersVariances) { int[] variances = new int[typeParametersVariances.size()]; *************** *** 119,124 **** } /** ! Replace those type parameters that have been introduced in the constraint by their definition. */ --- 124,137 ---- } + Constraint (TypeSymbol[] binders, List atoms, + mlsub.typing.Monotype[] typeParameters, + Location loc) + { + super(binders, atoms); + this.typeParameters = typeParameters; + } + /** ! Replace those type parameters that have been introduced in the constraint by their definition. */ *************** *** 156,160 **** } ! final Constraint classConstraint; mlsub.typing.AtomicConstraint[] resolvedConstraints; --- 169,173 ---- } ! Constraint classConstraint; mlsub.typing.AtomicConstraint[] resolvedConstraints; Index: MonotypeConstructor.java =================================================================== RCS file: /cvsroot/nice/Nice/src/bossa/syntax/MonotypeConstructor.java,v retrieving revision 1.33 retrieving revision 1.34 diff -C2 -d -r1.33 -r1.34 *** MonotypeConstructor.java 27 May 2003 07:41:37 -0000 1.33 --- MonotypeConstructor.java 12 Aug 2004 23:21:41 -0000 1.34 *************** *** 63,82 **** ****************************************************************/ ! mlsub.typing.Monotype rawResolve(TypeMap typeMap) { ! if(lowlevelTC==null) { TypeSymbol newTC = this.tc.resolveToTC(typeMap); ! if (!(newTC instanceof TypeConstructor)) User.error(this.tc, this.tc+" should be a type constructor"); lowlevelTC = (TypeConstructor) newTC; } ! try{ ! mlsub.typing.Monotype type = new mlsub.typing.MonotypeConstructor(lowlevelTC, parameters.resolve(typeMap)); ! return type; } catch(mlsub.typing.BadSizeEx e){ ! throw User.error(this, (tc!=null ? "Class "+tc : lowlevelTC.toString()) + Util.has(e.expected, "type parameter", e.actual)); } --- 63,88 ---- ****************************************************************/ ! mlsub.typing.Monotype rawResolve(TypeMap typeMap) { ! if (lowlevelTC == null) { TypeSymbol newTC = this.tc.resolveToTC(typeMap); ! if (! (newTC instanceof TypeConstructor)) User.error(this.tc, this.tc+" should be a type constructor"); lowlevelTC = (TypeConstructor) newTC; } ! ! mlsub.typing.Monotype[] resolvedParams = parameters.resolve(typeMap); ! try{ ! return new mlsub.typing.MonotypeConstructor(lowlevelTC, resolvedParams); } catch(mlsub.typing.BadSizeEx e){ ! // See if this is a class with default type parameters ! mlsub.typing.Monotype res = ClassDefinition.toType(lowlevelTC, resolvedParams); ! if (res != null) ! return res; ! ! throw User.error(this, (tc!=null ? "Class "+tc : lowlevelTC.toString()) + Util.has(e.expected, "type parameter", e.actual)); } Index: AbstractInterface.java =================================================================== RCS file: /cvsroot/nice/Nice/src/bossa/syntax/AbstractInterface.java,v retrieving revision 1.18 retrieving revision 1.19 diff -C2 -d -r1.18 -r1.19 *** AbstractInterface.java 15 Dec 2003 14:04:13 -0000 1.18 --- AbstractInterface.java 12 Aug 2004 23:21:42 -0000 1.19 *************** *** 55,63 **** ****************************************************************/ void resolve() { super.resolve(); ! surinterfaces = TypeIdent.resolveToItf(typeScope, extensions); extensions = null; --- 55,79 ---- ****************************************************************/ + static Interface[] resolve(TypeMap scope, List types) + { + if (types == null || types.size() == 0) return null; + + Interface[] res = new Interface[types.size()]; + + int n = 0; + for (Iterator i = types.iterator(); i.hasNext(); n++) + { + MonotypeConstructor parent = (MonotypeConstructor) i.next(); + res[n++] = parent.tc.resolveToItf(scope); + } + + return res; + } + void resolve() { super.resolve(); ! superInterfaces = resolve(typeScope, extensions); extensions = null; *************** *** 82,91 **** private void createContext() { ! if (surinterfaces != null) try{ ! Typing.assertLeq(itf, surinterfaces); } catch(mlsub.typing.KindingEx e){ ! User.error(name, name + " cannot extends one of the surinterfaces " + " because they don't have the same number or kind of " + " type parameters"); --- 98,107 ---- private void createContext() { ! if (superInterfaces != null) try{ ! Typing.assertLeq(itf, superInterfaces); } catch(mlsub.typing.KindingEx e){ ! User.error(name, name + " cannot extends one of the interfaces " + " because they don't have the same number or kind of " + " type parameters"); *************** *** 103,107 **** + getSimpleName() + printTypeParameters() ! + Util.map(" extends ",", ","", surinterfaces) + "{}\n"); --- 119,123 ---- + getSimpleName() + printTypeParameters() ! + Util.map(" extends ",", ","", superInterfaces) + "{}\n"); *************** *** 142,147 **** /** ML-Sub interface. */ private Interface itf; ! ! private List /* of Interface */ extensions; // the surinterfaces ! private Interface[] surinterfaces; // resolved surinterfaces } --- 158,163 ---- /** ML-Sub interface. */ private Interface itf; ! ! private List /* of Interface */ extensions; // the super-interfaces ! private Interface[] superInterfaces; // resolved super-interfaces } |