aspect BackendAspect { public String Program.generateAspect() { StringBuilder sb = new StringBuilder(); generateAspect(sb); return sb.toString(); } public void Program.generateAspect(StringBuilder sb) { sb.append("import java.util.ArrayList;\n"); sb.append("import java.util.Collections;\n"); sb.append("import java.time.Instant;\n"); sb.append("import java.time.Period;\n"); sb.append("aspect RelAstAPI {\n"); for (TypeDecl td: getTypeDecls()) { if (td.needsConstructor()) { td.generateConstructor(sb); } } for (Relation r: getRelations()) { r.generateAPI(sb); } generateLowerBoundCheck(sb); sb.append(ind(1) + "public static void ASTNode.assertNotNull(Object obj) {\n"); sb.append(ind(2) + "if (obj == null) {\n"); sb.append(ind(3) + "throw new NullPointerException();\n"); sb.append(ind(2) + "}\n"); sb.append(ind(1) + "}\n"); sb.append("}\n"); } public void TypeDecl.generateConstructor(StringBuilder sb) { sb.append(ind(1) + "public " + getID() + "." + getID() + "("); int i = 0; for (Component c: componentsTransitive()) { sb.append(c.constructorParameter()); if (++i < componentsTransitive().size()) { sb.append(", "); } } sb.append(") {\n"); for (Component c: componentsTransitive()) { sb.append(ind(2) + c.constructorSetMethod() + "(" + c.getID() + ");\n"); } sb.append(ind(1) + "}\n"); } public String Component.constructorParameter() { return getTypeUse() + " " + getID(); } public String ListComponent.constructorParameter() { return ASTNode.jastAddListType + "<" + getTypeUse() + "> " + getID(); } public String OptComponent.constructorParameter() { return "Opt<" + getTypeUse() + "> " + getID(); } public String Component.constructorSetMethod() { return "set" + getID(); } public String ListComponent.constructorSetMethod() { return "set" + getID() + "List"; } public String OptComponent.constructorSetMethod() { return "set" + getID() + "Opt"; } }