Commit cceb9033 authored by Johannes Mey's avatar Johannes Mey
Browse files

create unresolved classes with aspect, use $ for internal names and reduce visibility. fixes #11

parent 1ef3b087
Pipeline #3115 passed with stage
in 56 seconds
......@@ -112,6 +112,12 @@ aspect ComponentAnalysis {
}
return set;
}
syn boolean TypeDecl.needUnresolvedClass() {
// a TypeDecl needs an unresolved class, if it can appear in a relation
// TODO
return true;
}
}
aspect InstanceSupplier {
......@@ -129,34 +135,23 @@ aspect InstanceSupplier {
return subDecls;
}
syn UnresolvedTypeDecl TypeDecl.instantiableUnresolved() {
syn TypeDecl TypeDecl.instantiableSubType() {
if (getAbstract() == false) {
return this.getUnresolved();
return this;
} else {
for (TypeDecl sub : subTypeDecls()) {
if (sub.getAbstract() == false) {
return sub.getUnresolved();
return sub;
} else {
TypeDecl subInstance = sub.instantiableUnresolved();
TypeDecl subInstance = sub.instantiableSubType();
if (subInstance != null) {
return subInstance.getUnresolved();
return subInstance;
}
}
}
}
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 {
......
......@@ -19,6 +19,47 @@ aspect BackendAbstractGrammar {
}
}
public void TypeDecl.generateUnresolvedClass(StringBuilder sb) {
if (getAbstract()) {
sb.append(ind(1) + "abstract ");
} else {
sb.append(ind(1));
}
sb.append("class " + "Unresolved$" + getID() + " extends " + getID() + " implements Unresolved$Node {\n");
sb.append(ind(2) + "private String unresolved$Token;\n");
sb.append(ind(2) + "public String getUnresolved$Token() {\n");
sb.append(ind(3) + "return unresolved$Token;\n");
sb.append(ind(2) + "}\n");
sb.append(ind(2) + "void setUnresolved$Token(String token) {\n");
sb.append(ind(3) + "this.unresolved$Token = token;\n");
sb.append(ind(2) + "}\n");
sb.append(ind(2) + "private boolean unresolved$ResolveOpposite;\n");
sb.append(ind(2) + "public boolean getUnresolved$ResolveOpposite() {\n");
sb.append(ind(3) + "return unresolved$ResolveOpposite;\n");
sb.append(ind(2) + "}\n");
sb.append(ind(2) + "void setUnresolved$ResolveOpposite(boolean resolveOpposite) {\n");
sb.append(ind(3) + "this.unresolved$ResolveOpposite = resolveOpposite;\n");
sb.append(ind(2) + "}\n");
sb.append(ind(1) + "}\n");
sb.append(ind(1) + "Unresolved$Node " + getID() + ".as$Unresolved() {\n");
sb.append(ind(2) + "return null;\n");
sb.append(ind(1) + "}\n");
sb.append(ind(1) + "Unresolved$Node Unresolved$" + getID() + ".as$Unresolved() {\n");
sb.append(ind(2) + "return this;\n");
sb.append(ind(1) + "}\n");
sb.append(ind(1) + "boolean " + getID() + ".is$Unresolved() {\n");
sb.append(ind(2) + "return false;\n");
sb.append(ind(1) + "}\n");
sb.append(ind(1) + "boolean Unresolved$" + getID() + ".is$Unresolved() {\n");
sb.append(ind(2) + "return true;\n");
sb.append(ind(1) + "}\n");
}
public void TypeDecl.generateAbstractGrammar(StringBuilder sb) {
if (getAbstract()) {
sb.append("abstract ");
......@@ -212,9 +253,9 @@ aspect BackendDirectedAPI {
sb.append(ind(3) + "boolean changed = false;\n");
sb.append(ind(3) + "for (int i = 0; i < l.size(); i++) {\n");
sb.append(ind(4) + ofTypeDecl() + " element = l.get(i);\n");
sb.append(ind(4) + "if (element.unresolved()) {\n");
sb.append(ind(4) + "if (element.is$Unresolved()) {\n");
sb.append(ind(5) + "changed = true;\n");
sb.append(ind(5) + ofTypeDecl() + " resolvedElement = resolve" + nameCapitalized() + "ByToken(element.asUnresolved().get__token(), i);\n");
sb.append(ind(5) + ofTypeDecl() + " resolvedElement = resolve" + nameCapitalized() + "ByToken(element.as$Unresolved().getUnresolved$Token(), i);\n");
sb.append(ind(5) + "l.set(i, resolvedElement);\n");
sb.append(ind(4) + "}\n");
sb.append(ind(3) + "}\n");
......@@ -279,11 +320,11 @@ aspect BackendDirectedAPI {
}
sb.append("() {\n");
if (resolverHelper | serializer) {
sb.append(ind(2) + "if (get" + getImplAttributeName() + "() != null && get" + getImplAttributeName() + "().unresolved()) {\n");
sb.append(ind(3) + "if (get" + getImplAttributeName() + "().asUnresolved().get__resolve_opposite()) {\n");
sb.append(ind(4) + "set" + nameCapitalized() + "(resolve" + nameCapitalized() + "ByToken(get" + getImplAttributeName() + "().asUnresolved().get__token()));\n");
sb.append(ind(2) + "if (get" + getImplAttributeName() + "() != null && get" + getImplAttributeName() + "().is$Unresolved()) {\n");
sb.append(ind(3) + "if (get" + getImplAttributeName() + "().as$Unresolved().getUnresolved$ResolveOpposite()) {\n");
sb.append(ind(4) + "set" + nameCapitalized() + "(resolve" + nameCapitalized() + "ByToken(get" + getImplAttributeName() + "().as$Unresolved().getUnresolved$Token()));\n");
sb.append(ind(3) + "} else {\n");
sb.append(ind(4) + "set" + getImplAttributeName() + "(resolve" + nameCapitalized() + "ByToken(get" + getImplAttributeName() + "().asUnresolved().get__token()));\n");
sb.append(ind(4) + "set" + getImplAttributeName() + "(resolve" + nameCapitalized() + "ByToken(get" + getImplAttributeName() + "().as$Unresolved().getUnresolved$Token()));\n");
sb.append(ind(3) + "}\n");
sb.append(ind(2) + "}\n");
}
......@@ -368,7 +409,7 @@ aspect BackendBidirectionalAPI {
sb.append(ind(3) + "get" + getImplAttributeName() + "().set" + otherSide().getImplAttributeName() + "(null);\n");
sb.append(ind(2) + "}\n");
if (resolverHelper | serializer) {
sb.append(ind(2) + "if (o != null && !o.unresolved() && o.get" + otherSide().getImplAttributeName() + "() != null) {\n");
sb.append(ind(2) + "if (o != null && !o.is$Unresolved() && o.get" + otherSide().getImplAttributeName() + "() != null) {\n");
} else {
sb.append(ind(2) + "if (o != null && o.get" + otherSide().getImplAttributeName() + "() != null) {\n");
}
......@@ -376,7 +417,7 @@ aspect BackendBidirectionalAPI {
sb.append(ind(2) + "}\n");
sb.append(ind(2) + "set" + getImplAttributeName() + "(o);\n");
if (resolverHelper | serializer) {
sb.append(ind(2) + "if (o == null || !o.unresolved()) {\n");
sb.append(ind(2) + "if (o == null || !o.is$Unresolved()) {\n");
if (isOpt) {
sb.append(ind(3) + "if (o != null) {\n");
sb.append(ind(4) + "o.set" + otherSide().getImplAttributeName() + "(this);\n");
......@@ -425,10 +466,10 @@ aspect BackendBidirectionalAPI {
sb.append(ind(3) + "boolean changed = false;\n");
sb.append(ind(3) + "for (int i = 0; i < l.size(); i++) {\n");
sb.append(ind(4) + ofTypeDecl() + " element = l.get(i);\n");
sb.append(ind(4) + "if (element.unresolved()) {\n");
sb.append(ind(4) + "if (element.is$Unresolved()) {\n");
sb.append(ind(5) + "changed = true;\n");
sb.append(ind(5) + ofTypeDecl() + " resolvedElement = resolve" + nameCapitalized() + "ByToken(element.asUnresolved().get__token(), i);\n");
sb.append(ind(5) + "if (resolvedElement != null && element.asUnresolved().get__resolve_opposite()) {\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(6) + ASTNode.listClass + "<" + toTypeDecl() + "> otherList = resolvedElement.get" + opposite.getImplAttributeName() + "();\n");
sb.append(ind(6) + "if (otherList == null) {\n");
sb.append(ind(7) + "otherList = new " + listClass + "<>();\n");
......@@ -532,10 +573,10 @@ aspect BackendBidirectionalAPI {
sb.append(ind(3) + "boolean changed = false;\n");
sb.append(ind(3) + "for (int i = 0; i < l.size(); i++) {\n");
sb.append(ind(4) + ofTypeDecl() + " element = l.get(i);\n");
sb.append(ind(4) + "if (element.unresolved()) {\n");
sb.append(ind(4) + "if (element.is$Unresolved()) {\n");
sb.append(ind(5) + "changed = true;\n");
sb.append(ind(5) + ofTypeDecl() + " resolvedElement = resolve" + nameCapitalized() + "ByToken(element.asUnresolved().get__token(), i);\n");
sb.append(ind(5) + "if (element.asUnresolved().get__resolve_opposite()) {\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(6) + toTypeDecl() + " oldTarget = resolvedElement.get" + opposite.getImplAttributeName() + "();\n");
sb.append(ind(6) + "if (oldTarget != null && oldTarget != this) {\n");
sb.append(ind(7) + "oldTarget.get" + getImplAttributeName() + "().remove(resolvedElement);\n");
......@@ -745,12 +786,6 @@ aspect LowerBoundCheck {
aspect NameResolutionHelper {
syn boolean TypeDecl.isUnresolved() = false;
eq UnresolvedTypeDecl.isUnresolved() = true;
syn UnresolvedTypeDecl TypeDecl.asUnresolved() = null;
eq UnresolvedTypeDecl.asUnresolved() = this;
public String Program.generateRewriteToSuperTypeStub() {
StringBuilder sb = new StringBuilder();
generateRewriteToSuperTypeStub(sb);
......@@ -771,10 +806,8 @@ aspect NameResolutionHelper {
}
for (TypeDecl decl : getTypeDeclList()) {
if (decl.isUnresolved()) {
decl.asUnresolved().generateContextIndependentNameResolution(sb);
sb.append("\n");
}
decl.generateContextIndependentNameResolution(sb);
sb.append("\n");
}
sb.append("}\n\n");
}
......@@ -784,9 +817,7 @@ aspect NameResolutionHelper {
sb.append("aspect ReferenceCreation {\n\n");
for (TypeDecl decl : getTypeDeclList()) {
if (decl.isUnresolved()) {
decl.asUnresolved().createReferenceCreator(sb);
}
decl.createReferenceCreator(sb);
}
sb.append("}\n\n");
......@@ -796,78 +827,58 @@ aspect NameResolutionHelper {
resolveAll(sb);
for (TypeDecl decl : getTypeDeclList()) {
if (!decl.isUnresolved()) {
decl.resolveAll(sb);
}
decl.resolveAll(sb);
}
sb.append("}\n\n");
sb.append("aspect RefResolverHelpers {\n\n");
sb.append(ind(1) + "public interface __Unresolved {\n");
sb.append(ind(2) + "abstract String get__token();\n");
sb.append(ind(2) + "abstract boolean get__resolve_opposite();\n");
sb.append(ind(1) + "interface Unresolved$Node {\n");
sb.append(ind(2) + "String getUnresolved$Token();\n");
sb.append(ind(2) + "boolean getUnresolved$ResolveOpposite();\n");
sb.append(ind(1) + "}\n\n");
for (TypeDecl decl : getTypeDeclList()) {
if (decl.isUnresolved()) {
sb.append(ind(1) + decl.getID() + " implements __Unresolved;\n");
}
}
sb.append(ind(1) + "syn boolean ASTNode.unresolved() = false;\n");
for (TypeDecl decl : getTypeDeclList()) {
if (decl.isUnresolved()) {
sb.append(ind(1) + "eq " + decl.getID() + ".unresolved() = true;\n");
}
}
sb.append("\n");
sb.append(ind(1) + "syn __Unresolved ASTNode.asUnresolved() = null;\n");
for (TypeDecl decl : getTypeDeclList()) {
if (decl.isUnresolved()) {
sb.append(ind(1) + "eq " + decl.getID() + ".asUnresolved() = this;\n");
for (TypeDecl td: getTypeDecls()) {
if (td.needUnresolvedClass()) {
td.generateUnresolvedClass(sb);
}
}
sb.append("\n}\n");
}
public void UnresolvedTypeDecl.createReferenceCreator(StringBuilder sb) {
String superType = this.getSuper().getID();
public void TypeDecl.createReferenceCreator(StringBuilder sb) {
TypeDecl instantiableUnresolved = this.getSuper().decl().instantiableUnresolved();
if (instantiableUnresolved == null) {
System.out.println(getID());
TypeDecl instantiableSubType = instantiableSubType();
if (instantiableSubType == null) {
throw new RuntimeException("unable to find instantiable subtype for " + getID());
}
sb.append(ind(1) + "public static " + superType + " " + superType + ".createRef(String ref) {\n");
sb.append(ind(2) + instantiableUnresolved.getID() + " unresolvedNode = new " + instantiableUnresolved.getID() + "();\n");
sb.append(ind(2) + "unresolvedNode.set__token(ref);\n");
sb.append(ind(2) + "unresolvedNode.set__resolve_opposite(true);\n");
sb.append(ind(1) + "public static " + getID() + " " + getID() + ".createRef(String ref) {\n");
sb.append(ind(2) + "Unresolved$" + instantiableSubType.getID() + " unresolvedNode = new Unresolved$" + instantiableSubType.getID() + "();\n");
sb.append(ind(2) + "unresolvedNode.setUnresolved$Token(ref);\n");
sb.append(ind(2) + "unresolvedNode.setUnresolved$ResolveOpposite(true);\n");
sb.append(ind(2) + "return unresolvedNode;\n");
sb.append(ind(1) + "}\n");
sb.append(ind(1) + "public static " + superType + " " + superType + ".createRefDirection(String ref) {\n");
sb.append(ind(2) + instantiableUnresolved.getID() + " unresolvedNode = new " + instantiableUnresolved.getID() + "();\n");
sb.append(ind(2) + "unresolvedNode.set__token(ref);\n");
sb.append(ind(2) + "unresolvedNode.set__resolve_opposite(false);\n");
sb.append(ind(1) + "public static " + getID() + " " + getID() + ".createRefDirection(String ref) {\n");
sb.append(ind(2) + "Unresolved$" + instantiableSubType.getID() + " unresolvedNode = new Unresolved$" + instantiableSubType.getID() + "();\n");
sb.append(ind(2) + "unresolvedNode.setUnresolved$Token(ref);\n");
sb.append(ind(2) + "unresolvedNode.setUnresolved$ResolveOpposite(false);\n");
sb.append(ind(2) + "return unresolvedNode;\n");
sb.append(ind(1) + "}\n");
}
public void UnresolvedTypeDecl.generateContextIndependentNameResolution(StringBuilder sb) {
String superType = this.getSuper().getID();
public void TypeDecl.generateContextIndependentNameResolution(StringBuilder sb) {
sb.append(ind(1) + "// context-independent name resolution\n");
sb.append(ind(1) + "syn " + superType + " ASTNode.globallyResolve" + superType + "ByToken(String id) {\n");
sb.append(ind(1) + "syn " + getID() + " ASTNode.globallyResolve" + getID() + "ByToken(String id) {\n");
if (serializer) {
sb.append(ind(2) + "return (" + superType + ") globallyResolveASTNodeByUID(id);\n");
sb.append(ind(2) + "return (" + getID() + ") globallyResolveASTNodeByUID(id);\n");
} else {
sb.append(ind(2) + "// perform context independent name resolution here using the id\n");
sb.append(ind(2) + "throw new RuntimeException(\"Context-independent name resolution for " + superType + " not implemented.\");\n");
sb.append(ind(2) + "throw new RuntimeException(\"Context-independent name resolution for " + getID() + " not implemented.\");\n");
}
sb.append(ind(1) + "}\n");
}
......@@ -1006,9 +1017,7 @@ aspect Serializer {
sb.append(ind(1) + "}\n");
for (TypeDecl decl : getTypeDeclList()) {
if (!decl.isUnresolved()) {
decl.deserialize(sb);
}
decl.deserialize(sb);
}
sb.append("}\n");
......@@ -1027,9 +1036,7 @@ aspect Serializer {
sb.append(ind(1) + "}\n");
for (TypeDecl decl : getTypeDeclList()) {
if (!decl.isUnresolved()) {
decl.serialize(sb);
}
decl.serialize(sb);
}
sb.append("}\n");
......
Program ::= TypeDecl* Relation*;
TypeDecl ::= <ID> <Abstract:boolean> [Super:TypeUse] Component*;
UnresolvedTypeDecl:TypeDecl;
abstract Component ::= <ID>;
abstract SimpleTypeComponent : Component ::= TypeUse:SimpleTypeUse;
......
......@@ -36,7 +36,6 @@ public class Compiler {
}
List<String> filenames = commandLine.getArguments();
List<TypeDecl> unresolvedDecls = new ArrayList<>();
Program p = parseProgram(filenames);
if (optionJastAddList.isSet()) {
......@@ -51,18 +50,6 @@ public class Compiler {
for (TypeDecl typeDecl : p.getTypeDecls()) {
nonTerminals.add(typeDecl);
}
// add a new typeDecl with a prefix "Unresolved"
for (TypeDecl typeDecl : nonTerminals) {
UnresolvedTypeDecl unresolvedDecl = new UnresolvedTypeDecl();
unresolvedDecl.setID("__unresolved" + typeDecl.getID());
unresolvedDecl.setAbstract(typeDecl.getAbstract());
unresolvedDecl.setSuper(new SimpleTypeUse(typeDecl.getID()));
unresolvedDecl.addComponent(new TokenComponent("__token", new SimpleTypeUse("String")));
unresolvedDecl.addComponent(new TokenComponent("__resolve_opposite", new SimpleTypeUse("boolean")));
p.addTypeDecl(unresolvedDecl);
unresolvedDecls.add(unresolvedDecl);
}
}
if (!p.errors().isEmpty()) {
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment