diff --git a/src/main/jastadd/Analysis.jrag b/src/main/jastadd/Analysis.jrag index d96c5dbb48a2b644d9599ab3f407e9758393c714..48f1e58e5a61f8a77b0ba84eb93ba99a8c66427c 100644 --- a/src/main/jastadd/Analysis.jrag +++ b/src/main/jastadd/Analysis.jrag @@ -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 { diff --git a/src/main/jastadd/Backend.jadd b/src/main/jastadd/Backend.jadd index 5439024c5bc5245826d4856423e17b89b9fa26e1..528e4530ee0a14863ab1d56c2bb993c3a3a18f00 100644 --- a/src/main/jastadd/Backend.jadd +++ b/src/main/jastadd/Backend.jadd @@ -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"); diff --git a/src/main/jastadd/RelAst.ast b/src/main/jastadd/RelAst.ast index 5098ece3a779a7919dcf4af2ed6ce93cb5c40e6f..3a17c0cfb7fea19f5b33dc9a9bb8fe613137b12b 100644 --- a/src/main/jastadd/RelAst.ast +++ b/src/main/jastadd/RelAst.ast @@ -1,6 +1,5 @@ Program ::= TypeDecl* Relation*; TypeDecl ::= <ID> <Abstract:boolean> [Super:TypeUse] Component*; -UnresolvedTypeDecl:TypeDecl; abstract Component ::= <ID>; abstract SimpleTypeComponent : Component ::= TypeUse:SimpleTypeUse; diff --git a/src/main/java/org/jastadd/relast/compiler/Compiler.java b/src/main/java/org/jastadd/relast/compiler/Compiler.java index 93afb42b34eba9a1718af25658ecd2a414916d00..9100db9979018bc31be81308ee4c1d8214b3c6d5 100644 --- a/src/main/java/org/jastadd/relast/compiler/Compiler.java +++ b/src/main/java/org/jastadd/relast/compiler/Compiler.java @@ -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()) {