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