diff options
author | 2022-11-19 21:39:00 +0100 | |
---|---|---|
committer | 2022-11-22 16:40:03 +0100 | |
commit | 3aa4a2b58221a3e83b17d0c04c9a6e9c41e5500c (patch) | |
tree | 1e25f513e3b34b2ea29dbcc6cc3795e5927a1362 /subprojects/language/src/main/java | |
parent | feat(language): numeric expressions (diff) | |
download | refinery-3aa4a2b58221a3e83b17d0c04c9a6e9c41e5500c.tar.gz refinery-3aa4a2b58221a3e83b17d0c04c9a6e9c41e5500c.tar.zst refinery-3aa4a2b58221a3e83b17d0c04c9a6e9c41e5500c.zip |
refactor: separate primitive types from nodes
Diffstat (limited to 'subprojects/language/src/main/java')
11 files changed, 237 insertions, 284 deletions
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 bc1ee465..8b13a693 100644 --- a/subprojects/language/src/main/java/tools/refinery/language/Problem.xtext +++ b/subprojects/language/src/main/java/tools/refinery/language/Problem.xtext | |||
@@ -10,14 +10,13 @@ Problem: | |||
10 | Statement: | 10 | Statement: |
11 | ClassDeclaration | EnumDeclaration | | 11 | ClassDeclaration | EnumDeclaration | |
12 | PredicateDefinition | FunctionDefinition | /* RuleDefinition | */ | 12 | PredicateDefinition | FunctionDefinition | /* RuleDefinition | */ |
13 | Assertion | NodeValueAssertion | | 13 | Assertion | ScopeDeclaration | IndividualDeclaration; |
14 | ScopeDeclaration | IndividualDeclaration; | ||
15 | 14 | ||
16 | ClassDeclaration: | 15 | ClassDeclaration: |
17 | abstract?="abstract"? "class" | 16 | abstract?="abstract"? "class" |
18 | name=Identifier | 17 | name=Identifier |
19 | ("extends" superTypes+=[Relation|QualifiedName] ("," superTypes+=[Relation|QualifiedName])*)? | 18 | ("extends" superTypes+=[Relation|QualifiedName] ("," superTypes+=[Relation|QualifiedName])*)? |
20 | ("{" (referenceDeclarations+=ReferenceDeclaration ";"?)* "}" | "."); | 19 | ("{" (featureDeclarations+=FeatureDeclaration ";"?)* "}" | "."); |
21 | 20 | ||
22 | EnumDeclaration: | 21 | EnumDeclaration: |
23 | "enum" | 22 | "enum" |
@@ -27,16 +26,27 @@ EnumDeclaration: | |||
27 | EnumLiteral returns Node: | 26 | EnumLiteral returns Node: |
28 | name=Identifier; | 27 | name=Identifier; |
29 | 28 | ||
29 | FeatureDeclaration: | ||
30 | ReferenceDeclaration | AttributeDeclaration | FlagDeclaration; | ||
31 | |||
30 | enum ReferenceKind: | 32 | enum ReferenceKind: |
31 | REFERENCE="refers" | CONTAINMENT="contains" | CONTAINER="container"; | 33 | REFERENCE="refers" | CONTAINMENT="contains" | CONTAINER="container"; |
32 | 34 | ||
33 | ReferenceDeclaration: | 35 | ReferenceDeclaration: |
34 | (kind=ReferenceKind referenceType=[Relation|QualifiedName] | | 36 | kind=ReferenceKind referenceType=[Relation|QualifiedName] |
35 | referenceType=[Relation|NonRelationKindQualifiedName]) | ||
36 | ("[" multiplicity=Multiplicity "]")? | 37 | ("[" multiplicity=Multiplicity "]")? |
37 | name=Identifier | 38 | name=Identifier |
38 | ("opposite" opposite=[ReferenceDeclaration|QualifiedName])?; | 39 | ("opposite" opposite=[ReferenceDeclaration|QualifiedName])?; |
39 | 40 | ||
41 | enum PrimitiveType: | ||
42 | INT="int" | REAL="real" | STRING="string"; | ||
43 | |||
44 | AttributeDeclaration: | ||
45 | attributeType=PrimitiveType name=Identifier; | ||
46 | |||
47 | FlagDeclaration: | ||
48 | "bool" name=Identifier; | ||
49 | |||
40 | enum ErrorKind returns PredicateKind: | 50 | enum ErrorKind returns PredicateKind: |
41 | ERROR="error"; | 51 | ERROR="error"; |
42 | 52 | ||
@@ -54,7 +64,7 @@ Conjunction: | |||
54 | literals+=Expr ("," literals+=Expr)*; | 64 | literals+=Expr ("," literals+=Expr)*; |
55 | 65 | ||
56 | FunctionDefinition: | 66 | FunctionDefinition: |
57 | functionType=[Relation|QualifiedName] name=Identifier | 67 | functionType=PrimitiveType name=Identifier |
58 | "(" (parameters+=Parameter ("," parameters+=Parameter)*)? ")" | 68 | "(" (parameters+=Parameter ("," parameters+=Parameter)*)? ")" |
59 | ("=" cases+=Case (";" cases+=Case)*)? | 69 | ("=" cases+=Case (";" cases+=Case)*)? |
60 | "."; | 70 | "."; |
@@ -96,11 +106,21 @@ Expr: | |||
96 | ComparisonExpr; | 106 | ComparisonExpr; |
97 | 107 | ||
98 | enum ComparisonOp: | 108 | enum ComparisonOp: |
99 | LESS="<" | LESS_EQ="<=" | GREATER=">" | GREATER_EQ=">=" | EQ="==" | NOT_EQ="!="; | 109 | LESS="<" | LESS_EQ="<=" | GREATER=">" | GREATER_EQ=">=" | EQ="==" | NOT_EQ="!=" | IN="in"; |
100 | 110 | ||
101 | ComparisonExpr returns Expr: | 111 | ComparisonExpr returns Expr: |
102 | AdditiveExpr ({ComparisonExpr.left=current} | 112 | LatticeExpr ({ComparisonExpr.left=current} |
103 | op=ComparisonOp right=AdditiveExpr)*; | 113 | op=ComparisonOp right=LatticeExpr)*; |
114 | |||
115 | enum LatticeOp returns BinaryOp: | ||
116 | MEET="/\\" | JOIN="\\/"; | ||
117 | |||
118 | LatticeExpr returns Expr: | ||
119 | RangeExpr ({ArithmeticBinaryExpr.left=current} | ||
120 | op=LatticeOp right=RangeExpr)*; | ||
121 | |||
122 | RangeExpr returns Expr: | ||
123 | AdditiveExpr ({RangeExpr.left=current} ".." right=AdditiveExpr)*; | ||
104 | 124 | ||
105 | enum AdditiveOp returns BinaryOp: | 125 | enum AdditiveOp returns BinaryOp: |
106 | ADD="+" | SUB="-"; | 126 | ADD="+" | SUB="-"; |
@@ -125,7 +145,7 @@ ExponentialExpr returns Expr: | |||
125 | 145 | ||
126 | UnaryExpr returns Expr: | 146 | UnaryExpr returns Expr: |
127 | ArithmeticUnaryExpr | ModalExpr | NegationExpr | CountExpr | AggregationExpr | | 147 | ArithmeticUnaryExpr | ModalExpr | NegationExpr | CountExpr | AggregationExpr | |
128 | Atom | VariableOrNodeExpr | ConstantExpr | "(" Expr ")"; | 148 | Atom | VariableOrNodeExpr | Constant | "(" Expr ")"; |
129 | 149 | ||
130 | enum UnaryOp: | 150 | enum UnaryOp: |
131 | PLUS="+" | MINUS="-"; | 151 | PLUS="+" | MINUS="-"; |
@@ -159,21 +179,33 @@ Atom: | |||
159 | VariableOrNodeExpr: | 179 | VariableOrNodeExpr: |
160 | variableOrNode=[VariableOrNode|QualifiedName]; | 180 | variableOrNode=[VariableOrNode|QualifiedName]; |
161 | 181 | ||
162 | ConstantExpr: | 182 | Constant: |
163 | constant=Constant; | 183 | RealConstant | IntConstant | InfConstant | StringConstant; |
184 | |||
185 | IntConstant: | ||
186 | intValue=INT; | ||
187 | |||
188 | RealConstant: | ||
189 | realValue=Real; | ||
190 | |||
191 | InfConstant: | ||
192 | {InfConstant} "*"; | ||
193 | |||
194 | StringConstant: | ||
195 | stringValue=STRING; | ||
164 | 196 | ||
165 | Assertion: | 197 | Assertion: |
166 | default?="default"? | 198 | default?="default"? |
167 | (value=ShortLogicValue? | 199 | (relation=[Relation|QualifiedName] |
168 | relation=[Relation|QualifiedName] | ||
169 | "(" (arguments+=AssertionArgument ("," arguments+=AssertionArgument)*)? ")" | ||
170 | | relation=[Relation|QualifiedName] | ||
171 | "(" (arguments+=AssertionArgument ("," arguments+=AssertionArgument)*)? ")" | 200 | "(" (arguments+=AssertionArgument ("," arguments+=AssertionArgument)*)? ")" |
172 | ":" value=LogicValue) | 201 | value=AssertionValue | |
202 | value=ShortLogicAssertionValue | ||
203 | relation=[Relation|QualifiedName] | ||
204 | "(" (arguments+=AssertionArgument ("," arguments+=AssertionArgument)*)? ")") | ||
173 | "."; | 205 | "."; |
174 | 206 | ||
175 | AssertionArgument: | 207 | AssertionArgument: |
176 | NodeAssertionArgument | WildcardAssertionArgument | ConstantAssertionArgument; | 208 | NodeAssertionArgument | WildcardAssertionArgument; |
177 | 209 | ||
178 | NodeAssertionArgument: | 210 | NodeAssertionArgument: |
179 | node=[Node|QualifiedName]; | 211 | node=[Node|QualifiedName]; |
@@ -181,29 +213,23 @@ NodeAssertionArgument: | |||
181 | WildcardAssertionArgument: | 213 | WildcardAssertionArgument: |
182 | {WildcardAssertionArgument} "*"; | 214 | {WildcardAssertionArgument} "*"; |
183 | 215 | ||
184 | ConstantAssertionArgument: | 216 | AssertionValue: |
185 | negative?="-"? constant=Constant; | 217 | LogicAssertionValue | ExprAssertionValue; |
186 | 218 | ||
187 | enum LogicValue: | 219 | enum LogicValue: |
188 | TRUE="true" | FALSE="false" | UNKNOWN="unknown" | ERROR="error"; | 220 | TRUE="true" | FALSE="false" | UNKNOWN="unknown" | ERROR="error"; |
189 | 221 | ||
190 | enum ShortLogicValue returns LogicValue: | 222 | LogicAssertionValue: |
191 | FALSE="!" | UNKNOWN="?"; | 223 | ":" logicValue=LogicValue; |
192 | 224 | ||
193 | NodeValueAssertion: | 225 | ExprAssertionValue: |
194 | node=[Node|QualifiedName] ":" value=Constant "."; | 226 | (range?="in" | "=") body=Expr; |
195 | |||
196 | Constant: | ||
197 | RealConstant | IntConstant | StringConstant; | ||
198 | |||
199 | IntConstant: | ||
200 | intValue=INT; | ||
201 | 227 | ||
202 | RealConstant: | 228 | enum ShortLogicValue returns LogicValue: |
203 | realValue=Real; | 229 | FALSE="!" | UNKNOWN="?"; |
204 | 230 | ||
205 | StringConstant: | 231 | ShortLogicAssertionValue returns LogicAssertionValue: |
206 | stringValue=STRING; | 232 | {LogicAssertionValue} logicValue=ShortLogicValue?; |
207 | 233 | ||
208 | ScopeDeclaration: | 234 | ScopeDeclaration: |
209 | "scope" typeScopes+=TypeScope ("," typeScopes+=TypeScope)* "."; | 235 | "scope" typeScopes+=TypeScope ("," typeScopes+=TypeScope)* "."; |
@@ -234,17 +260,11 @@ IndividualDeclaration: | |||
234 | UpperBound returns ecore::EInt: | 260 | UpperBound returns ecore::EInt: |
235 | INT | "*"; | 261 | INT | "*"; |
236 | 262 | ||
237 | NonRelationKindQualifiedName hidden(): | ||
238 | NonRelationKindIdentifier ("::" Identifier)*; | ||
239 | |||
240 | QualifiedName hidden(): | 263 | QualifiedName hidden(): |
241 | Identifier ("::" Identifier)*; | 264 | Identifier ("::" Identifier)*; |
242 | 265 | ||
243 | NonRelationKindIdentifier: | ||
244 | ID | "true" | "false" | "contained" | "sum" | "prod" | "min" | "max"; | ||
245 | |||
246 | Identifier: | 266 | Identifier: |
247 | NonRelationKindIdentifier | "contains"; | 267 | ID | "contains" | "contained" | "sum" | "prod" | "min" | "max"; |
248 | 268 | ||
249 | Real returns ecore::EDouble: | 269 | Real returns ecore::EDouble: |
250 | EXPONENTIAL | INT "." (INT | EXPONENTIAL); | 270 | EXPONENTIAL | INT "." (INT | EXPONENTIAL); |
diff --git a/subprojects/language/src/main/java/tools/refinery/language/ProblemRuntimeModule.java b/subprojects/language/src/main/java/tools/refinery/language/ProblemRuntimeModule.java index c0777038..5efcdc81 100644 --- a/subprojects/language/src/main/java/tools/refinery/language/ProblemRuntimeModule.java +++ b/subprojects/language/src/main/java/tools/refinery/language/ProblemRuntimeModule.java | |||
@@ -3,25 +3,18 @@ | |||
3 | */ | 3 | */ |
4 | package tools.refinery.language; | 4 | package tools.refinery.language; |
5 | 5 | ||
6 | import com.google.inject.Binder; | ||
7 | import com.google.inject.name.Names; | ||
6 | import org.eclipse.xtext.conversion.IValueConverterService; | 8 | import org.eclipse.xtext.conversion.IValueConverterService; |
7 | import org.eclipse.xtext.naming.IQualifiedNameConverter; | 9 | import org.eclipse.xtext.naming.IQualifiedNameConverter; |
8 | import org.eclipse.xtext.parser.IParser; | 10 | import org.eclipse.xtext.parser.IParser; |
9 | import org.eclipse.xtext.resource.DerivedStateAwareResource; | 11 | import org.eclipse.xtext.resource.*; |
10 | import org.eclipse.xtext.resource.DerivedStateAwareResourceDescriptionManager; | ||
11 | import org.eclipse.xtext.resource.IDefaultResourceDescriptionStrategy; | ||
12 | import org.eclipse.xtext.resource.IDerivedStateComputer; | ||
13 | import org.eclipse.xtext.resource.ILocationInFileProvider; | ||
14 | import org.eclipse.xtext.resource.IResourceDescription; | ||
15 | import org.eclipse.xtext.resource.XtextResource; | ||
16 | import org.eclipse.xtext.scoping.IGlobalScopeProvider; | 12 | import org.eclipse.xtext.scoping.IGlobalScopeProvider; |
17 | import org.eclipse.xtext.scoping.IScopeProvider; | 13 | import org.eclipse.xtext.scoping.IScopeProvider; |
18 | import org.eclipse.xtext.scoping.impl.AbstractDeclarativeScopeProvider; | 14 | import org.eclipse.xtext.scoping.impl.AbstractDeclarativeScopeProvider; |
15 | import org.eclipse.xtext.serializer.sequencer.ISemanticSequencer; | ||
19 | import org.eclipse.xtext.validation.IResourceValidator; | 16 | import org.eclipse.xtext.validation.IResourceValidator; |
20 | import org.eclipse.xtext.xbase.annotations.validation.DerivedStateAwareResourceValidator; | 17 | import org.eclipse.xtext.xbase.annotations.validation.DerivedStateAwareResourceValidator; |
21 | |||
22 | import com.google.inject.Binder; | ||
23 | import com.google.inject.name.Names; | ||
24 | |||
25 | import tools.refinery.language.conversion.ProblemValueConverterService; | 18 | import tools.refinery.language.conversion.ProblemValueConverterService; |
26 | import tools.refinery.language.naming.ProblemQualifiedNameConverter; | 19 | import tools.refinery.language.naming.ProblemQualifiedNameConverter; |
27 | import tools.refinery.language.parser.antlr.TokenSourceInjectingProblemParser; | 20 | import tools.refinery.language.parser.antlr.TokenSourceInjectingProblemParser; |
@@ -30,6 +23,7 @@ import tools.refinery.language.resource.ProblemLocationInFileProvider; | |||
30 | import tools.refinery.language.resource.ProblemResourceDescriptionStrategy; | 23 | import tools.refinery.language.resource.ProblemResourceDescriptionStrategy; |
31 | import tools.refinery.language.scoping.ProblemGlobalScopeProvider; | 24 | import tools.refinery.language.scoping.ProblemGlobalScopeProvider; |
32 | import tools.refinery.language.scoping.ProblemLocalScopeProvider; | 25 | import tools.refinery.language.scoping.ProblemLocalScopeProvider; |
26 | import tools.refinery.language.serializer.PreferShortAssertionsProblemSemanticSequencer; | ||
33 | 27 | ||
34 | /** | 28 | /** |
35 | * Use this class to register components to be used at runtime / without the | 29 | * Use this class to register components to be used at runtime / without the |
@@ -88,4 +82,9 @@ public class ProblemRuntimeModule extends AbstractProblemRuntimeModule { | |||
88 | public Class<? extends ILocationInFileProvider> bindILocationInFileProvider() { | 82 | public Class<? extends ILocationInFileProvider> bindILocationInFileProvider() { |
89 | return ProblemLocationInFileProvider.class; | 83 | return ProblemLocationInFileProvider.class; |
90 | } | 84 | } |
85 | |||
86 | @Override | ||
87 | public Class<? extends ISemanticSequencer> bindISemanticSequencer() { | ||
88 | return PreferShortAssertionsProblemSemanticSequencer.class; | ||
89 | } | ||
91 | } | 90 | } |
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 a65e0750..46870edb 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 | |||
@@ -3,6 +3,7 @@ | |||
3 | */ | 3 | */ |
4 | package tools.refinery.language.formatting2; | 4 | package tools.refinery.language.formatting2; |
5 | 5 | ||
6 | import com.google.inject.Inject; | ||
6 | import org.eclipse.emf.ecore.EObject; | 7 | import org.eclipse.emf.ecore.EObject; |
7 | import org.eclipse.xtext.formatting2.AbstractJavaFormatter; | 8 | import org.eclipse.xtext.formatting2.AbstractJavaFormatter; |
8 | import org.eclipse.xtext.formatting2.IFormattableDocument; | 9 | import org.eclipse.xtext.formatting2.IFormattableDocument; |
@@ -12,9 +13,12 @@ import org.eclipse.xtext.formatting2.regionaccess.ISequentialRegion; | |||
12 | import org.eclipse.xtext.xbase.lib.Procedures.Procedure1; | 13 | import org.eclipse.xtext.xbase.lib.Procedures.Procedure1; |
13 | 14 | ||
14 | import tools.refinery.language.model.problem.*; | 15 | import tools.refinery.language.model.problem.*; |
16 | import tools.refinery.language.services.ProblemGrammarAccess; | ||
15 | 17 | ||
16 | @SuppressWarnings("UnstableApiUsage") | 18 | @SuppressWarnings("UnstableApiUsage") |
17 | public class ProblemFormatter extends AbstractJavaFormatter { | 19 | public class ProblemFormatter extends AbstractJavaFormatter { |
20 | @Inject | ||
21 | private ProblemGrammarAccess problemGrammarAccess; | ||
18 | 22 | ||
19 | protected void format(Problem problem, IFormattableDocument doc) { | 23 | protected void format(Problem problem, IFormattableDocument doc) { |
20 | doc.prepend(problem, this::noSpace); | 24 | doc.prepend(problem, this::noSpace); |
@@ -31,17 +35,35 @@ public class ProblemFormatter extends AbstractJavaFormatter { | |||
31 | surroundNewLines(doc, assertion, this::singleNewLine); | 35 | surroundNewLines(doc, assertion, this::singleNewLine); |
32 | var region = regionFor(assertion); | 36 | var region = regionFor(assertion); |
33 | doc.append(region.feature(ProblemPackage.Literals.ASSERTION__DEFAULT), this::oneSpace); | 37 | doc.append(region.feature(ProblemPackage.Literals.ASSERTION__DEFAULT), this::oneSpace); |
34 | doc.append(region.feature(ProblemPackage.Literals.ASSERTION__VALUE), this::noSpace); | ||
35 | doc.append(region.feature(ProblemPackage.Literals.ASSERTION__RELATION), this::noSpace); | 38 | doc.append(region.feature(ProblemPackage.Literals.ASSERTION__RELATION), this::noSpace); |
36 | formatParenthesizedList(region, doc); | 39 | formatParenthesizedList(region, doc); |
37 | doc.prepend(region.keyword(":"), this::noSpace); | 40 | var value = assertion.getValue(); |
38 | doc.append(region.keyword(":"), this::oneSpace); | 41 | if (value != null) { |
42 | doc.append(value, this::noSpace); | ||
43 | doc.format(value); | ||
44 | } | ||
39 | doc.prepend(region.keyword("."), this::noSpace); | 45 | doc.prepend(region.keyword("."), this::noSpace); |
40 | for (var argument : assertion.getArguments()) { | 46 | for (var argument : assertion.getArguments()) { |
41 | doc.format(argument); | 47 | doc.format(argument); |
42 | } | 48 | } |
43 | } | 49 | } |
44 | 50 | ||
51 | protected void format(LogicAssertionValue assertionValue, IFormattableDocument doc) { | ||
52 | var region = regionFor(assertionValue); | ||
53 | doc.prepend(region.keyword(":"), this::noSpace); | ||
54 | doc.append(region.keyword(":"), this::oneSpace); | ||
55 | } | ||
56 | |||
57 | protected void format(ExprAssertionValue assertionValue, IFormattableDocument doc) { | ||
58 | var region = regionFor(assertionValue); | ||
59 | doc.surround(region.keyword("="), this::oneSpace); | ||
60 | doc.surround(region.keyword("in"), this::oneSpace); | ||
61 | var body = assertionValue.getBody(); | ||
62 | if (body != null) { | ||
63 | doc.format(body); | ||
64 | } | ||
65 | } | ||
66 | |||
45 | protected void format(ClassDeclaration classDeclaration, IFormattableDocument doc) { | 67 | protected void format(ClassDeclaration classDeclaration, IFormattableDocument doc) { |
46 | surroundNewLines(doc, classDeclaration, this::twoNewLines); | 68 | surroundNewLines(doc, classDeclaration, this::twoNewLines); |
47 | var region = regionFor(classDeclaration); | 69 | var region = regionFor(classDeclaration); |
@@ -53,8 +75,8 @@ public class ProblemFormatter extends AbstractJavaFormatter { | |||
53 | doc.append(region.keyword("{"), it -> it.setNewLines(1, 1, 2)); | 75 | doc.append(region.keyword("{"), it -> it.setNewLines(1, 1, 2)); |
54 | doc.prepend(region.keyword("}"), it -> it.setNewLines(1, 1, 2)); | 76 | doc.prepend(region.keyword("}"), it -> it.setNewLines(1, 1, 2)); |
55 | doc.prepend(region.keyword("."), this::noSpace); | 77 | doc.prepend(region.keyword("."), this::noSpace); |
56 | for (var referenceDeclaration : classDeclaration.getReferenceDeclarations()) { | 78 | for (var featureDeclaration : classDeclaration.getFeatureDeclarations()) { |
57 | doc.format(referenceDeclaration); | 79 | doc.format(featureDeclaration); |
58 | } | 80 | } |
59 | } | 81 | } |
60 | 82 | ||
diff --git a/subprojects/language/src/main/java/tools/refinery/language/resource/NodeNameCollector.java b/subprojects/language/src/main/java/tools/refinery/language/resource/NodeNameCollector.java index 99bf9b64..419be0d3 100644 --- a/subprojects/language/src/main/java/tools/refinery/language/resource/NodeNameCollector.java +++ b/subprojects/language/src/main/java/tools/refinery/language/resource/NodeNameCollector.java | |||
@@ -1,10 +1,9 @@ | |||
1 | package tools.refinery.language.resource; | 1 | package tools.refinery.language.resource; |
2 | 2 | ||
3 | import java.util.List; | 3 | import com.google.common.collect.ImmutableSet; |
4 | import java.util.Set; | 4 | import com.google.inject.Inject; |
5 | 5 | import com.google.inject.name.Named; | |
6 | import org.eclipse.emf.ecore.EObject; | 6 | import org.eclipse.emf.ecore.EObject; |
7 | import org.eclipse.emf.ecore.EStructuralFeature; | ||
8 | import org.eclipse.xtext.linking.impl.LinkingHelper; | 7 | import org.eclipse.xtext.linking.impl.LinkingHelper; |
9 | import org.eclipse.xtext.naming.IQualifiedNameConverter; | 8 | import org.eclipse.xtext.naming.IQualifiedNameConverter; |
10 | import org.eclipse.xtext.nodemodel.INode; | 9 | import org.eclipse.xtext.nodemodel.INode; |
@@ -12,20 +11,12 @@ import org.eclipse.xtext.nodemodel.util.NodeModelUtils; | |||
12 | import org.eclipse.xtext.scoping.IScope; | 11 | import org.eclipse.xtext.scoping.IScope; |
13 | import org.eclipse.xtext.scoping.IScopeProvider; | 12 | import org.eclipse.xtext.scoping.IScopeProvider; |
14 | import org.eclipse.xtext.scoping.impl.AbstractDeclarativeScopeProvider; | 13 | import org.eclipse.xtext.scoping.impl.AbstractDeclarativeScopeProvider; |
15 | 14 | import tools.refinery.language.model.problem.*; | |
16 | import com.google.common.collect.ImmutableSet; | ||
17 | import com.google.inject.Inject; | ||
18 | import com.google.inject.name.Named; | ||
19 | |||
20 | import tools.refinery.language.model.problem.Assertion; | ||
21 | import tools.refinery.language.model.problem.AssertionArgument; | ||
22 | import tools.refinery.language.model.problem.NodeAssertionArgument; | ||
23 | import tools.refinery.language.model.problem.NodeValueAssertion; | ||
24 | import tools.refinery.language.model.problem.Problem; | ||
25 | import tools.refinery.language.model.problem.ProblemPackage; | ||
26 | import tools.refinery.language.model.problem.Statement; | ||
27 | import tools.refinery.language.naming.NamingUtil; | 15 | import tools.refinery.language.naming.NamingUtil; |
28 | 16 | ||
17 | import java.util.List; | ||
18 | import java.util.Set; | ||
19 | |||
29 | public class NodeNameCollector { | 20 | public class NodeNameCollector { |
30 | @Inject | 21 | @Inject |
31 | private LinkingHelper linkingHelper; | 22 | private LinkingHelper linkingHelper; |
@@ -55,25 +46,20 @@ public class NodeNameCollector { | |||
55 | protected void collectStatementNodeNames(Statement statement) { | 46 | protected void collectStatementNodeNames(Statement statement) { |
56 | if (statement instanceof Assertion assertion) { | 47 | if (statement instanceof Assertion assertion) { |
57 | collectAssertionNodeNames(assertion); | 48 | collectAssertionNodeNames(assertion); |
58 | } else if (statement instanceof NodeValueAssertion nodeValueAssertion) { | ||
59 | collectNodeValueAssertionNodeNames(nodeValueAssertion); | ||
60 | } | 49 | } |
61 | } | 50 | } |
62 | 51 | ||
63 | protected void collectAssertionNodeNames(Assertion assertion) { | 52 | protected void collectAssertionNodeNames(Assertion assertion) { |
64 | for (AssertionArgument argument : assertion.getArguments()) { | 53 | for (AssertionArgument argument : assertion.getArguments()) { |
65 | if (argument instanceof NodeAssertionArgument) { | 54 | if (argument instanceof NodeAssertionArgument) { |
66 | collectNodeNames(argument, ProblemPackage.Literals.NODE_ASSERTION_ARGUMENT__NODE); | 55 | collectNodeNames(argument); |
67 | } | 56 | } |
68 | } | 57 | } |
69 | } | 58 | } |
70 | 59 | ||
71 | protected void collectNodeValueAssertionNodeNames(NodeValueAssertion nodeValueAssertion) { | 60 | private void collectNodeNames(EObject eObject) { |
72 | collectNodeNames(nodeValueAssertion, ProblemPackage.Literals.NODE_VALUE_ASSERTION__NODE); | 61 | List<INode> nodes = NodeModelUtils.findNodesForFeature(eObject, |
73 | } | 62 | ProblemPackage.Literals.NODE_ASSERTION_ARGUMENT__NODE); |
74 | |||
75 | private void collectNodeNames(EObject eObject, EStructuralFeature feature) { | ||
76 | List<INode> nodes = NodeModelUtils.findNodesForFeature(eObject, feature); | ||
77 | for (INode node : nodes) { | 63 | for (INode node : nodes) { |
78 | var nodeName = linkingHelper.getCrossRefNodeAsString(node, true); | 64 | var nodeName = linkingHelper.getCrossRefNodeAsString(node, true); |
79 | if (!NamingUtil.isValidId(nodeName)) { | 65 | if (!NamingUtil.isValidId(nodeName)) { |
@@ -85,4 +71,4 @@ public class NodeNameCollector { | |||
85 | } | 71 | } |
86 | } | 72 | } |
87 | } | 73 | } |
88 | } \ No newline at end of file | 74 | } |
diff --git a/subprojects/language/src/main/java/tools/refinery/language/resource/ProblemDerivedStateComputer.java b/subprojects/language/src/main/java/tools/refinery/language/resource/ProblemDerivedStateComputer.java index f28e1791..8d3a552a 100644 --- a/subprojects/language/src/main/java/tools/refinery/language/resource/ProblemDerivedStateComputer.java +++ b/subprojects/language/src/main/java/tools/refinery/language/resource/ProblemDerivedStateComputer.java | |||
@@ -1,13 +1,9 @@ | |||
1 | package tools.refinery.language.resource; | 1 | package tools.refinery.language.resource; |
2 | 2 | ||
3 | import java.util.Collection; | 3 | import com.google.inject.Inject; |
4 | import java.util.HashMap; | 4 | import com.google.inject.Provider; |
5 | import java.util.HashSet; | 5 | import com.google.inject.Singleton; |
6 | import java.util.List; | 6 | import com.google.inject.name.Named; |
7 | import java.util.Map; | ||
8 | import java.util.Set; | ||
9 | import java.util.function.Function; | ||
10 | |||
11 | import org.eclipse.emf.common.notify.impl.AdapterImpl; | 7 | import org.eclipse.emf.common.notify.impl.AdapterImpl; |
12 | import org.eclipse.emf.ecore.EObject; | 8 | import org.eclipse.emf.ecore.EObject; |
13 | import org.eclipse.emf.ecore.resource.Resource; | 9 | import org.eclipse.emf.ecore.resource.Resource; |
@@ -16,37 +12,20 @@ import org.eclipse.xtext.Constants; | |||
16 | import org.eclipse.xtext.resource.DerivedStateAwareResource; | 12 | import org.eclipse.xtext.resource.DerivedStateAwareResource; |
17 | import org.eclipse.xtext.resource.IDerivedStateComputer; | 13 | import org.eclipse.xtext.resource.IDerivedStateComputer; |
18 | import org.eclipse.xtext.resource.XtextResource; | 14 | import org.eclipse.xtext.resource.XtextResource; |
19 | import org.eclipse.xtext.scoping.IScopeProvider; | 15 | import tools.refinery.language.model.problem.*; |
20 | import org.eclipse.xtext.scoping.impl.AbstractDeclarativeScopeProvider; | ||
21 | |||
22 | import com.google.inject.Inject; | ||
23 | import com.google.inject.Provider; | ||
24 | import com.google.inject.Singleton; | ||
25 | import com.google.inject.name.Named; | ||
26 | 16 | ||
27 | import tools.refinery.language.model.problem.Assertion; | 17 | import java.util.*; |
28 | import tools.refinery.language.model.problem.ClassDeclaration; | 18 | import java.util.function.Function; |
29 | import tools.refinery.language.model.problem.ConstantAssertionArgument; | ||
30 | import tools.refinery.language.model.problem.Node; | ||
31 | import tools.refinery.language.model.problem.Problem; | ||
32 | import tools.refinery.language.model.problem.ProblemFactory; | ||
33 | import tools.refinery.language.model.problem.Statement; | ||
34 | 19 | ||
35 | @Singleton | 20 | @Singleton |
36 | public class ProblemDerivedStateComputer implements IDerivedStateComputer { | 21 | public class ProblemDerivedStateComputer implements IDerivedStateComputer { |
37 | public static final String NEW_NODE = "new"; | 22 | public static final String NEW_NODE = "new"; |
38 | 23 | ||
39 | public static final String CONSTANT_NODE = "constant"; | ||
40 | |||
41 | @Inject | 24 | @Inject |
42 | @Named(Constants.LANGUAGE_NAME) | 25 | @Named(Constants.LANGUAGE_NAME) |
43 | private String languageName; | 26 | private String languageName; |
44 | 27 | ||
45 | @Inject | 28 | @Inject |
46 | @Named(AbstractDeclarativeScopeProvider.NAMED_DELEGATE) | ||
47 | private IScopeProvider scopeProvider; | ||
48 | |||
49 | @Inject | ||
50 | private Provider<NodeNameCollector> nodeNameCollectorProvider; | 29 | private Provider<NodeNameCollector> nodeNameCollectorProvider; |
51 | 30 | ||
52 | @Inject | 31 | @Inject |
@@ -88,15 +67,6 @@ public class ProblemDerivedStateComputer implements IDerivedStateComputer { | |||
88 | && declaration.getNewNode() == null) { | 67 | && declaration.getNewNode() == null) { |
89 | var newNode = adapter.createNewNodeIfAbsent(declaration, key -> createNode(NEW_NODE)); | 68 | var newNode = adapter.createNewNodeIfAbsent(declaration, key -> createNode(NEW_NODE)); |
90 | declaration.setNewNode(newNode); | 69 | declaration.setNewNode(newNode); |
91 | } else if (statement instanceof Assertion assertion) { | ||
92 | for (var argument : assertion.getArguments()) { | ||
93 | if (argument instanceof ConstantAssertionArgument constantAssertionArgument | ||
94 | && constantAssertionArgument.getNode() == null) { | ||
95 | var constantNode = adapter.createConstantNodeIfAbsent(constantAssertionArgument, | ||
96 | key -> createNode(CONSTANT_NODE)); | ||
97 | constantAssertionArgument.setNode(constantNode); | ||
98 | } | ||
99 | } | ||
100 | } | 70 | } |
101 | } | 71 | } |
102 | } | 72 | } |
@@ -130,22 +100,14 @@ public class ProblemDerivedStateComputer implements IDerivedStateComputer { | |||
130 | 100 | ||
131 | protected void discardDerivedProblemState(Problem problem, Adapter adapter) { | 101 | protected void discardDerivedProblemState(Problem problem, Adapter adapter) { |
132 | Set<ClassDeclaration> classDeclarations = new HashSet<>(); | 102 | Set<ClassDeclaration> classDeclarations = new HashSet<>(); |
133 | Set<ConstantAssertionArgument> constantAssertionArguments = new HashSet<>(); | ||
134 | problem.getNodes().clear(); | 103 | problem.getNodes().clear(); |
135 | for (var statement : problem.getStatements()) { | 104 | for (var statement : problem.getStatements()) { |
136 | if (statement instanceof ClassDeclaration classDeclaration) { | 105 | if (statement instanceof ClassDeclaration classDeclaration) { |
137 | classDeclaration.setNewNode(null); | 106 | classDeclaration.setNewNode(null); |
138 | classDeclarations.add(classDeclaration); | 107 | classDeclarations.add(classDeclaration); |
139 | } else if (statement instanceof Assertion assertion) { | ||
140 | for (var argument : assertion.getArguments()) { | ||
141 | if (argument instanceof ConstantAssertionArgument constantAssertionArgument) { | ||
142 | constantAssertionArgument.setNode(null); | ||
143 | constantAssertionArguments.add(constantAssertionArgument); | ||
144 | } | ||
145 | } | ||
146 | } | 108 | } |
147 | } | 109 | } |
148 | adapter.retainAll(classDeclarations, constantAssertionArguments); | 110 | adapter.retainAll(classDeclarations); |
149 | derivedVariableComputer.discardDerivedVariables(problem); | 111 | derivedVariableComputer.discardDerivedVariables(problem); |
150 | } | 112 | } |
151 | 113 | ||
@@ -166,24 +128,15 @@ public class ProblemDerivedStateComputer implements IDerivedStateComputer { | |||
166 | } | 128 | } |
167 | 129 | ||
168 | protected static class Adapter extends AdapterImpl { | 130 | protected static class Adapter extends AdapterImpl { |
169 | private Map<ClassDeclaration, Node> newNodes = new HashMap<>(); | 131 | private final Map<ClassDeclaration, Node> newNodes = new HashMap<>(); |
170 | |||
171 | private Map<ConstantAssertionArgument, Node> constantNodes = new HashMap<>(); | ||
172 | 132 | ||
173 | public Node createNewNodeIfAbsent(ClassDeclaration classDeclaration, | 133 | public Node createNewNodeIfAbsent(ClassDeclaration classDeclaration, |
174 | Function<ClassDeclaration, Node> createNode) { | 134 | Function<ClassDeclaration, Node> createNode) { |
175 | return newNodes.computeIfAbsent(classDeclaration, createNode); | 135 | return newNodes.computeIfAbsent(classDeclaration, createNode); |
176 | } | 136 | } |
177 | 137 | ||
178 | public Node createConstantNodeIfAbsent(ConstantAssertionArgument constantAssertionArgument, | 138 | public void retainAll(Collection<ClassDeclaration> classDeclarations) { |
179 | Function<ConstantAssertionArgument, Node> createNode) { | ||
180 | return constantNodes.computeIfAbsent(constantAssertionArgument, createNode); | ||
181 | } | ||
182 | |||
183 | public void retainAll(Collection<ClassDeclaration> classDeclarations, | ||
184 | Collection<ConstantAssertionArgument> constantAssertionArguments) { | ||
185 | newNodes.keySet().retainAll(classDeclarations); | 139 | newNodes.keySet().retainAll(classDeclarations); |
186 | constantNodes.keySet().retainAll(constantAssertionArguments); | ||
187 | } | 140 | } |
188 | 141 | ||
189 | @Override | 142 | @Override |
diff --git a/subprojects/language/src/main/java/tools/refinery/language/scoping/ProblemScopeProvider.java b/subprojects/language/src/main/java/tools/refinery/language/scoping/ProblemScopeProvider.java index c2045aea..3ab07496 100644 --- a/subprojects/language/src/main/java/tools/refinery/language/scoping/ProblemScopeProvider.java +++ b/subprojects/language/src/main/java/tools/refinery/language/scoping/ProblemScopeProvider.java | |||
@@ -29,8 +29,7 @@ public class ProblemScopeProvider extends AbstractProblemScopeProvider { | |||
29 | @Override | 29 | @Override |
30 | public IScope getScope(EObject context, EReference reference) { | 30 | public IScope getScope(EObject context, EReference reference) { |
31 | var scope = super.getScope(context, reference); | 31 | var scope = super.getScope(context, reference); |
32 | if (reference == ProblemPackage.Literals.NODE_ASSERTION_ARGUMENT__NODE | 32 | if (reference == ProblemPackage.Literals.NODE_ASSERTION_ARGUMENT__NODE) { |
33 | || reference == ProblemPackage.Literals.NODE_VALUE_ASSERTION__NODE) { | ||
34 | return getNodesScope(context, scope); | 33 | return getNodesScope(context, scope); |
35 | } | 34 | } |
36 | if (reference == ProblemPackage.Literals.VARIABLE_OR_NODE_EXPR__VARIABLE_OR_NODE | 35 | if (reference == ProblemPackage.Literals.VARIABLE_OR_NODE_EXPR__VARIABLE_OR_NODE |
diff --git a/subprojects/language/src/main/java/tools/refinery/language/serializer/PreferShortAssertionsProblemSemanticSequencer.java b/subprojects/language/src/main/java/tools/refinery/language/serializer/PreferShortAssertionsProblemSemanticSequencer.java new file mode 100644 index 00000000..c51a5e28 --- /dev/null +++ b/subprojects/language/src/main/java/tools/refinery/language/serializer/PreferShortAssertionsProblemSemanticSequencer.java | |||
@@ -0,0 +1,52 @@ | |||
1 | package tools.refinery.language.serializer; | ||
2 | |||
3 | import com.google.inject.Inject; | ||
4 | import org.eclipse.xtext.serializer.ISerializationContext; | ||
5 | import org.eclipse.xtext.serializer.sequencer.ITransientValueService.ListTransient; | ||
6 | import org.eclipse.xtext.serializer.sequencer.ITransientValueService.ValueTransient; | ||
7 | import tools.refinery.language.model.problem.Assertion; | ||
8 | import tools.refinery.language.model.problem.LogicAssertionValue; | ||
9 | import tools.refinery.language.model.problem.LogicValue; | ||
10 | import tools.refinery.language.model.problem.ProblemPackage; | ||
11 | import tools.refinery.language.services.ProblemGrammarAccess; | ||
12 | |||
13 | public class PreferShortAssertionsProblemSemanticSequencer extends ProblemSemanticSequencer { | ||
14 | @Inject | ||
15 | private ProblemGrammarAccess grammarAccess; | ||
16 | |||
17 | @Override | ||
18 | protected void sequence_Assertion(ISerializationContext context, Assertion semanticObject) { | ||
19 | if (semanticObject.isDefault() || | ||
20 | !(semanticObject.getValue() instanceof LogicAssertionValue logicAssertionValue) || | ||
21 | logicAssertionValue.getLogicValue() == LogicValue.ERROR) { | ||
22 | super.sequence_Assertion(context, semanticObject); | ||
23 | return; | ||
24 | } | ||
25 | if (errorAcceptor != null) { | ||
26 | if (transientValues.isValueTransient(semanticObject, ProblemPackage.Literals.ASSERTION__RELATION) == ValueTransient.YES) { | ||
27 | errorAcceptor.accept(diagnosticProvider.createFeatureValueMissing(semanticObject, | ||
28 | ProblemPackage.Literals.ASSERTION__RELATION)); | ||
29 | } | ||
30 | if (transientValues.isListTransient(semanticObject, ProblemPackage.Literals.ASSERTION__ARGUMENTS) == ListTransient.YES) { | ||
31 | errorAcceptor.accept(diagnosticProvider.createFeatureValueMissing(semanticObject, | ||
32 | ProblemPackage.Literals.ASSERTION__ARGUMENTS)); | ||
33 | } | ||
34 | } | ||
35 | var feeder = createSequencerFeeder(context, semanticObject); | ||
36 | var access = grammarAccess.getAssertionAccess(); | ||
37 | feeder.accept(access.getValueShortLogicAssertionValueParserRuleCall_1_1_0_0(), logicAssertionValue); | ||
38 | feeder.accept(access.getRelationRelationQualifiedNameParserRuleCall_1_1_1_0_1(), semanticObject.getRelation()); | ||
39 | var iterator = semanticObject.getArguments().iterator(); | ||
40 | if (iterator.hasNext()) { | ||
41 | var firstArgument = iterator.next(); | ||
42 | feeder.accept(access.getArgumentsAssertionArgumentParserRuleCall_1_1_3_0_0(), firstArgument, 0); | ||
43 | int index = 1; | ||
44 | while (iterator.hasNext()) { | ||
45 | var argument = iterator.next(); | ||
46 | feeder.accept(access.getArgumentsAssertionArgumentParserRuleCall_1_1_3_1_1_0(), argument, index); | ||
47 | index++; | ||
48 | } | ||
49 | } | ||
50 | feeder.finish(); | ||
51 | } | ||
52 | } | ||
diff --git a/subprojects/language/src/main/java/tools/refinery/language/utils/BuiltinSymbols.java b/subprojects/language/src/main/java/tools/refinery/language/utils/BuiltinSymbols.java index 7e43cecf..d3777cd3 100644 --- a/subprojects/language/src/main/java/tools/refinery/language/utils/BuiltinSymbols.java +++ b/subprojects/language/src/main/java/tools/refinery/language/utils/BuiltinSymbols.java | |||
@@ -1,14 +1,8 @@ | |||
1 | package tools.refinery.language.utils; | 1 | package tools.refinery.language.utils; |
2 | 2 | ||
3 | import tools.refinery.language.model.problem.ClassDeclaration; | 3 | import tools.refinery.language.model.problem.*; |
4 | import tools.refinery.language.model.problem.EnumDeclaration; | ||
5 | import tools.refinery.language.model.problem.Node; | ||
6 | import tools.refinery.language.model.problem.PredicateDefinition; | ||
7 | import tools.refinery.language.model.problem.Problem; | ||
8 | import tools.refinery.language.model.problem.ReferenceDeclaration; | ||
9 | 4 | ||
10 | public record BuiltinSymbols(Problem problem, ClassDeclaration node, ReferenceDeclaration equals, | 5 | public record BuiltinSymbols(Problem problem, ClassDeclaration node, ReferenceDeclaration equals, |
11 | PredicateDefinition exists, ClassDeclaration domain, ClassDeclaration data, EnumDeclaration bool, Node boolTrue, | 6 | PredicateDefinition exists, PredicateDefinition contained, PredicateDefinition contains, |
12 | Node boolFalse, ClassDeclaration intClass, ClassDeclaration real, ClassDeclaration string, | 7 | PredicateDefinition root) { |
13 | PredicateDefinition contained, PredicateDefinition contains, PredicateDefinition root) { | ||
14 | } | 8 | } |
diff --git a/subprojects/language/src/main/java/tools/refinery/language/utils/NodeInfo.java b/subprojects/language/src/main/java/tools/refinery/language/utils/NodeInfo.java index 38db0e29..c8f47653 100644 --- a/subprojects/language/src/main/java/tools/refinery/language/utils/NodeInfo.java +++ b/subprojects/language/src/main/java/tools/refinery/language/utils/NodeInfo.java | |||
@@ -1,12 +1,4 @@ | |||
1 | package tools.refinery.language.utils; | 1 | package tools.refinery.language.utils; |
2 | 2 | ||
3 | import java.util.ArrayList; | 3 | public record NodeInfo(String name, boolean individual) { |
4 | import java.util.Collection; | ||
5 | |||
6 | import tools.refinery.language.model.problem.NodeValueAssertion; | ||
7 | |||
8 | public record NodeInfo(String name, boolean individual, Collection<NodeValueAssertion> valueAssertions) { | ||
9 | public NodeInfo(String name, boolean individual) { | ||
10 | this(name, individual, new ArrayList<>()); | ||
11 | } | ||
12 | } | 4 | } |
diff --git a/subprojects/language/src/main/java/tools/refinery/language/utils/ProblemDesugarer.java b/subprojects/language/src/main/java/tools/refinery/language/utils/ProblemDesugarer.java index 23fd8982..b8200919 100644 --- a/subprojects/language/src/main/java/tools/refinery/language/utils/ProblemDesugarer.java +++ b/subprojects/language/src/main/java/tools/refinery/language/utils/ProblemDesugarer.java | |||
@@ -40,19 +40,10 @@ public class ProblemDesugarer { | |||
40 | var node = doGetDeclaration(builtin, ClassDeclaration.class, "node"); | 40 | var node = doGetDeclaration(builtin, ClassDeclaration.class, "node"); |
41 | var equals = doGetEqualsReference(node); | 41 | var equals = doGetEqualsReference(node); |
42 | var exists = doGetDeclaration(builtin, PredicateDefinition.class, "exists"); | 42 | var exists = doGetDeclaration(builtin, PredicateDefinition.class, "exists"); |
43 | var domain = doGetDeclaration(builtin, ClassDeclaration.class, "domain"); | ||
44 | var data = doGetDeclaration(builtin, ClassDeclaration.class, "data"); | ||
45 | var bool = doGetDeclaration(builtin, EnumDeclaration.class, "bool"); | ||
46 | var boolTrue = doGetLiteral(bool, "true"); | ||
47 | var boolFalse = doGetLiteral(bool, "false"); | ||
48 | var intClass = doGetDeclaration(builtin, ClassDeclaration.class, "int"); | ||
49 | var real = doGetDeclaration(builtin, ClassDeclaration.class, "real"); | ||
50 | var string = doGetDeclaration(builtin, ClassDeclaration.class, "string"); | ||
51 | var contained = doGetDeclaration(builtin, PredicateDefinition.class, "contained"); | 43 | var contained = doGetDeclaration(builtin, PredicateDefinition.class, "contained"); |
52 | var contains = doGetDeclaration(builtin, PredicateDefinition.class, "contains"); | 44 | var contains = doGetDeclaration(builtin, PredicateDefinition.class, "contains"); |
53 | var root = doGetDeclaration(builtin, PredicateDefinition.class, "root"); | 45 | var root = doGetDeclaration(builtin, PredicateDefinition.class, "root"); |
54 | return new BuiltinSymbols(builtin, node, equals, exists, domain, data, bool, boolTrue, boolFalse, intClass, | 46 | return new BuiltinSymbols(builtin, node, equals, exists, contained, contains, root); |
55 | real, string, contained, contains, root); | ||
56 | } | 47 | } |
57 | 48 | ||
58 | private <T extends Statement & NamedElement> T doGetDeclaration(Problem builtin, Class<T> type, String name) { | 49 | private <T extends Statement & NamedElement> T doGetDeclaration(Problem builtin, Class<T> type, String name) { |
@@ -62,16 +53,12 @@ public class ProblemDesugarer { | |||
62 | } | 53 | } |
63 | 54 | ||
64 | private ReferenceDeclaration doGetEqualsReference(ClassDeclaration nodeClassDeclaration) { | 55 | private ReferenceDeclaration doGetEqualsReference(ClassDeclaration nodeClassDeclaration) { |
65 | return nodeClassDeclaration.getReferenceDeclarations().stream() | 56 | return (ReferenceDeclaration) nodeClassDeclaration.getFeatureDeclarations().stream() |
66 | .filter(reference -> "equals".equals(reference.getName())).findFirst() | 57 | .filter(reference -> reference instanceof ReferenceDeclaration && |
58 | "equals".equals(reference.getName())).findFirst() | ||
67 | .orElseThrow(() -> new IllegalArgumentException("Reference " + "equals" + " not found")); | 59 | .orElseThrow(() -> new IllegalArgumentException("Reference " + "equals" + " not found")); |
68 | } | 60 | } |
69 | 61 | ||
70 | private Node doGetLiteral(EnumDeclaration enumDeclaration, String name) { | ||
71 | return enumDeclaration.getLiterals().stream().filter(literal -> name.equals(literal.getName())).findFirst() | ||
72 | .orElseThrow(() -> new IllegalArgumentException("Enum literal " + name + " not found")); | ||
73 | } | ||
74 | |||
75 | public Collection<ClassDeclaration> getSuperclassesAndSelf(ClassDeclaration classDeclaration) { | 62 | public Collection<ClassDeclaration> getSuperclassesAndSelf(ClassDeclaration classDeclaration) { |
76 | return cache.get(Tuples.create(classDeclaration, "superclassesAndSelf"), classDeclaration.eResource(), | 63 | return cache.get(Tuples.create(classDeclaration, "superclassesAndSelf"), classDeclaration.eResource(), |
77 | () -> doGetSuperclassesAndSelf(classDeclaration)); | 64 | () -> doGetSuperclassesAndSelf(classDeclaration)); |
@@ -94,9 +81,6 @@ public class ProblemDesugarer { | |||
94 | } | 81 | } |
95 | } | 82 | } |
96 | } | 83 | } |
97 | if (builtinSymbols.isPresent() && !found.contains(builtinSymbols.get().data())) { | ||
98 | found.add(builtinSymbols.get().domain()); | ||
99 | } | ||
100 | return found; | 84 | return found; |
101 | } | 85 | } |
102 | 86 | ||
@@ -108,31 +92,17 @@ public class ProblemDesugarer { | |||
108 | private Collection<ReferenceDeclaration> doGetAllReferenceDeclarations(ClassDeclaration classDeclaration) { | 92 | private Collection<ReferenceDeclaration> doGetAllReferenceDeclarations(ClassDeclaration classDeclaration) { |
109 | Set<ReferenceDeclaration> referenceDeclarations = new HashSet<>(); | 93 | Set<ReferenceDeclaration> referenceDeclarations = new HashSet<>(); |
110 | for (ClassDeclaration superclass : getSuperclassesAndSelf(classDeclaration)) { | 94 | for (ClassDeclaration superclass : getSuperclassesAndSelf(classDeclaration)) { |
111 | referenceDeclarations.addAll(superclass.getReferenceDeclarations()); | 95 | for (FeatureDeclaration featureDeclaration : superclass.getFeatureDeclarations()) { |
96 | if (featureDeclaration instanceof ReferenceDeclaration referenceDeclaration) { | ||
97 | referenceDeclarations.add(referenceDeclaration); | ||
98 | } | ||
99 | } | ||
112 | } | 100 | } |
113 | return referenceDeclarations; | 101 | return referenceDeclarations; |
114 | } | 102 | } |
115 | 103 | ||
116 | public boolean isContainmentReference(ReferenceDeclaration referenceDeclaration) { | 104 | public boolean isContainmentReference(ReferenceDeclaration referenceDeclaration) { |
117 | switch (referenceDeclaration.getKind()) { | 105 | return referenceDeclaration.getKind() == ReferenceKind.CONTAINMENT; |
118 | case REFERENCE, CONTAINER: | ||
119 | return false; | ||
120 | case CONTAINMENT: | ||
121 | return true; | ||
122 | case DEFAULT: | ||
123 | return isDataClass(referenceDeclaration.getReferenceType()); | ||
124 | default: | ||
125 | throw new IllegalArgumentException("Unknown reference kind " + referenceDeclaration.getKind()); | ||
126 | } | ||
127 | } | ||
128 | |||
129 | public boolean isDataClass(Relation relation) { | ||
130 | if (relation instanceof ClassDeclaration classDeclaration) { | ||
131 | var supertypes = getSuperclassesAndSelf(classDeclaration); | ||
132 | var builtinSymbols = getBuiltinSymbols(relation); | ||
133 | return builtinSymbols.isPresent() && supertypes.contains(builtinSymbols.get().data()); | ||
134 | } | ||
135 | return false; | ||
136 | } | 106 | } |
137 | 107 | ||
138 | public CollectedSymbols collectSymbols(Problem problem) { | 108 | public CollectedSymbols collectSymbols(Problem problem) { |
diff --git a/subprojects/language/src/main/java/tools/refinery/language/utils/SymbolCollector.java b/subprojects/language/src/main/java/tools/refinery/language/utils/SymbolCollector.java index 210e96ab..5412f620 100644 --- a/subprojects/language/src/main/java/tools/refinery/language/utils/SymbolCollector.java +++ b/subprojects/language/src/main/java/tools/refinery/language/utils/SymbolCollector.java | |||
@@ -2,7 +2,6 @@ package tools.refinery.language.utils; | |||
2 | 2 | ||
3 | import com.google.inject.Inject; | 3 | import com.google.inject.Inject; |
4 | import org.eclipse.emf.ecore.EObject; | 4 | import org.eclipse.emf.ecore.EObject; |
5 | import org.eclipse.emf.ecore.util.EcoreUtil; | ||
6 | import org.eclipse.xtext.naming.IQualifiedNameConverter; | 5 | import org.eclipse.xtext.naming.IQualifiedNameConverter; |
7 | import org.eclipse.xtext.naming.IQualifiedNameProvider; | 6 | import org.eclipse.xtext.naming.IQualifiedNameProvider; |
8 | import tools.refinery.language.model.problem.*; | 7 | import tools.refinery.language.model.problem.*; |
@@ -64,43 +63,65 @@ class SymbolCollector { | |||
64 | } | 63 | } |
65 | 64 | ||
66 | private void collectClass(ClassDeclaration classDeclaration) { | 65 | private void collectClass(ClassDeclaration classDeclaration) { |
67 | // node and domain classes are not contained by default, but every other type is | 66 | var contained = classDeclaration != builtinSymbols.node(); |
68 | // contained, including data types. | ||
69 | var contained = | ||
70 | classDeclaration != builtinSymbols.node() && classDeclaration != builtinSymbols.domain(); | ||
71 | var containmentRole = contained ? ContainmentRole.CONTAINED : ContainmentRole.NONE; | 67 | var containmentRole = contained ? ContainmentRole.CONTAINED : ContainmentRole.NONE; |
72 | var instanceParameter = ProblemFactory.eINSTANCE.createParameter(); | 68 | var instanceParameter = ProblemFactory.eINSTANCE.createParameter(); |
73 | instanceParameter.setName("instance"); | 69 | instanceParameter.setName("instance"); |
74 | var classInfo = new RelationInfo(getQualifiedNameString(classDeclaration), containmentRole, | 70 | var classInfo = new RelationInfo(getQualifiedNameString(classDeclaration), containmentRole, |
75 | List.of(instanceParameter), null, null, List.of()); | 71 | List.of(instanceParameter), null, null, List.of()); |
76 | relations.put(classDeclaration, classInfo); | 72 | relations.put(classDeclaration, classInfo); |
77 | collectReferences(classDeclaration); | 73 | collectFeatures(classDeclaration); |
78 | } | 74 | } |
79 | 75 | ||
80 | private void collectReferences(ClassDeclaration classDeclaration) { | 76 | private void collectFeatures(ClassDeclaration classDeclaration) { |
81 | for (var referenceDeclaration : classDeclaration.getReferenceDeclarations()) { | 77 | for (var featureDeclaration : classDeclaration.getFeatureDeclarations()) { |
82 | var referenceRole = desugarer.isContainmentReference(referenceDeclaration) ? | 78 | if (featureDeclaration instanceof ReferenceDeclaration referenceDeclaration) { |
83 | ContainmentRole.CONTAINMENT : | 79 | collectReference(classDeclaration, referenceDeclaration); |
84 | ContainmentRole.NONE; | 80 | } else if (featureDeclaration instanceof AttributeDeclaration attributeDeclaration) { |
85 | var sourceParameter = ProblemFactory.eINSTANCE.createParameter(); | 81 | collectAttribute(classDeclaration, attributeDeclaration); |
86 | sourceParameter.setName("source"); | 82 | } else if (featureDeclaration instanceof FlagDeclaration flagDeclaration) { |
87 | sourceParameter.setParameterType(classDeclaration); | 83 | collectFlag(classDeclaration, flagDeclaration); |
88 | var targetParameter = ProblemFactory.eINSTANCE.createParameter(); | 84 | } else { |
89 | targetParameter.setName("target"); | 85 | throw new IllegalArgumentException("Unknown FeatureDeclaration: " + featureDeclaration); |
90 | var multiplicity = referenceDeclaration.getMultiplicity(); | ||
91 | if (multiplicity == null) { | ||
92 | var exactMultiplicity = ProblemFactory.eINSTANCE.createExactMultiplicity(); | ||
93 | exactMultiplicity.setExactValue(1); | ||
94 | multiplicity = exactMultiplicity; | ||
95 | } | 86 | } |
96 | targetParameter.setParameterType(referenceDeclaration.getReferenceType()); | ||
97 | var referenceInfo = new RelationInfo(getQualifiedNameString(referenceDeclaration), referenceRole, | ||
98 | List.of(sourceParameter, targetParameter), multiplicity, referenceDeclaration.getOpposite(), | ||
99 | List.of()); | ||
100 | this.relations.put(referenceDeclaration, referenceInfo); | ||
101 | } | 87 | } |
102 | } | 88 | } |
103 | 89 | ||
90 | private void collectReference(ClassDeclaration classDeclaration, ReferenceDeclaration referenceDeclaration) { | ||
91 | var referenceRole = desugarer.isContainmentReference(referenceDeclaration) ? | ||
92 | ContainmentRole.CONTAINMENT : | ||
93 | ContainmentRole.NONE; | ||
94 | var sourceParameter = ProblemFactory.eINSTANCE.createParameter(); | ||
95 | sourceParameter.setName("source"); | ||
96 | sourceParameter.setParameterType(classDeclaration); | ||
97 | var targetParameter = ProblemFactory.eINSTANCE.createParameter(); | ||
98 | targetParameter.setName("target"); | ||
99 | var multiplicity = referenceDeclaration.getMultiplicity(); | ||
100 | if (multiplicity == null) { | ||
101 | var exactMultiplicity = ProblemFactory.eINSTANCE.createExactMultiplicity(); | ||
102 | exactMultiplicity.setExactValue(1); | ||
103 | multiplicity = exactMultiplicity; | ||
104 | } | ||
105 | targetParameter.setParameterType(referenceDeclaration.getReferenceType()); | ||
106 | var referenceInfo = new RelationInfo(getQualifiedNameString(referenceDeclaration), referenceRole, | ||
107 | List.of(sourceParameter, targetParameter), multiplicity, referenceDeclaration.getOpposite(), | ||
108 | List.of()); | ||
109 | this.relations.put(referenceDeclaration, referenceInfo); | ||
110 | } | ||
111 | |||
112 | private void collectAttribute(ClassDeclaration classDeclaration, AttributeDeclaration attributeDeclaration) { | ||
113 | // TODO Implement attribute handling. | ||
114 | } | ||
115 | |||
116 | private void collectFlag(ClassDeclaration classDeclaration, FlagDeclaration flagDeclaration) { | ||
117 | var parameter = ProblemFactory.eINSTANCE.createParameter(); | ||
118 | parameter.setName("object"); | ||
119 | parameter.setParameterType(classDeclaration); | ||
120 | var referenceInfo = new RelationInfo(getQualifiedNameString(flagDeclaration), ContainmentRole.NONE, | ||
121 | List.of(parameter), null, null, List.of()); | ||
122 | this.relations.put(flagDeclaration, referenceInfo); | ||
123 | } | ||
124 | |||
104 | private void collectEnum(EnumDeclaration enumDeclaration) { | 125 | private void collectEnum(EnumDeclaration enumDeclaration) { |
105 | var instanceParameter = ProblemFactory.eINSTANCE.createParameter(); | 126 | var instanceParameter = ProblemFactory.eINSTANCE.createParameter(); |
106 | instanceParameter.setName("instance"); | 127 | instanceParameter.setName("instance"); |
@@ -117,8 +138,6 @@ class SymbolCollector { | |||
117 | collectNewNode(classDeclaration); | 138 | collectNewNode(classDeclaration); |
118 | } else if (statement instanceof EnumDeclaration enumDeclaration) { | 139 | } else if (statement instanceof EnumDeclaration enumDeclaration) { |
119 | collectEnumLiterals(enumDeclaration); | 140 | collectEnumLiterals(enumDeclaration); |
120 | } else if (statement instanceof Assertion assertion) { | ||
121 | collectConstantNodes(assertion); | ||
122 | } | 141 | } |
123 | } | 142 | } |
124 | for (var node : problem.getNodes()) { | 143 | for (var node : problem.getNodes()) { |
@@ -145,17 +164,6 @@ class SymbolCollector { | |||
145 | } | 164 | } |
146 | } | 165 | } |
147 | 166 | ||
148 | private void collectConstantNodes(Assertion assertion) { | ||
149 | for (var argument : assertion.getArguments()) { | ||
150 | if (argument instanceof ConstantAssertionArgument constantAssertionArgument) { | ||
151 | var constantNode = constantAssertionArgument.getNode(); | ||
152 | if (constantNode != null) { | ||
153 | addNode(constantNode, false); | ||
154 | } | ||
155 | } | ||
156 | } | ||
157 | } | ||
158 | |||
159 | private void addNode(Node node, boolean individual) { | 167 | private void addNode(Node node, boolean individual) { |
160 | var info = new NodeInfo(getQualifiedNameString(node), individual); | 168 | var info = new NodeInfo(getQualifiedNameString(node), individual); |
161 | this.nodes.put(node, info); | 169 | this.nodes.put(node, info); |
@@ -173,8 +181,6 @@ class SymbolCollector { | |||
173 | for (var statement : problem.getStatements()) { | 181 | for (var statement : problem.getStatements()) { |
174 | if (statement instanceof Assertion assertion) { | 182 | if (statement instanceof Assertion assertion) { |
175 | collectAssertion(assertion); | 183 | collectAssertion(assertion); |
176 | } else if (statement instanceof NodeValueAssertion nodeValueAssertion) { | ||
177 | collectNodeValueAssertion(nodeValueAssertion); | ||
178 | } else if (statement instanceof PredicateDefinition predicateDefinition) { | 184 | } else if (statement instanceof PredicateDefinition predicateDefinition) { |
179 | collectPredicateAssertion(predicateDefinition); | 185 | collectPredicateAssertion(predicateDefinition); |
180 | } else if (statement instanceof ClassDeclaration classDeclaration) { | 186 | } else if (statement instanceof ClassDeclaration classDeclaration) { |
@@ -196,48 +202,6 @@ class SymbolCollector { | |||
196 | return; | 202 | return; |
197 | } | 203 | } |
198 | relationInfo.assertions().add(assertion); | 204 | relationInfo.assertions().add(assertion); |
199 | for (var argument : assertion.getArguments()) { | ||
200 | if (argument instanceof ConstantAssertionArgument constantAssertionArgument) { | ||
201 | var constantNode = constantAssertionArgument.getNode(); | ||
202 | if (constantNode != null) { | ||
203 | var valueAssertion = ProblemFactory.eINSTANCE.createNodeValueAssertion(); | ||
204 | valueAssertion.setNode(constantNode); | ||
205 | valueAssertion.setValue(EcoreUtil.copy(constantAssertionArgument.getConstant())); | ||
206 | collectNodeValueAssertion(valueAssertion); | ||
207 | var logicValue = assertion.getValue(); | ||
208 | if (logicValue != LogicValue.TRUE) { | ||
209 | addAssertion(builtinSymbols.exists(), logicValue, constantNode); | ||
210 | } | ||
211 | } | ||
212 | } | ||
213 | } | ||
214 | } | ||
215 | |||
216 | private void collectNodeValueAssertion(NodeValueAssertion nodeValueAssertion) { | ||
217 | var node = nodeValueAssertion.getNode(); | ||
218 | if (node == null) { | ||
219 | return; | ||
220 | } | ||
221 | var nodeInfo = this.nodes.get(node); | ||
222 | if (nodeInfo == null) { | ||
223 | throw new IllegalStateException("Node value assertion refers to unknown node"); | ||
224 | } | ||
225 | nodeInfo.valueAssertions().add(nodeValueAssertion); | ||
226 | var constant = nodeValueAssertion.getValue(); | ||
227 | if (constant == null) { | ||
228 | return; | ||
229 | } | ||
230 | Relation dataType; | ||
231 | if (constant instanceof IntConstant) { | ||
232 | dataType = builtinSymbols.intClass(); | ||
233 | } else if (constant instanceof RealConstant) { | ||
234 | dataType = builtinSymbols.real(); | ||
235 | } else if (constant instanceof StringConstant) { | ||
236 | dataType = builtinSymbols.string(); | ||
237 | } else { | ||
238 | throw new IllegalArgumentException("Unknown constant type"); | ||
239 | } | ||
240 | addAssertion(dataType, LogicValue.TRUE, node); | ||
241 | } | 205 | } |
242 | 206 | ||
243 | private void collectPredicateAssertion(PredicateDefinition predicateDefinition) { | 207 | private void collectPredicateAssertion(PredicateDefinition predicateDefinition) { |
@@ -278,7 +242,9 @@ class SymbolCollector { | |||
278 | } | 242 | } |
279 | assertion.getArguments().add(argument); | 243 | assertion.getArguments().add(argument); |
280 | } | 244 | } |
281 | assertion.setValue(logicValue); | 245 | var value = ProblemFactory.eINSTANCE.createLogicAssertionValue(); |
246 | value.setLogicValue(logicValue); | ||
247 | assertion.setValue(value); | ||
282 | collectAssertion(assertion); | 248 | collectAssertion(assertion); |
283 | } | 249 | } |
284 | } | 250 | } |