diff options
author | 2023-12-24 19:42:21 +0100 | |
---|---|---|
committer | 2023-12-25 00:04:37 +0100 | |
commit | 1f9b4652b1f85fc9f2cefcd46b34431ecea5c381 (patch) | |
tree | 84aba7f8ce90ff5aea38c912b3999ec7810f6f44 /subprojects/generator/src/main/java/tools | |
parent | feat: command line model generator (diff) | |
download | refinery-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.java | 61 |
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; | |||
17 | import org.eclipse.xtext.validation.CheckMode; | 17 | import org.eclipse.xtext.validation.CheckMode; |
18 | import org.eclipse.xtext.validation.IResourceValidator; | 18 | import org.eclipse.xtext.validation.IResourceValidator; |
19 | import tools.refinery.language.model.problem.Problem; | 19 | import tools.refinery.language.model.problem.Problem; |
20 | import tools.refinery.language.model.problem.Relation; | ||
21 | import tools.refinery.language.model.problem.ScopeDeclaration; | ||
20 | import tools.refinery.store.util.CancellationToken; | 22 | import tools.refinery.store.util.CancellationToken; |
21 | 23 | ||
24 | import java.io.ByteArrayOutputStream; | ||
22 | import java.io.File; | 25 | import java.io.File; |
23 | import java.io.IOException; | 26 | import java.io.IOException; |
24 | import java.io.InputStream; | 27 | import java.io.InputStream; |
28 | import java.nio.charset.StandardCharsets; | ||
29 | import java.util.ArrayList; | ||
30 | import java.util.HashSet; | ||
31 | import java.util.List; | ||
25 | import java.util.Map; | 32 | import java.util.Map; |
26 | 33 | ||
27 | public class ProblemLoader { | 34 | public 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 | } |