aboutsummaryrefslogtreecommitdiffstats
path: root/subprojects/generator/src/main/java/tools
diff options
context:
space:
mode:
authorLibravatar Kristóf Marussy <kristof@marussy.com>2023-12-24 19:42:21 +0100
committerLibravatar Kristóf Marussy <kristof@marussy.com>2023-12-25 00:04:37 +0100
commit1f9b4652b1f85fc9f2cefcd46b34431ecea5c381 (patch)
tree84aba7f8ce90ff5aea38c912b3999ec7810f6f44 /subprojects/generator/src/main/java/tools
parentfeat: command line model generator (diff)
downloadrefinery-1f9b4652b1f85fc9f2cefcd46b34431ecea5c381.tar.gz
refinery-1f9b4652b1f85fc9f2cefcd46b34431ecea5c381.tar.zst
refinery-1f9b4652b1f85fc9f2cefcd46b34431ecea5c381.zip
refactor(generator): scope overrides
Diffstat (limited to 'subprojects/generator/src/main/java/tools')
-rw-r--r--subprojects/generator/src/main/java/tools/refinery/generator/ProblemLoader.java61
1 files changed, 61 insertions, 0 deletions
diff --git a/subprojects/generator/src/main/java/tools/refinery/generator/ProblemLoader.java b/subprojects/generator/src/main/java/tools/refinery/generator/ProblemLoader.java
index abfbe7e6..20ea8132 100644
--- a/subprojects/generator/src/main/java/tools/refinery/generator/ProblemLoader.java
+++ b/subprojects/generator/src/main/java/tools/refinery/generator/ProblemLoader.java
@@ -17,11 +17,18 @@ import org.eclipse.xtext.util.LazyStringInputStream;
17import org.eclipse.xtext.validation.CheckMode; 17import org.eclipse.xtext.validation.CheckMode;
18import org.eclipse.xtext.validation.IResourceValidator; 18import org.eclipse.xtext.validation.IResourceValidator;
19import tools.refinery.language.model.problem.Problem; 19import tools.refinery.language.model.problem.Problem;
20import tools.refinery.language.model.problem.Relation;
21import tools.refinery.language.model.problem.ScopeDeclaration;
20import tools.refinery.store.util.CancellationToken; 22import tools.refinery.store.util.CancellationToken;
21 23
24import java.io.ByteArrayOutputStream;
22import java.io.File; 25import java.io.File;
23import java.io.IOException; 26import java.io.IOException;
24import java.io.InputStream; 27import java.io.InputStream;
28import java.nio.charset.StandardCharsets;
29import java.util.ArrayList;
30import java.util.HashSet;
31import java.util.List;
25import java.util.Map; 32import java.util.Map;
26 33
27public class ProblemLoader { 34public class ProblemLoader {
@@ -104,4 +111,58 @@ public class ProblemLoader {
104 } 111 }
105 return problem; 112 return problem;
106 } 113 }
114
115 public Problem loadScopeConstraints(Problem problem, List<String> extraScopes,
116 List<String> overrideScopes) throws IOException {
117 var allScopes = new ArrayList<>(extraScopes);
118 allScopes.addAll(overrideScopes);
119 if (allScopes.isEmpty()) {
120 return problem;
121 }
122 int originalStatementCount = problem.getStatements().size();
123 var builder = new StringBuilder();
124 var problemResource = problem.eResource();
125 try (var outputStream = new ByteArrayOutputStream()) {
126 problemResource.save(outputStream, Map.of());
127 builder.append(outputStream.toString(StandardCharsets.UTF_8));
128 }
129 builder.append('\n');
130 for (var scope : allScopes) {
131 builder.append("scope ").append(scope).append(".\n");
132 }
133 var modifiedProblem = loadString(builder.toString(), problemResource.getURI());
134 var modifiedStatements = modifiedProblem.getStatements();
135 int modifiedStatementCount = modifiedStatements.size();
136 if (modifiedStatementCount != originalStatementCount + allScopes.size()) {
137 throw new IllegalArgumentException("Failed to parse scope constraints");
138 }
139 // Override scopes remove any scope constraint from the original problem with the same target type.
140 var overriddenScopes = new HashSet<Relation>();
141 for (int i = modifiedStatementCount - overrideScopes.size(); i < modifiedStatementCount; i++) {
142 var statement = modifiedStatements.get(i);
143 if (!(statement instanceof ScopeDeclaration scopeDeclaration)) {
144 throw new IllegalStateException("Invalid scope constraint: " + statement);
145 }
146 for (var typeScope : scopeDeclaration.getTypeScopes()) {
147 overriddenScopes.add(typeScope.getTargetType());
148 }
149 }
150 int statementIndex = 0;
151 var iterator = modifiedStatements.iterator();
152 // Scope overrides only affect type scopes from the original problem and leave type scopes added on the
153 // command line intact.
154 while (statementIndex < originalStatementCount && iterator.hasNext()) {
155 var statement = iterator.next();
156 if (statement instanceof ScopeDeclaration scopeDeclaration) {
157 var typeScopes = scopeDeclaration.getTypeScopes();
158 typeScopes.removeIf(typeScope -> overriddenScopes.contains(typeScope.getTargetType()));
159 // Scope declarations with no type scopes are invalid, so we have to remove them.
160 if (typeScopes.isEmpty()) {
161 iterator.remove();
162 }
163 }
164 statementIndex++;
165 }
166 return modifiedProblem;
167 }
107} 168}