Select Git revision
Analysis.jrag
-
Johannes Mey authored
make unresolved subtypes of abstract types abstract, use unresolved interface. rename resolver methods (for MQuAT compatibility)
Johannes Mey authoredmake unresolved subtypes of abstract types abstract, use unresolved interface. rename resolver methods (for MQuAT compatibility)
Analysis.jrag 5.75 KiB
import java.util.*;
aspect TypeAnalysis {
public abstract TypeUse Component.getTypeUse();
syn TypeDecl TypeUse.decl() = lookupType(getID());
inh TypeDecl TypeUse.lookupType(String name);
eq Program.getChild().lookupType(String name) {
for (TypeDecl td: getTypeDecls()) {
if (td.getID().equals(name)) {
return td;
}
}
return null;
}
syn boolean TypeDecl.isAlreadyDeclared()
= lookupType(getID()) != this;
inh TypeDecl TypeDecl.lookupType(String name);
syn TypeDecl TypeDecl.mostGeneralSuperType() {
if (!hasSuper()) {
return this;
} else {
return getSuper().decl().mostGeneralSuperType();
}
}
}
aspect ComponentAnalysis {
syn boolean Component.isTargetOfDirectedRelation() = false;
eq RelationComponent.isTargetOfDirectedRelation() = isTargetOfRightDirection();
inh boolean RelationComponent.isTargetOfRightDirection();
eq Relation.getRight().isTargetOfRightDirection()
= getDirection() instanceof RightDirection;
eq Program.getChild().isTargetOfRightDirection() = false;
syn String Component.name() = getID();
syn TypeDecl Component.toTypeDecl() = enclosingTypeDecl();
eq RelationComponent.toTypeDecl() = getTypeUse().decl();
inh TypeDecl Component.enclosingTypeDecl();
eq TypeDecl.getChild().enclosingTypeDecl() = this;
eq Program.getChild().enclosingTypeDecl() = null;
inh RelationComponent RelationComponent.otherSide();
eq Relation.getLeft().otherSide() = getRight();
eq Relation.getRight().otherSide() = getLeft();
eq Program.getChild().otherSide() = null;
syn TypeDecl RelationComponent.ofTypeDecl() = otherSide().toTypeDecl();
syn boolean Component.isAlreadyDeclared()
= !isTargetOfDirectedRelation()
&& toTypeDecl() != null
&& lookupComponent(toTypeDecl(), name()) != this;
inh Component Component.lookupComponent(TypeDecl td, String name);
eq Program.getChild().lookupComponent(TypeDecl td, String name)
= lookupComponentSyn(td, name);
syn Component Program.lookupComponentSyn(TypeDecl td, String name) {
// Check super type first to find duplicates (shadowing is not allowed)
if (td.hasSuper() && td.getSuper().decl() != null) {
Component c = lookupComponentSyn(td.getSuper().decl(), name);
if (c != null) return c;
}
for (Component c: td.getComponents()) {
if (c.name().equals(name)) {
return c;
}
}
for (Relation r: getRelations()) {
Component c = r.getLeft().lookup(td, name);
if (c != null) return c;
c = r.getRight().lookup(td, name);
if (c != null) return c;
}
return null;
}
syn RelationComponent RelationComponent.lookup(TypeDecl td, String name)
= !isTargetOfDirectedRelation() && toTypeDecl() == td && name().equals(name)
? this
: null;
coll Set<RelationComponent> TypeDecl.relationComponents()
[new HashSet<RelationComponent>()]
root Program;
RelationComponent contributes this
when !isTargetOfDirectedRelation() && toTypeDecl() != null
to TypeDecl.relationComponents()
for toTypeDecl();
syn Set<OneRelationComponent> TypeDecl.oneRelationComponents() {
Set<OneRelationComponent> set = new HashSet<>();
for (RelationComponent rc: relationComponents()) {
if (rc instanceof OneRelationComponent) {
set.add((OneRelationComponent) rc);
}
}
return set;
}
}
aspect InstanceSupplier {
inh Program TypeDecl.program();
eq Program.getTypeDecl(int i).program() = this;
syn Collection<TypeDecl> TypeDecl.subTypeDecls() {
java.util.List<TypeDecl> subDecls = new ArrayList();
for (TypeDecl decl : program().getTypeDeclList()) {
if (decl.hasSuper() && decl.getSuper().getID().equals(getID())) {
subDecls.add(decl);
}
}
return subDecls;
}
syn UnresolvedTypeDecl TypeDecl.instantiableUnresolved() {
if (getAbstract() == false) {
return this.getUnresolved();
} else {
for (TypeDecl sub : subTypeDecls()) {
if (sub.getAbstract() == false) {
return sub.getUnresolved();
} else {
TypeDecl subInstance = sub.instantiableUnresolved();
if (subInstance != null) {
return subInstance.getUnresolved();
}
}
}
}
return null;
}
syn UnresolvedTypeDecl TypeDecl.getUnresolved() {
java.util.List<TypeDecl> subDecls = new ArrayList();
for (TypeDecl decl : program().getTypeDeclList()) {
if (decl.isUnresolved() && decl.hasSuper() && decl.getSuper().getID().equals(getID())) {
return decl.asUnresolved();
}
}
// this should not happen
return null;
}
}
aspect Constructors {
syn Collection<Component> TypeDecl.componentsTransitive() {
ArrayList<Component> list = new ArrayList<>();
if (hasSuper() && getSuper().decl() != null) {
list.addAll(getSuper().decl().componentsTransitive());
}
for (Component c: getComponents()) {
list.add(c);
}
return list;
}
syn boolean TypeDecl.needsConstructor() {
if (componentsTransitive().isEmpty()) {
return false;
}
if (!relationComponents().isEmpty()) {
return true;
}
return hasSuper()
&& getSuper().decl() != null
&& getSuper().decl().needsConstructor();
}
}
aspect Utils {
syn boolean RelationComponent.isMany() = false;
eq ManyRelationComponent.isMany() = true;
public String SimpleTypeUse.toString() {
return getID();
}
public String ParameterizedTypeUse.toString() {
StringBuilder sb = new StringBuilder();
sb.append(getID()).append("<");
int i = 0;
for (TypeUse u: getTypeUses()) {
sb.append(u.toString());
if (++i < getNumTypeUse()) {
sb.append(", ");
}
}
sb.append(">");
return sb.toString();
}
public String TypeDecl.toString() {
return getID();
}
}