aboutsummaryrefslogtreecommitdiffstats
path: root/subprojects/language/src/main/java
diff options
context:
space:
mode:
authorLibravatar Kristóf Marussy <kristof@marussy.com>2024-01-31 02:00:09 +0100
committerLibravatar Kristóf Marussy <kristof@marussy.com>2024-01-31 18:45:13 +0100
commitc63126d2f1ce5f571c316b37e00fb43d2da7c7d3 (patch)
tree16e9dd04624565f7c9ccedd17749a9f264e89cb0 /subprojects/language/src/main/java
parentfix(build): avoid cyclic dependency (diff)
downloadrefinery-c63126d2f1ce5f571c316b37e00fb43d2da7c7d3.tar.gz
refinery-c63126d2f1ce5f571c316b37e00fb43d2da7c7d3.tar.zst
refinery-c63126d2f1ce5f571c316b37e00fb43d2da7c7d3.zip
refactor(language): module and node declarations
* New default file extension: .refinery (.problem is also supported). * Add module keyword for self-contained modules. * Rename indiv declarations to atom declaration. * Add node and multi declarations for explicitly declared nodes and multi-objects, respectively.
Diffstat (limited to 'subprojects/language/src/main/java')
-rw-r--r--subprojects/language/src/main/java/tools/refinery/language/GenerateProblem.mwe22
-rw-r--r--subprojects/language/src/main/java/tools/refinery/language/Problem.xtext17
-rw-r--r--subprojects/language/src/main/java/tools/refinery/language/formatting2/ProblemFormatter.java10
-rw-r--r--subprojects/language/src/main/java/tools/refinery/language/resource/ProblemLocationInFileProvider.java4
-rw-r--r--subprojects/language/src/main/java/tools/refinery/language/resource/ProblemResourceDescriptionStrategy.java6
-rw-r--r--subprojects/language/src/main/java/tools/refinery/language/utils/ProblemUtil.java20
-rw-r--r--subprojects/language/src/main/java/tools/refinery/language/validation/ProblemValidator.java12
7 files changed, 43 insertions, 28 deletions
diff --git a/subprojects/language/src/main/java/tools/refinery/language/GenerateProblem.mwe2 b/subprojects/language/src/main/java/tools/refinery/language/GenerateProblem.mwe2
index 59eba8f7..863e55d4 100644
--- a/subprojects/language/src/main/java/tools/refinery/language/GenerateProblem.mwe2
+++ b/subprojects/language/src/main/java/tools/refinery/language/GenerateProblem.mwe2
@@ -51,7 +51,7 @@ Workflow {
51 51
52 language = StandardLanguage { 52 language = StandardLanguage {
53 name = 'tools.refinery.language.Problem' 53 name = 'tools.refinery.language.Problem'
54 fileExtensions = 'problem' 54 fileExtensions = 'refinery,problem'
55 referencedResource = 'platform:/resource/tools.refinery.refinery-language-model/model/problem.genmodel' 55 referencedResource = 'platform:/resource/tools.refinery.refinery-language-model/model/problem.genmodel'
56 serializer = { 56 serializer = {
57 generateStub = false 57 generateStub = false
diff --git a/subprojects/language/src/main/java/tools/refinery/language/Problem.xtext b/subprojects/language/src/main/java/tools/refinery/language/Problem.xtext
index 0fb96954..c5c42ebe 100644
--- a/subprojects/language/src/main/java/tools/refinery/language/Problem.xtext
+++ b/subprojects/language/src/main/java/tools/refinery/language/Problem.xtext
@@ -9,13 +9,16 @@ import "http://www.eclipse.org/emf/2002/Ecore" as ecore
9import "https://refinery.tools/emf/2021/Problem" 9import "https://refinery.tools/emf/2021/Problem"
10 10
11Problem: 11Problem:
12 ("problem" name=Identifier ".")? 12 (kind=ModuleKind name=QualifiedName? ".")?
13 statements+=Statement*; 13 statements+=Statement*;
14 14
15enum ModuleKind:
16 PROBLEM="problem" | MODULE="module";
17
15Statement: 18Statement:
16 Assertion | ClassDeclaration | EnumDeclaration | 19 Assertion | ClassDeclaration | EnumDeclaration |
17 PredicateDefinition | /* FunctionDefinition | RuleDefinition | */ 20 PredicateDefinition | /* FunctionDefinition | RuleDefinition | */
18 ScopeDeclaration | IndividualDeclaration; 21 ScopeDeclaration | NodeDeclaration;
19 22
20ClassDeclaration: 23ClassDeclaration:
21 abstract?="abstract"? "class" 24 abstract?="abstract"? "class"
@@ -252,8 +255,11 @@ RangeMultiplicity:
252ExactMultiplicity: 255ExactMultiplicity:
253 exactValue=INT; 256 exactValue=INT;
254 257
255IndividualDeclaration: 258NodeDeclaration:
256 "indiv" nodes+=EnumLiteral ("," nodes+=EnumLiteral)* "."; 259 kind=NodeKind nodes+=EnumLiteral ("," nodes+=EnumLiteral)* ".";
260
261enum NodeKind:
262 NODE="node" | ATOM="atom" | MULTI="multi";
257 263
258UpperBound returns ecore::EInt: 264UpperBound returns ecore::EInt:
259 INT | "*"; 265 INT | "*";
@@ -268,7 +274,8 @@ Identifier:
268 NonContainmentIdentifier | "contains" | "container"; 274 NonContainmentIdentifier | "contains" | "container";
269 275
270NonContainmentIdentifier: 276NonContainmentIdentifier:
271 ID | "contained" | "sum" | "prod" | "min" | "max"; 277 ID | "node" | "atom" | "multi" | "contained" |
278 "sum" | "prod" | "min" | "max" | "problem" | "module";
272 279
273Real returns ecore::EDouble: 280Real returns ecore::EDouble:
274 EXPONENTIAL | INT "." (INT | EXPONENTIAL); 281 EXPONENTIAL | INT "." (INT | EXPONENTIAL);
diff --git a/subprojects/language/src/main/java/tools/refinery/language/formatting2/ProblemFormatter.java b/subprojects/language/src/main/java/tools/refinery/language/formatting2/ProblemFormatter.java
index 0f3bd3ee..0b87e8bb 100644
--- a/subprojects/language/src/main/java/tools/refinery/language/formatting2/ProblemFormatter.java
+++ b/subprojects/language/src/main/java/tools/refinery/language/formatting2/ProblemFormatter.java
@@ -23,7 +23,7 @@ public class ProblemFormatter extends AbstractJavaFormatter {
23 protected void format(Problem problem, IFormattableDocument doc) { 23 protected void format(Problem problem, IFormattableDocument doc) {
24 doc.prepend(problem, this::noSpace); 24 doc.prepend(problem, this::noSpace);
25 var region = regionFor(problem); 25 var region = regionFor(problem);
26 doc.append(region.keyword("problem"), this::oneSpace); 26 doc.append(region.feature(ProblemPackage.Literals.PROBLEM__KIND), this::oneSpace);
27 doc.prepend(region.keyword("."), this::noSpace); 27 doc.prepend(region.keyword("."), this::noSpace);
28 appendNewLines(doc, region.keyword("."), this::twoNewLines); 28 appendNewLines(doc, region.keyword("."), this::twoNewLines);
29 for (var statement : problem.getStatements()) { 29 for (var statement : problem.getStatements()) {
@@ -132,10 +132,10 @@ public class ProblemFormatter extends AbstractJavaFormatter {
132 } 132 }
133 } 133 }
134 134
135 protected void format(IndividualDeclaration individualDeclaration, IFormattableDocument doc) { 135 protected void format(NodeDeclaration nodeDeclaration, IFormattableDocument doc) {
136 surroundNewLines(doc, individualDeclaration, this::singleNewLine); 136 surroundNewLines(doc, nodeDeclaration, this::singleNewLine);
137 var region = regionFor(individualDeclaration); 137 var region = regionFor(nodeDeclaration);
138 doc.append(region.keyword("indiv"), this::oneSpace); 138 doc.append(region.feature(ProblemPackage.Literals.NODE_DECLARATION__KIND), this::oneSpace);
139 formatList(region, ",", doc); 139 formatList(region, ",", doc);
140 doc.prepend(region.keyword("."), this::noSpace); 140 doc.prepend(region.keyword("."), this::noSpace);
141 } 141 }
diff --git a/subprojects/language/src/main/java/tools/refinery/language/resource/ProblemLocationInFileProvider.java b/subprojects/language/src/main/java/tools/refinery/language/resource/ProblemLocationInFileProvider.java
index 29eaad84..c81431e5 100644
--- a/subprojects/language/src/main/java/tools/refinery/language/resource/ProblemLocationInFileProvider.java
+++ b/subprojects/language/src/main/java/tools/refinery/language/resource/ProblemLocationInFileProvider.java
@@ -25,10 +25,10 @@ public class ProblemLocationInFileProvider extends DefaultLocationInFileProvider
25 } 25 }
26 26
27 protected ITextRegion getNodeTextRegion(Node node, RegionDescription query) { 27 protected ITextRegion getNodeTextRegion(Node node, RegionDescription query) {
28 if (ProblemUtil.isIndividualNode(node)) { 28 if (ProblemUtil.isDeclaredNode(node)) {
29 return super.doGetTextRegion(node, query); 29 return super.doGetTextRegion(node, query);
30 } 30 }
31 if (ProblemUtil.isNewNode(node)) { 31 if (ProblemUtil.isMultiNode(node)) {
32 EObject container = node.eContainer(); 32 EObject container = node.eContainer();
33 return doGetTextRegion(container, query); 33 return doGetTextRegion(container, query);
34 } 34 }
diff --git a/subprojects/language/src/main/java/tools/refinery/language/resource/ProblemResourceDescriptionStrategy.java b/subprojects/language/src/main/java/tools/refinery/language/resource/ProblemResourceDescriptionStrategy.java
index c04c7d09..79dad6e7 100644
--- a/subprojects/language/src/main/java/tools/refinery/language/resource/ProblemResourceDescriptionStrategy.java
+++ b/subprojects/language/src/main/java/tools/refinery/language/resource/ProblemResourceDescriptionStrategy.java
@@ -91,8 +91,7 @@ public class ProblemResourceDescriptionStrategy extends DefaultResourceDescripti
91 return false; 91 return false;
92 } 92 }
93 if (eObject instanceof Node node) { 93 if (eObject instanceof Node node) {
94 // Only enum literals and new nodes are visible across problem files. 94 return !ProblemUtil.isImplicitNode(node);
95 return ProblemUtil.isIndividualNode(node) || ProblemUtil.isNewNode(node);
96 } 95 }
97 return true; 96 return true;
98 } 97 }
@@ -111,7 +110,7 @@ public class ProblemResourceDescriptionStrategy extends DefaultResourceDescripti
111 110
112 protected boolean shouldExportSimpleName(EObject eObject) { 111 protected boolean shouldExportSimpleName(EObject eObject) {
113 if (eObject instanceof Node node) { 112 if (eObject instanceof Node node) {
114 return !ProblemUtil.isNewNode(node); 113 return !ProblemUtil.isMultiNode(node);
115 } 114 }
116 if (eObject instanceof PredicateDefinition predicateDefinition) { 115 if (eObject instanceof PredicateDefinition predicateDefinition) {
117 return !ProblemUtil.isInvalidMultiplicityConstraint(predicateDefinition); 116 return !ProblemUtil.isInvalidMultiplicityConstraint(predicateDefinition);
@@ -146,6 +145,5 @@ public class ProblemResourceDescriptionStrategy extends DefaultResourceDescripti
146 return false; 145 return false;
147 } 146 }
148 return eObject instanceof ClassDeclaration || eObject instanceof EnumDeclaration; 147 return eObject instanceof ClassDeclaration || eObject instanceof EnumDeclaration;
149
150 } 148 }
151} 149}
diff --git a/subprojects/language/src/main/java/tools/refinery/language/utils/ProblemUtil.java b/subprojects/language/src/main/java/tools/refinery/language/utils/ProblemUtil.java
index 7b6407e1..ee0e141d 100644
--- a/subprojects/language/src/main/java/tools/refinery/language/utils/ProblemUtil.java
+++ b/subprojects/language/src/main/java/tools/refinery/language/utils/ProblemUtil.java
@@ -54,14 +54,24 @@ public final class ProblemUtil {
54 return eObject instanceof PredicateDefinition predicateDefinition && predicateDefinition.isError(); 54 return eObject instanceof PredicateDefinition predicateDefinition && predicateDefinition.isError();
55 } 55 }
56 56
57 public static boolean isIndividualNode(Node node) { 57 public static boolean isAtomNode(Node node) {
58 var containingFeature = node.eContainingFeature(); 58 var containingFeature = node.eContainingFeature();
59 return containingFeature == ProblemPackage.Literals.INDIVIDUAL_DECLARATION__NODES 59 if (containingFeature == ProblemPackage.Literals.NODE_DECLARATION__NODES) {
60 || containingFeature == ProblemPackage.Literals.ENUM_DECLARATION__LITERALS; 60 return ((NodeDeclaration) node.eContainer()).getKind() == NodeKind.ATOM;
61 }
62 return containingFeature == ProblemPackage.Literals.ENUM_DECLARATION__LITERALS;
63 }
64
65 public static boolean isMultiNode(Node node) {
66 var containingFeature = node.eContainingFeature();
67 if (containingFeature == ProblemPackage.Literals.NODE_DECLARATION__NODES) {
68 return ((NodeDeclaration) node.eContainer()).getKind() == NodeKind.MULTI;
69 }
70 return containingFeature == ProblemPackage.Literals.CLASS_DECLARATION__NEW_NODE;
61 } 71 }
62 72
63 public static boolean isNewNode(Node node) { 73 public static boolean isDeclaredNode(Node node) {
64 return node.eContainingFeature() == ProblemPackage.Literals.CLASS_DECLARATION__NEW_NODE; 74 return node.eContainingFeature() == ProblemPackage.Literals.NODE_DECLARATION__NODES;
65 } 75 }
66 76
67 public static boolean isInvalidMultiplicityConstraint(PredicateDefinition predicateDefinition) { 77 public static boolean isInvalidMultiplicityConstraint(PredicateDefinition predicateDefinition) {
diff --git a/subprojects/language/src/main/java/tools/refinery/language/validation/ProblemValidator.java b/subprojects/language/src/main/java/tools/refinery/language/validation/ProblemValidator.java
index 8bda4b95..a95e8b3c 100644
--- a/subprojects/language/src/main/java/tools/refinery/language/validation/ProblemValidator.java
+++ b/subprojects/language/src/main/java/tools/refinery/language/validation/ProblemValidator.java
@@ -84,7 +84,7 @@ public class ProblemValidator extends AbstractProblemValidator {
84 @Check 84 @Check
85 public void checkNodeConstants(VariableOrNodeExpr expr) { 85 public void checkNodeConstants(VariableOrNodeExpr expr) {
86 var variableOrNode = expr.getVariableOrNode(); 86 var variableOrNode = expr.getVariableOrNode();
87 if (variableOrNode instanceof Node node && !ProblemUtil.isIndividualNode(node)) { 87 if (variableOrNode instanceof Node node && !ProblemUtil.isAtomNode(node)) {
88 var name = node.getName(); 88 var name = node.getName();
89 var message = ("Only individuals can be referenced in predicates. " + 89 var message = ("Only individuals can be referenced in predicates. " +
90 "Mark '%s' as individual with the declaration 'indiv %s.'").formatted(name, name); 90 "Mark '%s' as individual with the declaration 'indiv %s.'").formatted(name, name);
@@ -96,16 +96,16 @@ public class ProblemValidator extends AbstractProblemValidator {
96 @Check 96 @Check
97 public void checkUniqueDeclarations(Problem problem) { 97 public void checkUniqueDeclarations(Problem problem) {
98 var relations = new ArrayList<Relation>(); 98 var relations = new ArrayList<Relation>();
99 var individuals = new ArrayList<Node>(); 99 var nodes = new ArrayList<Node>();
100 for (var statement : problem.getStatements()) { 100 for (var statement : problem.getStatements()) {
101 if (statement instanceof Relation relation) { 101 if (statement instanceof Relation relation) {
102 relations.add(relation); 102 relations.add(relation);
103 } else if (statement instanceof IndividualDeclaration individualDeclaration) { 103 } else if (statement instanceof NodeDeclaration nodeDeclaration) {
104 individuals.addAll(individualDeclaration.getNodes()); 104 nodes.addAll(nodeDeclaration.getNodes());
105 } 105 }
106 } 106 }
107 checkUniqueSimpleNames(relations); 107 checkUniqueSimpleNames(relations);
108 checkUniqueSimpleNames(individuals); 108 checkUniqueSimpleNames(nodes);
109 } 109 }
110 110
111 @Check 111 @Check
@@ -362,7 +362,7 @@ public class ProblemValidator extends AbstractProblemValidator {
362 return; 362 return;
363 } 363 }
364 var node = getNodeArgumentForMultiObjectAssertion(arguments.get(0)); 364 var node = getNodeArgumentForMultiObjectAssertion(arguments.get(0));
365 if (node != null && !node.eIsProxy() && ProblemUtil.isIndividualNode(node)) { 365 if (node != null && !node.eIsProxy() && ProblemUtil.isAtomNode(node)) {
366 acceptError("Individual nodes must exist.", assertion, null, 0, UNSUPPORTED_ASSERTION_ISSUE); 366 acceptError("Individual nodes must exist.", assertion, null, 0, UNSUPPORTED_ASSERTION_ISSUE);
367 } 367 }
368 } 368 }