aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLibravatar Kristóf Marussy <marussy@mit.bme.hu>2021-07-29 17:09:24 +0200
committerLibravatar Kristóf Marussy <marussy@mit.bme.hu>2021-07-29 17:09:24 +0200
commit97ea34af2f8e5d0ca9da5dda331a9f54e580c4c6 (patch)
tree2f58b2e34609439b53e3a7ddd5337bb4733ce707
parentAppearance fixes (diff)
downloadrefinery-97ea34af2f8e5d0ca9da5dda331a9f54e580c4c6.tar.gz
refinery-97ea34af2f8e5d0ca9da5dda331a9f54e580c4c6.tar.zst
refinery-97ea34af2f8e5d0ca9da5dda331a9f54e580c4c6.zip
Refactoring based on Sonar reports
-rw-r--r--build.gradle30
-rw-r--r--gradle/java-common.gradle50
-rw-r--r--gradle/mwe2.gradle11
-rw-r--r--gradle/source-layout.gradle28
-rw-r--r--gradle/xtext-common.gradle21
-rw-r--r--language-ide/build.gradle2
-rw-r--r--language-ide/src/main/java/org/eclipse/viatra/solver/language/ide/syntaxcoloring/ProblemSemanticHighlightingCalculator.java85
-rw-r--r--language-model/build.gradle18
-rw-r--r--language-mwe2/build.gradle2
-rw-r--r--language-mwe2/src/main/java/org/eclipse/viatra/solver/language/mwe2/ProblemWebIntegrationFragment.java36
-rw-r--r--language-web/build.gradle8
-rw-r--r--language-web/src/main/java/org/eclipse/viatra/solver/language/web/ProblemServlet.java10
-rw-r--r--language-web/src/main/java/org/eclipse/viatra/solver/language/web/ServerLauncher.java55
-rw-r--r--language/build.gradle16
-rw-r--r--language/src/main/java/org/eclipse/viatra/solver/language/GenerateProblem.mwe24
-rw-r--r--language/src/main/java/org/eclipse/viatra/solver/language/ProblemRuntimeModule.java3
-rw-r--r--language/src/main/java/org/eclipse/viatra/solver/language/ProblemStandaloneSetup.java13
-rw-r--r--language/src/main/java/org/eclipse/viatra/solver/language/ProblemUtil.java26
-rw-r--r--language/src/main/java/org/eclipse/viatra/solver/language/conversion/ProblemValueConverterService.java4
-rw-r--r--language/src/main/java/org/eclipse/viatra/solver/language/generator/ProblemGenerator.java30
-rw-r--r--language/src/main/java/org/eclipse/viatra/solver/language/naming/NamingUtil.java35
-rw-r--r--language/src/main/java/org/eclipse/viatra/solver/language/resource/DerivedVariableComputer.java195
-rw-r--r--language/src/main/java/org/eclipse/viatra/solver/language/resource/NodeNameCollector.java52
-rw-r--r--language/src/main/java/org/eclipse/viatra/solver/language/resource/ProblemDerivedStateComputer.java213
-rw-r--r--language/src/main/java/org/eclipse/viatra/solver/language/resource/ProblemResourceDescriptionStrategy.java67
-rw-r--r--language/src/main/java/org/eclipse/viatra/solver/language/scoping/ProblemScopeProvider.java17
-rw-r--r--language/src/main/java/org/eclipse/viatra/solver/language/validation/ProblemValidator.java18
27 files changed, 551 insertions, 498 deletions
diff --git a/build.gradle b/build.gradle
index e1d31ecc..1736d644 100644
--- a/build.gradle
+++ b/build.gradle
@@ -12,35 +12,7 @@ plugins {
12 id 'com.moowork.node' version "1.3.1" apply false 12 id 'com.moowork.node' version "1.3.1" apply false
13} 13}
14 14
15subprojects { 15allprojects {
16 repositories {
17 mavenCentral()
18 }
19
20 apply plugin: 'java'
21 dependencies {
22 compile platform("org.eclipse.xtext:xtext-dev-bom:${xtextVersion}")
23 }
24
25 apply plugin: 'org.xtext.xtend'
26 apply from: "${rootDir}/gradle/source-layout.gradle"
27 apply plugin: 'eclipse'
28
29 group = 'org.eclipse.viatra.solver' 16 group = 'org.eclipse.viatra.solver'
30 version = '1.0.0-SNAPSHOT' 17 version = '1.0.0-SNAPSHOT'
31
32 sourceCompatibility = '11'
33 targetCompatibility = '11'
34
35 configurations.all {
36 exclude group: 'asm'
37 }
38
39 eclipse.classpath.file.whenMerged {
40 for (entry in entries) {
41 if (entry.path.endsWith('xtext-gen')) {
42 entry.entryAttributes['ignore_optional_problems'] = true
43 }
44 }
45 }
46} 18}
diff --git a/gradle/java-common.gradle b/gradle/java-common.gradle
new file mode 100644
index 00000000..0cc09a4f
--- /dev/null
+++ b/gradle/java-common.gradle
@@ -0,0 +1,50 @@
1repositories {
2 mavenCentral()
3}
4
5apply plugin: 'java'
6apply plugin: 'org.xtext.xtend'
7
8sourceCompatibility = '11'
9targetCompatibility = '11'
10
11sourceSets {
12 main {
13 xtendOutputDir = 'src/main/xtend-gen'
14 }
15 test {
16 xtendOutputDir = 'src/test/xtend-gen'
17 }
18}
19
20configurations.all {
21 exclude group: 'asm'
22}
23
24jar {
25 manifest {
26 attributes 'Bundle-SymbolicName': project.name
27 }
28}
29
30clean.doLast {
31 delete 'src/main/xtend-gen'
32 delete 'src/test/xtend-gen'
33}
34
35apply plugin: 'eclipse'
36
37eclipse {
38 classpath.file.whenMerged {
39 for (entry in entries) {
40 if (entry.path.endsWith('-gen')) {
41 entry.entryAttributes['ignore_optional_problems'] = true
42 }
43 }
44 }
45
46 jdt.file.whenMerged { properties ->
47 // Allow @SupperessWarnings to suppress SonalLint warnings
48 properties['org.eclipse.jdt.core.compiler.problem.unhandledWarningToken'] = 'ignore'
49 }
50}
diff --git a/gradle/mwe2.gradle b/gradle/mwe2.gradle
new file mode 100644
index 00000000..5fd53126
--- /dev/null
+++ b/gradle/mwe2.gradle
@@ -0,0 +1,11 @@
1configurations {
2 mwe2 {
3 extendsFrom compile
4 }
5}
6
7dependencies {
8 mwe2 "org.eclipse.emf:org.eclipse.emf.mwe2.launch:${mwe2Version}"
9}
10
11eclipse.classpath.plusConfigurations += [configurations.mwe2]
diff --git a/gradle/source-layout.gradle b/gradle/source-layout.gradle
deleted file mode 100644
index 254798f1..00000000
--- a/gradle/source-layout.gradle
+++ /dev/null
@@ -1,28 +0,0 @@
1sourceSets {
2 main {
3 java.srcDirs = ['src/main/java', 'src/main/xtext-gen']
4 resources.srcDirs = ['src/main/resources', 'src/main/xtext-gen']
5 xtendOutputDir = 'src/main/xtend-gen'
6 }
7 test {
8 java.srcDirs = ['src/test/java', 'src/test/xtext-gen']
9 resources.srcDirs = ['src/test/resources', 'src/test/xtext-gen']
10 xtendOutputDir = 'src/test/xtend-gen'
11 }
12}
13
14jar {
15 from(sourceSets.main.allSource) {
16 include '**/*.xtext'
17 }
18 manifest {
19 attributes 'Bundle-SymbolicName': project.name
20 }
21}
22
23clean.doLast {
24 delete 'src/main/xtend-gen'
25 delete 'src/main/xtext-gen'
26 delete 'src/test/xtend-gen'
27 delete 'src/test/xtext-gen'
28}
diff --git a/gradle/xtext-common.gradle b/gradle/xtext-common.gradle
new file mode 100644
index 00000000..cf6a5831
--- /dev/null
+++ b/gradle/xtext-common.gradle
@@ -0,0 +1,21 @@
1apply from: "${rootDir}/gradle/java-common.gradle"
2
3dependencies {
4 compile platform("org.eclipse.xtext:xtext-dev-bom:${xtextVersion}")
5}
6
7sourceSets {
8 main {
9 java.srcDirs += ['src/main/xtext-gen']
10 resources.srcDirs += ['src/main/xtext-gen']
11 }
12 test {
13 java.srcDirs = ['src/test/xtext-gen']
14 resources.srcDirs = ['src/test/xtext-gen']
15 }
16}
17
18clean.doLast {
19 delete 'src/main/xtext-gen'
20 delete 'src/test/xtext-gen'
21}
diff --git a/language-ide/build.gradle b/language-ide/build.gradle
index 396f63bd..1731cc59 100644
--- a/language-ide/build.gradle
+++ b/language-ide/build.gradle
@@ -1,3 +1,5 @@
1apply from: "${rootDir}/gradle/xtext-common.gradle"
2
1dependencies { 3dependencies {
2 compile project(':language') 4 compile project(':language')
3 compile "org.eclipse.xtext:org.eclipse.xtext.ide:${xtextVersion}" 5 compile "org.eclipse.xtext:org.eclipse.xtext.ide:${xtextVersion}"
diff --git a/language-ide/src/main/java/org/eclipse/viatra/solver/language/ide/syntaxcoloring/ProblemSemanticHighlightingCalculator.java b/language-ide/src/main/java/org/eclipse/viatra/solver/language/ide/syntaxcoloring/ProblemSemanticHighlightingCalculator.java
index eee5070b..b1a69e9d 100644
--- a/language-ide/src/main/java/org/eclipse/viatra/solver/language/ide/syntaxcoloring/ProblemSemanticHighlightingCalculator.java
+++ b/language-ide/src/main/java/org/eclipse/viatra/solver/language/ide/syntaxcoloring/ProblemSemanticHighlightingCalculator.java
@@ -3,26 +3,24 @@ package org.eclipse.viatra.solver.language.ide.syntaxcoloring;
3import java.util.List; 3import java.util.List;
4 4
5import org.eclipse.emf.common.util.EList; 5import org.eclipse.emf.common.util.EList;
6import org.eclipse.emf.ecore.EAttribute;
7import org.eclipse.emf.ecore.EObject; 6import org.eclipse.emf.ecore.EObject;
8import org.eclipse.emf.ecore.EReference; 7import org.eclipse.emf.ecore.EReference;
9import org.eclipse.emf.ecore.resource.Resource;
10import org.eclipse.viatra.solver.language.ProblemUtil; 8import org.eclipse.viatra.solver.language.ProblemUtil;
11import org.eclipse.viatra.solver.language.model.problem.ClassDeclaration; 9import org.eclipse.viatra.solver.language.model.problem.ClassDeclaration;
12import org.eclipse.viatra.solver.language.model.problem.EnumDeclaration; 10import org.eclipse.viatra.solver.language.model.problem.EnumDeclaration;
11import org.eclipse.viatra.solver.language.model.problem.NamedElement;
13import org.eclipse.viatra.solver.language.model.problem.Node; 12import org.eclipse.viatra.solver.language.model.problem.Node;
14import org.eclipse.viatra.solver.language.model.problem.Parameter; 13import org.eclipse.viatra.solver.language.model.problem.Parameter;
15import org.eclipse.viatra.solver.language.model.problem.PredicateDefinition; 14import org.eclipse.viatra.solver.language.model.problem.PredicateDefinition;
15import org.eclipse.viatra.solver.language.model.problem.ProblemPackage;
16import org.eclipse.viatra.solver.language.model.problem.ReferenceDeclaration; 16import org.eclipse.viatra.solver.language.model.problem.ReferenceDeclaration;
17import org.eclipse.viatra.solver.language.model.problem.Variable; 17import org.eclipse.viatra.solver.language.model.problem.Variable;
18import org.eclipse.viatra.solver.language.scoping.ProblemGlobalScopeProvider;
19import org.eclipse.xtext.ide.editor.syntaxcoloring.DefaultSemanticHighlightingCalculator; 18import org.eclipse.xtext.ide.editor.syntaxcoloring.DefaultSemanticHighlightingCalculator;
20import org.eclipse.xtext.ide.editor.syntaxcoloring.IHighlightedPositionAcceptor; 19import org.eclipse.xtext.ide.editor.syntaxcoloring.IHighlightedPositionAcceptor;
21import org.eclipse.xtext.nodemodel.INode; 20import org.eclipse.xtext.nodemodel.INode;
22import org.eclipse.xtext.nodemodel.util.NodeModelUtils; 21import org.eclipse.xtext.nodemodel.util.NodeModelUtils;
23import org.eclipse.xtext.service.OperationCanceledManager; 22import org.eclipse.xtext.service.OperationCanceledManager;
24import org.eclipse.xtext.util.CancelIndicator; 23import org.eclipse.xtext.util.CancelIndicator;
25import org.eclipse.xtext.util.SimpleAttributeResolver;
26 24
27import com.google.common.collect.ImmutableList; 25import com.google.common.collect.ImmutableList;
28import com.google.inject.Inject; 26import com.google.inject.Inject;
@@ -49,19 +47,18 @@ public class ProblemSemanticHighlightingCalculator extends DefaultSemanticHighli
49 @Override 47 @Override
50 protected boolean highlightElement(EObject object, IHighlightedPositionAcceptor acceptor, 48 protected boolean highlightElement(EObject object, IHighlightedPositionAcceptor acceptor,
51 CancelIndicator cancelIndicator) { 49 CancelIndicator cancelIndicator) {
52 highlightName(object, acceptor, cancelIndicator); 50 highlightName(object, acceptor);
53 highlightCrossReferences(object, acceptor, cancelIndicator); 51 highlightCrossReferences(object, acceptor, cancelIndicator);
54 return false; 52 return false;
55 } 53 }
56 54
57 protected void highlightName(EObject object, IHighlightedPositionAcceptor acceptor, 55 protected void highlightName(EObject object, IHighlightedPositionAcceptor acceptor) {
58 CancelIndicator cancelIndicator) { 56 if (!(object instanceof NamedElement)) {
57 return;
58 }
59 String[] highlightClass = getHighlightClass(object); 59 String[] highlightClass = getHighlightClass(object);
60 if (highlightClass.length > 0) { 60 if (highlightClass.length > 0) {
61 EAttribute nameAttribute = SimpleAttributeResolver.NAME_RESOLVER.getAttribute(object); 61 highlightFeature(acceptor, object, ProblemPackage.Literals.NAMED_ELEMENT__NAME, highlightClass);
62 if (nameAttribute != null) {
63 highlightFeature(acceptor, object, nameAttribute, highlightClass);
64 }
65 } 62 }
66 } 63 }
67 64
@@ -73,36 +70,44 @@ public class ProblemSemanticHighlightingCalculator extends DefaultSemanticHighli
73 } 70 }
74 operationCanceledManager.checkCanceled(cancelIndicator); 71 operationCanceledManager.checkCanceled(cancelIndicator);
75 if (reference.isMany()) { 72 if (reference.isMany()) {
76 @SuppressWarnings("unchecked") 73 highlightManyValues(object, reference, acceptor);
77 EList<? extends EObject> values = (EList<? extends EObject>) object.eGet(reference);
78 List<INode> nodes = NodeModelUtils.findNodesForFeature(object, reference);
79 int size = Math.min(values.size(), nodes.size());
80 for (int i = 0; i < size; i++) {
81 EObject valueInList = values.get(i);
82 INode node = nodes.get(i);
83 String[] highlightClass = getHighlightClass(valueInList);
84 if (highlightClass.length > 0) {
85 highlightNode(acceptor, node, highlightClass);
86 }
87 }
88 } else { 74 } else {
89 EObject valueObj = (EObject) object.eGet(reference); 75 highlightSingleValue(object, reference, acceptor);
90 String[] highlightClass = getHighlightClass(valueObj); 76 }
91 if (highlightClass.length > 0) { 77 }
92 highlightFeature(acceptor, object, reference, highlightClass); 78 }
93 } 79
80 protected void highlightSingleValue(EObject object, EReference reference, IHighlightedPositionAcceptor acceptor) {
81 EObject valueObj = (EObject) object.eGet(reference);
82 String[] highlightClass = getHighlightClass(valueObj);
83 if (highlightClass.length > 0) {
84 highlightFeature(acceptor, object, reference, highlightClass);
85 }
86 }
87
88 protected void highlightManyValues(EObject object, EReference reference, IHighlightedPositionAcceptor acceptor) {
89 @SuppressWarnings("unchecked")
90 EList<? extends EObject> values = (EList<? extends EObject>) object.eGet(reference);
91 List<INode> nodes = NodeModelUtils.findNodesForFeature(object, reference);
92 int size = Math.min(values.size(), nodes.size());
93 for (var i = 0; i < size; i++) {
94 EObject valueInList = values.get(i);
95 INode node = nodes.get(i);
96 String[] highlightClass = getHighlightClass(valueInList);
97 if (highlightClass.length > 0) {
98 highlightNode(acceptor, node, highlightClass);
94 } 99 }
95 } 100 }
96 } 101 }
97 102
98 protected String[] getHighlightClass(EObject eObject) { 103 protected String[] getHighlightClass(EObject eObject) {
99 if (isBuiltIn(eObject)) { 104 if (ProblemUtil.isBuiltIn(eObject)) {
100 return new String[] { BUILTIN_CLASS }; 105 return new String[] { BUILTIN_CLASS };
101 } 106 }
102 ImmutableList.Builder<String> classesBuilder = ImmutableList.builder(); 107 ImmutableList.Builder<String> classesBuilder = ImmutableList.builder();
103 if (eObject instanceof ClassDeclaration) { 108 if (eObject instanceof ClassDeclaration) {
104 classesBuilder.add(CLASS_CLASS); 109 classesBuilder.add(CLASS_CLASS);
105 ClassDeclaration classDeclaration = (ClassDeclaration) eObject; 110 var classDeclaration = (ClassDeclaration) eObject;
106 if (classDeclaration.isAbstract()) { 111 if (classDeclaration.isAbstract()) {
107 classesBuilder.add(ABSTRACT_CLASS); 112 classesBuilder.add(ABSTRACT_CLASS);
108 } 113 }
@@ -112,21 +117,21 @@ public class ProblemSemanticHighlightingCalculator extends DefaultSemanticHighli
112 } 117 }
113 if (eObject instanceof ReferenceDeclaration) { 118 if (eObject instanceof ReferenceDeclaration) {
114 classesBuilder.add(REFERENCE_CLASS); 119 classesBuilder.add(REFERENCE_CLASS);
115 ReferenceDeclaration referenceDeclaration = (ReferenceDeclaration) eObject; 120 var referenceDeclaration = (ReferenceDeclaration) eObject;
116 if (referenceDeclaration.isContainment()) { 121 if (referenceDeclaration.isContainment()) {
117 classesBuilder.add(CONTAINMENT_CLASS); 122 classesBuilder.add(CONTAINMENT_CLASS);
118 } 123 }
119 } 124 }
120 if (eObject instanceof PredicateDefinition) { 125 if (eObject instanceof PredicateDefinition) {
121 classesBuilder.add(PREDICATE_CLASS); 126 classesBuilder.add(PREDICATE_CLASS);
122 PredicateDefinition predicateDefinition = (PredicateDefinition) eObject; 127 var predicateDefinition = (PredicateDefinition) eObject;
123 if (predicateDefinition.isError()) { 128 if (predicateDefinition.isError()) {
124 classesBuilder.add(ERROR_CLASS); 129 classesBuilder.add(ERROR_CLASS);
125 } 130 }
126 } 131 }
127 if (eObject instanceof Node) { 132 if (eObject instanceof Node) {
128 classesBuilder.add(NODE_CLASS); 133 classesBuilder.add(NODE_CLASS);
129 Node node = (Node) eObject; 134 var node = (Node) eObject;
130 if (ProblemUtil.isEnumNode(node)) { 135 if (ProblemUtil.isEnumNode(node)) {
131 classesBuilder.add(ENUM_NODE_CLASS); 136 classesBuilder.add(ENUM_NODE_CLASS);
132 } 137 }
@@ -139,7 +144,7 @@ public class ProblemSemanticHighlightingCalculator extends DefaultSemanticHighli
139 } 144 }
140 if (eObject instanceof Variable) { 145 if (eObject instanceof Variable) {
141 classesBuilder.add(VARIABLE_CLASS); 146 classesBuilder.add(VARIABLE_CLASS);
142 Variable variable = (Variable) eObject; 147 var variable = (Variable) eObject;
143 if (ProblemUtil.isSingletonVariable(variable)) { 148 if (ProblemUtil.isSingletonVariable(variable)) {
144 classesBuilder.add(SINGLETON_VARIABLE_CLASS); 149 classesBuilder.add(SINGLETON_VARIABLE_CLASS);
145 } 150 }
@@ -147,14 +152,4 @@ public class ProblemSemanticHighlightingCalculator extends DefaultSemanticHighli
147 List<String> classes = classesBuilder.build(); 152 List<String> classes = classesBuilder.build();
148 return classes.toArray(new String[0]); 153 return classes.toArray(new String[0]);
149 } 154 }
150
151 protected boolean isBuiltIn(EObject eObject) {
152 if (eObject != null) {
153 Resource eResource = eObject.eResource();
154 if (eResource != null) {
155 return ProblemGlobalScopeProvider.BULTIN_LIBRARY_URI.equals(eResource.getURI());
156 }
157 }
158 return false;
159 }
160} 155}
diff --git a/language-model/build.gradle b/language-model/build.gradle
index 56ab4a19..2d9b54b9 100644
--- a/language-model/build.gradle
+++ b/language-model/build.gradle
@@ -1,14 +1,10 @@
1configurations { 1apply from: "${rootDir}/gradle/java-common.gradle"
2 mwe2 { 2apply from: "${rootDir}/gradle/mwe2.gradle"
3 extendsFrom compile
4 }
5}
6 3
7dependencies { 4dependencies {
8 compile "org.eclipse.emf:org.eclipse.emf.ecore:${ecoreVersion}" 5 compile "org.eclipse.emf:org.eclipse.emf.ecore:${ecoreVersion}"
9 mwe2 "org.eclipse.emf:org.eclipse.emf.codegen.ecore:${ecoreCodegenVersion}" 6 mwe2 "org.eclipse.emf:org.eclipse.emf.codegen.ecore:${ecoreCodegenVersion}"
10 mwe2 "org.eclipse.emf:org.eclipse.emf.mwe.utils:${mweVersion}" 7 mwe2 "org.eclipse.emf:org.eclipse.emf.mwe.utils:${mweVersion}"
11 mwe2 "org.eclipse.emf:org.eclipse.emf.mwe2.launch:${mwe2Version}"
12 mwe2 "org.eclipse.emf:org.eclipse.emf.mwe2.lib:${mwe2Version}" 8 mwe2 "org.eclipse.emf:org.eclipse.emf.mwe2.lib:${mwe2Version}"
13 mwe2 "org.eclipse.xtext:org.eclipse.xtext:${xtextVersion}" 9 mwe2 "org.eclipse.xtext:org.eclipse.xtext:${xtextVersion}"
14 mwe2 "org.eclipse.xtext:org.eclipse.xtext.xbase:${xtextVersion}" 10 mwe2 "org.eclipse.xtext:org.eclipse.xtext.xbase:${xtextVersion}"
@@ -35,12 +31,4 @@ task generateEPackage(type: JavaExec) {
35compileJava.dependsOn(generateEPackage) 31compileJava.dependsOn(generateEPackage)
36clean.dependsOn(cleanGenerateEPackage) 32clean.dependsOn(cleanGenerateEPackage)
37 33
38eclipse { 34eclipse.project.natures += ['org.eclipse.sirius.nature.modelingproject', 'org.eclipse.pde.PluginNature']
39 project {
40 natures += ['org.eclipse.sirius.nature.modelingproject', 'org.eclipse.pde.PluginNature']
41 }
42
43 classpath {
44 plusConfigurations += [configurations.mwe2]
45 }
46} \ No newline at end of file
diff --git a/language-mwe2/build.gradle b/language-mwe2/build.gradle
index 8596b4c1..ae456c39 100644
--- a/language-mwe2/build.gradle
+++ b/language-mwe2/build.gradle
@@ -1,3 +1,5 @@
1apply from: "${rootDir}/gradle/java-common.gradle"
2
1dependencies { 3dependencies {
2 compile "org.eclipse.xtext:org.eclipse.xtext.xtext.generator:${xtextVersion}" 4 compile "org.eclipse.xtext:org.eclipse.xtext.xtext.generator:${xtextVersion}"
3} 5}
diff --git a/language-mwe2/src/main/java/org/eclipse/viatra/solver/language/mwe2/ProblemWebIntegrationFragment.java b/language-mwe2/src/main/java/org/eclipse/viatra/solver/language/mwe2/ProblemWebIntegrationFragment.java
index 83b56bc6..78311e0d 100644
--- a/language-mwe2/src/main/java/org/eclipse/viatra/solver/language/mwe2/ProblemWebIntegrationFragment.java
+++ b/language-mwe2/src/main/java/org/eclipse/viatra/solver/language/mwe2/ProblemWebIntegrationFragment.java
@@ -7,6 +7,10 @@ import org.eclipse.xtext.xtext.generator.web.WebIntegrationFragment;
7import com.google.common.collect.Multimap; 7import com.google.common.collect.Multimap;
8 8
9public class ProblemWebIntegrationFragment extends WebIntegrationFragment { 9public class ProblemWebIntegrationFragment extends WebIntegrationFragment {
10 private static final String START_STATE = "start";
11 private static final String PREDICATE_BODY_STATE = "predicateBody";
12 private static final String CM_MODE_META = "meta";
13
10 public ProblemWebIntegrationFragment() { 14 public ProblemWebIntegrationFragment() {
11 setFramework(Framework.CODEMIRROR.name()); 15 setFramework(Framework.CODEMIRROR.name());
12 // We use our custom token style for single-quoted names 16 // We use our custom token style for single-quoted names
@@ -36,25 +40,27 @@ public class ProblemWebIntegrationFragment extends WebIntegrationFragment {
36 protected Multimap<String, String> createCodeMirrorPatterns(String langId, Set<String> keywords) { 40 protected Multimap<String, String> createCodeMirrorPatterns(String langId, Set<String> keywords) {
37 Multimap<String, String> patterns = super.createCodeMirrorPatterns(langId, keywords); 41 Multimap<String, String> patterns = super.createCodeMirrorPatterns(langId, keywords);
38 // We use our custom token style for single-quoted names 42 // We use our custom token style for single-quoted names
39 patterns.put("start", "{token: \"quoted-name\", regex: \"['](?:(?:\\\\\\\\.)|(?:[^'\\\\\\\\]))*?[']\"}"); 43 patterns.put(START_STATE, "{token: \"quoted-name\", regex: \"['](?:(?:\\\\\\\\.)|(?:[^'\\\\\\\\]))*?[']\"}");
40 // Use the CodeMirror default .cm-number instead of .cm-constant.cm-numeric 44 // Use the CodeMirror default .cm-number instead of .cm-constant.cm-numeric
41 patterns.put("start", 45 patterns.put(START_STATE,
42 "{token: \"number\", regex: \"[+-]?\\\\d+(?:(?:\\\\.\\\\d*)?(?:[eE][+-]?\\\\d+)?)?\\\\b\"}"); 46 "{token: \"number\", regex: \"[+-]?\\\\d+(?:(?:\\\\.\\\\d*)?(?:[eE][+-]?\\\\d+)?)?\\\\b\"}");
43 patterns.put("start", "{token: \"number\", regex: \"[*]\"}"); 47 patterns.put(START_STATE, "{token: \"number\", regex: \"[*]\"}");
44 // We use our own custom single-line comments 48 // We use our own custom single-line comments
45 patterns.put("start", "{token: \"comment\", regex: \"%.*$\"}"); 49 patterns.put(START_STATE, "{token: \"comment\", regex: \"%.*$\"}");
46 patterns.put("start", "{token: \"comment\", regex: \"\\\\/\\\\/.*$\"}"); 50 patterns.put(START_STATE, "{token: \"comment\", regex: \"\\\\/\\\\/.*$\"}");
47 patterns.put("meta", "lineComment: \"%\""); 51 patterns.put(CM_MODE_META, "lineComment: \"%\"");
48 // Override indentation behavior 52 // Override indentation behavior
49 patterns.put("start", "{token: \"lparen\", indent: true, regex: \"[[({]\"}"); 53 patterns.put(START_STATE, "{token: \"lparen\", indent: true, regex: \"[[({]\"}");
50 patterns.put("start", "{token: \"rparen\", dedent: true, regex: \"[\\\\])}]\"}"); 54 patterns.put(START_STATE, "{token: \"rparen\", dedent: true, regex: \"[\\\\])}]\"}");
51 patterns.putAll("predicateBody", patterns.get("start")); 55 patterns.putAll(PREDICATE_BODY_STATE, patterns.get(START_STATE));
52 patterns.put("start", "{indent: true, push: \"predicateBody\", regex: \"<=>\"}"); 56 patterns.put(START_STATE, "{indent: true, push: \"" + PREDICATE_BODY_STATE + "\", regex: \"<=>\"}");
53 patterns.put("predicateBody", "{dedent: true, dedentIfLineStart: false, pop: true, regex: \"\\\\.\\\\s*$\"}"); 57 patterns.put(PREDICATE_BODY_STATE,
54 patterns.put("predicateBody", "{indent: true, dedent: true, regex: \"[;]\"}"); 58 "{dedent: true, dedentIfLineStart: false, pop: true, regex: \"\\\\.\\\\s*$\"}");
55 // We must repeat the keyword rule here, because Xtext only adds it to "main" later. 59 patterns.put(PREDICATE_BODY_STATE, "{indent: true, dedent: true, regex: \"[;]\"}");
56 patterns.put("predicateBody", "{token: \"keyword\", regex: \"\\\\b(?:\" + keywords + \")\\\\b\"}"); 60 // We must repeat the keyword rule here, because Xtext only adds it to "main"
57 patterns.put("meta", "electricChars: \"])];\""); 61 // later
62 patterns.put(PREDICATE_BODY_STATE, "{token: \"keyword\", regex: \"\\\\b(?:\" + keywords + \")\\\\b\"}");
63 patterns.put(CM_MODE_META, "electricChars: \"])];\"");
58 return patterns; 64 return patterns;
59 } 65 }
60} 66}
diff --git a/language-web/build.gradle b/language-web/build.gradle
index e04af7cb..e00b88d8 100644
--- a/language-web/build.gradle
+++ b/language-web/build.gradle
@@ -1,3 +1,5 @@
1apply from: "${rootDir}/gradle/xtext-common.gradle"
2
1dependencies { 3dependencies {
2 compile project(':language') 4 compile project(':language')
3 compile project(':language-ide') 5 compile project(':language-ide')
@@ -94,9 +96,7 @@ task webpackServe(type: NpmTask) {
94} 96}
95 97
96eclipse { 98eclipse {
97 project { 99 project.file.whenMerged {
98 file.whenMerged { 100 natures.remove('org.eclipse.wst.common.modulecore.ModuleCoreNature')
99 natures.remove('org.eclipse.wst.common.modulecore.ModuleCoreNature')
100 }
101 } 101 }
102} 102}
diff --git a/language-web/src/main/java/org/eclipse/viatra/solver/language/web/ProblemServlet.java b/language-web/src/main/java/org/eclipse/viatra/solver/language/web/ProblemServlet.java
index 5de708f0..337df54b 100644
--- a/language-web/src/main/java/org/eclipse/viatra/solver/language/web/ProblemServlet.java
+++ b/language-web/src/main/java/org/eclipse/viatra/solver/language/web/ProblemServlet.java
@@ -3,9 +3,9 @@
3 */ 3 */
4package org.eclipse.viatra.solver.language.web; 4package org.eclipse.viatra.solver.language.web;
5 5
6import com.google.inject.Injector;
7import javax.servlet.ServletException; 6import javax.servlet.ServletException;
8import javax.servlet.annotation.WebServlet; 7import javax.servlet.annotation.WebServlet;
8
9import org.eclipse.xtext.util.DisposableRegistry; 9import org.eclipse.xtext.util.DisposableRegistry;
10import org.eclipse.xtext.web.servlet.XtextServlet; 10import org.eclipse.xtext.web.servlet.XtextServlet;
11 11
@@ -17,14 +17,18 @@ public class ProblemServlet extends XtextServlet {
17 17
18 private static final long serialVersionUID = 1L; 18 private static final long serialVersionUID = 1L;
19 19
20 DisposableRegistry disposableRegistry; 20 // Xtext requires a mutable servlet instance field.
21 @SuppressWarnings("squid:S2226")
22 private DisposableRegistry disposableRegistry;
21 23
24 @Override
22 public void init() throws ServletException { 25 public void init() throws ServletException {
23 super.init(); 26 super.init();
24 Injector injector = new ProblemWebSetup().createInjectorAndDoEMFRegistration(); 27 var injector = new ProblemWebSetup().createInjectorAndDoEMFRegistration();
25 this.disposableRegistry = injector.getInstance(DisposableRegistry.class); 28 this.disposableRegistry = injector.getInstance(DisposableRegistry.class);
26 } 29 }
27 30
31 @Override
28 public void destroy() { 32 public void destroy() {
29 if (disposableRegistry != null) { 33 if (disposableRegistry != null) {
30 disposableRegistry.dispose(); 34 disposableRegistry.dispose();
diff --git a/language-web/src/main/java/org/eclipse/viatra/solver/language/web/ServerLauncher.java b/language-web/src/main/java/org/eclipse/viatra/solver/language/web/ServerLauncher.java
index efa6b034..2c0413df 100644
--- a/language-web/src/main/java/org/eclipse/viatra/solver/language/web/ServerLauncher.java
+++ b/language-web/src/main/java/org/eclipse/viatra/solver/language/web/ServerLauncher.java
@@ -7,7 +7,6 @@ import java.io.IOException;
7import java.net.InetSocketAddress; 7import java.net.InetSocketAddress;
8import java.net.URI; 8import java.net.URI;
9import java.net.URISyntaxException; 9import java.net.URISyntaxException;
10import java.net.URL;
11 10
12import org.eclipse.jetty.annotations.AnnotationConfiguration; 11import org.eclipse.jetty.annotations.AnnotationConfiguration;
13import org.eclipse.jetty.server.Server; 12import org.eclipse.jetty.server.Server;
@@ -24,9 +23,9 @@ public class ServerLauncher {
24 23
25 private final Server server; 24 private final Server server;
26 25
27 public ServerLauncher(InetSocketAddress bindAddress, Resource baseResource) throws IOException, URISyntaxException { 26 public ServerLauncher(InetSocketAddress bindAddress, Resource baseResource) {
28 server = new Server(bindAddress); 27 server = new Server(bindAddress);
29 WebAppContext ctx = new WebAppContext(); 28 var ctx = new WebAppContext();
30 ctx.setBaseResource(baseResource); 29 ctx.setBaseResource(baseResource);
31 ctx.setWelcomeFiles(new String[] { "index.html" }); 30 ctx.setWelcomeFiles(new String[] { "index.html" });
32 ctx.setContextPath("/"); 31 ctx.setContextPath("/");
@@ -40,27 +39,13 @@ public class ServerLauncher {
40 public void start() throws Exception { 39 public void start() throws Exception {
41 server.start(); 40 server.start();
42 LOG.info("Server started " + server.getURI() + "..."); 41 LOG.info("Server started " + server.getURI() + "...");
43 new Thread() { 42 LOG.info("Press enter to stop the server...");
44 public void run() { 43 int key = System.in.read();
45 try { 44 if (key != -1) {
46 LOG.info("Press enter to stop the server..."); 45 server.stop();
47 int key = System.in.read(); 46 } else {
48 if (key != -1) { 47 LOG.warn(
49 server.stop(); 48 "Console input is not available. In order to stop the server, you need to cancel process manually.");
50 } else {
51 LOG.warn(
52 "Console input is not available. In order to stop the server, you need to cancel process manually.");
53 }
54 } catch (Exception e) {
55 LOG.warn(e);
56 System.exit(-1);
57 }
58 }
59 }.start();
60 try {
61 server.join();
62 } catch (InterruptedException e) {
63 LOG.info(e);
64 } 49 }
65 } 50 }
66 51
@@ -75,34 +60,34 @@ public class ServerLauncher {
75 if (baseResourceOverride != null) { 60 if (baseResourceOverride != null) {
76 return Resource.newResource(baseResourceOverride); 61 return Resource.newResource(baseResourceOverride);
77 } 62 }
78 URL indexUrlInJar = ServerLauncher.class.getResource("/webapp/index.html"); 63 var indexUrlInJar = ServerLauncher.class.getResource("/webapp/index.html");
79 if (indexUrlInJar == null) { 64 if (indexUrlInJar == null) {
80 throw new RuntimeException("Cannot find pacakged web assets"); 65 throw new IOException("Cannot find pacakged web assets");
81 } 66 }
82 URI webRootUri = URI.create(indexUrlInJar.toURI().toASCIIString().replaceFirst("/index.html$", "/")); 67 var webRootUri = URI.create(indexUrlInJar.toURI().toASCIIString().replaceFirst("/index.html$", "/"));
83 return Resource.newResource(webRootUri); 68 return Resource.newResource(webRootUri);
84 } 69 }
85 70
86 public static void main(String[] args) { 71 public static void main(String[] args) {
87 String listenAddress = System.getenv("LISTEN_ADDRESS"); 72 var listenAddress = System.getenv("LISTEN_ADDRESS");
88 if (listenAddress == null) { 73 if (listenAddress == null) {
89 listenAddress = "localhost"; 74 listenAddress = "localhost";
90 } 75 }
91 int port = 1312; 76 var port = 1312;
92 String portStr = System.getenv("LISTEN_PORT"); 77 var portStr = System.getenv("LISTEN_PORT");
93 if (portStr != null) { 78 if (portStr != null) {
94 try { 79 try {
95 port = Integer.parseInt(portStr); 80 port = Integer.parseInt(portStr);
96 } catch (NumberFormatException e) { 81 } catch (NumberFormatException e) {
97 LOG.warn(e); 82 LOG.warn(e);
98 System.exit(-1); 83 System.exit(1);
99 } 84 }
100 } 85 }
101 String baseResourceOverride = System.getenv("BASE_RESOURCE"); 86 var baseResourceOverride = System.getenv("BASE_RESOURCE");
102 try { 87 try {
103 InetSocketAddress bindAddress = getBindAddress(listenAddress, port); 88 var bindAddress = getBindAddress(listenAddress, port);
104 Resource baseResource = getBaseResource(baseResourceOverride); 89 var baseResource = getBaseResource(baseResourceOverride);
105 ServerLauncher serverLauncher = new ServerLauncher(bindAddress, baseResource); 90 var serverLauncher = new ServerLauncher(bindAddress, baseResource);
106 serverLauncher.start(); 91 serverLauncher.start();
107 } catch (Exception exception) { 92 } catch (Exception exception) {
108 LOG.warn(exception); 93 LOG.warn(exception);
diff --git a/language/build.gradle b/language/build.gradle
index 7e079f27..5ad5ab1f 100644
--- a/language/build.gradle
+++ b/language/build.gradle
@@ -1,8 +1,5 @@
1configurations { 1apply from: "${rootDir}/gradle/xtext-common.gradle"
2 mwe2 { 2apply from: "${rootDir}/gradle/mwe2.gradle"
3 extendsFrom compile
4 }
5}
6 3
7dependencies { 4dependencies {
8 testCompile "org.junit.jupiter:junit-jupiter-api:${junitVersion}" 5 testCompile "org.junit.jupiter:junit-jupiter-api:${junitVersion}"
@@ -15,13 +12,18 @@ dependencies {
15 compile "org.eclipse.xtext:org.eclipse.xtext.xbase:${xtextVersion}" 12 compile "org.eclipse.xtext:org.eclipse.xtext.xbase:${xtextVersion}"
16 compile "org.eclipse.emf:org.eclipse.emf.ecore:${ecoreVersion}" 13 compile "org.eclipse.emf:org.eclipse.emf.ecore:${ecoreVersion}"
17 compile project(':language-model') 14 compile project(':language-model')
18 mwe2 "org.eclipse.emf:org.eclipse.emf.mwe2.launch:${mwe2Version}"
19 mwe2 "org.eclipse.xtext:org.eclipse.xtext.common.types:${xtextVersion}" 15 mwe2 "org.eclipse.xtext:org.eclipse.xtext.common.types:${xtextVersion}"
20 mwe2 "org.eclipse.xtext:org.eclipse.xtext.xtext.generator:${xtextVersion}" 16 mwe2 "org.eclipse.xtext:org.eclipse.xtext.xtext.generator:${xtextVersion}"
21 mwe2 "org.eclipse.xtext:xtext-antlr-generator:${xtextAntlrGeneratorVersion}" 17 mwe2 "org.eclipse.xtext:xtext-antlr-generator:${xtextAntlrGeneratorVersion}"
22 mwe2 project(':language-mwe2') 18 mwe2 project(':language-mwe2')
23} 19}
24 20
21jar {
22 from(sourceSets.main.allSource) {
23 include '**/*.xtext'
24 }
25}
26
25task generateXtextLanguage(type: JavaExec) { 27task generateXtextLanguage(type: JavaExec) {
26 main = 'org.eclipse.emf.mwe2.launch.runtime.Mwe2Launcher' 28 main = 'org.eclipse.emf.mwe2.launch.runtime.Mwe2Launcher'
27 classpath = configurations.mwe2 29 classpath = configurations.mwe2
@@ -43,5 +45,3 @@ test {
43 45
44generateXtext.dependsOn(generateXtextLanguage) 46generateXtext.dependsOn(generateXtextLanguage)
45clean.dependsOn(cleanGenerateXtextLanguage) 47clean.dependsOn(cleanGenerateXtextLanguage)
46
47eclipse.classpath.plusConfigurations += [configurations.mwe2]
diff --git a/language/src/main/java/org/eclipse/viatra/solver/language/GenerateProblem.mwe2 b/language/src/main/java/org/eclipse/viatra/solver/language/GenerateProblem.mwe2
index 18f70080..ca3e2665 100644
--- a/language/src/main/java/org/eclipse/viatra/solver/language/GenerateProblem.mwe2
+++ b/language/src/main/java/org/eclipse/viatra/solver/language/GenerateProblem.mwe2
@@ -44,7 +44,9 @@ Workflow {
44 validator = { 44 validator = {
45 generateDeprecationValidation = true 45 generateDeprecationValidation = true
46 } 46 }
47 generator = null 47 generator = {
48 generateStub = false
49 }
48 junitSupport = { 50 junitSupport = {
49 junitVersion = "5" 51 junitVersion = "5"
50 } 52 }
diff --git a/language/src/main/java/org/eclipse/viatra/solver/language/ProblemRuntimeModule.java b/language/src/main/java/org/eclipse/viatra/solver/language/ProblemRuntimeModule.java
index eb9ddd77..9fec7d75 100644
--- a/language/src/main/java/org/eclipse/viatra/solver/language/ProblemRuntimeModule.java
+++ b/language/src/main/java/org/eclipse/viatra/solver/language/ProblemRuntimeModule.java
@@ -62,6 +62,8 @@ public class ProblemRuntimeModule extends AbstractProblemRuntimeModule {
62 return DerivedStateAwareResource.class; 62 return DerivedStateAwareResource.class;
63 } 63 }
64 64
65 // Method name follows Xtext convention.
66 @SuppressWarnings("squid:S100")
65 public Class<? extends IResourceDescription.Manager> bindIResourceDescription$Manager() { 67 public Class<? extends IResourceDescription.Manager> bindIResourceDescription$Manager() {
66 return DerivedStateAwareResourceDescriptionManager.class; 68 return DerivedStateAwareResourceDescriptionManager.class;
67 } 69 }
@@ -74,6 +76,7 @@ public class ProblemRuntimeModule extends AbstractProblemRuntimeModule {
74 return ProblemDerivedStateComputer.class; 76 return ProblemDerivedStateComputer.class;
75 } 77 }
76 78
79 @Override
77 public Class<? extends ILocationInFileProvider> bindILocationInFileProvider() { 80 public Class<? extends ILocationInFileProvider> bindILocationInFileProvider() {
78 return ProblemLocationInFileProvider.class; 81 return ProblemLocationInFileProvider.class;
79 } 82 }
diff --git a/language/src/main/java/org/eclipse/viatra/solver/language/ProblemStandaloneSetup.java b/language/src/main/java/org/eclipse/viatra/solver/language/ProblemStandaloneSetup.java
index 5652f859..11e5ad8a 100644
--- a/language/src/main/java/org/eclipse/viatra/solver/language/ProblemStandaloneSetup.java
+++ b/language/src/main/java/org/eclipse/viatra/solver/language/ProblemStandaloneSetup.java
@@ -9,18 +9,25 @@ import org.eclipse.viatra.solver.language.model.problem.ProblemPackage;
9import com.google.inject.Injector; 9import com.google.inject.Injector;
10 10
11/** 11/**
12 * Initialization support for running Xtext languages without Equinox extension registry. 12 * Initialization support for running Xtext languages without Equinox extension
13 * registry.
13 */ 14 */
14public class ProblemStandaloneSetup extends ProblemStandaloneSetupGenerated { 15public class ProblemStandaloneSetup extends ProblemStandaloneSetupGenerated {
15 16
16 public static void doSetup() { 17 public static void doSetup() {
17 new ProblemStandaloneSetup().createInjectorAndDoEMFRegistration(); 18 new ProblemStandaloneSetup().createInjectorAndDoEMFRegistration();
18 } 19 }
19 20
20 @Override 21 @Override
22 // Here we can't rely on java.util.HashMap#computeIfAbsent, because
23 // org.eclipse.emf.ecore.impl.EPackageRegistryImpl#containsKey is overridden
24 // without also overriding computeIfAbsent. We must make sure to call the
25 // overridden containsKey implementation.
26 @SuppressWarnings("squid:S3824")
21 public Injector createInjectorAndDoEMFRegistration() { 27 public Injector createInjectorAndDoEMFRegistration() {
22 if (!EPackage.Registry.INSTANCE.containsKey(ProblemPackage.eNS_URI)) 28 if (!EPackage.Registry.INSTANCE.containsKey(ProblemPackage.eNS_URI)) {
23 EPackage.Registry.INSTANCE.put(ProblemPackage.eNS_URI, ProblemPackage.eINSTANCE); 29 EPackage.Registry.INSTANCE.put(ProblemPackage.eNS_URI, ProblemPackage.eINSTANCE);
30 }
24 return super.createInjectorAndDoEMFRegistration(); 31 return super.createInjectorAndDoEMFRegistration();
25 } 32 }
26} 33}
diff --git a/language/src/main/java/org/eclipse/viatra/solver/language/ProblemUtil.java b/language/src/main/java/org/eclipse/viatra/solver/language/ProblemUtil.java
index e0a72687..2d7fede6 100644
--- a/language/src/main/java/org/eclipse/viatra/solver/language/ProblemUtil.java
+++ b/language/src/main/java/org/eclipse/viatra/solver/language/ProblemUtil.java
@@ -16,27 +16,18 @@ import org.eclipse.viatra.solver.language.model.problem.ProblemPackage;
16import org.eclipse.viatra.solver.language.model.problem.ReferenceDeclaration; 16import org.eclipse.viatra.solver.language.model.problem.ReferenceDeclaration;
17import org.eclipse.viatra.solver.language.model.problem.Relation; 17import org.eclipse.viatra.solver.language.model.problem.Relation;
18import org.eclipse.viatra.solver.language.model.problem.Variable; 18import org.eclipse.viatra.solver.language.model.problem.Variable;
19import org.eclipse.viatra.solver.language.naming.NamingUtil;
19import org.eclipse.viatra.solver.language.scoping.ProblemGlobalScopeProvider; 20import org.eclipse.viatra.solver.language.scoping.ProblemGlobalScopeProvider;
20 21
21import com.google.common.collect.ImmutableList; 22import com.google.common.collect.ImmutableList;
22import com.google.inject.Singleton;
23 23
24@Singleton
25public final class ProblemUtil { 24public final class ProblemUtil {
26 private ProblemUtil() { 25 private ProblemUtil() {
27 throw new IllegalStateException("This is a static utility class and should not be instantiated directly"); 26 throw new IllegalStateException("This is a static utility class and should not be instantiated directly");
28 } 27 }
29 28
30 public static final String SINGLETON_VARIABLE_PREFIX = "_";
31
32 public static final String ENUM_NODE_NAME_QUOTE = "'";
33
34 public static final String NODE_CLASS_NAME = "node"; 29 public static final String NODE_CLASS_NAME = "node";
35 30
36 public static boolean isSingletonVariableName(String name) {
37 return name != null && name.startsWith(SINGLETON_VARIABLE_PREFIX);
38 }
39
40 public static boolean isSingletonVariable(Variable variable) { 31 public static boolean isSingletonVariable(Variable variable) {
41 return variable.eContainingFeature() == ProblemPackage.Literals.VARIABLE_OR_NODE_ARGUMENT__SINGLETON_VARIABLE; 32 return variable.eContainingFeature() == ProblemPackage.Literals.VARIABLE_OR_NODE_ARGUMENT__SINGLETON_VARIABLE;
42 } 33 }
@@ -46,10 +37,7 @@ public final class ProblemUtil {
46 } 37 }
47 38
48 public static boolean isEnumNode(Node node) { 39 public static boolean isEnumNode(Node node) {
49 String name = node.getName(); 40 return NamingUtil.isQuotedName(node.getName()) || isEnumLiteral(node);
50 boolean isNameQuoted = name != null && name.startsWith(ENUM_NODE_NAME_QUOTE)
51 && name.endsWith(ENUM_NODE_NAME_QUOTE);
52 return isNameQuoted || isEnumLiteral(node);
53 } 41 }
54 42
55 public static boolean isNewNode(Node node) { 43 public static boolean isNewNode(Node node) {
@@ -63,6 +51,16 @@ public final class ProblemUtil {
63 .filter(Problem.class::isInstance).map(Problem.class::cast); 51 .filter(Problem.class::isInstance).map(Problem.class::cast);
64 } 52 }
65 53
54 public static boolean isBuiltIn(EObject eObject) {
55 if (eObject != null) {
56 var eResource = eObject.eResource();
57 if (eResource != null) {
58 return ProblemGlobalScopeProvider.BULTIN_LIBRARY_URI.equals(eResource.getURI());
59 }
60 }
61 return false;
62 }
63
66 public static Optional<ClassDeclaration> getNodeClassDeclaration(EObject context) { 64 public static Optional<ClassDeclaration> getNodeClassDeclaration(EObject context) {
67 return getBuiltInLibrary(context).flatMap(problem -> problem.getStatements().stream() 65 return getBuiltInLibrary(context).flatMap(problem -> problem.getStatements().stream()
68 .filter(ClassDeclaration.class::isInstance).map(ClassDeclaration.class::cast) 66 .filter(ClassDeclaration.class::isInstance).map(ClassDeclaration.class::cast)
diff --git a/language/src/main/java/org/eclipse/viatra/solver/language/conversion/ProblemValueConverterService.java b/language/src/main/java/org/eclipse/viatra/solver/language/conversion/ProblemValueConverterService.java
index 4f5fd069..1c665e6f 100644
--- a/language/src/main/java/org/eclipse/viatra/solver/language/conversion/ProblemValueConverterService.java
+++ b/language/src/main/java/org/eclipse/viatra/solver/language/conversion/ProblemValueConverterService.java
@@ -9,8 +9,10 @@ import com.google.inject.Inject;
9public class ProblemValueConverterService extends DefaultTerminalConverters { 9public class ProblemValueConverterService extends DefaultTerminalConverters {
10 @Inject 10 @Inject
11 private UpperBoundValueConverter upperBoundValueConverter; 11 private UpperBoundValueConverter upperBoundValueConverter;
12 12
13 @ValueConverter(rule = "UpperBound") 13 @ValueConverter(rule = "UpperBound")
14 // Method name follows Xtext convention.
15 @SuppressWarnings("squid:S100")
14 public IValueConverter<Integer> UpperBound() { 16 public IValueConverter<Integer> UpperBound() {
15 return upperBoundValueConverter; 17 return upperBoundValueConverter;
16 } 18 }
diff --git a/language/src/main/java/org/eclipse/viatra/solver/language/generator/ProblemGenerator.java b/language/src/main/java/org/eclipse/viatra/solver/language/generator/ProblemGenerator.java
deleted file mode 100644
index b6ea3553..00000000
--- a/language/src/main/java/org/eclipse/viatra/solver/language/generator/ProblemGenerator.java
+++ /dev/null
@@ -1,30 +0,0 @@
1/*
2 * generated by Xtext 2.26.0.M1
3 */
4package org.eclipse.viatra.solver.language.generator;
5
6import org.eclipse.emf.ecore.resource.Resource;
7import org.eclipse.xtext.generator.AbstractGenerator;
8import org.eclipse.xtext.generator.IFileSystemAccess2;
9import org.eclipse.xtext.generator.IGeneratorContext;
10
11/**
12 * Generates code from your model files on save.
13 *
14 * See https://www.eclipse.org/Xtext/documentation/303_runtime_concepts.html#code-generation
15 */
16public class ProblemGenerator extends AbstractGenerator {
17
18 @Override
19 public void doGenerate(Resource resource, IFileSystemAccess2 fsa, IGeneratorContext context) {
20// Iterator<Greeting> filtered = Iterators.filter(resource.getAllContents(), Greeting.class);
21// Iterator<String> names = Iterators.transform(filtered, new Function<Greeting, String>() {
22//
23// @Override
24// public String apply(Greeting greeting) {
25// return greeting.getName();
26// }
27// });
28// fsa.generateFile("greetings.txt", "People to greet: " + IteratorExtensions.join(names, ", "));
29 }
30}
diff --git a/language/src/main/java/org/eclipse/viatra/solver/language/naming/NamingUtil.java b/language/src/main/java/org/eclipse/viatra/solver/language/naming/NamingUtil.java
new file mode 100644
index 00000000..decc014a
--- /dev/null
+++ b/language/src/main/java/org/eclipse/viatra/solver/language/naming/NamingUtil.java
@@ -0,0 +1,35 @@
1package org.eclipse.viatra.solver.language.naming;
2
3import java.util.regex.Pattern;
4
5public final class NamingUtil {
6 private static final String SINGLETON_VARIABLE_PREFIX = "_";
7
8 private static final String ENUM_NODE_NAME_QUOTE = "'";
9
10 private static final Pattern ID_REGEX = Pattern.compile("[_a-zA-Z][_0-9a-zA-Z]*");
11
12 private NamingUtil() {
13 throw new IllegalStateException("This is a static utility class and should not be instantiated directly");
14 }
15
16 public static boolean isNullOrEmpty(String name) {
17 return name == null || name.isEmpty();
18 }
19
20 public static boolean isSingletonVariableName(String name) {
21 return name != null && name.startsWith(SINGLETON_VARIABLE_PREFIX);
22 }
23
24 public static boolean isQuotedName(String name) {
25 return name != null && name.startsWith(ENUM_NODE_NAME_QUOTE) && name.endsWith(ENUM_NODE_NAME_QUOTE);
26 }
27
28 public static boolean isValidId(String name) {
29 return name != null && ID_REGEX.matcher(name).matches();
30 }
31
32 public static boolean isValidNodeName(String name) {
33 return isValidId(name) || isQuotedName(name);
34 }
35}
diff --git a/language/src/main/java/org/eclipse/viatra/solver/language/resource/DerivedVariableComputer.java b/language/src/main/java/org/eclipse/viatra/solver/language/resource/DerivedVariableComputer.java
new file mode 100644
index 00000000..1b0146b6
--- /dev/null
+++ b/language/src/main/java/org/eclipse/viatra/solver/language/resource/DerivedVariableComputer.java
@@ -0,0 +1,195 @@
1package org.eclipse.viatra.solver.language.resource;
2
3import java.util.HashSet;
4import java.util.List;
5import java.util.Set;
6
7import org.eclipse.viatra.solver.language.model.problem.Argument;
8import org.eclipse.viatra.solver.language.model.problem.Atom;
9import org.eclipse.viatra.solver.language.model.problem.Conjunction;
10import org.eclipse.viatra.solver.language.model.problem.ExistentialQuantifier;
11import org.eclipse.viatra.solver.language.model.problem.ImplicitVariable;
12import org.eclipse.viatra.solver.language.model.problem.Literal;
13import org.eclipse.viatra.solver.language.model.problem.NegativeLiteral;
14import org.eclipse.viatra.solver.language.model.problem.Parameter;
15import org.eclipse.viatra.solver.language.model.problem.PredicateDefinition;
16import org.eclipse.viatra.solver.language.model.problem.Problem;
17import org.eclipse.viatra.solver.language.model.problem.ProblemFactory;
18import org.eclipse.viatra.solver.language.model.problem.ProblemPackage;
19import org.eclipse.viatra.solver.language.model.problem.Statement;
20import org.eclipse.viatra.solver.language.model.problem.VariableOrNodeArgument;
21import org.eclipse.viatra.solver.language.naming.NamingUtil;
22import org.eclipse.xtext.linking.impl.LinkingHelper;
23import org.eclipse.xtext.naming.IQualifiedNameConverter;
24import org.eclipse.xtext.nodemodel.INode;
25import org.eclipse.xtext.nodemodel.util.NodeModelUtils;
26import org.eclipse.xtext.scoping.IScope;
27import org.eclipse.xtext.scoping.IScopeProvider;
28import org.eclipse.xtext.scoping.impl.AbstractDeclarativeScopeProvider;
29
30import com.google.inject.Inject;
31import com.google.inject.Singleton;
32import com.google.inject.name.Named;
33
34@Singleton
35public class DerivedVariableComputer {
36 @Inject
37 private LinkingHelper linkingHelper;
38
39 @Inject
40 private IQualifiedNameConverter qualifiedNameConverter;
41
42 @Inject
43 @Named(AbstractDeclarativeScopeProvider.NAMED_DELEGATE)
44 private IScopeProvider scopeProvider;
45
46 public void installDerivedVariables(Problem problem, Set<String> nodeNames) {
47 for (Statement statement : problem.getStatements()) {
48 if (statement instanceof PredicateDefinition) {
49 PredicateDefinition definition = (PredicateDefinition) statement;
50 installDerivedPredicateDefinitionState(definition, nodeNames);
51 }
52 }
53 }
54
55 protected void installDerivedPredicateDefinitionState(PredicateDefinition definition, Set<String> nodeNames) {
56 Set<String> knownVariables = new HashSet<>();
57 knownVariables.addAll(nodeNames);
58 for (Parameter parameter : definition.getParameters()) {
59 String name = parameter.getName();
60 if (name != null) {
61 knownVariables.add(name);
62 }
63 }
64 for (Conjunction body : definition.getBodies()) {
65 installDeriveConjunctionState(body, knownVariables);
66 }
67 }
68
69 protected void installDeriveConjunctionState(Conjunction conjunction, Set<String> knownVariables) {
70 Set<String> newVariables = new HashSet<>();
71 for (Literal literal : conjunction.getLiterals()) {
72 if (literal instanceof Atom) {
73 var atom = (Atom) literal;
74 createSigletonVariablesAndCollectVariables(atom, knownVariables, newVariables);
75 }
76 }
77 createVariables(conjunction, newVariables);
78 newVariables.addAll(knownVariables);
79 for (Literal literal : conjunction.getLiterals()) {
80 if (literal instanceof NegativeLiteral) {
81 var negativeLiteral = (NegativeLiteral) literal;
82 installDeriveNegativeLiteralState(negativeLiteral, newVariables);
83 }
84 }
85 }
86
87 protected void installDeriveNegativeLiteralState(NegativeLiteral negativeLiteral, Set<String> knownVariables) {
88 Set<String> newVariables = new HashSet<>();
89 createSigletonVariablesAndCollectVariables(negativeLiteral.getAtom(), knownVariables, newVariables);
90 createVariables(negativeLiteral, newVariables);
91 }
92
93 protected void createSigletonVariablesAndCollectVariables(Atom atom, Set<String> knownVariables,
94 Set<String> newVariables) {
95 for (Argument argument : atom.getArguments()) {
96 if (argument instanceof VariableOrNodeArgument) {
97 var variableOrNodeArgument = (VariableOrNodeArgument) argument;
98 IScope scope = scopeProvider.getScope(variableOrNodeArgument,
99 ProblemPackage.Literals.VARIABLE_OR_NODE_ARGUMENT__VARIABLE_OR_NODE);
100 List<INode> nodes = NodeModelUtils.findNodesForFeature(variableOrNodeArgument,
101 ProblemPackage.Literals.VARIABLE_OR_NODE_ARGUMENT__VARIABLE_OR_NODE);
102 for (INode node : nodes) {
103 var variableName = linkingHelper.getCrossRefNodeAsString(node, true);
104 var created = tryCreateVariableForArgument(variableOrNodeArgument, variableName, scope,
105 knownVariables, newVariables);
106 if (created) {
107 break;
108 }
109 }
110 }
111 }
112 }
113
114 protected boolean tryCreateVariableForArgument(VariableOrNodeArgument variableOrNodeArgument, String variableName,
115 IScope scope, Set<String> knownVariables, Set<String> newVariables) {
116 if (!NamingUtil.isValidId(variableName)) {
117 return false;
118 }
119 var qualifiedName = qualifiedNameConverter.toQualifiedName(variableName);
120 if (scope.getSingleElement(qualifiedName) != null) {
121 return false;
122 }
123 if (NamingUtil.isSingletonVariableName(variableName)) {
124 createSingletonVariable(variableOrNodeArgument, variableName);
125 return true;
126 }
127 if (!knownVariables.contains(variableName)) {
128 newVariables.add(variableName);
129 return true;
130 }
131 return false;
132 }
133
134 protected void createVariables(ExistentialQuantifier quantifier, Set<String> newVariables) {
135 for (String variableName : newVariables) {
136 createVariable(quantifier, variableName);
137 }
138 }
139
140 protected void createVariable(ExistentialQuantifier quantifier, String variableName) {
141 if (NamingUtil.isValidId(variableName)) {
142 ImplicitVariable variable = createNamedVariable(variableName);
143 quantifier.getImplicitVariables().add(variable);
144 }
145 }
146
147 protected void createSingletonVariable(VariableOrNodeArgument argument, String variableName) {
148 if (NamingUtil.isValidId(variableName)) {
149 ImplicitVariable variable = createNamedVariable(variableName);
150 argument.setSingletonVariable(variable);
151 }
152 }
153
154 protected ImplicitVariable createNamedVariable(String variableName) {
155 var variable = ProblemFactory.eINSTANCE.createImplicitVariable();
156 variable.setName(variableName);
157 return variable;
158 }
159
160 public void discardDerivedVariables(Problem problem) {
161 for (Statement statement : problem.getStatements()) {
162 if (statement instanceof PredicateDefinition) {
163 discardPredicateDefinitionState((PredicateDefinition) statement);
164 }
165 }
166 }
167
168 protected void discardPredicateDefinitionState(PredicateDefinition definition) {
169 for (Conjunction body : definition.getBodies()) {
170 body.getImplicitVariables().clear();
171 for (Literal literal : body.getLiterals()) {
172 if (literal instanceof Atom) {
173 discardDerivedAtomState((Atom) literal);
174 }
175 if (literal instanceof NegativeLiteral) {
176 var negativeLiteral = (NegativeLiteral) literal;
177 negativeLiteral.getImplicitVariables().clear();
178 discardDerivedAtomState(negativeLiteral.getAtom());
179 }
180 }
181 }
182 }
183
184 protected void discardDerivedAtomState(Atom atom) {
185 if (atom == null) {
186 return;
187 }
188 for (Argument argument : atom.getArguments()) {
189 if (argument instanceof VariableOrNodeArgument) {
190 var variableOrNodeArgument = (VariableOrNodeArgument) argument;
191 variableOrNodeArgument.setSingletonVariable(null);
192 }
193 }
194 }
195}
diff --git a/language/src/main/java/org/eclipse/viatra/solver/language/resource/NodeNameCollector.java b/language/src/main/java/org/eclipse/viatra/solver/language/resource/NodeNameCollector.java
index 79d7ffbb..597dd92d 100644
--- a/language/src/main/java/org/eclipse/viatra/solver/language/resource/NodeNameCollector.java
+++ b/language/src/main/java/org/eclipse/viatra/solver/language/resource/NodeNameCollector.java
@@ -1,6 +1,5 @@
1package org.eclipse.viatra.solver.language.resource; 1package org.eclipse.viatra.solver.language.resource;
2 2
3import java.util.HashSet;
4import java.util.List; 3import java.util.List;
5import java.util.Set; 4import java.util.Set;
6import java.util.function.Predicate; 5import java.util.function.Predicate;
@@ -21,15 +20,16 @@ import org.eclipse.viatra.solver.language.model.problem.Problem;
21import org.eclipse.viatra.solver.language.model.problem.ProblemPackage; 20import org.eclipse.viatra.solver.language.model.problem.ProblemPackage;
22import org.eclipse.viatra.solver.language.model.problem.Statement; 21import org.eclipse.viatra.solver.language.model.problem.Statement;
23import org.eclipse.viatra.solver.language.model.problem.VariableOrNodeArgument; 22import org.eclipse.viatra.solver.language.model.problem.VariableOrNodeArgument;
23import org.eclipse.viatra.solver.language.naming.NamingUtil;
24import org.eclipse.xtext.linking.impl.LinkingHelper; 24import org.eclipse.xtext.linking.impl.LinkingHelper;
25import org.eclipse.xtext.naming.IQualifiedNameConverter; 25import org.eclipse.xtext.naming.IQualifiedNameConverter;
26import org.eclipse.xtext.naming.QualifiedName;
27import org.eclipse.xtext.nodemodel.INode; 26import org.eclipse.xtext.nodemodel.INode;
28import org.eclipse.xtext.nodemodel.util.NodeModelUtils; 27import org.eclipse.xtext.nodemodel.util.NodeModelUtils;
29import org.eclipse.xtext.scoping.IScope; 28import org.eclipse.xtext.scoping.IScope;
30import org.eclipse.xtext.scoping.IScopeProvider; 29import org.eclipse.xtext.scoping.IScopeProvider;
31import org.eclipse.xtext.scoping.impl.AbstractDeclarativeScopeProvider; 30import org.eclipse.xtext.scoping.impl.AbstractDeclarativeScopeProvider;
32 31
32import com.google.common.collect.ImmutableSet;
33import com.google.inject.Inject; 33import com.google.inject.Inject;
34import com.google.inject.name.Named; 34import com.google.inject.name.Named;
35 35
@@ -44,12 +44,12 @@ public class NodeNameCollector {
44 @Named(AbstractDeclarativeScopeProvider.NAMED_DELEGATE) 44 @Named(AbstractDeclarativeScopeProvider.NAMED_DELEGATE)
45 private IScopeProvider scopeProvider; 45 private IScopeProvider scopeProvider;
46 46
47 private final Set<String> nodeNames = new HashSet<>(); 47 private final ImmutableSet.Builder<String> nodeNames = ImmutableSet.builder();
48 48
49 private IScope nodeScope; 49 private IScope nodeScope;
50 50
51 public Set<String> getNodeNames() { 51 public Set<String> getNodeNames() {
52 return nodeNames; 52 return nodeNames.build();
53 } 53 }
54 54
55 public void collectNodeNames(Problem problem) { 55 public void collectNodeNames(Problem problem) {
@@ -73,35 +73,39 @@ public class NodeNameCollector {
73 for (AssertionArgument argument : assertion.getArguments()) { 73 for (AssertionArgument argument : assertion.getArguments()) {
74 if (argument instanceof NodeAssertionArgument) { 74 if (argument instanceof NodeAssertionArgument) {
75 collectNodeNames(argument, ProblemPackage.Literals.NODE_ASSERTION_ARGUMENT__NODE, 75 collectNodeNames(argument, ProblemPackage.Literals.NODE_ASSERTION_ARGUMENT__NODE,
76 ProblemDerivedStateComputer::validNodeName); 76 NamingUtil::isValidNodeName);
77 } 77 }
78 } 78 }
79 } 79 }
80 80
81 protected void collectNodeValueAssertionNodeNames(NodeValueAssertion nodeValueAssertion) { 81 protected void collectNodeValueAssertionNodeNames(NodeValueAssertion nodeValueAssertion) {
82 collectNodeNames(nodeValueAssertion, ProblemPackage.Literals.NODE_VALUE_ASSERTION__NODE, 82 collectNodeNames(nodeValueAssertion, ProblemPackage.Literals.NODE_VALUE_ASSERTION__NODE,
83 ProblemDerivedStateComputer::validNodeName); 83 NamingUtil::isValidNodeName);
84 } 84 }
85 85
86 protected void collectPredicateDefinitionNodeNames(PredicateDefinition predicateDefinition) { 86 protected void collectPredicateDefinitionNodeNames(PredicateDefinition predicateDefinition) {
87 for (Conjunction body : predicateDefinition.getBodies()) { 87 for (Conjunction body : predicateDefinition.getBodies()) {
88 for (Literal literal : body.getLiterals()) { 88 for (Literal literal : body.getLiterals()) {
89 Atom atom = null; 89 collectLiteralNodeNames(literal);
90 if (literal instanceof Atom) { 90 }
91 atom = (Atom) literal; 91 }
92 } else if (literal instanceof NegativeLiteral) { 92 }
93 NegativeLiteral negativeLiteral = (NegativeLiteral) literal; 93
94 atom = negativeLiteral.getAtom(); 94 protected void collectLiteralNodeNames(Literal literal) {
95 } 95 Atom atom = null;
96 if (atom == null) { 96 if (literal instanceof Atom) {
97 continue; 97 atom = (Atom) literal;
98 } 98 } else if (literal instanceof NegativeLiteral) {
99 for (Argument argument : atom.getArguments()) { 99 var negativeLiteral = (NegativeLiteral) literal;
100 if (argument instanceof VariableOrNodeArgument) { 100 atom = negativeLiteral.getAtom();
101 collectNodeNames(argument, ProblemPackage.Literals.VARIABLE_OR_NODE_ARGUMENT__VARIABLE_OR_NODE, 101 }
102 ProblemDerivedStateComputer::validQuotedId); 102 if (atom == null) {
103 } 103 return;
104 } 104 }
105 for (Argument argument : atom.getArguments()) {
106 if (argument instanceof VariableOrNodeArgument) {
107 collectNodeNames(argument, ProblemPackage.Literals.VARIABLE_OR_NODE_ARGUMENT__VARIABLE_OR_NODE,
108 NamingUtil::isQuotedName);
105 } 109 }
106 } 110 }
107 } 111 }
@@ -109,11 +113,11 @@ public class NodeNameCollector {
109 private void collectNodeNames(EObject eObject, EStructuralFeature feature, Predicate<String> condition) { 113 private void collectNodeNames(EObject eObject, EStructuralFeature feature, Predicate<String> condition) {
110 List<INode> nodes = NodeModelUtils.findNodesForFeature(eObject, feature); 114 List<INode> nodes = NodeModelUtils.findNodesForFeature(eObject, feature);
111 for (INode node : nodes) { 115 for (INode node : nodes) {
112 String nodeName = linkingHelper.getCrossRefNodeAsString(node, true); 116 var nodeName = linkingHelper.getCrossRefNodeAsString(node, true);
113 if (!condition.test(nodeName)) { 117 if (!condition.test(nodeName)) {
114 continue; 118 continue;
115 } 119 }
116 QualifiedName qualifiedName = qualifiedNameConverter.toQualifiedName(nodeName); 120 var qualifiedName = qualifiedNameConverter.toQualifiedName(nodeName);
117 if (nodeScope.getSingleElement(qualifiedName) == null) { 121 if (nodeScope.getSingleElement(qualifiedName) == null) {
118 nodeNames.add(nodeName); 122 nodeNames.add(nodeName);
119 } 123 }
diff --git a/language/src/main/java/org/eclipse/viatra/solver/language/resource/ProblemDerivedStateComputer.java b/language/src/main/java/org/eclipse/viatra/solver/language/resource/ProblemDerivedStateComputer.java
index 81236afd..a2d0eef6 100644
--- a/language/src/main/java/org/eclipse/viatra/solver/language/resource/ProblemDerivedStateComputer.java
+++ b/language/src/main/java/org/eclipse/viatra/solver/language/resource/ProblemDerivedStateComputer.java
@@ -1,43 +1,26 @@
1package org.eclipse.viatra.solver.language.resource; 1package org.eclipse.viatra.solver.language.resource;
2 2
3import java.util.Collection;
3import java.util.HashMap; 4import java.util.HashMap;
4import java.util.HashSet; 5import java.util.HashSet;
5import java.util.List; 6import java.util.List;
6import java.util.Map; 7import java.util.Map;
7import java.util.Set; 8import java.util.Set;
8import java.util.regex.Pattern; 9import java.util.function.Function;
9 10
10import org.eclipse.emf.common.notify.impl.AdapterImpl; 11import org.eclipse.emf.common.notify.impl.AdapterImpl;
11import org.eclipse.emf.ecore.EObject; 12import org.eclipse.emf.ecore.EObject;
12import org.eclipse.emf.ecore.resource.Resource; 13import org.eclipse.emf.ecore.resource.Resource;
13import org.eclipse.emf.ecore.util.EcoreUtil; 14import org.eclipse.emf.ecore.util.EcoreUtil;
14import org.eclipse.viatra.solver.language.ProblemUtil;
15import org.eclipse.viatra.solver.language.model.problem.Argument;
16import org.eclipse.viatra.solver.language.model.problem.Atom;
17import org.eclipse.viatra.solver.language.model.problem.ClassDeclaration; 15import org.eclipse.viatra.solver.language.model.problem.ClassDeclaration;
18import org.eclipse.viatra.solver.language.model.problem.Conjunction;
19import org.eclipse.viatra.solver.language.model.problem.ExistentialQuantifier;
20import org.eclipse.viatra.solver.language.model.problem.ImplicitVariable;
21import org.eclipse.viatra.solver.language.model.problem.Literal;
22import org.eclipse.viatra.solver.language.model.problem.NegativeLiteral;
23import org.eclipse.viatra.solver.language.model.problem.Node; 16import org.eclipse.viatra.solver.language.model.problem.Node;
24import org.eclipse.viatra.solver.language.model.problem.Parameter;
25import org.eclipse.viatra.solver.language.model.problem.PredicateDefinition;
26import org.eclipse.viatra.solver.language.model.problem.Problem; 17import org.eclipse.viatra.solver.language.model.problem.Problem;
27import org.eclipse.viatra.solver.language.model.problem.ProblemFactory; 18import org.eclipse.viatra.solver.language.model.problem.ProblemFactory;
28import org.eclipse.viatra.solver.language.model.problem.ProblemPackage;
29import org.eclipse.viatra.solver.language.model.problem.Statement; 19import org.eclipse.viatra.solver.language.model.problem.Statement;
30import org.eclipse.viatra.solver.language.model.problem.VariableOrNodeArgument;
31import org.eclipse.xtext.Constants; 20import org.eclipse.xtext.Constants;
32import org.eclipse.xtext.linking.impl.LinkingHelper;
33import org.eclipse.xtext.naming.IQualifiedNameConverter;
34import org.eclipse.xtext.naming.QualifiedName;
35import org.eclipse.xtext.nodemodel.INode;
36import org.eclipse.xtext.nodemodel.util.NodeModelUtils;
37import org.eclipse.xtext.resource.DerivedStateAwareResource; 21import org.eclipse.xtext.resource.DerivedStateAwareResource;
38import org.eclipse.xtext.resource.IDerivedStateComputer; 22import org.eclipse.xtext.resource.IDerivedStateComputer;
39import org.eclipse.xtext.resource.XtextResource; 23import org.eclipse.xtext.resource.XtextResource;
40import org.eclipse.xtext.scoping.IScope;
41import org.eclipse.xtext.scoping.IScopeProvider; 24import org.eclipse.xtext.scoping.IScopeProvider;
42import org.eclipse.xtext.scoping.impl.AbstractDeclarativeScopeProvider; 25import org.eclipse.xtext.scoping.impl.AbstractDeclarativeScopeProvider;
43 26
@@ -50,32 +33,25 @@ import com.google.inject.name.Named;
50public class ProblemDerivedStateComputer implements IDerivedStateComputer { 33public class ProblemDerivedStateComputer implements IDerivedStateComputer {
51 public static final String NEW_NODE = "new"; 34 public static final String NEW_NODE = "new";
52 35
53 private static final Pattern ID_REGEX = Pattern.compile("[_a-zA-Z][_0-9a-zA-Z]*");
54
55 private static final Pattern QUOTED_ID_REGEX = Pattern.compile("'(\\\\.|[^\\'])*'");
56
57 @Inject 36 @Inject
58 @Named(Constants.LANGUAGE_NAME) 37 @Named(Constants.LANGUAGE_NAME)
59 private String languageName; 38 private String languageName;
60 39
61 @Inject 40 @Inject
62 private LinkingHelper linkingHelper;
63
64 @Inject
65 private IQualifiedNameConverter qualifiedNameConverter;
66
67 @Inject
68 @Named(AbstractDeclarativeScopeProvider.NAMED_DELEGATE) 41 @Named(AbstractDeclarativeScopeProvider.NAMED_DELEGATE)
69 private IScopeProvider scopeProvider; 42 private IScopeProvider scopeProvider;
70 43
71 @Inject 44 @Inject
72 private Provider<NodeNameCollector> nodeNameCollectorProvider; 45 private Provider<NodeNameCollector> nodeNameCollectorProvider;
73 46
47 @Inject
48 private DerivedVariableComputer derivedVariableComputer;
49
74 @Override 50 @Override
75 public void installDerivedState(DerivedStateAwareResource resource, boolean preLinkingPhase) { 51 public void installDerivedState(DerivedStateAwareResource resource, boolean preLinkingPhase) {
76 Problem problem = getProblem(resource); 52 var problem = getProblem(resource);
77 if (problem != null) { 53 if (problem != null) {
78 Adapter adapter = getOrInstallAdapter(resource); 54 var adapter = getOrInstallAdapter(resource);
79 installDerivedProblemState(problem, adapter, preLinkingPhase); 55 installDerivedProblemState(problem, adapter, preLinkingPhase);
80 } 56 }
81 } 57 }
@@ -98,20 +74,15 @@ public class ProblemDerivedStateComputer implements IDerivedStateComputer {
98 return; 74 return;
99 } 75 }
100 Set<String> nodeNames = installDerivedNodes(problem); 76 Set<String> nodeNames = installDerivedNodes(problem);
101 for (Statement statement : problem.getStatements()) { 77 derivedVariableComputer.installDerivedVariables(problem, nodeNames);
102 if (statement instanceof PredicateDefinition) {
103 PredicateDefinition definition = (PredicateDefinition) statement;
104 installDerivedPredicateDefinitionState(definition, nodeNames);
105 }
106 }
107 } 78 }
108 79
109 protected void installNewNodes(Problem problem, Adapter adapter) { 80 protected void installNewNodes(Problem problem, Adapter adapter) {
110 for (Statement statement : problem.getStatements()) { 81 for (Statement statement : problem.getStatements()) {
111 if (statement instanceof ClassDeclaration) { 82 if (statement instanceof ClassDeclaration) {
112 ClassDeclaration declaration = (ClassDeclaration) statement; 83 var declaration = (ClassDeclaration) statement;
113 if (!declaration.isAbstract() && declaration.getNewNode() == null) { 84 if (!declaration.isAbstract() && declaration.getNewNode() == null) {
114 Node newNode = adapter.newNodes.computeIfAbsent(declaration, key -> createNode(NEW_NODE)); 85 var newNode = adapter.createNodeIfAbsent(declaration, key -> createNode(NEW_NODE));
115 declaration.setNewNode(newNode); 86 declaration.setNewNode(newNode);
116 } 87 }
117 } 88 }
@@ -119,123 +90,28 @@ public class ProblemDerivedStateComputer implements IDerivedStateComputer {
119 } 90 }
120 91
121 protected Set<String> installDerivedNodes(Problem problem) { 92 protected Set<String> installDerivedNodes(Problem problem) {
122 NodeNameCollector collector = nodeNameCollectorProvider.get(); 93 var collector = nodeNameCollectorProvider.get();
123 collector.collectNodeNames(problem); 94 collector.collectNodeNames(problem);
124 Set<String> nodeNames = collector.getNodeNames(); 95 Set<String> nodeNames = collector.getNodeNames();
125 List<Node> grapNodes = problem.getNodes(); 96 List<Node> grapNodes = problem.getNodes();
126 for (String nodeName : nodeNames) { 97 for (String nodeName : nodeNames) {
127 Node graphNode = createNode(nodeName); 98 var graphNode = createNode(nodeName);
128 grapNodes.add(graphNode); 99 grapNodes.add(graphNode);
129 } 100 }
130 return nodeNames; 101 return nodeNames;
131 } 102 }
132 103
133 protected Node createNode(String name) { 104 protected Node createNode(String name) {
134 Node node = ProblemFactory.eINSTANCE.createNode(); 105 var node = ProblemFactory.eINSTANCE.createNode();
135 node.setName(name); 106 node.setName(name);
136 return node; 107 return node;
137 } 108 }
138 109
139 protected void installDerivedPredicateDefinitionState(PredicateDefinition definition, Set<String> nodeNames) {
140 Set<String> knownVariables = new HashSet<>();
141 knownVariables.addAll(nodeNames);
142 for (Parameter parameter : definition.getParameters()) {
143 String name = parameter.getName();
144 if (name != null) {
145 knownVariables.add(name);
146 }
147 }
148 for (Conjunction body : definition.getBodies()) {
149 installDeriveConjunctionState(body, knownVariables);
150 }
151 }
152
153 protected void installDeriveConjunctionState(Conjunction conjunction, Set<String> knownVariables) {
154 Set<String> newVariables = new HashSet<>();
155 for (Literal literal : conjunction.getLiterals()) {
156 if (literal instanceof Atom) {
157 Atom atom = (Atom) literal;
158 createSigletonVariablesAndCollectVariables(atom, knownVariables, newVariables);
159 }
160 }
161 createVariables(conjunction, newVariables);
162 newVariables.addAll(knownVariables);
163 for (Literal literal : conjunction.getLiterals()) {
164 if (literal instanceof NegativeLiteral) {
165 NegativeLiteral negativeLiteral = (NegativeLiteral) literal;
166 installDeriveNegativeLiteralState(negativeLiteral, newVariables);
167 }
168 }
169 }
170
171 protected void installDeriveNegativeLiteralState(NegativeLiteral negativeLiteral, Set<String> knownVariables) {
172 Set<String> newVariables = new HashSet<>();
173 createSigletonVariablesAndCollectVariables(negativeLiteral.getAtom(), knownVariables, newVariables);
174 createVariables(negativeLiteral, newVariables);
175 }
176
177 protected void createSigletonVariablesAndCollectVariables(Atom atom, Set<String> knownVariables,
178 Set<String> newVariables) {
179 for (Argument argument : atom.getArguments()) {
180 if (argument instanceof VariableOrNodeArgument) {
181 VariableOrNodeArgument variableOrNodeArgument = (VariableOrNodeArgument) argument;
182 IScope scope = scopeProvider.getScope(variableOrNodeArgument,
183 ProblemPackage.Literals.VARIABLE_OR_NODE_ARGUMENT__VARIABLE_OR_NODE);
184 List<INode> nodes = NodeModelUtils.findNodesForFeature(variableOrNodeArgument,
185 ProblemPackage.Literals.VARIABLE_OR_NODE_ARGUMENT__VARIABLE_OR_NODE);
186 for (INode node : nodes) {
187 String variableName = linkingHelper.getCrossRefNodeAsString(node, true);
188 if (!validId(variableName)) {
189 continue;
190 }
191 QualifiedName qualifiedName = qualifiedNameConverter.toQualifiedName(variableName);
192 if (scope.getSingleElement(qualifiedName) != null) {
193 continue;
194 }
195 if (ProblemUtil.isSingletonVariableName(variableName)) {
196 createSingletonVariable(variableOrNodeArgument, variableName);
197 break;
198 }
199 if (!knownVariables.contains(variableName)) {
200 newVariables.add(variableName);
201 break;
202 }
203 }
204 }
205 }
206 }
207
208 protected void createVariables(ExistentialQuantifier quantifier, Set<String> newVariables) {
209 for (String variableName : newVariables) {
210 createVariable(quantifier, variableName);
211 }
212 }
213
214 protected void createVariable(ExistentialQuantifier quantifier, String variableName) {
215 if (validId(variableName)) {
216 ImplicitVariable variable = createNamedVariable(variableName);
217 quantifier.getImplicitVariables().add(variable);
218 }
219 }
220
221 protected void createSingletonVariable(VariableOrNodeArgument argument, String variableName) {
222 if (validId(variableName)) {
223 ImplicitVariable variable = createNamedVariable(variableName);
224 argument.setSingletonVariable(variable);
225 }
226 }
227
228 protected ImplicitVariable createNamedVariable(String variableName) {
229 ImplicitVariable variable = ProblemFactory.eINSTANCE.createImplicitVariable();
230 variable.setName(variableName);
231 return variable;
232 }
233
234 @Override 110 @Override
235 public void discardDerivedState(DerivedStateAwareResource resource) { 111 public void discardDerivedState(DerivedStateAwareResource resource) {
236 Problem problem = getProblem(resource); 112 var problem = getProblem(resource);
237 if (problem != null) { 113 if (problem != null) {
238 Adapter adapter = getOrInstallAdapter(resource); 114 var adapter = getOrInstallAdapter(resource);
239 discardDerivedProblemState(problem, adapter); 115 discardDerivedProblemState(problem, adapter);
240 } 116 }
241 } 117 }
@@ -245,52 +121,13 @@ public class ProblemDerivedStateComputer implements IDerivedStateComputer {
245 problem.getNodes().clear(); 121 problem.getNodes().clear();
246 for (Statement statement : problem.getStatements()) { 122 for (Statement statement : problem.getStatements()) {
247 if (statement instanceof ClassDeclaration) { 123 if (statement instanceof ClassDeclaration) {
248 ClassDeclaration classDeclaration = (ClassDeclaration) statement; 124 var classDeclaration = (ClassDeclaration) statement;
249 classDeclaration.setNewNode(null); 125 classDeclaration.setNewNode(null);
250 classDeclarations.add(classDeclaration); 126 classDeclarations.add(classDeclaration);
251 } 127 }
252 if (statement instanceof PredicateDefinition) {
253 PredicateDefinition definition = (PredicateDefinition) statement;
254 for (Conjunction body : definition.getBodies()) {
255 body.getImplicitVariables().clear();
256 for (Literal literal : body.getLiterals()) {
257 if (literal instanceof Atom) {
258 discardDerivedAtomState((Atom) literal);
259 }
260 if (literal instanceof NegativeLiteral) {
261 NegativeLiteral negativeLiteral = (NegativeLiteral) literal;
262 negativeLiteral.getImplicitVariables().clear();
263 discardDerivedAtomState(negativeLiteral.getAtom());
264 }
265 }
266 }
267 }
268 } 128 }
269 adapter.newNodes.keySet().retainAll(classDeclarations); 129 adapter.retainAll(classDeclarations);
270 } 130 derivedVariableComputer.discardDerivedVariables(problem);
271
272 protected void discardDerivedAtomState(Atom atom) {
273 if (atom == null) {
274 return;
275 }
276 for (Argument argument : atom.getArguments()) {
277 if (argument instanceof VariableOrNodeArgument) {
278 VariableOrNodeArgument variableOrNodeArgument = (VariableOrNodeArgument) argument;
279 variableOrNodeArgument.setSingletonVariable(null);
280 }
281 }
282 }
283
284 protected static boolean validId(String name) {
285 return name != null && ID_REGEX.matcher(name).matches();
286 }
287
288 protected static boolean validQuotedId(String name) {
289 return name != null && QUOTED_ID_REGEX.matcher(name).matches();
290 }
291
292 protected static boolean validNodeName(String name) {
293 return validId(name) || validQuotedId(name);
294 } 131 }
295 132
296 protected Adapter getOrInstallAdapter(Resource resource) { 133 protected Adapter getOrInstallAdapter(Resource resource) {
@@ -301,7 +138,7 @@ public class ProblemDerivedStateComputer implements IDerivedStateComputer {
301 if (!languageName.equals(resourceLanguageName)) { 138 if (!languageName.equals(resourceLanguageName)) {
302 return new Adapter(); 139 return new Adapter();
303 } 140 }
304 Adapter adapter = (Adapter) EcoreUtil.getAdapter(resource.eAdapters(), Adapter.class); 141 var adapter = (Adapter) EcoreUtil.getAdapter(resource.eAdapters(), Adapter.class);
305 if (adapter == null) { 142 if (adapter == null) {
306 adapter = new Adapter(); 143 adapter = new Adapter();
307 resource.eAdapters().add(adapter); 144 resource.eAdapters().add(adapter);
@@ -310,7 +147,15 @@ public class ProblemDerivedStateComputer implements IDerivedStateComputer {
310 } 147 }
311 148
312 protected static class Adapter extends AdapterImpl { 149 protected static class Adapter extends AdapterImpl {
313 public Map<ClassDeclaration, Node> newNodes = new HashMap<>(); 150 private Map<ClassDeclaration, Node> newNodes = new HashMap<>();
151
152 public Node createNodeIfAbsent(ClassDeclaration classDeclaration, Function<ClassDeclaration, Node> createNode) {
153 return newNodes.computeIfAbsent(classDeclaration, createNode);
154 }
155
156 public void retainAll(Collection<ClassDeclaration> classDeclarations) {
157 newNodes.keySet().retainAll(classDeclarations);
158 }
314 159
315 @Override 160 @Override
316 public boolean isAdapterForType(Object type) { 161 public boolean isAdapterForType(Object type) {
diff --git a/language/src/main/java/org/eclipse/viatra/solver/language/resource/ProblemResourceDescriptionStrategy.java b/language/src/main/java/org/eclipse/viatra/solver/language/resource/ProblemResourceDescriptionStrategy.java
index 686e54df..da737e3d 100644
--- a/language/src/main/java/org/eclipse/viatra/solver/language/resource/ProblemResourceDescriptionStrategy.java
+++ b/language/src/main/java/org/eclipse/viatra/solver/language/resource/ProblemResourceDescriptionStrategy.java
@@ -6,6 +6,7 @@ import org.eclipse.viatra.solver.language.model.problem.NamedElement;
6import org.eclipse.viatra.solver.language.model.problem.Node; 6import org.eclipse.viatra.solver.language.model.problem.Node;
7import org.eclipse.viatra.solver.language.model.problem.Problem; 7import org.eclipse.viatra.solver.language.model.problem.Problem;
8import org.eclipse.viatra.solver.language.model.problem.Variable; 8import org.eclipse.viatra.solver.language.model.problem.Variable;
9import org.eclipse.viatra.solver.language.naming.NamingUtil;
9import org.eclipse.xtext.EcoreUtil2; 10import org.eclipse.xtext.EcoreUtil2;
10import org.eclipse.xtext.naming.IQualifiedNameConverter; 11import org.eclipse.xtext.naming.IQualifiedNameConverter;
11import org.eclipse.xtext.naming.QualifiedName; 12import org.eclipse.xtext.naming.QualifiedName;
@@ -27,61 +28,59 @@ public class ProblemResourceDescriptionStrategy extends DefaultResourceDescripti
27 if (!shouldExport(eObject)) { 28 if (!shouldExport(eObject)) {
28 return false; 29 return false;
29 } 30 }
30 if (!(eObject instanceof NamedElement)) { 31 var qualifiedName = getNameAsQualifiedName(eObject);
31 return true; 32 if (qualifiedName == null) {
32 }
33 NamedElement namedElement = (NamedElement) eObject;
34 String name = namedElement.getName();
35 if (name == null || name.isEmpty()) {
36 return true; 33 return true;
37 } 34 }
38 Problem problem = EcoreUtil2.getContainerOfType(namedElement, Problem.class); 35 var problem = EcoreUtil2.getContainerOfType(eObject, Problem.class);
39 QualifiedName problemQualifiedName = null; 36 var problemQualifiedName = getNameAsQualifiedName(problem);
40 if (problem != null) {
41 String problemName = problem.getName();
42 if (problemName != null && !problemName.isEmpty()) {
43 problemQualifiedName = qualifiedNameConverter.toQualifiedName(problemName);
44 }
45 }
46 QualifiedName qualifiedName = qualifiedNameConverter.toQualifiedName(namedElement.getName());
47 boolean nameExported; 37 boolean nameExported;
48 if (shouldExportSimpleName(namedElement)) { 38 if (shouldExportSimpleName(eObject)) {
49 acceptEObjectDescription(namedElement, problemQualifiedName, qualifiedName, acceptor); 39 acceptEObjectDescription(eObject, problemQualifiedName, qualifiedName, acceptor);
50 nameExported = true; 40 nameExported = true;
51 } else { 41 } else {
52 nameExported = false; 42 nameExported = false;
53 } 43 }
54 EObject parent = namedElement.eContainer(); 44 var parent = eObject.eContainer();
55 while (parent != null && parent != problem) { 45 while (parent != null && parent != problem) {
56 if (parent instanceof NamedElement) { 46 var parentQualifiedName = getNameAsQualifiedName(parent);
57 NamedElement namedParent = (NamedElement) parent; 47 if (parentQualifiedName == null) {
58 String parentName = namedParent.getName(); 48 continue;
59 if (parentName != null || !name.isEmpty()) { 49 }
60 QualifiedName parentQualifiedName = qualifiedNameConverter.toQualifiedName(parentName); 50 qualifiedName = parentQualifiedName.append(qualifiedName);
61 qualifiedName = parentQualifiedName.append(qualifiedName); 51 if (shouldExportSimpleName(parent)) {
62 if (shouldExportSimpleName(namedParent)) { 52 acceptEObjectDescription(eObject, problemQualifiedName, qualifiedName, acceptor);
63 acceptEObjectDescription(namedElement, problemQualifiedName, qualifiedName, acceptor); 53 nameExported = true;
64 nameExported = true; 54 } else {
65 } else { 55 nameExported = false;
66 nameExported = false;
67 }
68 }
69 } 56 }
70 parent = parent.eContainer(); 57 parent = parent.eContainer();
71 } 58 }
72 if (!nameExported) { 59 if (!nameExported) {
73 acceptEObjectDescription(namedElement, problemQualifiedName, qualifiedName, acceptor); 60 acceptEObjectDescription(eObject, problemQualifiedName, qualifiedName, acceptor);
74 } 61 }
75 return true; 62 return true;
76 } 63 }
77 64
65 protected QualifiedName getNameAsQualifiedName(EObject eObject) {
66 if (!(eObject instanceof NamedElement)) {
67 return null;
68 }
69 var namedElement = (NamedElement) eObject;
70 var name = namedElement.getName();
71 if (NamingUtil.isNullOrEmpty(name)) {
72 return null;
73 }
74 return qualifiedNameConverter.toQualifiedName(name);
75 }
76
78 protected boolean shouldExport(EObject eObject) { 77 protected boolean shouldExport(EObject eObject) {
79 if (eObject instanceof Variable) { 78 if (eObject instanceof Variable) {
80 // Variables are always private to the containing predicate definition. 79 // Variables are always private to the containing predicate definition.
81 return false; 80 return false;
82 } 81 }
83 if (eObject instanceof Node) { 82 if (eObject instanceof Node) {
84 Node node = (Node) eObject; 83 var node = (Node) eObject;
85 // Only enum literals and new nodes are visible across problem files. 84 // Only enum literals and new nodes are visible across problem files.
86 return ProblemUtil.isEnumLiteral(node) || ProblemUtil.isNewNode(node); 85 return ProblemUtil.isEnumLiteral(node) || ProblemUtil.isNewNode(node);
87 } 86 }
@@ -97,7 +96,7 @@ public class ProblemResourceDescriptionStrategy extends DefaultResourceDescripti
97 96
98 private void acceptEObjectDescription(EObject eObject, QualifiedName prefix, QualifiedName qualifiedName, 97 private void acceptEObjectDescription(EObject eObject, QualifiedName prefix, QualifiedName qualifiedName,
99 IAcceptor<IEObjectDescription> acceptor) { 98 IAcceptor<IEObjectDescription> acceptor) {
100 QualifiedName qualifiedNameWithPrefix = prefix == null ? qualifiedName : prefix.append(qualifiedName); 99 var qualifiedNameWithPrefix = prefix == null ? qualifiedName : prefix.append(qualifiedName);
101 acceptor.accept(EObjectDescription.create(qualifiedNameWithPrefix, eObject)); 100 acceptor.accept(EObjectDescription.create(qualifiedNameWithPrefix, eObject));
102 } 101 }
103} 102}
diff --git a/language/src/main/java/org/eclipse/viatra/solver/language/scoping/ProblemScopeProvider.java b/language/src/main/java/org/eclipse/viatra/solver/language/scoping/ProblemScopeProvider.java
index 597085a8..33f8c50f 100644
--- a/language/src/main/java/org/eclipse/viatra/solver/language/scoping/ProblemScopeProvider.java
+++ b/language/src/main/java/org/eclipse/viatra/solver/language/scoping/ProblemScopeProvider.java
@@ -4,7 +4,6 @@
4package org.eclipse.viatra.solver.language.scoping; 4package org.eclipse.viatra.solver.language.scoping;
5 5
6import java.util.ArrayList; 6import java.util.ArrayList;
7import java.util.Collection;
8import java.util.List; 7import java.util.List;
9 8
10import org.eclipse.emf.ecore.EObject; 9import org.eclipse.emf.ecore.EObject;
@@ -16,7 +15,6 @@ import org.eclipse.viatra.solver.language.model.problem.PredicateDefinition;
16import org.eclipse.viatra.solver.language.model.problem.Problem; 15import org.eclipse.viatra.solver.language.model.problem.Problem;
17import org.eclipse.viatra.solver.language.model.problem.ProblemPackage; 16import org.eclipse.viatra.solver.language.model.problem.ProblemPackage;
18import org.eclipse.viatra.solver.language.model.problem.ReferenceDeclaration; 17import org.eclipse.viatra.solver.language.model.problem.ReferenceDeclaration;
19import org.eclipse.viatra.solver.language.model.problem.Relation;
20import org.eclipse.viatra.solver.language.model.problem.Variable; 18import org.eclipse.viatra.solver.language.model.problem.Variable;
21import org.eclipse.viatra.solver.language.model.problem.VariableOrNodeArgument; 19import org.eclipse.viatra.solver.language.model.problem.VariableOrNodeArgument;
22import org.eclipse.xtext.EcoreUtil2; 20import org.eclipse.xtext.EcoreUtil2;
@@ -34,7 +32,7 @@ public class ProblemScopeProvider extends AbstractProblemScopeProvider {
34 32
35 @Override 33 @Override
36 public IScope getScope(EObject context, EReference reference) { 34 public IScope getScope(EObject context, EReference reference) {
37 IScope scope = super.getScope(context, reference); 35 var scope = super.getScope(context, reference);
38 if (reference == ProblemPackage.Literals.NODE_ASSERTION_ARGUMENT__NODE 36 if (reference == ProblemPackage.Literals.NODE_ASSERTION_ARGUMENT__NODE
39 || reference == ProblemPackage.Literals.NODE_VALUE_ASSERTION__NODE) { 37 || reference == ProblemPackage.Literals.NODE_VALUE_ASSERTION__NODE) {
40 return getNodesScope(context, scope); 38 return getNodesScope(context, scope);
@@ -49,7 +47,7 @@ public class ProblemScopeProvider extends AbstractProblemScopeProvider {
49 } 47 }
50 48
51 protected IScope getNodesScope(EObject context, IScope delegateScope) { 49 protected IScope getNodesScope(EObject context, IScope delegateScope) {
52 Problem problem = EcoreUtil2.getContainerOfType(context, Problem.class); 50 var problem = EcoreUtil2.getContainerOfType(context, Problem.class);
53 if (problem == null) { 51 if (problem == null) {
54 return delegateScope; 52 return delegateScope;
55 } 53 }
@@ -73,7 +71,7 @@ public class ProblemScopeProvider extends AbstractProblemScopeProvider {
73 } 71 }
74 currentContext = currentContext.eContainer(); 72 currentContext = currentContext.eContainer();
75 } 73 }
76 if (currentContext instanceof PredicateDefinition) { 74 if (currentContext != null) {
77 PredicateDefinition definition = (PredicateDefinition) currentContext; 75 PredicateDefinition definition = (PredicateDefinition) currentContext;
78 variables.addAll(definition.getParameters()); 76 variables.addAll(definition.getParameters());
79 } 77 }
@@ -81,17 +79,16 @@ public class ProblemScopeProvider extends AbstractProblemScopeProvider {
81 } 79 }
82 80
83 protected IScope getOppositeScope(EObject context, IScope delegateScope) { 81 protected IScope getOppositeScope(EObject context, IScope delegateScope) {
84 ReferenceDeclaration referenceDeclaration = EcoreUtil2.getContainerOfType(context, ReferenceDeclaration.class); 82 var referenceDeclaration = EcoreUtil2.getContainerOfType(context, ReferenceDeclaration.class);
85 if (referenceDeclaration == null) { 83 if (referenceDeclaration == null) {
86 return delegateScope; 84 return delegateScope;
87 } 85 }
88 Relation relation = referenceDeclaration.getReferenceType(); 86 var relation = referenceDeclaration.getReferenceType();
89 if (!(relation instanceof ClassDeclaration)) { 87 if (!(relation instanceof ClassDeclaration)) {
90 return delegateScope; 88 return delegateScope;
91 } 89 }
92 ClassDeclaration classDeclaration = (ClassDeclaration) relation; 90 var classDeclaration = (ClassDeclaration) relation;
93 Collection<ReferenceDeclaration> referenceDeclarations = ProblemUtil 91 var referenceDeclarations = ProblemUtil.getAllReferenceDeclarations(classDeclaration);
94 .getAllReferenceDeclarations(classDeclaration);
95 return Scopes.scopeFor(referenceDeclarations, delegateScope); 92 return Scopes.scopeFor(referenceDeclarations, delegateScope);
96 } 93 }
97} 94}
diff --git a/language/src/main/java/org/eclipse/viatra/solver/language/validation/ProblemValidator.java b/language/src/main/java/org/eclipse/viatra/solver/language/validation/ProblemValidator.java
index 2b17e222..96b656a3 100644
--- a/language/src/main/java/org/eclipse/viatra/solver/language/validation/ProblemValidator.java
+++ b/language/src/main/java/org/eclipse/viatra/solver/language/validation/ProblemValidator.java
@@ -3,23 +3,11 @@
3 */ 3 */
4package org.eclipse.viatra.solver.language.validation; 4package org.eclipse.viatra.solver.language.validation;
5 5
6
7/** 6/**
8 * This class contains custom validation rules. 7 * This class contains custom validation rules.
9 * 8 *
10 * See https://www.eclipse.org/Xtext/documentation/303_runtime_concepts.html#validation 9 * See
10 * https://www.eclipse.org/Xtext/documentation/303_runtime_concepts.html#validation
11 */ 11 */
12public class ProblemValidator extends AbstractProblemValidator { 12public class ProblemValidator extends AbstractProblemValidator {
13
14// public static final String INVALID_NAME = "invalidName";
15//
16// @Check
17// public void checkGreetingStartsWithCapital(Greeting greeting) {
18// if (!Character.isUpperCase(greeting.getName().charAt(0))) {
19// warning("Name should start with a capital",
20// ProblemPackage.Literals.GREETING__NAME,
21// INVALID_NAME);
22// }
23// }
24
25} 13}