Skip to content
Snippets Groups Projects
Select Git revision
  • dev default protected
  • main protected
  • feature/better-placeholders
  • 0.3.0
  • 0.2.5
  • 0.2.4
  • 0.2.3
  • 0.2.1
  • 0.2
  • 0.1
10 results

Analysis.jrag

Blame
  • 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();
      }
    }