aspect TypeVariableExt { public TypeVariable TypeVariable.lockedCopy() { List bounds = new List(); for(Access bound : getTypeBounds()) bounds.add(bound.type().createLockedAccess()); return new TypeVariable(new Modifiers(new List()), name(), new List(), bounds); } interface GenericElement { int getNumTypeParameter(); TypeVariable getTypeParameter(int i); } GenericMethodDecl implements GenericElement; GenericConstructorDecl implements GenericElement; GenericTypeDecl implements GenericElement; inh GenericElement TypeVariable.owner(); eq Program.getChild().owner() { throw new IllegalStateException("owner() on type variable that is not in tree"); } eq GenericElement.getTypeParameter().owner() = this; eq GenericTypeDecl.getTypeParameter().owner() = this; // collect all references to type variables in a subtree public java.util.Set ASTNode.typeVarAccesses() { java.util.Set res = new LinkedHashSet(); typeVarAccesses(res); return res; } public void ASTNode.typeVarAccesses(java.util.Set res) { for(int i=0;i res) { if(decl().isTypeVariable()) res.add(this); super.typeVarAccesses(res); } // collect all type variables used in a subtree syn lazy Collection ASTNode.usedTypeVars() { Collection res = new LinkedHashSet(); collectUsedTypeVars(res); return res; } protected void ASTNode.collectUsedTypeVars(Collection tvars) { for(int i=0;i tvars) { if(decl().isTypeVariable()) tvars.add((TypeVariable)decl()); super.collectUsedTypeVars(tvars); } syn lazy Collection ASTNode.usedForeignTypeVars() { Collection res = new LinkedHashSet(); for(TypeVariable tv : usedTypeVars()) if (!tv.isDescendantTo(this)) res.add(tv); return res; } // does this subtree use type variables declared outside it? public boolean ASTNode.usesForeignTypeVars() { Collection tvars = usedTypeVars(); for(TypeVariable tv : tvars) if(!tv.isDescendantTo(this)) return true; return false; } // translating type variables public void ASTNode.translateTypeVars(Map dict) { for(int i=0;i dict) { if(decl().isTypeVariable()) { TypeVariable tv = (TypeVariable)decl(); TypeVariable tv2 = dict.get(tv); if(tv2 != null) lock(tv2); } super.translateTypeVars(dict); } // translate type variables in a method from sup to sub public void MethodDecl.translateTypeVars(TypeDecl sub, TypeDecl sup) { if(!sub.isGenericType() || !sup.isParameterizedType()) return; GenericTypeDecl gsub = (GenericTypeDecl)sub; ParTypeDecl psup = (ParTypeDecl)sup; GenericTypeDecl gsup = (GenericTypeDecl)psup.genericDecl(); Map dict = new HashMap(); for(TypeVariable tv : (List)gsub.getTypeParameterList()) { for(int i=0;i