aspect GenericsJPI{ syn boolean AdviceSpec.isGeneric() = false; eq GenericCJPBeforeSpec.isGeneric() = true; eq GenericCJPAfterSpec.isGeneric() = true; eq GenericCJPAfterReturningSpec.isGeneric() = true; eq GenericCJPAfterThrowingSpec.isGeneric() = true; eq GenericCJPAroundSpec.isGeneric() = true; interface GenericCJPAdviceSpec { int getNumTypeVar(); TypeVariable getTypeVar(int i); } GenericCJPBeforeSpec implements GenericCJPAdviceSpec; GenericCJPAfterSpec implements GenericCJPAdviceSpec; GenericCJPAfterReturningSpec implements GenericCJPAdviceSpec; GenericCJPAfterThrowingSpec implements GenericCJPAdviceSpec; GenericCJPAroundSpec implements GenericCJPAdviceSpec; syn lazy GenericCJPAdviceSpec CJPAdviceDecl.getGenericCJPAdviceSpec(){ return (GenericCJPAdviceSpec)getAdviceSpec(); } inh SimpleSet GenericJPITypeDecl.lookupType(String name); syn SimpleSet GenericJPITypeDecl.localLookupType(String name) { for(int i = 0; i < getNumTypeVar(); i++) { if(getTypeVar(i).name().equals(name)) return SimpleSet.emptySet.add(getTypeVar(i)); } return SimpleSet.emptySet; } eq GenericJPITypeDecl.getChild().lookupType(String name) = localLookupType(name).isEmpty() ? lookupType(name) : localLookupType(name); inh SimpleSet GenericExhibitBodyDecl.lookupType(String name); syn SimpleSet GenericExhibitBodyDecl.localLookupType(String name) { for(int i = 0; i < getNumTypeVar(); i++) { if(getTypeVar(i).name().equals(name)) return SimpleSet.emptySet.add(getTypeVar(i)); } return SimpleSet.emptySet; } eq GenericExhibitBodyDecl.getChild().lookupType(String name) = localLookupType(name).isEmpty() ? lookupType(name) : localLookupType(name); inh SimpleSet CJPAdviceDecl.lookupType(String name); syn SimpleSet CJPAdviceDecl.localLookupType(String name) { if (getAdviceSpec().isGeneric()){ GenericCJPAdviceSpec spec = (GenericCJPAdviceSpec)getAdviceSpec(); for(int i = 0; i < spec.getNumTypeVar(); i++) { if(spec.getTypeVar(i).name().equals(name)) return SimpleSet.emptySet.add(spec.getTypeVar(i)); } } return SimpleSet.emptySet; } eq CJPAdviceDecl.getChild().lookupType(String name) = localLookupType(name).isEmpty() ? lookupType(name) : localLookupType(name); inh SimpleSet GenericCJPBeforeSpec.lookupType(String name); inh SimpleSet GenericCJPAfterSpec.lookupType(String name); inh SimpleSet GenericCJPAfterReturningSpec.lookupType(String name); inh SimpleSet GenericCJPAfterThrowingSpec.lookupType(String name); inh SimpleSet GenericCJPAroundSpec.lookupType(String name); syn SimpleSet GenericCJPBeforeSpec.localLookupType(String name) { for(int i = 0; i < getNumTypeVar(); i++) { if(getTypeVar(i).name().equals(name)) return SimpleSet.emptySet.add(getTypeVar(i)); } return SimpleSet.emptySet; } syn SimpleSet GenericCJPAfterSpec.localLookupType(String name) { for(int i = 0; i < getNumTypeVar(); i++) { if(getTypeVar(i).name().equals(name)) return SimpleSet.emptySet.add(getTypeVar(i)); } return SimpleSet.emptySet; } syn SimpleSet GenericCJPAfterReturningSpec.localLookupType(String name) { for(int i = 0; i < getNumTypeVar(); i++) { if(getTypeVar(i).name().equals(name)) return SimpleSet.emptySet.add(getTypeVar(i)); } return SimpleSet.emptySet; } syn SimpleSet GenericCJPAfterThrowingSpec.localLookupType(String name) { for(int i = 0; i < getNumTypeVar(); i++) { if(getTypeVar(i).name().equals(name)) return SimpleSet.emptySet.add(getTypeVar(i)); } return SimpleSet.emptySet; } syn SimpleSet GenericCJPAroundSpec.localLookupType(String name) { for(int i = 0; i < getNumTypeVar(); i++) { if(getTypeVar(i).name().equals(name)) return SimpleSet.emptySet.add(getTypeVar(i)); } return SimpleSet.emptySet; } eq GenericCJPBeforeSpec.getChild().lookupType(String name) = localLookupType(name).isEmpty() ? lookupType(name) : localLookupType(name); eq GenericCJPAfterSpec.getChild().lookupType(String name) = localLookupType(name).isEmpty() ? lookupType(name) : localLookupType(name); eq GenericCJPAfterReturningSpec.getChild().lookupType(String name) = localLookupType(name).isEmpty() ? lookupType(name) : localLookupType(name); eq GenericCJPAfterThrowingSpec.getChild().lookupType(String name) = localLookupType(name).isEmpty() ? lookupType(name) : localLookupType(name); eq GenericCJPAroundSpec.getChild().lookupType(String name) = localLookupType(name).isEmpty() ? lookupType(name) : localLookupType(name); public void GenericExhibitBodyDecl.doTypeChecking(JPITypeDecl jpiDecl){ TypeVariable exhibitTypeVariable, jpiTypeVariable; if (getReturnType().type().isTypeVariable() && jpiDecl.getTypeAccess().type().isTypeVariable()){ exhibitTypeVariable = (TypeVariable) getReturnType().type(); jpiTypeVariable = (TypeVariable) jpiDecl.getTypeAccess().type(); if(!exhibitTypeVariable.getTypeBound(0).type().equals(jpiTypeVariable.getTypeBound(0).type())){ error("TypeCheck: Exhibit return type: "+getReturnType().type().name()+" instead "+jpiDecl.getTypeAccess().type().name()); } } else{ if(!getReturnType().type().equals(jpiDecl.getTypeAccess().type())){ error("TypeCheck: Exhibit return type: "+getReturnType().type().name()+" instead "+jpiDecl.getTypeAccess().type().name()); } } if(getNumParameter() != jpiDecl.getNumParameter()){ error("TypeCheck: Exhibit clause must declare the same quantity of arguments that its JPI"); } else{ ParameterDeclaration exhibitParameter; ParameterDeclaration jpiParameter; for(int i=0; i parameterList) { String fullName = packageName.equals("") ? typeName : packageName + "." + typeName; boolean match; for(int i = 0; i < getNumCompilationUnit(); i++) { for(int j = 0; j < getCompilationUnit(i).getNumTypeDecl(); j++) { if (getCompilationUnit(i).getTypeDecl(j).isJPITypeDecl()){ JPITypeDecl type = (JPITypeDecl)getCompilationUnit(i).getTypeDecl(j); if(type.fullName().equals(fullName)){ if (type.getNumParameter() == parameterList.size()){ match = true; for(int k=0; k parameterList) { boolean match; JPITypeDecl jpiType; SimpleSet set = SimpleSet.emptySet; for(int i = 0; i < getNumTypeDecl(); i++){ match = true; if (getTypeDecl(i).isJPITypeDecl()){ jpiType = (JPITypeDecl)getTypeDecl(i); if(jpiType.name().equals(name)){ if(jpiType.getNumParameter() == parameterList.size()){ for(int j=0; j parameterList){ JoinpointTypeDecl member; boolean match = true; if (this instanceof MemberCJPTypeDecl){ member = ((MemberCJPTypeDecl)this).getJoinpointTypeDecl(); if (member.name().equals(name)){ if (member.getNumParameter() == parameterList.size()){ for(int i=0; i ThrowStmt.exceptionCollection() { TypeAccess jpiAccess = (TypeAccess)getJPIAccess(); JPITypeDecl jpiTypeDecl; HashSet set = new HashSet(); if(!jpiAccess.type().isJoinpointTypeDecl()){ return set; } jpiTypeDecl = (JPITypeDecl)jpiAccess.type(); for(Access exception : jpiTypeDecl.getExceptionList()){ set.add(exception.type()); } return set; } refine PreciseRethrow protected boolean ThrowStmt.reachedException(TypeDecl catchType) { if (!insideCJPAdviceDecl()) return true; for(TypeDecl exceptionType : exceptionCollection()){ if(catchType.mayCatch(exceptionType)){ return true; } } return super.reachedException(catchType); } }