Skip to content
GitLab
Menu
Projects
Groups
Snippets
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
JastAdd
relational-rags
Commits
f11bded4
Commit
f11bded4
authored
Mar 28, 2020
by
Johannes Mey
Browse files
only create reference creation and resolution methods for types that can be instantiated
parent
8a5cec44
Pipeline
#6289
passed with stage
in 1 minute and 49 seconds
Changes
11
Pipelines
2
Hide whitespace changes
Inline
Side-by-side
src/main/jastadd/Analysis.jrag
View file @
f11bded4
...
...
@@ -160,11 +160,39 @@ aspect ComponentAnalysis {
return set;
}
//--- needUnresolvedClass ---
syn boolean TypeDecl.needUnresolvedClass() {
// a TypeDecl needs an unresolved class, if it can appear in a relation
// TODO
return true;
/**
* @return a set of all types that refer to this type using a non-containment relation
*/
coll Set<TypeDecl> TypeDecl.referencingTypes() [new HashSet<TypeDecl>()];
RelationComponent contributes opposite().getTypeUse().decl()
when opposite().isNavigable()
to TypeDecl.referencingTypes()
for getTypeUse().decl();
/**
* @return true, if the type can be the target of a non-containment relation
*/
syn boolean TypeDecl.isReferenceTarget() {
return !referencingTypes().isEmpty();
}
/**
* @return true, if the type or one of its abstract supertypes can be the target of a non-containment relation
*/
syn boolean TypeDecl.requiresUresolvedClass() {
if (referencingTypes().isEmpty()) {
// if the type is not referenced itself, it may still be required by an abstract supertype that is referenced
TypeDecl decl = this;
while (decl.hasSuper()) {
decl = decl.getSuper().decl();
if (decl.getAbstract() && !decl.referencingTypes().isEmpty()) {
return true;
}
}
return false;
} else {
return true;
}
}
//--- isList ---
...
...
@@ -201,6 +229,8 @@ aspect InstanceSupplier {
return subDecls;
}
syn boolean TypeDecl.instantiable() = instantiableSubType() != null;
//--- instantiableSubType ---
syn TypeDecl TypeDecl.instantiableSubType() {
if (getAbstract() == false) {
...
...
src/main/jastadd/backend/NameResolution.jadd
View file @
f11bded4
...
...
@@ -149,7 +149,9 @@ aspect NameResolutionHelper {
sb.append("aspect ReferenceCreation {\n\n");
for (TypeDecl decl : getTypeDeclList()) {
decl.createReferenceCreator(sb);
if (decl.isReferenceTarget()) {
decl.createReferenceCreator(sb);
}
}
sb.append("}\n\n");
...
...
@@ -172,7 +174,7 @@ aspect NameResolutionHelper {
sb.append(ind(1) + "}\n\n");
for (TypeDecl td: getTypeDecls()) {
if (td.
needUn
resolvedClass()) {
if (td.
requiresU
resolvedClass()) {
td.generateUnresolvedClass(sb);
}
}
...
...
@@ -182,24 +184,24 @@ aspect NameResolutionHelper {
public void TypeDecl.createReferenceCreator(StringBuilder sb) {
TypeDecl instantiableSubType = instantiableSubType();
if (instantiableSubType == null) {
throw new RuntimeException("unable to find instantiable subtype for " + getID());
}
sb.append(ind(1) + "public static " + getID() + " " + getID() + "." + createRefMethod + "(String ref) {\n");
sb.append(ind(2) + unresolvedPrefix + instantiableSubType.getID() + " unresolvedNode = new " + unresolvedPrefix + instantiableSubType.getID() + "();\n");
sb.append(ind(2) + "unresolvedNode.set" + unresolvedPrefix + "Token(ref);\n");
sb.append(ind(2) + "unresolvedNode.set" + unresolvedPrefix + "ResolveOpposite(true);\n");
sb.append(ind(2) + "return unresolvedNode;\n");
sb.append(ind(1) + "}\n");
if (!instantiable()) {
System.out.println("WARNING: unable to find instantiable subtype for " + getID() + "! Skipping the creation of reference creator methods.");
} else {
TypeDecl instantiableSubType = instantiableSubType();
sb.append(ind(1) + "public static " + getID() + " " + getID() + "." + createRefMethod + "(String ref) {\n");
sb.append(ind(2) + unresolvedPrefix + instantiableSubType.getID() + " unresolvedNode = new " + unresolvedPrefix + instantiableSubType.getID() + "();\n");
sb.append(ind(2) + "unresolvedNode.set" + unresolvedPrefix + "Token(ref);\n");
sb.append(ind(2) + "unresolvedNode.set" + unresolvedPrefix + "ResolveOpposite(true);\n");
sb.append(ind(2) + "return unresolvedNode;\n");
sb.append(ind(1) + "}\n");
sb.append(ind(1) + "public static " + getID() + " " + getID() + "." + createRefDirectionMethod + "(String ref) {\n");
sb.append(ind(2) + unresolvedPrefix + instantiableSubType.getID() + " unresolvedNode = new " + unresolvedPrefix + instantiableSubType.getID() + "();\n");
sb.append(ind(2) + "unresolvedNode.set" + unresolvedPrefix + "Token(ref);\n");
sb.append(ind(2) + "unresolvedNode.set" + unresolvedPrefix + "ResolveOpposite(false);\n");
sb.append(ind(2) + "return unresolvedNode;\n");
sb.append(ind(1) + "}\n");
sb.append(ind(1) + "public static " + getID() + " " + getID() + "." + createRefDirectionMethod + "(String ref) {\n");
sb.append(ind(2) + unresolvedPrefix + instantiableSubType.getID() + " unresolvedNode = new " + unresolvedPrefix + instantiableSubType.getID() + "();\n");
sb.append(ind(2) + "unresolvedNode.set" + unresolvedPrefix + "Token(ref);\n");
sb.append(ind(2) + "unresolvedNode.set" + unresolvedPrefix + "ResolveOpposite(false);\n");
sb.append(ind(2) + "return unresolvedNode;\n");
sb.append(ind(1) + "}\n");
}
}
public void TypeDecl.generateContextIndependentNameResolution(StringBuilder sb) {
...
...
src/main/jastadd/backend/Serializer.jadd
View file @
f11bded4
...
...
@@ -268,67 +268,73 @@ aspect Serializer {
public void TypeDecl.deserialize(StringBuilder sb) {
sb.append(ind(1) + "public static " + getID() + " " + getID() + ".deserialize(java.io.File file) throws DeserializationException {\n");
sb.append(ind(2) + "try {\n");
sb.append(ind(3) + "com.fasterxml.jackson.databind.ObjectMapper mapper = new com.fasterxml.jackson.databind.ObjectMapper();\n");
sb.append(ind(3) + "com.fasterxml.jackson.core.JsonFactory factory = mapper.getFactory();\n");
sb.append(ind(3) + "com.fasterxml.jackson.core.JsonParser parser = factory.createParser(file);\n");
sb.append(ind(3) + getID() + " result = deserialize((com.fasterxml.jackson.databind.JsonNode)mapper.readTree(parser));\n");
sb.append(ind(3) + "parser.close();\n");
sb.append(ind(3) + "return result;\n");
sb.append(ind(2) + "} catch (java.io.IOException e) {\n");
sb.append(ind(3) + "throw new DeserializationException(\"unable to deserialize \" + file.getAbsolutePath(), e);\n");
sb.append(ind(2) + "}\n");
sb.append(ind(1) + "}\n");
sb.append(ind(1) + "public static " + getID() + " " + getID() + ".deserialize(" + jsonNodeType + " node) throws DeserializationException {\n");
sb.append(ind(2) + getID() + " element;\n");
if (getAbstract()) {
// switch case between all implementations of the abstract class
sb.append(ind(2) + "switch (node" + jsonNodeTypeAccessor + ") {\n");
for (TypeDecl subType : subTypeDecls()) {
sb.append(ind(3) + "case \"" + subType.getID() + "\":\n");
sb.append(ind(4) + "element = " + subType.getID() + ".deserialize(node);\n");
sb.append(ind(4) + "break;\n");
}
sb.append(ind(3) + "default:\n");
sb.append(ind(4) + "throw new DeserializationException(\"Unable to deserialize child of unexpected type \" + node" + jsonNodeTypeAccessor + " + \"(" + getID() + " expected)\");\n");
if (instantiable()) {
sb.append(ind(2) + "try {\n");
sb.append(ind(3) + "com.fasterxml.jackson.databind.ObjectMapper mapper = new com.fasterxml.jackson.databind.ObjectMapper();\n");
sb.append(ind(3) + "com.fasterxml.jackson.core.JsonFactory factory = mapper.getFactory();\n");
sb.append(ind(3) + "com.fasterxml.jackson.core.JsonParser parser = factory.createParser(file);\n");
sb.append(ind(3) + getID() + " result = deserialize((com.fasterxml.jackson.databind.JsonNode)mapper.readTree(parser));\n");
sb.append(ind(3) + "parser.close();\n");
sb.append(ind(3) + "return result;\n");
sb.append(ind(2) + "} catch (java.io.IOException e) {\n");
sb.append(ind(3) + "throw new DeserializationException(\"unable to deserialize \" + file.getAbsolutePath(), e);\n");
sb.append(ind(2) + "}\n");
} else {
sb.append(ind(2) + "element = new " + getID() + "();\n");
}
sb.append(ind(1) + "}\n");
sb.append(ind(1) + "public static " + getID() + " " + getID() + ".deserialize(" + jsonNodeType + " node) throws DeserializationException {\n");
sb.append(ind(2) + getID() + " element;\n");
if (getAbstract()) {
// switch case between all implementations of the abstract class
sb.append(ind(2) + "switch (node" + jsonNodeTypeAccessor + ") {\n");
for (TypeDecl subType : subTypeDecls()) {
sb.append(ind(3) + "case \"" + subType.getID() + "\":\n");
sb.append(ind(4) + "element = " + subType.getID() + ".deserialize(node);\n");
sb.append(ind(4) + "break;\n");
}
sb.append(ind(3) + "default:\n");
sb.append(ind(4) + "throw new DeserializationException(\"Unable to deserialize child of unexpected type \" + node" + jsonNodeTypeAccessor + " + \"(" + getID() + " expected)\");\n");
sb.append(ind(2) + "}\n");
} else {
sb.append(ind(2) + "element = new " + getID() + "();\n");
}
if (!jsonPointer && !manualReferences) {
// deserialize id
sb.append(ind(2) + "if (node.has(\"id\")) {\n");
sb.append(ind(3) + "element.unique$Id = node.get(\"id\").asText();\n");
sb.append(ind(2) + "}\n");
}
if (!jsonPointer && !manualReferences) {
// deserialize id
sb.append(ind(2) + "if (node.has(\"id\")) {\n");
sb.append(ind(3) + "element.unique$Id = node.get(\"id\").asText();\n");
sb.append(ind(2) + "}\n");
}
// deserialize containment children
if (componentsTransitive().size() > 0) {
sb.append(ind(2) + "if (node.has(\"children\")) {\n");
sb.append(ind(3) + jsonNodeType + " children = node.get(\"children\");\n");
for (Component component : componentsTransitive()) {
sb.append(ind(3) + "if (children.has(\"" + component.getID() + "\")) {\n");
component.deserialize(sb, 4);
sb.append(ind(3) + "}\n");
// deserialize containment children
if (componentsTransitive().size() > 0) {
sb.append(ind(2) + "if (node.has(\"children\")) {\n");
sb.append(ind(3) + jsonNodeType + " children = node.get(\"children\");\n");
for (Component component : componentsTransitive()) {
sb.append(ind(3) + "if (children.has(\"" + component.getID() + "\")) {\n");
component.deserialize(sb, 4);
sb.append(ind(3) + "}\n");
}
sb.append(ind(2) + "}\n");
}
sb.append(ind(2) + "}\n");
}
// deserialize non-containment children
Set<RelationComponent> relationComponents = relationComponents(
);
if (relationComponents.size() > 0) {
sb.append(ind(2) + "if (node.has(\"relations\")) {\n");
sb.append(ind(3) +
jsonNodeType + " relations = node.get(\"relations\");
\n");
for (RelationComponent component : relationComponents) {
sb.append(ind(3) + "
if (relations.has(\"" + component.getID() + "\")) {
\n");
component.deserialize(sb, 4);
sb.append(ind(
3
) + "}\n");
// deserialize non-containment children
Set<RelationComponent> relationComponents = relationComponents();
if (relationComponents.size() > 0) {
sb.append(ind(2) + "if (node.has(\"relations\")) {\n"
);
sb.append(ind(3) + jsonNodeType + " relations = node.get(\"relations\");\n");
for (RelationComponent component : relationComponents) {
sb.append(ind(3) +
"if (relations.has(\"" + component.getID() + "\")) {
\n");
component.deserialize(sb, 4);
sb.append(ind(3) + "
}
\n");
}
sb.append(ind(
2
) + "}\n");
}
sb.append(ind(2) + "}\n");
}
sb.append(ind(2) + "return element;\n");
sb.append(ind(2) + "return element;\n");
} else {
sb.append(ind(2) + "throw new DeserializationException(\"Unable to deserialize type \\\"" + getID() + "\\\" because it is not instantiable.\");\n");
}
sb.append(ind(1) + "}\n");
}
...
...
src/test/jastadd/relations/Relations.relast
View file @
f11bded4
...
...
@@ -62,3 +62,5 @@ G : C ::= [D] ;
// line comment with special symbols like |, *, ->, <-, <->, [A], B ::= C, :, \n, \r, ~, #, /A/
/* block comment with special symbols like |, *, ->, <-, <->, [A], B ::= C, :, \n, \r, ~, #, /A/ */
abstract Uninstantiable:A;
src/test/jastadd/resolver/Resolver.relast
View file @
f11bded4
...
...
@@ -21,3 +21,5 @@ rel A.Bi6? <-> B.Bi6*;
rel A.Bi7* <-> B.Bi7;
rel A.Bi8* <-> B.Bi8?;
rel A.Bi9* <-> B.Bi9*;
abstract Uninstantiable:A;
src/test/jastadd/resolver2/Resolver.relast
View file @
f11bded4
...
...
@@ -21,3 +21,5 @@ rel A.Bi6l? <-> B.Bi6*;
rel A.Bi7l* <-> B.Bi7;
rel A.Bi8l* <-> B.Bi8?;
rel A.Bi9l* <-> B.Bi9*;
abstract Uninstantiable:A;
src/test/jastadd/serializer-manual-relative/Serializer.relast
View file @
f11bded4
...
...
@@ -21,3 +21,5 @@ rel A.Bi6? <-> B.Bi6*;
rel A.Bi9* <-> B.Bi9*;
rel Root.D <-> D.Root?;
abstract Uninstantiable:A;
src/test/jastadd/serializer-manual/Serializer.relast
View file @
f11bded4
...
...
@@ -21,3 +21,5 @@ rel A.Bi6? <-> B.Bi6*;
rel A.Bi9* <-> B.Bi9*;
rel Root.D <-> D.Root?;
abstract Uninstantiable:A;
src/test/jastadd/serializer-names/Serializer.relast
View file @
f11bded4
...
...
@@ -32,3 +32,5 @@ rel A.Bi5? <-> B.Bi5?;
rel A.Bi6? <-> B.Bi6*;
rel A.Bi9* <-> B.Bi9*;
abstract Uninstantiable:A;
src/test/jastadd/serializer-pointer/Serializer.relast
View file @
f11bded4
...
...
@@ -21,3 +21,5 @@ rel A.Bi6? <-> B.Bi6*;
rel A.Bi9* <-> B.Bi9*;
rel Root.D <-> D.Root?;
abstract Uninstantiable:A;
src/test/jastadd/serializer/Serializer.relast
View file @
f11bded4
...
...
@@ -32,3 +32,5 @@ rel A.Bi5? <-> B.Bi5?;
rel A.Bi6? <-> B.Bi6*;
rel A.Bi9* <-> B.Bi9*;
abstract Uninstantiable:A;
Johannes Mey
@johannes.mey
mentioned in issue
#12 (closed)
·
Apr 20, 2020
mentioned in issue
#12 (closed)
mentioned in issue #12
Toggle commit list
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment