From 1d43c802f853b08f03c4b3954af242ad005c8afd Mon Sep 17 00:00:00 2001 From: Kristóf Marussy Date: Fri, 29 Jul 2022 21:58:47 +0200 Subject: refactor: simplify language project * Move all utilities for language-model to language, since they do not make sense on their own * Convert xtend code into java --- .../ProblemCrossrefProposalProvider.java | 2 +- .../ProblemSemanticHighlightingCalculator.java | 2 +- subprojects/language-model/build.gradle | 1 - .../refinery/language/model/ProblemEMFSetup.java | 34 --- .../src/main/resources/model/builtin.problem_xmi | 67 ----- .../language/model/tests/ProblemTestUtil.java | 197 ------------- subprojects/language-to-store/build.gradle | 2 +- .../language/mapping/PartialModelMapper.java | 2 +- subprojects/language-web/build.gradle | 1 - subprojects/language/build.gradle | 7 +- .../refinery/language/ProblemStandaloneSetup.java | 30 +- .../java/tools/refinery/language/ProblemUtil.java | 11 +- .../refinery/language/ProblemXmiRuntimeModule.java | 35 --- .../resource/ProblemLocationInFileProvider.java | 2 +- .../ProblemResourceDescriptionStrategy.java | 2 +- .../scoping/ProblemGlobalScopeProvider.java | 2 +- .../scoping/ProblemLocalScopeProvider.java | 2 +- .../language/scoping/ProblemScopeProvider.java | 4 +- .../language/validation/ProblemValidator.java | 2 +- .../tools/refinery/language/builtin.problem | 21 ++ .../language/tests/ProblemParsingTest.java | 58 ++++ .../language/tests/ProblemParsingTest_.xtend | 64 ---- .../tests/formatting2/ProblemFormatterTest.java | 2 +- .../tests/rules/DirectRuleParsingTest.java | 84 ++++++ .../tests/rules/DirectRuleParsingTest_.xtend | 96 ------ .../language/tests/scoping/NodeScopingTest.java | 321 ++++++++++++++++++++ .../language/tests/scoping/NodeScopingTest_.xtend | 322 --------------------- .../tests/serializer/ProblemSerializerTest.java | 31 +- .../model/tests/utils/ProblemNavigationUtil.java | 20 ++ .../model/tests/utils/ProblemParseHelper.java | 22 ++ .../model/tests/utils/WrappedActionLiteral.java | 25 ++ .../model/tests/utils/WrappedArgument.java | 25 ++ .../model/tests/utils/WrappedAssertion.java | 13 + .../tests/utils/WrappedAssertionArgument.java | 15 + .../language/model/tests/utils/WrappedAtom.java | 13 + .../model/tests/utils/WrappedClassDeclaration.java | 14 + .../model/tests/utils/WrappedConjunction.java | 13 + .../model/tests/utils/WrappedEnumDeclaration.java | 14 + .../language/model/tests/utils/WrappedLiteral.java | 24 ++ .../tests/utils/WrappedParametricDefinition.java | 16 + .../tests/utils/WrappedPredicateDefinition.java | 11 + .../language/model/tests/utils/WrappedProblem.java | 85 ++++++ .../model/tests/utils/WrappedRuleDefinition.java | 14 + 43 files changed, 853 insertions(+), 875 deletions(-) delete mode 100644 subprojects/language-model/src/main/java/tools/refinery/language/model/ProblemEMFSetup.java delete mode 100644 subprojects/language-model/src/main/resources/model/builtin.problem_xmi delete mode 100644 subprojects/language-model/src/testFixtures/java/tools/refinery/language/model/tests/ProblemTestUtil.java delete mode 100644 subprojects/language/src/main/java/tools/refinery/language/ProblemXmiRuntimeModule.java create mode 100644 subprojects/language/src/main/resources/tools/refinery/language/builtin.problem create mode 100644 subprojects/language/src/test/java/tools/refinery/language/tests/ProblemParsingTest.java delete mode 100644 subprojects/language/src/test/java/tools/refinery/language/tests/ProblemParsingTest_.xtend create mode 100644 subprojects/language/src/test/java/tools/refinery/language/tests/rules/DirectRuleParsingTest.java delete mode 100644 subprojects/language/src/test/java/tools/refinery/language/tests/rules/DirectRuleParsingTest_.xtend create mode 100644 subprojects/language/src/test/java/tools/refinery/language/tests/scoping/NodeScopingTest.java delete mode 100644 subprojects/language/src/test/java/tools/refinery/language/tests/scoping/NodeScopingTest_.xtend create mode 100644 subprojects/language/src/testFixtures/java/tools/refinery/language/model/tests/utils/ProblemNavigationUtil.java create mode 100644 subprojects/language/src/testFixtures/java/tools/refinery/language/model/tests/utils/ProblemParseHelper.java create mode 100644 subprojects/language/src/testFixtures/java/tools/refinery/language/model/tests/utils/WrappedActionLiteral.java create mode 100644 subprojects/language/src/testFixtures/java/tools/refinery/language/model/tests/utils/WrappedArgument.java create mode 100644 subprojects/language/src/testFixtures/java/tools/refinery/language/model/tests/utils/WrappedAssertion.java create mode 100644 subprojects/language/src/testFixtures/java/tools/refinery/language/model/tests/utils/WrappedAssertionArgument.java create mode 100644 subprojects/language/src/testFixtures/java/tools/refinery/language/model/tests/utils/WrappedAtom.java create mode 100644 subprojects/language/src/testFixtures/java/tools/refinery/language/model/tests/utils/WrappedClassDeclaration.java create mode 100644 subprojects/language/src/testFixtures/java/tools/refinery/language/model/tests/utils/WrappedConjunction.java create mode 100644 subprojects/language/src/testFixtures/java/tools/refinery/language/model/tests/utils/WrappedEnumDeclaration.java create mode 100644 subprojects/language/src/testFixtures/java/tools/refinery/language/model/tests/utils/WrappedLiteral.java create mode 100644 subprojects/language/src/testFixtures/java/tools/refinery/language/model/tests/utils/WrappedParametricDefinition.java create mode 100644 subprojects/language/src/testFixtures/java/tools/refinery/language/model/tests/utils/WrappedPredicateDefinition.java create mode 100644 subprojects/language/src/testFixtures/java/tools/refinery/language/model/tests/utils/WrappedProblem.java create mode 100644 subprojects/language/src/testFixtures/java/tools/refinery/language/model/tests/utils/WrappedRuleDefinition.java (limited to 'subprojects') diff --git a/subprojects/language-ide/src/main/java/tools/refinery/language/ide/contentassist/ProblemCrossrefProposalProvider.java b/subprojects/language-ide/src/main/java/tools/refinery/language/ide/contentassist/ProblemCrossrefProposalProvider.java index f828e836..3650561a 100644 --- a/subprojects/language-ide/src/main/java/tools/refinery/language/ide/contentassist/ProblemCrossrefProposalProvider.java +++ b/subprojects/language-ide/src/main/java/tools/refinery/language/ide/contentassist/ProblemCrossrefProposalProvider.java @@ -14,7 +14,7 @@ import org.eclipse.xtext.resource.IEObjectDescription; import com.google.inject.Inject; -import tools.refinery.language.model.ProblemUtil; +import tools.refinery.language.ProblemUtil; import tools.refinery.language.model.problem.Problem; import tools.refinery.language.resource.ReferenceCounter; diff --git a/subprojects/language-ide/src/main/java/tools/refinery/language/ide/syntaxcoloring/ProblemSemanticHighlightingCalculator.java b/subprojects/language-ide/src/main/java/tools/refinery/language/ide/syntaxcoloring/ProblemSemanticHighlightingCalculator.java index 01ac33f7..9c061c8f 100644 --- a/subprojects/language-ide/src/main/java/tools/refinery/language/ide/syntaxcoloring/ProblemSemanticHighlightingCalculator.java +++ b/subprojects/language-ide/src/main/java/tools/refinery/language/ide/syntaxcoloring/ProblemSemanticHighlightingCalculator.java @@ -15,7 +15,7 @@ import org.eclipse.xtext.util.CancelIndicator; import com.google.common.collect.ImmutableList; import com.google.inject.Inject; -import tools.refinery.language.model.ProblemUtil; +import tools.refinery.language.ProblemUtil; import tools.refinery.language.model.problem.ClassDeclaration; import tools.refinery.language.model.problem.NamedElement; import tools.refinery.language.model.problem.Node; diff --git a/subprojects/language-model/build.gradle b/subprojects/language-model/build.gradle index 67883a3d..275db188 100644 --- a/subprojects/language-model/build.gradle +++ b/subprojects/language-model/build.gradle @@ -1,6 +1,5 @@ plugins { id 'refinery-java-library' - id 'refinery-java-test-fixtures' id 'refinery-mwe2' id 'refinery-sonarqube' } diff --git a/subprojects/language-model/src/main/java/tools/refinery/language/model/ProblemEMFSetup.java b/subprojects/language-model/src/main/java/tools/refinery/language/model/ProblemEMFSetup.java deleted file mode 100644 index 9383098b..00000000 --- a/subprojects/language-model/src/main/java/tools/refinery/language/model/ProblemEMFSetup.java +++ /dev/null @@ -1,34 +0,0 @@ -package tools.refinery.language.model; - -import org.eclipse.emf.ecore.EPackage; -import org.eclipse.emf.ecore.resource.Resource; - -import tools.refinery.language.model.problem.ProblemPackage; -import tools.refinery.language.model.problem.impl.ProblemFactoryImpl; - -public class ProblemEMFSetup { - public static final String XMI_RESOURCE_EXTENSION = "problem_xmi"; - - private ProblemEMFSetup() { - throw new IllegalStateException("This is a static utility class and should not be instantiated directly"); - } - - // Here we can't rely on java.util.HashMap#putIfAbsent, because - // org.eclipse.emf.ecore.impl.EPackageRegistryImpl#containsKey is overridden - // without also overriding putIfAbsent. We must make sure to call the - // overridden containsKey implementation. - @SuppressWarnings("squid:S3824") - public static void doEMFRegistration() { - if (!EPackage.Registry.INSTANCE.containsKey(ProblemPackage.eNS_URI)) { - EPackage.Registry.INSTANCE.put(ProblemPackage.eNS_URI, ProblemPackage.eINSTANCE); - } - - // This Resource.Factory is not actually used once - // tools.refinery.language.ProblemStandaloneSetup.createInjectorAndDoEMFRegistration() - // is called, because if will be replaced by - // tools.refinery.language.resource.ProblemXmiResourceFactory, which implements - // org.eclipse.xtext.resource.IResourceFactory as required by Xtext. - Resource.Factory.Registry.INSTANCE.getExtensionToFactoryMap().putIfAbsent(XMI_RESOURCE_EXTENSION, - new ProblemFactoryImpl()); - } -} diff --git a/subprojects/language-model/src/main/resources/model/builtin.problem_xmi b/subprojects/language-model/src/main/resources/model/builtin.problem_xmi deleted file mode 100644 index 9255ab66..00000000 --- a/subprojects/language-model/src/main/resources/model/builtin.problem_xmi +++ /dev/null @@ -1,67 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/subprojects/language-model/src/testFixtures/java/tools/refinery/language/model/tests/ProblemTestUtil.java b/subprojects/language-model/src/testFixtures/java/tools/refinery/language/model/tests/ProblemTestUtil.java deleted file mode 100644 index d0990dc0..00000000 --- a/subprojects/language-model/src/testFixtures/java/tools/refinery/language/model/tests/ProblemTestUtil.java +++ /dev/null @@ -1,197 +0,0 @@ -package tools.refinery.language.model.tests; - -import java.util.List; -import java.util.stream.Stream; - -import org.eclipse.emf.ecore.resource.Resource.Diagnostic; -import org.eclipse.emf.ecore.util.EcoreUtil; - -import tools.refinery.language.model.ProblemUtil; -import tools.refinery.language.model.problem.ActionLiteral; -import tools.refinery.language.model.problem.Argument; -import tools.refinery.language.model.problem.Assertion; -import tools.refinery.language.model.problem.AssertionArgument; -import tools.refinery.language.model.problem.Atom; -import tools.refinery.language.model.problem.ClassDeclaration; -import tools.refinery.language.model.problem.Conjunction; -import tools.refinery.language.model.problem.DeleteActionLiteral; -import tools.refinery.language.model.problem.EnumDeclaration; -import tools.refinery.language.model.problem.IndividualDeclaration; -import tools.refinery.language.model.problem.Literal; -import tools.refinery.language.model.problem.NamedElement; -import tools.refinery.language.model.problem.NegativeLiteral; -import tools.refinery.language.model.problem.NewActionLiteral; -import tools.refinery.language.model.problem.Node; -import tools.refinery.language.model.problem.NodeAssertionArgument; -import tools.refinery.language.model.problem.NodeValueAssertion; -import tools.refinery.language.model.problem.Parameter; -import tools.refinery.language.model.problem.ParametricDefinition; -import tools.refinery.language.model.problem.PredicateDefinition; -import tools.refinery.language.model.problem.Problem; -import tools.refinery.language.model.problem.ReferenceDeclaration; -import tools.refinery.language.model.problem.Relation; -import tools.refinery.language.model.problem.RuleDefinition; -import tools.refinery.language.model.problem.Statement; -import tools.refinery.language.model.problem.ValueActionLiteral; -import tools.refinery.language.model.problem.ValueLiteral; -import tools.refinery.language.model.problem.Variable; -import tools.refinery.language.model.problem.VariableOrNode; -import tools.refinery.language.model.problem.VariableOrNodeArgument; - -public class ProblemTestUtil { - public Problem builtin(Problem problem) { - return ProblemUtil.getBuiltInLibrary(problem).get(); - } - - public List errors(Problem problem) { - EcoreUtil.resolveAll(problem); - return problem.eResource().getErrors(); - } - - public List nodeNames(Problem problem) { - return problem.getNodes().stream().map(node -> node.getName()).toList(); - } - - public PredicateDefinition pred(Problem problem, String name) { - return namedStatementOfType(problem, PredicateDefinition.class, name); - } - - public RuleDefinition rule(Problem problem, String name) { - return namedStatementOfType(problem, RuleDefinition.class, name); - } - - public Parameter param(ParametricDefinition definition, int i) { - return definition.getParameters().get(i); - } - - public Conjunction conj(ParametricDefinition definition, int i) { - return definition.getBodies().get(i); - } - - public Literal lit(Conjunction conjunction, int i) { - return conjunction.getLiterals().get(i); - } - - public ActionLiteral actionLit(RuleDefinition rule, int i) { - return rule.getAction().getActionLiterals().get(i); - } - - public Atom valueAtom(Literal literal) { - return ((ValueLiteral) literal).getAtom(); - } - - public Atom negated(Literal literal) { - return ((NegativeLiteral) literal).getAtom(); - } - - public Relation relation(Literal literal) { - return ((Atom) literal).getRelation(); - } - - public Argument arg(Atom atom, int i) { - return atom.getArguments().get(i); - } - - public Argument arg(Literal literal, int i) { - return arg((Atom) literal, i); - } - - public VariableOrNode variableOrNode(Argument argument) { - return ((VariableOrNodeArgument) argument).getVariableOrNode(); - } - - public Variable variable(Argument argument) { - return (Variable) variableOrNode(argument); - } - - public Variable variable(ValueActionLiteral valueActionLiteral, int i) { - return variable(arg(valueActionLiteral.getAtom(), i)); - } - - public Variable variable(NewActionLiteral newActionLiteral) { - return newActionLiteral.getVariable(); - } - - public VariableOrNode deleteVar(ActionLiteral actionLiteral) { - return ((DeleteActionLiteral) actionLiteral).getVariableOrNode(); - } - - public VariableOrNode newVar(ActionLiteral actionLiteral) { - return ((NewActionLiteral) actionLiteral).getVariable(); - } - - public Atom valueAtom(ActionLiteral actionLiteral) { - return ((ValueActionLiteral) actionLiteral).getAtom(); - } - - public Variable variable(DeleteActionLiteral deleteActionLiteral) { - return (Variable) deleteActionLiteral.getVariableOrNode(); - } - - public Node node(Argument argument) { - return (Node) variableOrNode(argument); - } - - public Assertion assertion(Problem problem, int i) { - return nthStatementOfType(problem, Assertion.class, i); - } - - public AssertionArgument arg(Assertion assertion, int i) { - return assertion.getArguments().get(i); - } - - public Node node(AssertionArgument argument) { - return ((NodeAssertionArgument) argument).getNode(); - } - - public Node node(Problem problem, String name) { - return named(problem.getNodes(), name); - } - - public Node individualNode(Problem problem, String name) { - var uniqueNodes = statementsOfType(problem, IndividualDeclaration.class) - .flatMap(declaration -> declaration.getNodes().stream()); - return named(uniqueNodes, name); - } - - public NodeValueAssertion nodeValueAssertion(Problem problem, int i) { - return nthStatementOfType(problem, NodeValueAssertion.class, i); - } - - public ClassDeclaration findClass(Problem problem, String name) { - return namedStatementOfType(problem, ClassDeclaration.class, name); - } - - public ReferenceDeclaration reference(ClassDeclaration declaration, String name) { - return named(declaration.getReferenceDeclarations(), name); - } - - public EnumDeclaration findEnum(Problem problem, String name) { - return namedStatementOfType(problem, EnumDeclaration.class, name); - } - - public Node literal(EnumDeclaration declaration, String name) { - return named(declaration.getLiterals(), name); - } - - private T named(Stream stream, String name) { - return stream.filter(statement -> name.equals(statement.getName())).findAny().get(); - } - - private T named(List list, String name) { - return named(list.stream(), name); - } - - private Stream statementsOfType(Problem problem, Class type) { - return problem.getStatements().stream().filter(type::isInstance).map(type::cast); - } - - private T namedStatementOfType(Problem problem, Class type, - String name) { - return named(statementsOfType(problem, type), name); - } - - private T nthStatementOfType(Problem problem, Class type, int n) { - return statementsOfType(problem, type).skip(n).findFirst().get(); - } -} diff --git a/subprojects/language-to-store/build.gradle b/subprojects/language-to-store/build.gradle index f1c1564d..edaeb48e 100644 --- a/subprojects/language-to-store/build.gradle +++ b/subprojects/language-to-store/build.gradle @@ -4,7 +4,7 @@ plugins { } dependencies { - api project(':refinery-language-model') + api project(':refinery-language') api project(':refinery-store') testImplementation testFixtures(project(':refinery-language')) } diff --git a/subprojects/language-to-store/src/main/java/tools/refinery/language/mapping/PartialModelMapper.java b/subprojects/language-to-store/src/main/java/tools/refinery/language/mapping/PartialModelMapper.java index 8f90a743..1f972e0f 100644 --- a/subprojects/language-to-store/src/main/java/tools/refinery/language/mapping/PartialModelMapper.java +++ b/subprojects/language-to-store/src/main/java/tools/refinery/language/mapping/PartialModelMapper.java @@ -7,7 +7,7 @@ import java.util.Optional; import org.eclipse.emf.common.util.EList; -import tools.refinery.language.model.ProblemUtil; +import tools.refinery.language.ProblemUtil; import tools.refinery.language.model.problem.Assertion; import tools.refinery.language.model.problem.AssertionArgument; import tools.refinery.language.model.problem.ClassDeclaration; diff --git a/subprojects/language-web/build.gradle b/subprojects/language-web/build.gradle index a1d4753a..6cbacc7b 100644 --- a/subprojects/language-web/build.gradle +++ b/subprojects/language-web/build.gradle @@ -24,7 +24,6 @@ dependencies { implementation libs.slf4j.api implementation libs.slf4j.simple implementation libs.slf4j.log4j - implementation libs.xtend.lib implementation libs.xtext.web webapp project(path: ':refinery-frontend', configuration: 'productionAssets') testImplementation testFixtures(project(':refinery-language')) diff --git a/subprojects/language/build.gradle b/subprojects/language/build.gradle index 91b65c82..654558e3 100644 --- a/subprojects/language/build.gradle +++ b/subprojects/language/build.gradle @@ -3,7 +3,6 @@ plugins { id 'refinery-java-test-fixtures' id 'refinery-mwe2' id 'refinery-sonarqube' - id 'refinery-xtend' id 'refinery-xtext-conventions' } @@ -14,7 +13,6 @@ dependencies { api libs.xtext.xbase api project(':refinery-language-model') testFixturesApi libs.xtext.testing - testFixturesApi testFixtures(project(':refinery-language-model')) mwe2 libs.xtext.generator mwe2 libs.xtext.generator.antlr } @@ -50,7 +48,6 @@ for (taskName in [ 'compileJava', 'processResources', 'processTestFixturesResources', - 'generateXtext', 'generateEclipseSourceFolders' ]) { tasks.named(taskName) { @@ -70,3 +67,7 @@ sonarqube.properties { 'src/testFixtures/xtext-gen/**', ] } + +eclipse.project.natures += [ + 'org.eclipse.xtext.ui.shared.xtextNature' +] diff --git a/subprojects/language/src/main/java/tools/refinery/language/ProblemStandaloneSetup.java b/subprojects/language/src/main/java/tools/refinery/language/ProblemStandaloneSetup.java index d753a119..41c96114 100644 --- a/subprojects/language/src/main/java/tools/refinery/language/ProblemStandaloneSetup.java +++ b/subprojects/language/src/main/java/tools/refinery/language/ProblemStandaloneSetup.java @@ -3,14 +3,11 @@ */ package tools.refinery.language; -import org.eclipse.emf.ecore.resource.Resource; -import org.eclipse.xtext.resource.IResourceFactory; -import org.eclipse.xtext.resource.IResourceServiceProvider; +import org.eclipse.emf.ecore.EPackage; -import com.google.inject.Guice; import com.google.inject.Injector; -import tools.refinery.language.model.ProblemEMFSetup; +import tools.refinery.language.model.problem.ProblemPackage; /** * Initialization support for running Xtext languages without Equinox extension @@ -22,23 +19,16 @@ public class ProblemStandaloneSetup extends ProblemStandaloneSetupGenerated { new ProblemStandaloneSetup().createInjectorAndDoEMFRegistration(); } + // Here we can't rely on java.util.HashMap#putIfAbsent, because + // org.eclipse.emf.ecore.impl.EPackageRegistryImpl#containsKey is overridden + // without also overriding putIfAbsent. We must make sure to call the + // overridden containsKey implementation. + @SuppressWarnings("squid:S3824") @Override public Injector createInjectorAndDoEMFRegistration() { - ProblemEMFSetup.doEMFRegistration(); - var xmiInjector = createXmiInjector(); - registerXmiInjector(xmiInjector); + if (!EPackage.Registry.INSTANCE.containsKey(ProblemPackage.eNS_URI)) { + EPackage.Registry.INSTANCE.put(ProblemPackage.eNS_URI, ProblemPackage.eINSTANCE); + } return super.createInjectorAndDoEMFRegistration(); } - - protected Injector createXmiInjector() { - return Guice.createInjector(new ProblemXmiRuntimeModule()); - } - - protected void registerXmiInjector(Injector injector) { - IResourceFactory resourceFactory = injector.getInstance(IResourceFactory.class); - IResourceServiceProvider serviceProvider = injector.getInstance(IResourceServiceProvider.class); - - Resource.Factory.Registry.INSTANCE.getExtensionToFactoryMap().put(ProblemEMFSetup.XMI_RESOURCE_EXTENSION, resourceFactory); - IResourceServiceProvider.Registry.INSTANCE.getExtensionToFactoryMap().put(ProblemEMFSetup.XMI_RESOURCE_EXTENSION, serviceProvider); - } } diff --git a/subprojects/language/src/main/java/tools/refinery/language/ProblemUtil.java b/subprojects/language/src/main/java/tools/refinery/language/ProblemUtil.java index d8958381..b1e39176 100644 --- a/subprojects/language/src/main/java/tools/refinery/language/ProblemUtil.java +++ b/subprojects/language/src/main/java/tools/refinery/language/ProblemUtil.java @@ -1,4 +1,4 @@ -package tools.refinery.language.model; +package tools.refinery.language; import java.util.ArrayDeque; import java.util.Collection; @@ -34,15 +34,15 @@ public final class ProblemUtil { public static boolean isSingletonVariable(Variable variable) { return variable.eContainingFeature() == ProblemPackage.Literals.VARIABLE_OR_NODE_ARGUMENT__SINGLETON_VARIABLE; } - + public static boolean isImplicitVariable(Variable variable) { return variable instanceof ImplicitVariable; } - + public static boolean isImplicitNode(Node node) { return node.eContainingFeature() == ProblemPackage.Literals.PROBLEM__NODES; } - + public static boolean isImplicit(EObject eObject) { if (eObject instanceof Node node) { return isImplicitNode(node); @@ -115,7 +115,6 @@ public final class ProblemUtil { private static URI getLibraryUri(String libraryName) { return URI.createURI(ProblemUtil.class.getClassLoader() - .getResource("model/" + libraryName + "." + ProblemEMFSetup.XMI_RESOURCE_EXTENSION) - .toString()); + .getResource("tools/refinery/language/%s.problem".formatted(libraryName)).toString()); } } diff --git a/subprojects/language/src/main/java/tools/refinery/language/ProblemXmiRuntimeModule.java b/subprojects/language/src/main/java/tools/refinery/language/ProblemXmiRuntimeModule.java deleted file mode 100644 index 03a33bee..00000000 --- a/subprojects/language/src/main/java/tools/refinery/language/ProblemXmiRuntimeModule.java +++ /dev/null @@ -1,35 +0,0 @@ -package tools.refinery.language; - -import org.eclipse.xtext.naming.IQualifiedNameConverter; -import org.eclipse.xtext.resource.IDefaultResourceDescriptionStrategy; -import org.eclipse.xtext.resource.IResourceFactory; -import org.eclipse.xtext.resource.generic.AbstractGenericResourceRuntimeModule; - -import tools.refinery.language.model.ProblemEMFSetup; -import tools.refinery.language.naming.ProblemQualifiedNameConverter; -import tools.refinery.language.resource.ProblemResourceDescriptionStrategy; -import tools.refinery.language.resource.ProblemXmiResourceFactory; - -public class ProblemXmiRuntimeModule extends AbstractGenericResourceRuntimeModule { - @Override - protected String getLanguageName() { - return "tools.refinery.language.ProblemXmi"; - } - - @Override - protected String getFileExtensions() { - return ProblemEMFSetup.XMI_RESOURCE_EXTENSION; - } - - public Class bindIResourceFactory() { - return ProblemXmiResourceFactory.class; - } - - public Class bindIQualifiedNameConverter() { - return ProblemQualifiedNameConverter.class; - } - - public Class bindIDefaultResourceDescriptionStrategy() { - return ProblemResourceDescriptionStrategy.class; - } -} diff --git a/subprojects/language/src/main/java/tools/refinery/language/resource/ProblemLocationInFileProvider.java b/subprojects/language/src/main/java/tools/refinery/language/resource/ProblemLocationInFileProvider.java index 7aa75833..f6ae4f1e 100644 --- a/subprojects/language/src/main/java/tools/refinery/language/resource/ProblemLocationInFileProvider.java +++ b/subprojects/language/src/main/java/tools/refinery/language/resource/ProblemLocationInFileProvider.java @@ -4,7 +4,7 @@ import org.eclipse.emf.ecore.EObject; import org.eclipse.xtext.resource.DefaultLocationInFileProvider; import org.eclipse.xtext.util.ITextRegion; -import tools.refinery.language.model.ProblemUtil; +import tools.refinery.language.ProblemUtil; import tools.refinery.language.model.problem.ImplicitVariable; import tools.refinery.language.model.problem.Node; diff --git a/subprojects/language/src/main/java/tools/refinery/language/resource/ProblemResourceDescriptionStrategy.java b/subprojects/language/src/main/java/tools/refinery/language/resource/ProblemResourceDescriptionStrategy.java index f86ebd38..24d00f07 100644 --- a/subprojects/language/src/main/java/tools/refinery/language/resource/ProblemResourceDescriptionStrategy.java +++ b/subprojects/language/src/main/java/tools/refinery/language/resource/ProblemResourceDescriptionStrategy.java @@ -12,7 +12,7 @@ import org.eclipse.xtext.util.IAcceptor; import com.google.inject.Inject; import com.google.inject.Singleton; -import tools.refinery.language.model.ProblemUtil; +import tools.refinery.language.ProblemUtil; import tools.refinery.language.model.problem.NamedElement; import tools.refinery.language.model.problem.Node; import tools.refinery.language.model.problem.Problem; diff --git a/subprojects/language/src/main/java/tools/refinery/language/scoping/ProblemGlobalScopeProvider.java b/subprojects/language/src/main/java/tools/refinery/language/scoping/ProblemGlobalScopeProvider.java index b582d16b..ea4682f9 100644 --- a/subprojects/language/src/main/java/tools/refinery/language/scoping/ProblemGlobalScopeProvider.java +++ b/subprojects/language/src/main/java/tools/refinery/language/scoping/ProblemGlobalScopeProvider.java @@ -6,7 +6,7 @@ import org.eclipse.emf.common.util.URI; import org.eclipse.emf.ecore.resource.Resource; import org.eclipse.xtext.scoping.impl.ImportUriGlobalScopeProvider; -import tools.refinery.language.model.ProblemUtil; +import tools.refinery.language.ProblemUtil; public class ProblemGlobalScopeProvider extends ImportUriGlobalScopeProvider { @Override diff --git a/subprojects/language/src/main/java/tools/refinery/language/scoping/ProblemLocalScopeProvider.java b/subprojects/language/src/main/java/tools/refinery/language/scoping/ProblemLocalScopeProvider.java index 85797025..53815e37 100644 --- a/subprojects/language/src/main/java/tools/refinery/language/scoping/ProblemLocalScopeProvider.java +++ b/subprojects/language/src/main/java/tools/refinery/language/scoping/ProblemLocalScopeProvider.java @@ -13,7 +13,7 @@ import org.eclipse.xtext.scoping.impl.ImportedNamespaceAwareLocalScopeProvider; import com.google.inject.Inject; -import tools.refinery.language.model.ProblemUtil; +import tools.refinery.language.ProblemUtil; public class ProblemLocalScopeProvider extends ImportedNamespaceAwareLocalScopeProvider { private static final QualifiedName BUILTIN_LIBRARY_QUALIFIED_NAME = QualifiedName 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 d31a5308..7a3e77a4 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 @@ -12,12 +12,12 @@ import org.eclipse.xtext.EcoreUtil2; import org.eclipse.xtext.scoping.IScope; import org.eclipse.xtext.scoping.Scopes; -import tools.refinery.language.model.ProblemUtil; +import tools.refinery.language.ProblemUtil; +import tools.refinery.language.model.problem.Action; import tools.refinery.language.model.problem.ClassDeclaration; import tools.refinery.language.model.problem.ExistentialQuantifier; import tools.refinery.language.model.problem.NewActionLiteral; import tools.refinery.language.model.problem.ParametricDefinition; -import tools.refinery.language.model.problem.Action; import tools.refinery.language.model.problem.Problem; import tools.refinery.language.model.problem.ProblemPackage; import tools.refinery.language.model.problem.ReferenceDeclaration; diff --git a/subprojects/language/src/main/java/tools/refinery/language/validation/ProblemValidator.java b/subprojects/language/src/main/java/tools/refinery/language/validation/ProblemValidator.java index 975fdca2..6b0982eb 100644 --- a/subprojects/language/src/main/java/tools/refinery/language/validation/ProblemValidator.java +++ b/subprojects/language/src/main/java/tools/refinery/language/validation/ProblemValidator.java @@ -8,7 +8,7 @@ import org.eclipse.xtext.validation.Check; import com.google.inject.Inject; -import tools.refinery.language.model.ProblemUtil; +import tools.refinery.language.ProblemUtil; import tools.refinery.language.model.problem.Node; import tools.refinery.language.model.problem.Problem; import tools.refinery.language.model.problem.ProblemPackage; diff --git a/subprojects/language/src/main/resources/tools/refinery/language/builtin.problem b/subprojects/language/src/main/resources/tools/refinery/language/builtin.problem new file mode 100644 index 00000000..5e913b51 --- /dev/null +++ b/subprojects/language/src/main/resources/tools/refinery/language/builtin.problem @@ -0,0 +1,21 @@ +problem builtin. + +abstract class node { + refers node[] equals opposite equals. +} + +pred exists(node node). + +abstract class domain extends node. + +abstract class data extends node. + +enum bool { + true, false +} + +class real extends data. + +class int extends data. + +class string extends data. diff --git a/subprojects/language/src/test/java/tools/refinery/language/tests/ProblemParsingTest.java b/subprojects/language/src/test/java/tools/refinery/language/tests/ProblemParsingTest.java new file mode 100644 index 00000000..1e8682a3 --- /dev/null +++ b/subprojects/language/src/test/java/tools/refinery/language/tests/ProblemParsingTest.java @@ -0,0 +1,58 @@ +package tools.refinery.language.tests; + +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.empty; + +import org.eclipse.xtext.testing.InjectWith; +import org.eclipse.xtext.testing.extensions.InjectionExtension; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; + +import com.google.inject.Inject; + +import tools.refinery.language.model.tests.utils.ProblemParseHelper; + +@ExtendWith(InjectionExtension.class) +@InjectWith(ProblemInjectorProvider.class) +class ProblemParsingTest { + @Inject + private ProblemParseHelper parseHelper; + + @Test + void exampleTest() { + var problem = parseHelper.parse(""" + class Family { + contains Person[] members + } + + class Person { + Person[0..*] children opposite parent + Person[0..1] parent opposite children + int age + TaxStatus taxStatus + } + + enum TaxStatus { + child, student, adult, retired + } + + % A child cannot have any dependents. + error invalidTaxStatus(Person p) <-> + taxStatus(p, child), children(p, _q). + + indiv family. + Family(family). + members(family, anne): true. + members(family, bob). + members(family, ciri). + children(anne, ciri). + ?children(bob, ciri). + taxStatus(anne, adult). + age(anne, 35). + bobAge: 27. + age(bob, bobAge). + !age(ciri, bobAge). + """); + assertThat(problem.errors(), empty()); + } +} diff --git a/subprojects/language/src/test/java/tools/refinery/language/tests/ProblemParsingTest_.xtend b/subprojects/language/src/test/java/tools/refinery/language/tests/ProblemParsingTest_.xtend deleted file mode 100644 index 53d31a6c..00000000 --- a/subprojects/language/src/test/java/tools/refinery/language/tests/ProblemParsingTest_.xtend +++ /dev/null @@ -1,64 +0,0 @@ -/* - * generated by Xtext 2.26.0.M1 - */ -package tools.refinery.language.tests - -import com.google.inject.Inject -import org.eclipse.xtext.testing.InjectWith -import org.eclipse.xtext.testing.extensions.InjectionExtension -import org.eclipse.xtext.testing.util.ParseHelper -import org.junit.jupiter.api.Test -import org.junit.jupiter.api.^extension.ExtendWith -import tools.refinery.language.model.problem.Problem -import tools.refinery.language.model.tests.ProblemTestUtil - -import static org.hamcrest.MatcherAssert.assertThat -import static org.hamcrest.Matchers.* - -@ExtendWith(InjectionExtension) -@InjectWith(ProblemInjectorProvider) -class ProblemParsingTest { - @Inject - ParseHelper parseHelper - - @Inject - extension ProblemTestUtil - - @Test - def void exampleTest() { - val it = parseHelper.parse(''' - class Family { - contains Person[] members - } - - class Person { - Person[0..*] children opposite parent - Person[0..1] parent opposite children - int age - TaxStatus taxStatus - } - - enum TaxStatus { - child, student, adult, retired - } - - % A child cannot have any dependents. - error invalidTaxStatus(Person p) <-> - taxStatus(p, child), children(p, _q). - - indiv family. - Family(family). - members(family, anne): true. - members(family, bob). - members(family, ciri). - children(anne, ciri). - ?children(bob, ciri). - taxStatus(anne, adult). - age(anne, 35). - bobAge: 27. - age(bob, bobAge). - !age(ciri, bobAge). - ''') - assertThat(errors, empty) - } -} diff --git a/subprojects/language/src/test/java/tools/refinery/language/tests/formatting2/ProblemFormatterTest.java b/subprojects/language/src/test/java/tools/refinery/language/tests/formatting2/ProblemFormatterTest.java index 41ad2d31..083c5184 100644 --- a/subprojects/language/src/test/java/tools/refinery/language/tests/formatting2/ProblemFormatterTest.java +++ b/subprojects/language/src/test/java/tools/refinery/language/tests/formatting2/ProblemFormatterTest.java @@ -230,6 +230,6 @@ class ProblemFormatterTest { request.setTextRegionAccess(regionAccess); List replacements = formatter2.format(request); var formattedString = regionAccess.getRewriter().renderToString(replacements); - assertThat(formattedString, equalTo(expected)); + assertThat(formattedString.replace("\r\n", "\n"), equalTo(expected.replace("\r\n", "\n"))); } } diff --git a/subprojects/language/src/test/java/tools/refinery/language/tests/rules/DirectRuleParsingTest.java b/subprojects/language/src/test/java/tools/refinery/language/tests/rules/DirectRuleParsingTest.java new file mode 100644 index 00000000..d5ee722b --- /dev/null +++ b/subprojects/language/src/test/java/tools/refinery/language/tests/rules/DirectRuleParsingTest.java @@ -0,0 +1,84 @@ +package tools.refinery.language.tests.rules; + +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.empty; +import static org.hamcrest.Matchers.equalTo; +import static org.hamcrest.Matchers.not; + +import org.eclipse.xtext.testing.InjectWith; +import org.eclipse.xtext.testing.extensions.InjectionExtension; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.ValueSource; + +import com.google.inject.Inject; + +import tools.refinery.language.model.tests.utils.ProblemParseHelper; +import tools.refinery.language.tests.ProblemInjectorProvider; + +@ExtendWith(InjectionExtension.class) +@InjectWith(ProblemInjectorProvider.class) +class DirectRuleParsingTest { + @Inject + private ProblemParseHelper parseHelper; + + @ParameterizedTest + @ValueSource(strings = { """ + pred Person(p). + direct rule r(p1): Person(p1) = true ~> Person(p1) = false. + """, """ + pred Person(p). + direct rule r(p1): Person(p1) = true ~> Person(p1): false. + """, """ + pred Person(p). + direct rule r(p1): Person(p1): false ~> delete p1. + """ }) + void simpleTest(String text) { + var problem = parseHelper.parse(text); + assertThat(problem.errors(), empty()); + } + + @Test + void newNodeTest() { + var problem = parseHelper.parse(""" + pred Person(p). + direct rule r(p1): Person(p1) = true ~> new p2, Person(p2) = unknown. + """); + assertThat(problem.errors(), empty()); + assertThat(problem.rule("r").param(0), equalTo(problem.rule("r").conj(0).lit(0).valueAtom().arg(0).variable())); + assertThat(problem.rule("r").actionLit(0).newVar(), + equalTo(problem.rule("r").actionLit(1).valueAtom().arg(0).variable())); + } + + @Test + void differentScopeTest() { + var problem = parseHelper.parse(""" + pred Friend(a, b). + direct rule r(p1): Friend(p1, p2) = false ~> new p2, Friend(p1, p2) = true. + """); + assertThat(problem.errors(), empty()); + assertThat(problem.rule("r").conj(0).lit(0).valueAtom().arg(1).variable(), + not(equalTo(problem.rule("r").actionLit(1).valueAtom().arg(1).variable()))); + } + + @Test + void parameterShadowingTest() { + var problem = parseHelper.parse(""" + pred Friend(a, b). + direct rule r(p1, p2): Friend(p1, p2) = false ~> new p2, Friend(p1, p2) = true. + """); + assertThat(problem.errors(), empty()); + assertThat(problem.rule("r").param(1), + not(equalTo(problem.rule("r").actionLit(1).valueAtom().arg(1).variable()))); + } + + @Test + void deleteDifferentScopeNodeTest() { + var problem = parseHelper.parse(""" + pred Person(p). + direct rule r(p1): Friend(p1, p2) = true ~> delete p2. + """); + assertThat(problem.errors(), not(empty())); + } +} diff --git a/subprojects/language/src/test/java/tools/refinery/language/tests/rules/DirectRuleParsingTest_.xtend b/subprojects/language/src/test/java/tools/refinery/language/tests/rules/DirectRuleParsingTest_.xtend deleted file mode 100644 index d60651a0..00000000 --- a/subprojects/language/src/test/java/tools/refinery/language/tests/rules/DirectRuleParsingTest_.xtend +++ /dev/null @@ -1,96 +0,0 @@ -package tools.refinery.language.tests.rules - -import com.google.inject.Inject -import org.eclipse.xtext.testing.InjectWith -import org.eclipse.xtext.testing.extensions.InjectionExtension -import org.eclipse.xtext.testing.util.ParseHelper -import org.junit.jupiter.api.Test -import org.junit.jupiter.api.^extension.ExtendWith -import tools.refinery.language.model.problem.Problem -import tools.refinery.language.tests.ProblemInjectorProvider -import tools.refinery.language.model.tests.ProblemTestUtil - -import static org.hamcrest.MatcherAssert.assertThat -import static org.hamcrest.Matchers.* - -@ExtendWith(InjectionExtension) -@InjectWith(ProblemInjectorProvider) -class DirectRuleParsingTest { - @Inject - ParseHelper parseHelper - - @Inject - extension ProblemTestUtil - - @Test - def void relationValueRewriteTest() { - val it = parseHelper.parse(''' - pred Person(p). - direct rule r(p1): Person(p1) = true ~> Person(p1) = false. - ''') - assertThat(errors, empty) - } - - @Test - def void relationValueMergeTest() { - val it = parseHelper.parse(''' - pred Person(p). - direct rule r(p1): Person(p1): true ~> Person(p1): false. - ''') - assertThat(errors, empty) - } - - @Test - def void newNodeTest() { - val it = parseHelper.parse(''' - pred Person(p). - direct rule r(p1): Person(p1) = true ~> new p2, Person(p2) = unknown. - ''') - assertThat(errors, empty) - assertThat(rule("r").param(0), equalTo(rule("r").conj(0).lit(0).valueAtom.arg(0).variable)) - assertThat(rule("r").actionLit(0).newVar, - equalTo(rule("r").actionLit(1).valueAtom.arg(0).variable) - ) - } - - @Test - def void differentScopeTest() { - val it = parseHelper.parse(''' - pred Friend(a, b). - direct rule r(p1): Friend(p1, p2) = false ~> new p2, Friend(p1, p2) = true. - ''') - assertThat(errors, empty) - assertThat(rule("r").conj(0).lit(0).valueAtom.arg(1).variable, - not(equalTo(rule("r").actionLit(1).valueAtom.arg(1).variable))) - } - - @Test - def void parameterShadowingTest() { - val it = parseHelper.parse(''' - pred Friend(a, b). - direct rule r(p1, p2): Friend(p1, p2) = false ~> new p2, Friend(p1, p2) = true. - ''') - assertThat(errors, empty) - assertThat(rule("r").param(1), - not(equalTo(rule("r").actionLit(1).valueAtom.arg(1).variable))) - } - - @Test - def void deleteParameterNodeTest() { - val it = parseHelper.parse(''' - pred Person(p). - direct rule r(p1): Person(p1): false ~> delete p1. - ''') - assertThat(errors, empty) - } - - @Test - def void deleteDifferentScopeNodeTest() { - val it = parseHelper.parse(''' - pred Friend(p). - direct rule r(p1): Friend(p1, p2) = true ~> delete p2. - ''') - assertThat(errors, not(empty)) - } - -} diff --git a/subprojects/language/src/test/java/tools/refinery/language/tests/scoping/NodeScopingTest.java b/subprojects/language/src/test/java/tools/refinery/language/tests/scoping/NodeScopingTest.java new file mode 100644 index 00000000..5c905ede --- /dev/null +++ b/subprojects/language/src/test/java/tools/refinery/language/tests/scoping/NodeScopingTest.java @@ -0,0 +1,321 @@ +package tools.refinery.language.tests.scoping; + +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.empty; +import static org.hamcrest.Matchers.equalTo; +import static org.hamcrest.Matchers.hasItems; +import static org.hamcrest.Matchers.not; + +import java.util.stream.Stream; + +import org.eclipse.xtext.testing.InjectWith; +import org.eclipse.xtext.testing.extensions.InjectionExtension; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; +import org.junit.jupiter.params.provider.ValueSource; + +import com.google.inject.Inject; + +import tools.refinery.language.model.tests.utils.ProblemParseHelper; +import tools.refinery.language.model.tests.utils.WrappedProblem; +import tools.refinery.language.tests.ProblemInjectorProvider; + +@ExtendWith(InjectionExtension.class) +@InjectWith(ProblemInjectorProvider.class) +class NodeScopingTest { + @Inject + private ProblemParseHelper parseHelper; + + @ParameterizedTest + @ValueSource(strings = { "", "builtin::" }) + void builtInArgumentTypeTest(String qualifiedNamePrefix) { + var problem = parse(""" + pred predicate({PARAM}node a, {PARAM}data b, {PARAM}int c). + """, qualifiedNamePrefix); + assertThat(problem.errors(), empty()); + assertThat(problem.pred("predicate").param(0).getParameterType(), + equalTo(problem.builtin().findClass("node").get())); + assertThat(problem.pred("predicate").param(1).getParameterType(), + equalTo(problem.builtin().findClass("data").get())); + assertThat(problem.pred("predicate").param(2).getParameterType(), + equalTo(problem.builtin().findClass("int").get())); + } + + @Test + void implicitNodeInAssertionTest() { + var problem = parse(""" + pred predicate(node x, node y) <-> node(x). + predicate(a, a). + ?predicate(a, b). + """); + assertThat(problem.errors(), empty()); + assertThat(problem.nodeNames(), hasItems("a", "b")); + assertThat(problem.assertion(0).arg(0).node(), equalTo(problem.node("a"))); + assertThat(problem.assertion(0).arg(1).node(), equalTo(problem.node("a"))); + assertThat(problem.assertion(1).arg(0).node(), equalTo(problem.node("a"))); + assertThat(problem.assertion(1).arg(1).node(), equalTo(problem.node("b"))); + } + + @Test + void implicitNodeInNodeValueAssertionTest() { + var problem = parseHelper.parse(""" + a: 16. + """); + assertThat(problem.errors(), empty()); + assertThat(problem.nodeNames(), hasItems("a")); + assertThat(problem.nodeValueAssertion(0).getNode(), equalTo(problem.node("a"))); + } + + @Test + void implicitNodeInPredicateTest() { + var problem = parse(""" + pred predicate(node a) <-> node(b). + predicate(b). + """); + assertThat(problem.errors(), empty()); + assertThat(problem.nodeNames(), hasItems("b")); + assertThat(problem.pred("predicate").conj(0).lit(0).arg(0).node(), equalTo(problem.node("b"))); + assertThat(problem.assertion(0).arg(0).node(), equalTo(problem.node("b"))); + } + + @ParameterizedTest + @MethodSource("individualNodeReferenceSource") + void individualNodeInAssertionTest(String qualifiedNamePrefix, boolean namedProblem) { + var problem = parse(""" + indiv a, b. + pred predicate(node x, node y) <-> node(x). + predicate({PARAM}a, {PARAM}a). + ?predicate({PARAM}a, {PARAM}b). + """, qualifiedNamePrefix, namedProblem); + assertThat(problem.errors(), empty()); + assertThat(problem.nodeNames(), empty()); + assertThat(problem.assertion(0).arg(0).node(), equalTo(problem.individualNode("a"))); + assertThat(problem.assertion(0).arg(1).node(), equalTo(problem.individualNode("a"))); + assertThat(problem.assertion(1).arg(0).node(), equalTo(problem.individualNode("a"))); + assertThat(problem.assertion(1).arg(1).node(), equalTo(problem.individualNode("b"))); + } + + @ParameterizedTest + @MethodSource("individualNodeReferenceSource") + void individualNodeInNodeValueAssertionTest(String qualifiedNamePrefix, boolean namedProblem) { + var problem = parse(""" + indiv a. + {PARAM}a: 16. + """, qualifiedNamePrefix, namedProblem); + assertThat(problem.errors(), empty()); + assertThat(problem.nodeNames(), empty()); + assertThat(problem.nodeValueAssertion(0).getNode(), equalTo(problem.individualNode("a"))); + } + + @ParameterizedTest + @MethodSource("individualNodeReferenceSource") + void individualNodeInPredicateTest(String qualifiedNamePrefix, boolean namedProblem) { + var problem = parse(""" + indiv b. + pred predicate(node a) <-> node({PARAM}b). + """); + assertThat(problem.errors(), empty()); + assertThat(problem.nodeNames(), empty()); + assertThat(problem.pred("predicate").conj(0).lit(0).arg(0).node(), equalTo(problem.individualNode("b"))); + } + + static Stream individualNodeReferenceSource() { + return Stream.of(Arguments.of("", false), Arguments.of("", true), Arguments.of("test::", true)); + } + + @ParameterizedTest + @MethodSource("builtInNodeReferencesSource") + void builtInNodeTest(String qualifiedName) { + var problem = parse(""" + pred predicate(node x) <-> node(x). + predicate({PARAM}). + """, qualifiedName); + assertThat(problem.errors(), empty()); + assertThat(problem.nodeNames(), empty()); + assertThat(problem.assertion(0).arg(0).node(), equalTo(problem.builtin().findClass("int").get().getNewNode())); + } + + @ParameterizedTest + @MethodSource("builtInNodeReferencesSource") + void builtInNodeInNodeValueAssertionTest(String qualifiedName) { + var problem = parse(""" + {PARAM}: 16. + """, qualifiedName); + assertThat(problem.errors(), empty()); + assertThat(problem.nodeNames(), empty()); + assertThat(problem.nodeValueAssertion(0).getNode(), + equalTo(problem.builtin().findClass("int").get().getNewNode())); + } + + @ParameterizedTest + @MethodSource("builtInNodeReferencesSource") + void builtInNodeInPredicateTest(String qualifiedName) { + var problem = parse(""" + pred predicate(node x) <-> node({PARAM}). + """, qualifiedName); + assertThat(problem.errors(), empty()); + assertThat(problem.nodeNames(), empty()); + assertThat(problem.pred("predicate").conj(0).lit(0).arg(0).node(), + equalTo(problem.builtin().findClass("int").get().getNewNode())); + } + + static Stream builtInNodeReferencesSource() { + return Stream.of(Arguments.of("int::new"), Arguments.of("builtin::int::new")); + } + + @ParameterizedTest + @MethodSource("classNewNodeReferencesSource") + void classNewNodeTest(String qualifiedName, boolean namedProblem) { + var problem = parse(""" + class Foo. + pred predicate(node x) <-> node(x). + predicate({PARAM}). + """, qualifiedName, namedProblem); + assertThat(problem.errors(), empty()); + assertThat(problem.nodeNames(), empty()); + assertThat(problem.assertion(0).arg(0).node(), equalTo(problem.findClass("Foo").get().getNewNode())); + } + + @ParameterizedTest + @MethodSource("classNewNodeReferencesSource") + void classNewNodeInNodeValueAssertionTest(String qualifiedName, boolean namedProblem) { + var problem = parse(""" + class Foo. + {PARAM}: 16. + """, qualifiedName, namedProblem); + assertThat(problem.errors(), empty()); + assertThat(problem.nodeNames(), empty()); + assertThat(problem.nodeValueAssertion(0).getNode(), equalTo(problem.findClass("Foo").get().getNewNode())); + } + + @ParameterizedTest + @MethodSource("classNewNodeReferencesSource") + void classNewNodeInPredicateTest(String qualifiedName, boolean namedProblem) { + var problem = parse(""" + class Foo. + pred predicate(node x) <-> node({PARAM}). + """, qualifiedName, namedProblem); + assertThat(problem.errors(), empty()); + assertThat(problem.nodeNames(), empty()); + assertThat(problem.pred("predicate").conj(0).lit(0).arg(0).node(), + equalTo(problem.findClass("Foo").get().getNewNode())); + } + + static Stream classNewNodeReferencesSource() { + return Stream.of(Arguments.of("Foo::new", false), Arguments.of("Foo::new", true), + Arguments.of("test::Foo::new", true)); + } + + @Test + void newNodeIsNotSpecial() { + var problem = parse(""" + class Foo. + pred predicate(node x) <-> node(x). + predicate(new). + """); + assertThat(problem.errors(), empty()); + assertThat(problem.nodeNames(), hasItems("new")); + assertThat(problem.assertion(0).arg(0).node(), not(equalTo(problem.findClass("Foo").get().getNewNode()))); + } + + @ParameterizedTest + @MethodSource("enumLiteralReferencesSource") + void enumLiteralTest(String qualifiedName, boolean namedProblem) { + var problem = parse(""" + enum Foo { alpha, beta } + pred predicate(Foo a) <-> node(a). + predicate({PARAM}). + """, qualifiedName, namedProblem); + assertThat(problem.errors(), empty()); + assertThat(problem.nodeNames(), empty()); + assertThat(problem.assertion(0).arg(0).node(), equalTo(problem.findEnum("Foo").literal("alpha"))); + } + + @ParameterizedTest + @MethodSource("enumLiteralReferencesSource") + void enumLiteralInNodeValueAssertionTest(String qualifiedName, boolean namedProblem) { + var problem = parse(""" + enum Foo { alpha, beta } + {PARAM}: 16. + """, qualifiedName, namedProblem); + assertThat(problem.errors(), empty()); + assertThat(problem.nodeNames(), empty()); + assertThat(problem.nodeValueAssertion(0).getNode(), equalTo(problem.findEnum("Foo").literal("alpha"))); + } + + @ParameterizedTest + @MethodSource("enumLiteralReferencesSource") + void enumLiteralInPredicateTest(String qualifiedName, boolean namedProblem) { + var problem = parse(""" + enum Foo { alpha, beta } + pred predicate(Foo a) <-> node({PARAM}). + """, qualifiedName, namedProblem); + assertThat(problem.errors(), empty()); + assertThat(problem.nodeNames(), empty()); + assertThat(problem.pred("predicate").conj(0).lit(0).arg(0).node(), + equalTo(problem.findEnum("Foo").literal("alpha"))); + } + + static Stream enumLiteralReferencesSource() { + return Stream.of(Arguments.of("alpha", false), Arguments.of("alpha", true), Arguments.of("Foo::alpha", false), + Arguments.of("Foo::alpha", true), Arguments.of("test::alpha", true), + Arguments.of("test::Foo::alpha", true)); + } + + @ParameterizedTest + @MethodSource("builtInEnumLiteralReferencesSource") + void builtInEnumLiteralTest(String qualifiedName) { + var problem = parse(""" + pred predicate(node a) <-> node(a). + predicate({PARAM}). + """, qualifiedName); + assertThat(problem.errors(), empty()); + assertThat(problem.nodeNames(), empty()); + assertThat(problem.assertion(0).arg(0).node(), equalTo(problem.builtin().findEnum("bool").literal("true"))); + } + + @ParameterizedTest + @MethodSource("builtInEnumLiteralReferencesSource") + void builtInEnumLiteralInNodeValueAssertionTest(String qualifiedName) { + var problem = parse(""" + {PARAM}: 16. + """, qualifiedName); + assertThat(problem.errors(), empty()); + assertThat(problem.nodeNames(), empty()); + assertThat(problem.nodeValueAssertion(0).getNode(), + equalTo(problem.builtin().findEnum("bool").literal("true"))); + } + + @ParameterizedTest + @MethodSource("builtInEnumLiteralReferencesSource") + void bultInEnumLiteralInPredicateTest(String qualifiedName) { + var problem = parse(""" + pred predicate() <-> node({PARAM}). + """, qualifiedName); + assertThat(problem.errors(), empty()); + assertThat(problem.nodeNames(), empty()); + assertThat(problem.pred("predicate").conj(0).lit(0).arg(0).node(), + equalTo(problem.builtin().findEnum("bool").literal("true"))); + } + + static Stream builtInEnumLiteralReferencesSource() { + return Stream.of(Arguments.of("true"), Arguments.of("bool::true"), Arguments.of("builtin::true"), + Arguments.of("builtin::bool::true")); + } + + private WrappedProblem parse(String text, String parameter, boolean namedProblem) { + var problemName = namedProblem ? "problem test.\n" : ""; + return parseHelper.parse(problemName + text.replace("{PARAM}", parameter)); + } + + private WrappedProblem parse(String text, String parameter) { + return parse(text, parameter, false); + } + + private WrappedProblem parse(String text) { + return parse(text, ""); + } +} diff --git a/subprojects/language/src/test/java/tools/refinery/language/tests/scoping/NodeScopingTest_.xtend b/subprojects/language/src/test/java/tools/refinery/language/tests/scoping/NodeScopingTest_.xtend deleted file mode 100644 index 3a046341..00000000 --- a/subprojects/language/src/test/java/tools/refinery/language/tests/scoping/NodeScopingTest_.xtend +++ /dev/null @@ -1,322 +0,0 @@ -package tools.refinery.language.tests.scoping - -import com.google.inject.Inject -import java.util.stream.Stream -import org.eclipse.xtext.testing.InjectWith -import org.eclipse.xtext.testing.extensions.InjectionExtension -import org.eclipse.xtext.testing.util.ParseHelper -import org.junit.jupiter.api.Test -import org.junit.jupiter.api.^extension.ExtendWith -import org.junit.jupiter.params.ParameterizedTest -import org.junit.jupiter.params.provider.Arguments -import org.junit.jupiter.params.provider.MethodSource -import org.junit.jupiter.params.provider.ValueSource -import tools.refinery.language.model.problem.Problem -import tools.refinery.language.model.tests.ProblemTestUtil -import tools.refinery.language.tests.ProblemInjectorProvider - -import static org.hamcrest.MatcherAssert.assertThat -import static org.hamcrest.Matchers.* - -@ExtendWith(InjectionExtension) -@InjectWith(ProblemInjectorProvider) -class NodeScopingTest { - @Inject - ParseHelper parseHelper - - @Inject - extension ProblemTestUtil - - @ParameterizedTest - @ValueSource(strings=#["", "builtin::"]) - def void builtInArgumentTypeTest(String prefix) { - val it = parseHelper.parse(''' - pred predicate(«prefix»node a, «prefix»data b, «prefix»int c). - ''') - assertThat(errors, empty) - assertThat(pred('predicate').param(0).parameterType, equalTo(builtin.findClass('node'))) - assertThat(pred('predicate').param(1).parameterType, equalTo(builtin.findClass('data'))) - assertThat(pred('predicate').param(2).parameterType, equalTo(builtin.findClass('int'))) - } - - @Test - def void implicitNodeInAssertionTest() { - val it = parseHelper.parse(''' - pred predicate(node x, node y) <-> node(x). - predicate(a, a). - ?predicate(a, b). - ''') - assertThat(errors, empty) - assertThat(nodeNames, hasItems('a', 'b')) - assertThat(assertion(0).arg(0).node, equalTo(node('a'))) - assertThat(assertion(0).arg(1).node, equalTo(node('a'))) - assertThat(assertion(1).arg(0).node, equalTo(node('a'))) - assertThat(assertion(1).arg(1).node, equalTo(node('b'))) - } - - @Test - def void implicitNodeInNodeValueAssertionTest() { - val it = parseHelper.parse(''' - a: 16. - ''') - assertThat(errors, empty) - assertThat(nodeNames, hasItems('a')) - assertThat(nodeValueAssertion(0).node, equalTo(node('a'))) - } - - @Test - def void implicitNodeInPredicateTest() { - val it = parseHelper.parse(''' - pred predicate(node a) <-> node(b). - predicate(b). - ''') - assertThat(errors, empty) - assertThat(nodeNames, hasItem("b")) - assertThat(pred("predicate").conj(0).lit(0).arg(0).node, equalTo(node("b"))) - assertThat(assertion(0).arg(0).node, equalTo(node("b"))) - } - - @ParameterizedTest - @MethodSource("individualNodeReferenceSource") - def void individualNodeInAssertionTest(String qualifiedNamePrefix, boolean namedProblem) { - val it = parseHelper.parse(''' - «IF namedProblem»problem test.«ENDIF» - indiv a, b. - pred predicate(node x, node y) <-> node(x). - predicate(«qualifiedNamePrefix»a, «qualifiedNamePrefix»a). - ?predicate(«qualifiedNamePrefix»a, «qualifiedNamePrefix»b). - ''') - assertThat(errors, empty) - assertThat(nodeNames, empty) - assertThat(assertion(0).arg(0).node, equalTo(individualNode('a'))) - assertThat(assertion(0).arg(1).node, equalTo(individualNode('a'))) - assertThat(assertion(1).arg(0).node, equalTo(individualNode('a'))) - assertThat(assertion(1).arg(1).node, equalTo(individualNode('b'))) - } - - @ParameterizedTest - @MethodSource("individualNodeReferenceSource") - def void individualNodeInNodeValueAssertionTest(String qualifiedNamePrefix, boolean namedProblem) { - val it = parseHelper.parse(''' - «IF namedProblem»problem test.«ENDIF» - indiv a. - «qualifiedNamePrefix»a: 16. - ''') - assertThat(errors, empty) - assertThat(nodeNames, empty) - assertThat(nodeValueAssertion(0).node, equalTo(individualNode('a'))) - } - - @ParameterizedTest - @MethodSource("individualNodeReferenceSource") - def void individualNodeInPredicateTest(String qualifiedNamePrefix, boolean namedProblem) { - val it = parseHelper.parse(''' - «IF namedProblem»problem test.«ENDIF» - indiv b. - pred predicate(node a) <-> node(«qualifiedNamePrefix»b). - ''') - assertThat(errors, empty) - assertThat(nodeNames, empty) - assertThat(pred("predicate").conj(0).lit(0).arg(0).node, equalTo(individualNode("b"))) - } - - static def individualNodeReferenceSource() { - Stream.of( - Arguments.of("", false), - Arguments.of("", true), - Arguments.of("test::", true) - ) - } - - @ParameterizedTest - @MethodSource("builtInNodeReferencesSource") - def void builtInNodeTest(String qualifiedName) { - val it = parseHelper.parse(''' - pred predicate(node x) <-> node(x). - predicate(«qualifiedName»). - ''') - assertThat(errors, empty) - assertThat(nodes, empty) - assertThat(assertion(0).arg(0).node, equalTo(builtin.findClass('int').newNode)) - } - - @ParameterizedTest - @MethodSource("builtInNodeReferencesSource") - def void builtInNodeInNodeValueAssertionTest(String qualifiedName) { - val it = parseHelper.parse(''' - «qualifiedName»: 16. - ''') - assertThat(errors, empty) - assertThat(nodes, empty) - assertThat(nodeValueAssertion(0).node, equalTo(builtin.findClass('int').newNode)) - } - - @ParameterizedTest - @MethodSource("builtInNodeReferencesSource") - def void builtInNodeInPredicateTest(String qualifiedName) { - val it = parseHelper.parse(''' - pred predicate(node x) <-> node(«qualifiedName»). - ''') - assertThat(errors, empty) - assertThat(pred("predicate").conj(0).lit(0).arg(0).node, equalTo(builtin.findClass('int').newNode)) - } - - static def builtInNodeReferencesSource() { - Stream.of( - Arguments.of("int::new"), - Arguments.of("builtin::int::new") - ) - } - - @ParameterizedTest(name="{0}, namedProblem={1}") - @MethodSource("classNewNodeReferencesSource") - def void classNewNodeTest(String qualifiedName, boolean namedProblem) { - val it = parseHelper.parse(''' - «IF namedProblem»problem test.«ENDIF» - class Foo. - pred predicate(node x) <-> node(x). - predicate(«qualifiedName»). - ''') - assertThat(errors, empty) - assertThat(nodes, empty) - assertThat(assertion(0).arg(0).node, equalTo(findClass('Foo').newNode)) - } - - @ParameterizedTest(name="{0}, namedProblem={1}") - @MethodSource("classNewNodeReferencesSource") - def void classNewNodeInNodeValueAssertionTest(String qualifiedName, boolean namedProblem) { - val it = parseHelper.parse(''' - «IF namedProblem»problem test.«ENDIF» - class Foo. - «qualifiedName»: 16. - ''') - assertThat(errors, empty) - assertThat(nodes, empty) - assertThat(nodeValueAssertion(0).node, equalTo(findClass('Foo').newNode)) - } - - @ParameterizedTest(name="{0}, namedProblem={1}") - @MethodSource("classNewNodeReferencesSource") - def void classNewNodeInPredicateTest(String qualifiedName, boolean namedProblem) { - val it = parseHelper.parse(''' - «IF namedProblem»problem test.«ENDIF» - class Foo. - pred predicate(node x) <-> node(«qualifiedName»). - ''') - assertThat(errors, empty) - assertThat(pred("predicate").conj(0).lit(0).arg(0).node, equalTo(findClass('Foo').newNode)) - } - - static def classNewNodeReferencesSource() { - Stream.of( - Arguments.of("Foo::new", false), - Arguments.of("Foo::new", true), - Arguments.of("test::Foo::new", true) - ) - } - - @Test - def void newNodeIsNotSpecial() { - val it = parseHelper.parse(''' - class Foo. - pred predicate(node x) <-> node(x). - predicate(new). - ''') - assertThat(errors, empty) - assertThat(nodeNames, hasItem('new')) - assertThat(assertion(0).arg(0).node, not(equalTo(findClass('Foo').newNode))) - } - - @ParameterizedTest(name="{0}, namedProblem={1}") - @MethodSource("enumLiteralReferencesSource") - def void enumLiteralTest(String qualifiedName, boolean namedProblem) { - val it = parseHelper.parse(''' - «IF namedProblem»problem test.«ENDIF» - enum Foo { alpha, beta } - pred predicate(Foo a) <-> node(a). - predicate(«qualifiedName»). - ''') - assertThat(errors, empty) - assertThat(nodes, empty) - assertThat(assertion(0).arg(0).node, equalTo(findEnum("Foo").literal("alpha"))) - } - - @ParameterizedTest(name="{0}, namedProblem={1}") - @MethodSource("enumLiteralReferencesSource") - def void enumLiteralInNodeValueAssertionTest(String qualifiedName, boolean namedProblem) { - val it = parseHelper.parse(''' - «IF namedProblem»problem test.«ENDIF» - enum Foo { alpha, beta } - «qualifiedName»: 16. - ''') - assertThat(errors, empty) - assertThat(nodes, empty) - assertThat(nodeValueAssertion(0).node, equalTo(findEnum("Foo").literal("alpha"))) - } - - @ParameterizedTest(name="{0}, namedProblem={1}") - @MethodSource("enumLiteralReferencesSource") - def void enumLiteralInPredicateTest(String qualifiedName, boolean namedProblem) { - val it = parseHelper.parse(''' - «IF namedProblem»problem test.«ENDIF» - enum Foo { alpha, beta } - pred predicate(Foo a) <-> node(«qualifiedName»). - ''') - assertThat(errors, empty) - assertThat(nodes, empty) - assertThat(pred("predicate").conj(0).lit(0).arg(0).node, equalTo(findEnum("Foo").literal("alpha"))) - } - - static def enumLiteralReferencesSource() { - Stream.of( - Arguments.of("alpha", false), - Arguments.of("alpha", true), - Arguments.of("Foo::alpha", false), - Arguments.of("Foo::alpha", true), - Arguments.of("test::alpha", true), - Arguments.of("test::Foo::alpha", true) - ) - } - - @ParameterizedTest - @MethodSource("builtInEnumLiteralReferencesSource") - def void builtInEnumLiteralTest(String qualifiedName) { - val it = parseHelper.parse(''' - pred predicate(node a) <-> node(a). - predicate(«qualifiedName»). - ''') - assertThat(errors, empty) - assertThat(nodes, empty) - assertThat(assertion(0).arg(0).node, equalTo(builtin.findEnum("bool").literal("true"))) - } - - @ParameterizedTest - @MethodSource("builtInEnumLiteralReferencesSource") - def void builtInEnumLiteralInNodeValueAssertionTest(String qualifiedName) { - val it = parseHelper.parse(''' - «qualifiedName»: 16. - ''') - assertThat(errors, empty) - assertThat(nodes, empty) - assertThat(nodeValueAssertion(0).node, equalTo(builtin.findEnum("bool").literal("true"))) - } - - @ParameterizedTest - @MethodSource("builtInEnumLiteralReferencesSource") - def void bultInEnumLiteralInPredicateTest(String qualifiedName) { - val it = parseHelper.parse(''' - pred predicate() <-> node(«qualifiedName»). - ''') - assertThat(errors, empty) - assertThat(pred("predicate").conj(0).lit(0).arg(0).node, equalTo(builtin.findEnum("bool").literal("true"))) - } - - static def builtInEnumLiteralReferencesSource() { - Stream.of( - Arguments.of("true"), - Arguments.of("bool::true"), - Arguments.of("builtin::true"), - Arguments.of("builtin::bool::true") - ) - } -} diff --git a/subprojects/language/src/test/java/tools/refinery/language/tests/serializer/ProblemSerializerTest.java b/subprojects/language/src/test/java/tools/refinery/language/tests/serializer/ProblemSerializerTest.java index ba3aaeb7..ea858e92 100644 --- a/subprojects/language/src/test/java/tools/refinery/language/tests/serializer/ProblemSerializerTest.java +++ b/subprojects/language/src/test/java/tools/refinery/language/tests/serializer/ProblemSerializerTest.java @@ -22,7 +22,6 @@ import org.junit.jupiter.params.provider.MethodSource; import com.google.inject.Inject; -import tools.refinery.language.model.ProblemUtil; import tools.refinery.language.model.problem.Atom; import tools.refinery.language.model.problem.LogicValue; import tools.refinery.language.model.problem.Node; @@ -31,7 +30,7 @@ import tools.refinery.language.model.problem.Problem; import tools.refinery.language.model.problem.ProblemFactory; import tools.refinery.language.model.problem.Relation; import tools.refinery.language.model.problem.VariableOrNode; -import tools.refinery.language.model.tests.ProblemTestUtil; +import tools.refinery.language.model.tests.utils.WrappedProblem; import tools.refinery.language.tests.ProblemInjectorProvider; @ExtendWith(InjectionExtension.class) @@ -40,21 +39,19 @@ class ProblemSerializerTest { @Inject private ResourceSet resourceSet; - @Inject - private ProblemTestUtil testUtil; - private Resource resource; private Problem problem; - private Problem builtin; + private WrappedProblem builtin; @BeforeEach void beforeEach() { problem = ProblemFactory.eINSTANCE.createProblem(); resource = resourceSet.createResource(URI.createFileURI("test.problem")); resource.getContents().add(problem); - builtin = ProblemUtil.getBuiltInLibrary(problem).get(); + var wrappedProblem = new WrappedProblem(problem); + builtin = wrappedProblem.builtin(); } @ParameterizedTest @@ -99,8 +96,8 @@ class ProblemSerializerTest { var pred = ProblemFactory.eINSTANCE.createPredicateDefinition(); pred.setName("foo"); var parameter = ProblemFactory.eINSTANCE.createParameter(); - var nodeType = testUtil.findClass(builtin, "node"); - parameter.setParameterType(nodeType); + var nodeType = builtin.findClass("node"); + parameter.setParameterType(nodeType.get()); parameter.setName("p"); pred.getParameters().add(parameter); problem.getStatements().add(pred); @@ -142,20 +139,20 @@ class ProblemSerializerTest { void implicitVariableTest() { var pred = ProblemFactory.eINSTANCE.createPredicateDefinition(); pred.setName("foo"); - var nodeType = testUtil.findClass(builtin, "node"); + var nodeType = builtin.findClass("node"); var parameter1 = ProblemFactory.eINSTANCE.createParameter(); - parameter1.setParameterType(nodeType); + parameter1.setParameterType(nodeType.get()); parameter1.setName("p1"); pred.getParameters().add(parameter1); var parameter2 = ProblemFactory.eINSTANCE.createParameter(); - parameter2.setParameterType(nodeType); + parameter2.setParameterType(nodeType.get()); parameter2.setName("p2"); pred.getParameters().add(parameter2); var conjunction = ProblemFactory.eINSTANCE.createConjunction(); var variable = ProblemFactory.eINSTANCE.createImplicitVariable(); variable.setName("q"); conjunction.getImplicitVariables().add(variable); - var equals = testUtil.reference(nodeType, "equals"); + var equals = nodeType.reference("equals"); conjunction.getLiterals().add(createAtom(equals, parameter1, variable)); conjunction.getLiterals().add(createAtom(equals, variable, parameter2)); pred.getBodies().add(conjunction); @@ -182,14 +179,14 @@ class ProblemSerializerTest { void singletonVariableTest() { var pred = ProblemFactory.eINSTANCE.createPredicateDefinition(); pred.setName("foo"); - var nodeType = testUtil.findClass(builtin, "node"); + var nodeType = builtin.findClass("node"); var parameter = ProblemFactory.eINSTANCE.createParameter(); - parameter.setParameterType(nodeType); + parameter.setParameterType(nodeType.get()); parameter.setName("p"); pred.getParameters().add(parameter); var conjunction = ProblemFactory.eINSTANCE.createConjunction(); var atom = ProblemFactory.eINSTANCE.createAtom(); - var equals = testUtil.reference(nodeType, "equals"); + var equals = nodeType.reference("equals"); atom.setRelation(equals); var arg1 = ProblemFactory.eINSTANCE.createVariableOrNodeArgument(); arg1.setVariableOrNode(parameter); @@ -224,6 +221,6 @@ class ProblemSerializerTest { } var problemString = outputStream.toString(); - assertThat(problemString, equalTo(expected)); + assertThat(problemString.replace("\r\n", "\n"), equalTo(expected.replace("\r\n", "\n"))); } } diff --git a/subprojects/language/src/testFixtures/java/tools/refinery/language/model/tests/utils/ProblemNavigationUtil.java b/subprojects/language/src/testFixtures/java/tools/refinery/language/model/tests/utils/ProblemNavigationUtil.java new file mode 100644 index 00000000..5761935b --- /dev/null +++ b/subprojects/language/src/testFixtures/java/tools/refinery/language/model/tests/utils/ProblemNavigationUtil.java @@ -0,0 +1,20 @@ +package tools.refinery.language.model.tests.utils; + +import java.util.List; +import java.util.stream.Stream; + +import tools.refinery.language.model.problem.NamedElement; + +class ProblemNavigationUtil { + private ProblemNavigationUtil() { + throw new IllegalStateException("This is a static utility class and should not be instantiated directly"); + } + + public static T named(Stream stream, String name) { + return stream.filter(statement -> name.equals(statement.getName())).findAny().get(); + } + + public static T named(List list, String name) { + return named(list.stream(), name); + } +} diff --git a/subprojects/language/src/testFixtures/java/tools/refinery/language/model/tests/utils/ProblemParseHelper.java b/subprojects/language/src/testFixtures/java/tools/refinery/language/model/tests/utils/ProblemParseHelper.java new file mode 100644 index 00000000..5e044a94 --- /dev/null +++ b/subprojects/language/src/testFixtures/java/tools/refinery/language/model/tests/utils/ProblemParseHelper.java @@ -0,0 +1,22 @@ +package tools.refinery.language.model.tests.utils; + +import org.eclipse.xtext.testing.util.ParseHelper; + +import com.google.inject.Inject; + +import tools.refinery.language.model.problem.Problem; + +public class ProblemParseHelper { + @Inject + private ParseHelper parseHelper; + + public WrappedProblem parse(String text) { + Problem problem; + try { + problem = parseHelper.parse(text); + } catch (Exception e) { + throw new RuntimeException("Unexpected exception while parsing Problem", e); + } + return new WrappedProblem(problem); + } +} diff --git a/subprojects/language/src/testFixtures/java/tools/refinery/language/model/tests/utils/WrappedActionLiteral.java b/subprojects/language/src/testFixtures/java/tools/refinery/language/model/tests/utils/WrappedActionLiteral.java new file mode 100644 index 00000000..1411a7ba --- /dev/null +++ b/subprojects/language/src/testFixtures/java/tools/refinery/language/model/tests/utils/WrappedActionLiteral.java @@ -0,0 +1,25 @@ +package tools.refinery.language.model.tests.utils; + +import tools.refinery.language.model.problem.ActionLiteral; +import tools.refinery.language.model.problem.DeleteActionLiteral; +import tools.refinery.language.model.problem.NewActionLiteral; +import tools.refinery.language.model.problem.ValueActionLiteral; +import tools.refinery.language.model.problem.VariableOrNode; + +public record WrappedActionLiteral(ActionLiteral actionLiteral) { + public ActionLiteral get() { + return actionLiteral; + } + + public VariableOrNode newVar() { + return ((NewActionLiteral) actionLiteral).getVariable(); + } + + public VariableOrNode deleteVar() { + return ((DeleteActionLiteral) actionLiteral).getVariableOrNode(); + } + + public WrappedAtom valueAtom() { + return new WrappedAtom(((ValueActionLiteral) actionLiteral).getAtom()); + } +} diff --git a/subprojects/language/src/testFixtures/java/tools/refinery/language/model/tests/utils/WrappedArgument.java b/subprojects/language/src/testFixtures/java/tools/refinery/language/model/tests/utils/WrappedArgument.java new file mode 100644 index 00000000..61492184 --- /dev/null +++ b/subprojects/language/src/testFixtures/java/tools/refinery/language/model/tests/utils/WrappedArgument.java @@ -0,0 +1,25 @@ +package tools.refinery.language.model.tests.utils; + +import tools.refinery.language.model.problem.Argument; +import tools.refinery.language.model.problem.Node; +import tools.refinery.language.model.problem.Variable; +import tools.refinery.language.model.problem.VariableOrNode; +import tools.refinery.language.model.problem.VariableOrNodeArgument; + +public record WrappedArgument(Argument argument) { + public Argument get() { + return argument; + } + + public VariableOrNode variableOrNode() { + return ((VariableOrNodeArgument) argument).getVariableOrNode(); + } + + public Variable variable() { + return (Variable) variableOrNode(); + } + + public Node node() { + return (Node) variableOrNode(); + } +} diff --git a/subprojects/language/src/testFixtures/java/tools/refinery/language/model/tests/utils/WrappedAssertion.java b/subprojects/language/src/testFixtures/java/tools/refinery/language/model/tests/utils/WrappedAssertion.java new file mode 100644 index 00000000..2c38639d --- /dev/null +++ b/subprojects/language/src/testFixtures/java/tools/refinery/language/model/tests/utils/WrappedAssertion.java @@ -0,0 +1,13 @@ +package tools.refinery.language.model.tests.utils; + +import tools.refinery.language.model.problem.Assertion; + +public record WrappedAssertion(Assertion assertion) { + public Assertion get() { + return assertion; + } + + public WrappedAssertionArgument arg(int i) { + return new WrappedAssertionArgument(assertion.getArguments().get(i)); + } +} diff --git a/subprojects/language/src/testFixtures/java/tools/refinery/language/model/tests/utils/WrappedAssertionArgument.java b/subprojects/language/src/testFixtures/java/tools/refinery/language/model/tests/utils/WrappedAssertionArgument.java new file mode 100644 index 00000000..77ad3746 --- /dev/null +++ b/subprojects/language/src/testFixtures/java/tools/refinery/language/model/tests/utils/WrappedAssertionArgument.java @@ -0,0 +1,15 @@ +package tools.refinery.language.model.tests.utils; + +import tools.refinery.language.model.problem.AssertionArgument; +import tools.refinery.language.model.problem.Node; +import tools.refinery.language.model.problem.NodeAssertionArgument; + +public record WrappedAssertionArgument(AssertionArgument assertionArgument) { + public AssertionArgument get() { + return assertionArgument; + } + + public Node node() { + return ((NodeAssertionArgument) assertionArgument).getNode(); + } +} diff --git a/subprojects/language/src/testFixtures/java/tools/refinery/language/model/tests/utils/WrappedAtom.java b/subprojects/language/src/testFixtures/java/tools/refinery/language/model/tests/utils/WrappedAtom.java new file mode 100644 index 00000000..498991f8 --- /dev/null +++ b/subprojects/language/src/testFixtures/java/tools/refinery/language/model/tests/utils/WrappedAtom.java @@ -0,0 +1,13 @@ +package tools.refinery.language.model.tests.utils; + +import tools.refinery.language.model.problem.Atom; + +public record WrappedAtom(Atom atom) { + public Atom get() { + return atom; + } + + public WrappedArgument arg(int i) { + return new WrappedArgument(atom.getArguments().get(i)); + } +} diff --git a/subprojects/language/src/testFixtures/java/tools/refinery/language/model/tests/utils/WrappedClassDeclaration.java b/subprojects/language/src/testFixtures/java/tools/refinery/language/model/tests/utils/WrappedClassDeclaration.java new file mode 100644 index 00000000..d8926c29 --- /dev/null +++ b/subprojects/language/src/testFixtures/java/tools/refinery/language/model/tests/utils/WrappedClassDeclaration.java @@ -0,0 +1,14 @@ +package tools.refinery.language.model.tests.utils; + +import tools.refinery.language.model.problem.ClassDeclaration; +import tools.refinery.language.model.problem.ReferenceDeclaration; + +public record WrappedClassDeclaration(ClassDeclaration classDeclaration) { + public ClassDeclaration get() { + return classDeclaration; + } + + public ReferenceDeclaration reference(String name) { + return ProblemNavigationUtil.named(classDeclaration.getReferenceDeclarations(), name); + } +} diff --git a/subprojects/language/src/testFixtures/java/tools/refinery/language/model/tests/utils/WrappedConjunction.java b/subprojects/language/src/testFixtures/java/tools/refinery/language/model/tests/utils/WrappedConjunction.java new file mode 100644 index 00000000..88ff71ab --- /dev/null +++ b/subprojects/language/src/testFixtures/java/tools/refinery/language/model/tests/utils/WrappedConjunction.java @@ -0,0 +1,13 @@ +package tools.refinery.language.model.tests.utils; + +import tools.refinery.language.model.problem.Conjunction; + +public record WrappedConjunction(Conjunction conjunction) { + public Conjunction get() { + return conjunction; + } + + public WrappedLiteral lit(int i) { + return new WrappedLiteral(conjunction.getLiterals().get(i)); + } +} diff --git a/subprojects/language/src/testFixtures/java/tools/refinery/language/model/tests/utils/WrappedEnumDeclaration.java b/subprojects/language/src/testFixtures/java/tools/refinery/language/model/tests/utils/WrappedEnumDeclaration.java new file mode 100644 index 00000000..74dcf01b --- /dev/null +++ b/subprojects/language/src/testFixtures/java/tools/refinery/language/model/tests/utils/WrappedEnumDeclaration.java @@ -0,0 +1,14 @@ +package tools.refinery.language.model.tests.utils; + +import tools.refinery.language.model.problem.EnumDeclaration; +import tools.refinery.language.model.problem.Node; + +public record WrappedEnumDeclaration(EnumDeclaration enumDeclaration) { + public EnumDeclaration get() { + return enumDeclaration; + } + + public Node literal(String name) { + return ProblemNavigationUtil.named(enumDeclaration.getLiterals(), name); + } +} diff --git a/subprojects/language/src/testFixtures/java/tools/refinery/language/model/tests/utils/WrappedLiteral.java b/subprojects/language/src/testFixtures/java/tools/refinery/language/model/tests/utils/WrappedLiteral.java new file mode 100644 index 00000000..95d651e6 --- /dev/null +++ b/subprojects/language/src/testFixtures/java/tools/refinery/language/model/tests/utils/WrappedLiteral.java @@ -0,0 +1,24 @@ +package tools.refinery.language.model.tests.utils; + +import tools.refinery.language.model.problem.Atom; +import tools.refinery.language.model.problem.Literal; +import tools.refinery.language.model.problem.NegativeLiteral; +import tools.refinery.language.model.problem.ValueLiteral; + +public record WrappedLiteral(Literal literal) { + public Literal get() { + return literal; + } + + public WrappedAtom valueAtom() { + return new WrappedAtom(((ValueLiteral) literal).getAtom()); + } + + public WrappedAtom negated() { + return new WrappedAtom(((NegativeLiteral) literal).getAtom()); + } + + public WrappedArgument arg(int i) { + return new WrappedAtom((Atom) literal).arg(i); + } +} diff --git a/subprojects/language/src/testFixtures/java/tools/refinery/language/model/tests/utils/WrappedParametricDefinition.java b/subprojects/language/src/testFixtures/java/tools/refinery/language/model/tests/utils/WrappedParametricDefinition.java new file mode 100644 index 00000000..b390051a --- /dev/null +++ b/subprojects/language/src/testFixtures/java/tools/refinery/language/model/tests/utils/WrappedParametricDefinition.java @@ -0,0 +1,16 @@ +package tools.refinery.language.model.tests.utils; + +import tools.refinery.language.model.problem.Parameter; +import tools.refinery.language.model.problem.ParametricDefinition; + +public interface WrappedParametricDefinition { + public ParametricDefinition get(); + + public default Parameter param(int i) { + return get().getParameters().get(i); + } + + public default WrappedConjunction conj(int i) { + return new WrappedConjunction(get().getBodies().get(i)); + } +} diff --git a/subprojects/language/src/testFixtures/java/tools/refinery/language/model/tests/utils/WrappedPredicateDefinition.java b/subprojects/language/src/testFixtures/java/tools/refinery/language/model/tests/utils/WrappedPredicateDefinition.java new file mode 100644 index 00000000..6b07366d --- /dev/null +++ b/subprojects/language/src/testFixtures/java/tools/refinery/language/model/tests/utils/WrappedPredicateDefinition.java @@ -0,0 +1,11 @@ +package tools.refinery.language.model.tests.utils; + +import tools.refinery.language.model.problem.PredicateDefinition; + +public record WrappedPredicateDefinition(PredicateDefinition predicateDefinition) + implements WrappedParametricDefinition { + @Override + public PredicateDefinition get() { + return predicateDefinition; + } +} diff --git a/subprojects/language/src/testFixtures/java/tools/refinery/language/model/tests/utils/WrappedProblem.java b/subprojects/language/src/testFixtures/java/tools/refinery/language/model/tests/utils/WrappedProblem.java new file mode 100644 index 00000000..2bedb4a6 --- /dev/null +++ b/subprojects/language/src/testFixtures/java/tools/refinery/language/model/tests/utils/WrappedProblem.java @@ -0,0 +1,85 @@ +package tools.refinery.language.model.tests.utils; + +import java.util.List; +import java.util.stream.Stream; + +import org.eclipse.emf.ecore.resource.Resource.Diagnostic; +import org.eclipse.emf.ecore.util.EcoreUtil; + +import tools.refinery.language.ProblemUtil; +import tools.refinery.language.model.problem.Assertion; +import tools.refinery.language.model.problem.ClassDeclaration; +import tools.refinery.language.model.problem.EnumDeclaration; +import tools.refinery.language.model.problem.IndividualDeclaration; +import tools.refinery.language.model.problem.NamedElement; +import tools.refinery.language.model.problem.Node; +import tools.refinery.language.model.problem.NodeValueAssertion; +import tools.refinery.language.model.problem.PredicateDefinition; +import tools.refinery.language.model.problem.Problem; +import tools.refinery.language.model.problem.RuleDefinition; +import tools.refinery.language.model.problem.Statement; + +public record WrappedProblem(Problem problem) { + public Problem get() { + return problem; + } + + public List errors() { + EcoreUtil.resolveAll(problem); + return problem.eResource().getErrors(); + } + + public WrappedProblem builtin() { + return new WrappedProblem(ProblemUtil.getBuiltInLibrary(problem).get()); + } + + public List nodeNames() { + return problem.getNodes().stream().map(node -> node.getName()).toList(); + } + + public WrappedPredicateDefinition pred(String name) { + return new WrappedPredicateDefinition(namedStatementOfType(PredicateDefinition.class, name)); + } + + public WrappedRuleDefinition rule(String name) { + return new WrappedRuleDefinition(namedStatementOfType(RuleDefinition.class, name)); + } + + public WrappedClassDeclaration findClass(String name) { + return new WrappedClassDeclaration(namedStatementOfType(ClassDeclaration.class, name)); + } + + public WrappedEnumDeclaration findEnum(String name) { + return new WrappedEnumDeclaration(namedStatementOfType(EnumDeclaration.class, name)); + } + + public WrappedAssertion assertion(int i) { + return new WrappedAssertion(nthStatementOfType(Assertion.class, i)); + } + + public Node node(String name) { + return ProblemNavigationUtil.named(problem.getNodes(), name); + } + + public Node individualNode(String name) { + var uniqueNodes = statementsOfType(IndividualDeclaration.class) + .flatMap(declaration -> declaration.getNodes().stream()); + return ProblemNavigationUtil.named(uniqueNodes, name); + } + + public NodeValueAssertion nodeValueAssertion(int i) { + return nthStatementOfType(NodeValueAssertion.class, i); + } + + private Stream statementsOfType(Class type) { + return problem.getStatements().stream().filter(type::isInstance).map(type::cast); + } + + private T namedStatementOfType(Class type, String name) { + return ProblemNavigationUtil.named(statementsOfType(type), name); + } + + private T nthStatementOfType(Class type, int n) { + return statementsOfType(type).skip(n).findFirst().get(); + } +} diff --git a/subprojects/language/src/testFixtures/java/tools/refinery/language/model/tests/utils/WrappedRuleDefinition.java b/subprojects/language/src/testFixtures/java/tools/refinery/language/model/tests/utils/WrappedRuleDefinition.java new file mode 100644 index 00000000..53a90dde --- /dev/null +++ b/subprojects/language/src/testFixtures/java/tools/refinery/language/model/tests/utils/WrappedRuleDefinition.java @@ -0,0 +1,14 @@ +package tools.refinery.language.model.tests.utils; + +import tools.refinery.language.model.problem.RuleDefinition; + +public record WrappedRuleDefinition(RuleDefinition ruleDefinition) implements WrappedParametricDefinition { + @Override + public RuleDefinition get() { + return ruleDefinition; + } + + public WrappedActionLiteral actionLit(int i) { + return new WrappedActionLiteral(ruleDefinition.getAction().getActionLiterals().get(i)); + } +} -- cgit v1.2.3-54-g00ecf