Skip to content
Snippets Groups Projects
Commit 20e70452 authored by Johannes Mey's avatar Johannes Mey
Browse files

Merge branch 'master' into json-pointer

parents 21f989ad 6a3f2671
No related branches found
No related tags found
1 merge request!5Json pointer
...@@ -4,8 +4,10 @@ import java.util.*; ...@@ -4,8 +4,10 @@ import java.util.*;
aspect TypeAnalysis { aspect TypeAnalysis {
public abstract TypeUse Component.getTypeUse(); public abstract TypeUse Component.getTypeUse();
//--- lookupType ---
syn TypeDecl TypeUse.decl() = lookupType(getID()); syn TypeDecl TypeUse.decl() = lookupType(getID());
inh TypeDecl TypeUse.lookupType(String name); inh TypeDecl TypeUse.lookupType(String name);
inh TypeDecl TypeDecl.lookupType(String name);
eq Program.getChild().lookupType(String name) { eq Program.getChild().lookupType(String name) {
for (TypeDecl td : getTypeDecls()) { for (TypeDecl td : getTypeDecls()) {
if (td.getID().equals(name)) { if (td.getID().equals(name)) {
...@@ -14,60 +16,50 @@ aspect TypeAnalysis { ...@@ -14,60 +16,50 @@ aspect TypeAnalysis {
} }
return null; return null;
} }
syn boolean TypeDecl.isAlreadyDeclared()
= lookupType(getID()) != this;
inh TypeDecl TypeDecl.lookupType(String name);
syn TypeDecl TypeDecl.mostGeneralSuperType() { //--- isAlreadyDeclared ---
if (!hasSuper()) { syn boolean TypeDecl.isAlreadyDeclared() = lookupType(getID()) != this;
return this;
} else {
return getSuper().decl().mostGeneralSuperType();
}
}
} }
aspect ComponentAnalysis { aspect ComponentAnalysis {
syn boolean Component.isTargetOfDirectedRelation() = false; //--- isTargetOfDirectedRelation ---
eq RelationComponent.isTargetOfDirectedRelation() = isTargetOfRightDirection() | isTargetOfLeftDirection(); inh boolean Component.isTargetOfDirectedRelation();
inh boolean RelationComponent.isTargetOfRightDirection(); eq Relation.getRight().isTargetOfDirectedRelation() = getDirection() instanceof RightDirection;
eq Relation.getRight().isTargetOfRightDirection() eq Program.getChild().isTargetOfDirectedRelation() = false;
= getDirection() instanceof RightDirection;
eq Program.getChild().isTargetOfRightDirection() = false;
inh boolean RelationComponent.isTargetOfLeftDirection();
eq Relation.getLeft().isTargetOfLeftDirection()
= getDirection() instanceof LeftDirection;
eq Program.getChild().isTargetOfLeftDirection() = false;
//--- name ---
syn String Component.name() = getID(); syn String Component.name() = getID();
syn TypeDecl Component.toTypeDecl() = enclosingTypeDecl(); //--- enclosingTypeDecl ---
eq RelationComponent.toTypeDecl() = getTypeUse().decl();
inh TypeDecl Component.enclosingTypeDecl(); inh TypeDecl Component.enclosingTypeDecl();
eq TypeDecl.getChild().enclosingTypeDecl() = this; eq TypeDecl.getChild().enclosingTypeDecl() = this;
eq Program.getChild().enclosingTypeDecl() = null; eq Program.getChild().enclosingTypeDecl() = null;
//--- otherSide ---
inh RelationComponent RelationComponent.otherSide(); inh RelationComponent RelationComponent.otherSide();
eq Relation.getLeft().otherSide() = getRight(); eq Relation.getLeft().otherSide() = getRight();
eq Relation.getRight().otherSide() = getLeft(); eq Relation.getRight().otherSide() = getLeft();
eq Program.getChild().otherSide() = null; eq Program.getChild().otherSide() = null;
syn TypeDecl RelationComponent.ofTypeDecl() = otherSide().toTypeDecl(); //--- ofTypeDecl ---
syn TypeDecl RelationComponent.ofTypeDecl() = otherSide().getTypeUse().decl();
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;
}
//--- isAlreadyDeclared ---
/**
* Check, if role with the same name is already declared on the same nonterminal
*/
syn boolean RelationComponent.isAlreadyDeclared()
= !isTargetOfDirectedRelation() /* if unnamed in relation, there is no role name, so no error */
&& getTypeUse().decl() != null /* nonterminal type of role is defined */
&& findComponent(getTypeUse().decl(), name()) != this; /* there is another role defined previously with the same name */
//--- findComponent ---
/** Search for either a component on the RHS of the given type with the given name,
* or a relation part for the given type and a role with the given name */
inh Component Component.findComponent(TypeDecl td, String name);
eq Program.getChild().findComponent(TypeDecl td, String name)
= findComponentSyn(td, name);
syn Component Program.findComponentSyn(TypeDecl td, String name) {
for (Component c: td.getComponents()) { for (Component c: td.getComponents()) {
if (c.name().equals(name)) { if (c.name().equals(name)) {
return c; return c;
...@@ -75,29 +67,74 @@ aspect ComponentAnalysis { ...@@ -75,29 +67,74 @@ aspect ComponentAnalysis {
} }
for (Relation r : getRelations()) { for (Relation r : getRelations()) {
Component c = r.getLeft().lookup(td, name); if (r.getLeft().matches(td, name))
if (c != null) return c; return r.getLeft();
c = r.getRight().lookup(td, name); if (r.getRight().matches(td, name))
if (c != null) return c; return r.getRight();
} }
return null; return null;
} }
syn RelationComponent RelationComponent.lookup(TypeDecl td, String name) //--- isInvalidRedefinition ---
= !isTargetOfDirectedRelation() && toTypeDecl() == td && name().equals(name) /**
? this * Check, if a component with the same name is already declared in some supertype
: null; */
syn boolean Component.isInvalidRedefinition() = invalidRedefinition() != null;
/**
* Check, if a component with the same name is already declared in some supertype, and return it, if any
*/
syn Component Component.invalidRedefinition() = null;
eq TokenComponent.invalidRedefinition() = invalidRedefinitionOn(enclosingTypeDecl());
eq RelationComponent.invalidRedefinition() = invalidRedefinitionOn(getTypeUse().decl());
syn Component Component.invalidRedefinitionOn(TypeDecl td) {
if (td == null) return null;
while (td.hasSuper() && td.getSuper().decl() != null) {
td = td.getSuper().decl();
// find a matching component on the RHS of the (current) super type
Component c = findComponent(td, getID());
if (c != null && !this.isEqual(c)) return c;
}
return null;
}
//--- isEqual ---
syn boolean Component.isEqual(Component c) = this.getClass() == c.getClass() && getTypeUse().isEqual(c.getTypeUse());
syn boolean TypeUse.isEqual(TypeUse u);
eq SimpleTypeUse.isEqual(TypeUse u) = u instanceof SimpleTypeUse && getID().equals(u.getID());
eq ParameterizedTypeUse.isEqual(TypeUse u) {
if (!getID().equals(u.getID())) return false;
if (!(u instanceof ParameterizedTypeUse)) return false;
ParameterizedTypeUse pu = (ParameterizedTypeUse) u;
if (getNumTypeUse() != pu.getNumTypeUse()) return false;
for (int i = 0; i < getNumTypeUse(); i++) {
if (!getTypeUse(i).isEqual(pu.getTypeUse(i))) return false;
}
return true;
}
//--- matches ---
/**
* @return true, if the component has both type and role, its type matches the given typeDecl and its name matches the given name
*/
syn boolean RelationComponent.matches(TypeDecl td, String name)
= !isTargetOfDirectedRelation() && getTypeUse().decl() == td && name().equals(name);
//--- relationComponents ---
coll Set<RelationComponent> TypeDecl.relationComponents() coll Set<RelationComponent> TypeDecl.relationComponents()
[new HashSet<RelationComponent>()] [new HashSet<RelationComponent>()]
root Program; root Program;
RelationComponent contributes this RelationComponent contributes this
when !isTargetOfDirectedRelation() && toTypeDecl() != null when !isTargetOfDirectedRelation() && getTypeUse().decl() != null
to TypeDecl.relationComponents() to TypeDecl.relationComponents()
for toTypeDecl(); for getTypeUse().decl();
//--- relationComponentsTransitive ---
syn Collection<RelationComponent> TypeDecl.relationComponentsTransitive() { syn Collection<RelationComponent> TypeDecl.relationComponentsTransitive() {
ArrayList<RelationComponent> list = new ArrayList<>(); ArrayList<RelationComponent> list = new ArrayList<>();
if (hasSuper() && getSuper().decl() != null) { if (hasSuper() && getSuper().decl() != null) {
...@@ -107,6 +144,7 @@ aspect ComponentAnalysis { ...@@ -107,6 +144,7 @@ aspect ComponentAnalysis {
return list; return list;
} }
//--- oneRelationComponents ---
syn Set<OneRelationComponent> TypeDecl.oneRelationComponents() { syn Set<OneRelationComponent> TypeDecl.oneRelationComponents() {
Set<OneRelationComponent> set = new HashSet<>(); Set<OneRelationComponent> set = new HashSet<>();
for (RelationComponent rc: relationComponents()) { for (RelationComponent rc: relationComponents()) {
...@@ -117,27 +155,33 @@ aspect ComponentAnalysis { ...@@ -117,27 +155,33 @@ aspect ComponentAnalysis {
return set; return set;
} }
//--- needUnresolvedClass ---
syn boolean TypeDecl.needUnresolvedClass() { syn boolean TypeDecl.needUnresolvedClass() {
// a TypeDecl needs an unresolved class, if it can appear in a relation // a TypeDecl needs an unresolved class, if it can appear in a relation
// TODO // TODO
return true; return true;
} }
//--- isList ---
syn boolean Component.isList() = false; syn boolean Component.isList() = false;
eq ListComponent.isList() = true; eq ListComponent.isList() = true;
//--- isOpt ---
syn boolean Component.isOpt() = false; syn boolean Component.isOpt() = false;
eq OptComponent.isOpt() = true; eq OptComponent.isOpt() = true;
//--- isNullable ---
syn boolean Component.isNullable() = false; syn boolean Component.isNullable() = false;
eq TokenComponent.isNullable() = !"float double int short long char byte boolean".contains(getTypeUse().getID()); eq TokenComponent.isNullable() = !"float double int short long char byte boolean".contains(getTypeUse().getID());
} }
aspect InstanceSupplier { aspect InstanceSupplier {
//--- program ---
inh Program TypeDecl.program(); inh Program TypeDecl.program();
eq Program.getTypeDecl(int i).program() = this; eq Program.getTypeDecl(int i).program() = this;
//--- subTypeDecls ---
syn Collection<TypeDecl> TypeDecl.subTypeDecls() { syn Collection<TypeDecl> TypeDecl.subTypeDecls() {
java.util.List<TypeDecl> subDecls = new ArrayList(); java.util.List<TypeDecl> subDecls = new ArrayList();
for (TypeDecl decl : program().getTypeDeclList()) { for (TypeDecl decl : program().getTypeDeclList()) {
...@@ -148,6 +192,7 @@ aspect InstanceSupplier { ...@@ -148,6 +192,7 @@ aspect InstanceSupplier {
return subDecls; return subDecls;
} }
//--- instantiableSubType ---
syn TypeDecl TypeDecl.instantiableSubType() { syn TypeDecl TypeDecl.instantiableSubType() {
if (getAbstract() == false) { if (getAbstract() == false) {
return this; return this;
...@@ -168,6 +213,7 @@ aspect InstanceSupplier { ...@@ -168,6 +213,7 @@ aspect InstanceSupplier {
} }
aspect Constructors { aspect Constructors {
//--- componentsTransitive ---
syn Collection<Component> TypeDecl.componentsTransitive() { syn Collection<Component> TypeDecl.componentsTransitive() {
ArrayList<Component> list = new ArrayList<>(); ArrayList<Component> list = new ArrayList<>();
if (hasSuper() && getSuper().decl() != null) { if (hasSuper() && getSuper().decl() != null) {
...@@ -181,6 +227,7 @@ aspect Constructors { ...@@ -181,6 +227,7 @@ aspect Constructors {
return list; return list;
} }
//--- needsConstructor ---
syn boolean TypeDecl.needsConstructor() { syn boolean TypeDecl.needsConstructor() {
if (componentsTransitive().isEmpty()) { if (componentsTransitive().isEmpty()) {
return false; return false;
...@@ -193,30 +240,37 @@ aspect Constructors { ...@@ -193,30 +240,37 @@ aspect Constructors {
&& getSuper().decl().needsConstructor(); && getSuper().decl().needsConstructor();
} }
//--- inConstructor ---
/** /**
* @return true, if the component should be added to the constructor (i.e., is not an NTA) * @return true, if the component should be added to the constructor (i.e., is not an NTA)
*/ */
syn boolean Component.inConstructor() = true; syn boolean Component.inConstructor() = true;
eq NTAComponent.inConstructor() = false; eq NTAComponent.inConstructor() = false;
eq NTAOptComponent.inConstructor() = false;
eq NTAListComponent.inConstructor() = false;
} }
aspect Utils { aspect Utils {
//--- isMany ---
syn boolean RelationComponent.isMany() = false; syn boolean RelationComponent.isMany() = false;
eq ManyRelationComponent.isMany() = true; eq ManyRelationComponent.isMany() = true;
//--- toString ---
public String SimpleTypeUse.toString() { public String SimpleTypeUse.toString() {
return getID(); return getID();
} }
public String ParameterizedTypeUse.toString() { public String ParameterizedTypeUse.toString() {
StringBuilder sb = new StringBuilder(); StringBuilder sb = new StringBuilder();
sb.append(getID()).append("<"); sb.append(getID()).append("<");
int i = 0; boolean first = true;
for (TypeUse u: getTypeUses()) { for (TypeUse u: getTypeUses()) {
sb.append(u.toString()); if (first) {
if (++i < getNumTypeUse()) { first = false;
} else {
sb.append(", "); sb.append(", ");
} }
sb.append(u.toString());
} }
sb.append(">"); sb.append(">");
return sb.toString(); return sb.toString();
......
...@@ -242,7 +242,7 @@ aspect BackendDirectedAPI { ...@@ -242,7 +242,7 @@ aspect BackendDirectedAPI {
generateGetOne(sb); generateGetOne(sb);
// Set // Set
sb.append(ind(1) + "public " + toTypeDecl() + " " + toTypeDecl()); sb.append(ind(1) + "public " + getTypeUse().decl() + " " + getTypeUse().decl());
sb.append(".set" + nameCapitalized() + "(" + ofTypeDecl() + " o) {\n"); sb.append(".set" + nameCapitalized() + "(" + ofTypeDecl() + " o) {\n");
if (!optional) { if (!optional) {
sb.append(ind(2) + "assertNotNull(o);\n"); sb.append(ind(2) + "assertNotNull(o);\n");
...@@ -254,7 +254,7 @@ aspect BackendDirectedAPI { ...@@ -254,7 +254,7 @@ aspect BackendDirectedAPI {
public void ManyRelationComponent.generateDirectedAPI(StringBuilder sb) { public void ManyRelationComponent.generateDirectedAPI(StringBuilder sb) {
// Get // Get
sb.append(ind(1) + "public java.util.List<" + ofTypeDecl() + "> " + toTypeDecl() + "."); sb.append(ind(1) + "public java.util.List<" + ofTypeDecl() + "> " + getTypeUse().decl() + ".");
if (useJastAddNames) { if (useJastAddNames) {
// getXs // getXs
sb.append("get" + nameCapitalized() + "s() {\n"); sb.append("get" + nameCapitalized() + "s() {\n");
...@@ -262,7 +262,7 @@ aspect BackendDirectedAPI { ...@@ -262,7 +262,7 @@ aspect BackendDirectedAPI {
sb.append(ind(1) + "}\n"); sb.append(ind(1) + "}\n");
// getXList // getXList
sb.append(ind(1) + "public java.util.List<" + ofTypeDecl() + "> " + toTypeDecl()); sb.append(ind(1) + "public java.util.List<" + ofTypeDecl() + "> " + getTypeUse().decl());
sb.append(".get" + nameCapitalized() + "List() {\n"); sb.append(".get" + nameCapitalized() + "List() {\n");
} else { } else {
sb.append(name() + "() {\n"); sb.append(name() + "() {\n");
...@@ -289,7 +289,7 @@ aspect BackendDirectedAPI { ...@@ -289,7 +289,7 @@ aspect BackendDirectedAPI {
sb.append(ind(1) + "}\n"); sb.append(ind(1) + "}\n");
// Add // Add
sb.append(ind(1) + "public void " + toTypeDecl() + ".add"); sb.append(ind(1) + "public void " + getTypeUse().decl() + ".add");
if (!useJastAddNames) { if (!useJastAddNames) {
sb.append("To"); sb.append("To");
} }
...@@ -304,7 +304,7 @@ aspect BackendDirectedAPI { ...@@ -304,7 +304,7 @@ aspect BackendDirectedAPI {
sb.append(ind(1) + "}\n"); sb.append(ind(1) + "}\n");
// Insert / add at specific position // Insert / add at specific position
sb.append(ind(1) + "public void " + toTypeDecl() + ".add"); sb.append(ind(1) + "public void " + getTypeUse().decl() + ".add");
if (!useJastAddNames) { if (!useJastAddNames) {
sb.append("To"); sb.append("To");
} }
...@@ -319,7 +319,7 @@ aspect BackendDirectedAPI { ...@@ -319,7 +319,7 @@ aspect BackendDirectedAPI {
sb.append(ind(1) + "}\n"); sb.append(ind(1) + "}\n");
// Remove // Remove
sb.append(ind(1) + "public void " + toTypeDecl() + ".remove"); sb.append(ind(1) + "public void " + getTypeUse().decl() + ".remove");
if (!useJastAddNames) { if (!useJastAddNames) {
sb.append("From"); sb.append("From");
} }
...@@ -333,7 +333,7 @@ aspect BackendDirectedAPI { ...@@ -333,7 +333,7 @@ aspect BackendDirectedAPI {
} }
public void RelationComponent.generateGetOne(StringBuilder sb) { public void RelationComponent.generateGetOne(StringBuilder sb) {
sb.append(ind(1) + "public " + ofTypeDecl() + " " + toTypeDecl() + "."); sb.append(ind(1) + "public " + ofTypeDecl() + " " + getTypeUse().decl() + ".");
if (useJastAddNames) { if (useJastAddNames) {
sb.append("get" + nameCapitalized()); sb.append("get" + nameCapitalized());
} else { } else {
...@@ -355,7 +355,7 @@ aspect BackendDirectedAPI { ...@@ -355,7 +355,7 @@ aspect BackendDirectedAPI {
public void RelationComponent.generateExtraOptAPI(StringBuilder sb) { public void RelationComponent.generateExtraOptAPI(StringBuilder sb) {
// has // has
sb.append(ind(1) + "public boolean " + toTypeDecl()); sb.append(ind(1) + "public boolean " + getTypeUse().decl());
sb.append(".has" + nameCapitalized() + "() {\n"); sb.append(".has" + nameCapitalized() + "() {\n");
sb.append(ind(2) + "return "); sb.append(ind(2) + "return ");
if (useJastAddNames) { if (useJastAddNames) {
...@@ -367,7 +367,7 @@ aspect BackendDirectedAPI { ...@@ -367,7 +367,7 @@ aspect BackendDirectedAPI {
sb.append(ind(1) + "}\n"); sb.append(ind(1) + "}\n");
// clear // clear
sb.append(ind(1) + "public void " + toTypeDecl()); sb.append(ind(1) + "public void " + getTypeUse().decl());
sb.append(".clear" + nameCapitalized() + "() {\n"); sb.append(".clear" + nameCapitalized() + "() {\n");
sb.append(ind(2) + "set" + nameCapitalized() + "(null);\n"); sb.append(ind(2) + "set" + nameCapitalized() + "(null);\n");
sb.append(ind(1) + "}\n"); sb.append(ind(1) + "}\n");
...@@ -420,7 +420,7 @@ aspect BackendBidirectionalAPI { ...@@ -420,7 +420,7 @@ aspect BackendBidirectionalAPI {
generateGetOne(sb); generateGetOne(sb);
// Set // Set
sb.append(ind(1) + "public " + toTypeDecl() + " " + toTypeDecl()); sb.append(ind(1) + "public " + getTypeUse().decl() + " " + getTypeUse().decl());
sb.append(".set" + nameCapitalized() + "(" + ofTypeDecl() + " o) {\n"); sb.append(".set" + nameCapitalized() + "(" + ofTypeDecl() + " o) {\n");
if (!isOpt) { if (!isOpt) {
sb.append(ind(2) + "assertNotNull(o);\n"); sb.append(ind(2) + "assertNotNull(o);\n");
...@@ -467,7 +467,7 @@ aspect BackendBidirectionalAPI { ...@@ -467,7 +467,7 @@ aspect BackendBidirectionalAPI {
public void RelationComponent.generateBiManyMany(StringBuilder sb, RelationComponent opposite) { public void RelationComponent.generateBiManyMany(StringBuilder sb, RelationComponent opposite) {
// Get // Get
sb.append(ind(1) + "public java.util.List<" + ofTypeDecl() + "> " + toTypeDecl() + "."); sb.append(ind(1) + "public java.util.List<" + ofTypeDecl() + "> " + getTypeUse().decl() + ".");
if (useJastAddNames) { if (useJastAddNames) {
// getXs // getXs
sb.append("get" + nameCapitalized() + "s() {\n"); sb.append("get" + nameCapitalized() + "s() {\n");
...@@ -475,7 +475,7 @@ aspect BackendBidirectionalAPI { ...@@ -475,7 +475,7 @@ aspect BackendBidirectionalAPI {
sb.append(ind(1) + "}\n"); sb.append(ind(1) + "}\n");
// getXList // getXList
sb.append(ind(1) + "public java.util.List<" + ofTypeDecl() + "> " + toTypeDecl()); sb.append(ind(1) + "public java.util.List<" + ofTypeDecl() + "> " + getTypeUse().decl());
sb.append(".get" + nameCapitalized() + "List() {\n"); sb.append(".get" + nameCapitalized() + "List() {\n");
} else { } else {
sb.append(name() + "() {\n"); sb.append(name() + "() {\n");
...@@ -491,7 +491,7 @@ aspect BackendBidirectionalAPI { ...@@ -491,7 +491,7 @@ aspect BackendBidirectionalAPI {
sb.append(ind(5) + "changed = true;\n"); sb.append(ind(5) + "changed = true;\n");
sb.append(ind(5) + ofTypeDecl() + " resolvedElement = resolve" + nameCapitalized() + "ByToken(element.as$Unresolved().getUnresolved$Token(), i);\n"); sb.append(ind(5) + ofTypeDecl() + " resolvedElement = resolve" + nameCapitalized() + "ByToken(element.as$Unresolved().getUnresolved$Token(), i);\n");
sb.append(ind(5) + "if (resolvedElement != null && element.as$Unresolved().getUnresolved$ResolveOpposite()) {\n"); sb.append(ind(5) + "if (resolvedElement != null && element.as$Unresolved().getUnresolved$ResolveOpposite()) {\n");
sb.append(ind(6) + ASTNode.listClass + "<" + toTypeDecl() + "> otherList = resolvedElement." + opposite.getImplAttributeField() + ";\n"); sb.append(ind(6) + ASTNode.listClass + "<" + getTypeUse().decl() + "> otherList = resolvedElement." + opposite.getImplAttributeField() + ";\n");
sb.append(ind(6) + "if (otherList == null) {\n"); sb.append(ind(6) + "if (otherList == null) {\n");
sb.append(ind(7) + "otherList = new " + listClass + "<>();\n"); sb.append(ind(7) + "otherList = new " + listClass + "<>();\n");
sb.append(ind(6) + "}\n"); sb.append(ind(6) + "}\n");
...@@ -510,7 +510,7 @@ aspect BackendBidirectionalAPI { ...@@ -510,7 +510,7 @@ aspect BackendBidirectionalAPI {
sb.append(ind(1) + "}\n"); sb.append(ind(1) + "}\n");
// Add // Add
sb.append(ind(1) + "public void " + toTypeDecl() + ".add"); sb.append(ind(1) + "public void " + getTypeUse().decl() + ".add");
if (!useJastAddNames) { if (!useJastAddNames) {
sb.append("To"); sb.append("To");
} }
...@@ -531,7 +531,7 @@ aspect BackendBidirectionalAPI { ...@@ -531,7 +531,7 @@ aspect BackendBidirectionalAPI {
sb.append(ind(1) + "}\n"); sb.append(ind(1) + "}\n");
// Insert / add at specific position // Insert / add at specific position
sb.append(ind(1) + "public void " + toTypeDecl() + ".add"); sb.append(ind(1) + "public void " + getTypeUse().decl() + ".add");
if (!useJastAddNames) { if (!useJastAddNames) {
sb.append("To"); sb.append("To");
} }
...@@ -553,7 +553,7 @@ aspect BackendBidirectionalAPI { ...@@ -553,7 +553,7 @@ aspect BackendBidirectionalAPI {
sb.append(ind(1) + "}\n"); sb.append(ind(1) + "}\n");
// Remove // Remove
sb.append(ind(1) + "public void " + toTypeDecl() + ".remove"); sb.append(ind(1) + "public void " + getTypeUse().decl() + ".remove");
if (!useJastAddNames) { if (!useJastAddNames) {
sb.append("From"); sb.append("From");
} }
...@@ -573,7 +573,7 @@ aspect BackendBidirectionalAPI { ...@@ -573,7 +573,7 @@ aspect BackendBidirectionalAPI {
public void RelationComponent.generateBiManyOne(StringBuilder sb, RelationComponent opposite) { public void RelationComponent.generateBiManyOne(StringBuilder sb, RelationComponent opposite) {
// Get // Get
sb.append(ind(1) + "public java.util.List<" + ofTypeDecl() + "> " + toTypeDecl() + "."); sb.append(ind(1) + "public java.util.List<" + ofTypeDecl() + "> " + getTypeUse().decl() + ".");
if (useJastAddNames) { if (useJastAddNames) {
// getXs // getXs
sb.append("get" + nameCapitalized() + "s() {\n"); sb.append("get" + nameCapitalized() + "s() {\n");
...@@ -581,7 +581,7 @@ aspect BackendBidirectionalAPI { ...@@ -581,7 +581,7 @@ aspect BackendBidirectionalAPI {
sb.append(ind(1) + "}\n"); sb.append(ind(1) + "}\n");
// getXList // getXList
sb.append(ind(1) + "public java.util.List<" + ofTypeDecl() + "> " + toTypeDecl()); sb.append(ind(1) + "public java.util.List<" + ofTypeDecl() + "> " + getTypeUse().decl());
sb.append(".get" + nameCapitalized() + "List() {\n"); sb.append(".get" + nameCapitalized() + "List() {\n");
} else { } else {
sb.append(name() + "() {\n"); sb.append(name() + "() {\n");
...@@ -597,7 +597,7 @@ aspect BackendBidirectionalAPI { ...@@ -597,7 +597,7 @@ aspect BackendBidirectionalAPI {
sb.append(ind(5) + "changed = true;\n"); sb.append(ind(5) + "changed = true;\n");
sb.append(ind(5) + ofTypeDecl() + " resolvedElement = resolve" + nameCapitalized() + "ByToken(element.as$Unresolved().getUnresolved$Token(), i);\n"); sb.append(ind(5) + ofTypeDecl() + " resolvedElement = resolve" + nameCapitalized() + "ByToken(element.as$Unresolved().getUnresolved$Token(), i);\n");
sb.append(ind(5) + "if (element.as$Unresolved().getUnresolved$ResolveOpposite()) {\n"); sb.append(ind(5) + "if (element.as$Unresolved().getUnresolved$ResolveOpposite()) {\n");
sb.append(ind(6) + toTypeDecl() + " oldTarget = resolvedElement." + opposite.getImplAttributeField() + ";\n"); sb.append(ind(6) + getTypeUse().decl() + " oldTarget = resolvedElement." + opposite.getImplAttributeField() + ";\n");
sb.append(ind(6) + "if (oldTarget != null && oldTarget != this) {\n"); sb.append(ind(6) + "if (oldTarget != null && oldTarget != this) {\n");
sb.append(ind(7) + "oldTarget." + getImplAttributeField() + ".remove(resolvedElement);\n"); sb.append(ind(7) + "oldTarget." + getImplAttributeField() + ".remove(resolvedElement);\n");
sb.append(ind(6) + "}\n"); sb.append(ind(6) + "}\n");
...@@ -622,7 +622,7 @@ aspect BackendBidirectionalAPI { ...@@ -622,7 +622,7 @@ aspect BackendBidirectionalAPI {
sb.append(ind(1) + "}\n"); sb.append(ind(1) + "}\n");
// Add // Add
sb.append(ind(1) + "public void " + toTypeDecl() + ".add"); sb.append(ind(1) + "public void " + getTypeUse().decl() + ".add");
if (!useJastAddNames) { if (!useJastAddNames) {
sb.append("To"); sb.append("To");
} }
...@@ -645,7 +645,7 @@ aspect BackendBidirectionalAPI { ...@@ -645,7 +645,7 @@ aspect BackendBidirectionalAPI {
sb.append(ind(1) + "}\n"); sb.append(ind(1) + "}\n");
// Insert / add at specific position // Insert / add at specific position
sb.append(ind(1) + "public void " + toTypeDecl() + ".add"); sb.append(ind(1) + "public void " + getTypeUse().decl() + ".add");
if (!useJastAddNames) { if (!useJastAddNames) {
sb.append("To"); sb.append("To");
} }
...@@ -666,7 +666,7 @@ aspect BackendBidirectionalAPI { ...@@ -666,7 +666,7 @@ aspect BackendBidirectionalAPI {
sb.append(ind(1) + "}\n"); sb.append(ind(1) + "}\n");
// Remove // Remove
sb.append(ind(1) + "public void " + toTypeDecl() + ".remove"); sb.append(ind(1) + "public void " + getTypeUse().decl() + ".remove");
if (!useJastAddNames) { if (!useJastAddNames) {
sb.append("From"); sb.append("From");
} }
...@@ -687,13 +687,13 @@ aspect BackendBidirectionalAPI { ...@@ -687,13 +687,13 @@ aspect BackendBidirectionalAPI {
generateGetOne(sb); generateGetOne(sb);
// Set // Set
sb.append(ind(1) + "public " + toTypeDecl() + " " + toTypeDecl() + ".set" + nameCapitalized() sb.append(ind(1) + "public " + getTypeUse().decl() + " " + getTypeUse().decl() + ".set" + nameCapitalized()
+ "(" + ofTypeDecl() + " o) {\n"); + "(" + ofTypeDecl() + " o) {\n");
if (!isOpt) { if (!isOpt) {
sb.append(ind(2) + "assertNotNull(o);\n"); sb.append(ind(2) + "assertNotNull(o);\n");
} }
sb.append(ind(2) + "if (" + getImplAttributeField() + " != null) {\n"); sb.append(ind(2) + "if (" + getImplAttributeField() + " != null) {\n");
sb.append(ind(3) + ASTNode.listClass + "<" + toTypeDecl() + "> list2 = " + getImplAttributeField() sb.append(ind(3) + ASTNode.listClass + "<" + getTypeUse().decl() + "> list2 = " + getImplAttributeField()
+ "." + otherSide().getImplAttributeField() + ";\n"); + "." + otherSide().getImplAttributeField() + ";\n");
sb.append(ind(3) + "list2.remove(this);\n"); sb.append(ind(3) + "list2.remove(this);\n");
sb.append(ind(3) + getImplAttributeField() + "." + "set" sb.append(ind(3) + getImplAttributeField() + "." + "set"
...@@ -705,7 +705,7 @@ aspect BackendBidirectionalAPI { ...@@ -705,7 +705,7 @@ aspect BackendBidirectionalAPI {
if (isOpt) { if (isOpt) {
sb.append(ind(2) + "if (o != null) {\n"); sb.append(ind(2) + "if (o != null) {\n");
} }
sb.append(ind(ind) + ASTNode.listClass + "<" + toTypeDecl() + "> list = o." sb.append(ind(ind) + ASTNode.listClass + "<" + getTypeUse().decl() + "> list = o."
+ otherSide().getImplAttributeField() + ";\n"); + otherSide().getImplAttributeField() + ";\n");
sb.append(ind(ind) + "if (list == null) {\n"); sb.append(ind(ind) + "if (list == null) {\n");
sb.append(ind(ind+1) + "list = new " + ASTNode.listClass + "<>();\n"); sb.append(ind(ind+1) + "list = new " + ASTNode.listClass + "<>();\n");
...@@ -880,7 +880,7 @@ aspect NameResolutionHelper { ...@@ -880,7 +880,7 @@ aspect NameResolutionHelper {
public void RelationComponent.generateContextDependentRefCreation(StringBuilder sb) { public void RelationComponent.generateContextDependentRefCreation(StringBuilder sb) {
sb.append(ind(1) + "// context-dependent reference creation\n"); sb.append(ind(1) + "// context-dependent reference creation\n");
sb.append(ind(1) + "syn String " + toTypeDecl() + ".createRefTo" + nameCapitalized() + "(" + ofTypeDecl() + " target) {\n"); sb.append(ind(1) + "syn String " + getTypeUse().decl() + ".createRefTo" + nameCapitalized() + "(" + ofTypeDecl() + " target) {\n");
sb.append(ind(2) + "// default to context-independent reference creation\n"); sb.append(ind(2) + "// default to context-independent reference creation\n");
sb.append(ind(2) + "return target.createReference();\n"); sb.append(ind(2) + "return target.createReference();\n");
sb.append(ind(1) + "}\n"); sb.append(ind(1) + "}\n");
...@@ -999,13 +999,13 @@ aspect NameResolutionHelper { ...@@ -999,13 +999,13 @@ aspect NameResolutionHelper {
public void ManyRelationComponent.generateContextDependentNameResolution(StringBuilder sb) { public void ManyRelationComponent.generateContextDependentNameResolution(StringBuilder sb) {
if (serializer && !resolverHelper) { if (serializer && !resolverHelper) {
sb.append(ind(1) + ofTypeDecl() + " " + toTypeDecl() + ".resolve" + nameCapitalized() + "ByToken(String id, int position) {\n"); sb.append(ind(1) + ofTypeDecl() + " " + getTypeUse().decl() + ".resolve" + nameCapitalized() + "ByToken(String id, int position) {\n");
sb.append(ind(2) + "return (" + ofTypeDecl() + ") globallyResolveASTNodeByUID(id);\n"); sb.append(ind(2) + "return (" + ofTypeDecl() + ") globallyResolveASTNodeByUID(id);\n");
sb.append(ind(1) + "}\n"); sb.append(ind(1) + "}\n");
} else { } else {
sb.append(ind(1) + "// context-dependent name resolution\n"); sb.append(ind(1) + "// context-dependent name resolution\n");
sb.append(ind(1) + "uncache " + toTypeDecl() + ".resolve" + nameCapitalized() + "ByToken(String id, int position);\n"); sb.append(ind(1) + "uncache " + getTypeUse().decl() + ".resolve" + nameCapitalized() + "ByToken(String id, int position);\n");
sb.append(ind(1) + "syn " + ofTypeDecl() + " " + toTypeDecl() + ".resolve" + nameCapitalized() + "ByToken(String id, int position) {\n"); sb.append(ind(1) + "syn " + ofTypeDecl() + " " + getTypeUse().decl() + ".resolve" + nameCapitalized() + "ByToken(String id, int position) {\n");
sb.append(ind(2) + "// default to context-independent name resolution\n"); sb.append(ind(2) + "// default to context-independent name resolution\n");
sb.append(ind(2) + "return globallyResolve" + ofTypeDecl() + "ByToken(id);\n"); sb.append(ind(2) + "return globallyResolve" + ofTypeDecl() + "ByToken(id);\n");
sb.append(ind(1) + "}\n"); sb.append(ind(1) + "}\n");
...@@ -1014,13 +1014,13 @@ aspect NameResolutionHelper { ...@@ -1014,13 +1014,13 @@ aspect NameResolutionHelper {
public void RelationComponent.generateDirectedContextDependentNameResolution(StringBuilder sb) { public void RelationComponent.generateDirectedContextDependentNameResolution(StringBuilder sb) {
if (serializer && !resolverHelper) { if (serializer && !resolverHelper) {
sb.append(ind(1) + ofTypeDecl() + " " + toTypeDecl() + ".resolve" + nameCapitalized() + "ByToken(String id) {\n"); sb.append(ind(1) + ofTypeDecl() + " " + getTypeUse().decl() + ".resolve" + nameCapitalized() + "ByToken(String id) {\n");
sb.append(ind(2) + "return (" + ofTypeDecl() + ") globallyResolveASTNodeByUID(id);\n"); sb.append(ind(2) + "return (" + ofTypeDecl() + ") globallyResolveASTNodeByUID(id);\n");
sb.append(ind(1) + "}\n"); sb.append(ind(1) + "}\n");
} else { } else {
sb.append(ind(1) + "// context-dependent name resolution\n"); sb.append(ind(1) + "// context-dependent name resolution\n");
sb.append(ind(1) + "uncache " + toTypeDecl() + ".resolve" + nameCapitalized() + "ByToken(String id);\n"); sb.append(ind(1) + "uncache " + getTypeUse().decl() + ".resolve" + nameCapitalized() + "ByToken(String id);\n");
sb.append(ind(1) + "syn " + ofTypeDecl() + " " + toTypeDecl() + ".resolve" + nameCapitalized() + "ByToken(String id) {\n"); sb.append(ind(1) + "syn " + ofTypeDecl() + " " + getTypeUse().decl() + ".resolve" + nameCapitalized() + "ByToken(String id) {\n");
sb.append(ind(2) + "// default to context-independent name resolution\n"); sb.append(ind(2) + "// default to context-independent name resolution\n");
sb.append(ind(2) + "return globallyResolve" + ofTypeDecl() + "ByToken(id);\n"); sb.append(ind(2) + "return globallyResolve" + ofTypeDecl() + "ByToken(id);\n");
sb.append(ind(1) + "}\n"); sb.append(ind(1) + "}\n");
......
...@@ -15,13 +15,25 @@ aspect Errors { ...@@ -15,13 +15,25 @@ aspect Errors {
when isAlreadyDeclared() when isAlreadyDeclared()
to Program.errors(); to Program.errors();
Component contributes error("Component '" + name() RelationComponent contributes error("Role '" + name()
+ "' is already declared for type '" + toTypeDecl() + "'") + "' is already declared for type '" + getTypeUse().decl() + "'")
when isAlreadyDeclared() when isAlreadyDeclared()
to Program.errors(); to Program.errors();
RelationComponent contributes error("Role '" + name()
+ "' is an invalid redefinition for type '" + getTypeUse().decl() + "', conflicts with supertype '"
+ invalidRedefinition().enclosingTypeDecl() + "'")
when isInvalidRedefinition()
to Program.errors();
TokenComponent contributes error("Token '" + name()
+ "' is an invalid redefinition for type '" + enclosingTypeDecl() + "', conflicts with supertype '"
+ invalidRedefinition().enclosingTypeDecl() + "'")
when isInvalidRedefinition()
to Program.errors();
RelationComponent contributes RelationComponent contributes
error("Role name missing for type '" + toTypeDecl() + "'") error("Role name missing for type '" + getTypeUse().decl() + "'")
when !isTargetOfDirectedRelation() && name().isEmpty() when !isTargetOfDirectedRelation() && name().isEmpty()
to Program.errors(); to Program.errors();
......
...@@ -86,9 +86,15 @@ Relation relation = ...@@ -86,9 +86,15 @@ Relation relation =
RELATION relation_comp.l direction relation_comp.r SCOL RELATION relation_comp.l direction relation_comp.r SCOL
{: {:
Relation result = new Relation(); Relation result = new Relation();
if (direction instanceof LeftDirection) {
result.setLeft(r);
result.setDirection(new RightDirection());
result.setRight(l);
} else {
result.setLeft(l); result.setLeft(l);
result.setDirection(direction); result.setDirection(direction);
result.setRight(r); result.setRight(r);
}
return result; return result;
:} :}
; ;
......
...@@ -3,3 +3,4 @@ $FILENAME Line 5, column 5: Role name missing for type 'A' ...@@ -3,3 +3,4 @@ $FILENAME Line 5, column 5: Role name missing for type 'A'
$FILENAME Line 6, column 15: Role name missing for type 'B' $FILENAME Line 6, column 15: Role name missing for type 'B'
$FILENAME Line 7, column 12: The target of a directed relation cannot have a role name $FILENAME Line 7, column 12: The target of a directed relation cannot have a role name
$FILENAME Line 8, column 13: The target of a directed relation may only have multiplicity 1 $FILENAME Line 8, column 13: The target of a directed relation may only have multiplicity 1
$FILENAME Line 9, column 5: Role 'b2' is already declared for type 'A'
...@@ -6,3 +6,4 @@ rel A -> B; ...@@ -6,3 +6,4 @@ rel A -> B;
rel A.bs* <-> B*; rel A.bs* <-> B*;
rel A.b -> B.b; rel A.b -> B.b;
rel A.b2 -> B*; rel A.b2 -> B*;
rel A.b2 -> A;
...@@ -3,3 +3,4 @@ $FILENAME Line 5, column 10: Role name missing for type 'A' ...@@ -3,3 +3,4 @@ $FILENAME Line 5, column 10: Role name missing for type 'A'
$FILENAME Line 6, column 15: Role name missing for type 'B' $FILENAME Line 6, column 15: Role name missing for type 'B'
$FILENAME Line 7, column 5: The target of a directed relation cannot have a role name $FILENAME Line 7, column 5: The target of a directed relation cannot have a role name
$FILENAME Line 8, column 5: The target of a directed relation may only have multiplicity 1 $FILENAME Line 8, column 5: The target of a directed relation may only have multiplicity 1
$FILENAME Line 9, column 10: Role 'b2' is already declared for type 'A'
...@@ -6,3 +6,4 @@ rel B <- A; ...@@ -6,3 +6,4 @@ rel B <- A;
rel A.bs* <-> B*; rel A.bs* <-> B*;
rel B.b <- A.b; rel B.b <- A.b;
rel B* <- A.b2; rel B* <- A.b2;
rel A <- A.b2;
Errors: Errors:
$FILENAME Line 2, column 12: Component 'X' is already declared for type 'B1' $FILENAME Line 4, column 12: Token 'X' is an invalid redefinition for type 'B3', conflicts with supertype 'A'
$FILENAME Line 6, column 5: Component 'X' is already declared for type 'B2' $FILENAME Line 7, column 5: Role 'X' is an invalid redefinition for type 'B2', conflicts with supertype 'A'
A ::= X; A ::= X;
B1 : A ::= X; B1 : A ::= X;
B2 : A; B2 : A;
B3 : A ::= <X:String>;
X; X;
rel B2.X -> X; rel B2.X -> X;
Errors: Errors:
$FILENAME Line 2, column 12: Component 'X' is already declared for type 'B1' $FILENAME Line 4, column 12: Token 'X' is an invalid redefinition for type 'B3', conflicts with supertype 'A'
$FILENAME Line 6, column 10: Component 'X' is already declared for type 'B2' $FILENAME Line 7, column 10: Role 'X' is an invalid redefinition for type 'B2', conflicts with supertype 'A'
A ::= X; A ::= X;
B1 : A ::= X; B1 : A ::= X;
B2 : A; B2 : A;
B3 : A ::= <X:String>;
X; X;
rel X <- B2.X; rel X <- B2.X;
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment