From fc7e9312d00e60171ed77c477ed91231d3dbfff9 Mon Sep 17 00:00:00 2001 From: Kristóf Marussy Date: Sun, 12 Dec 2021 17:48:47 +0100 Subject: build: move modules into subproject directory --- language/build.gradle | 66 ----- .../tools/refinery/language/GenerateProblem.mwe2 | 68 ----- .../java/tools/refinery/language/Problem.xtext | 205 ------------- .../refinery/language/ProblemRuntimeModule.java | 84 ------ .../refinery/language/ProblemStandaloneSetup.java | 44 --- .../refinery/language/ProblemXmiRuntimeModule.java | 35 --- .../conversion/ProblemValueConverterService.java | 19 -- .../conversion/UpperBoundValueConverter.java | 35 --- .../language/formatting2/ProblemFormatter.java | 183 ------------ .../tools/refinery/language/naming/NamingUtil.java | 25 -- .../naming/ProblemQualifiedNameConverter.java | 15 - .../language/resource/DerivedVariableComputer.java | 194 ------------- .../language/resource/NodeNameCollector.java | 88 ------ .../resource/ProblemDerivedStateComputer.java | 163 ----------- .../resource/ProblemLocationInFileProvider.java | 33 --- .../ProblemResourceDescriptionStrategy.java | 103 ------- .../resource/ProblemXmiResourceFactory.java | 16 - .../language/resource/ReferenceCounter.java | 51 ---- .../scoping/ProblemGlobalScopeProvider.java | 18 -- .../scoping/ProblemLocalScopeProvider.java | 42 --- .../language/scoping/ProblemScopeProvider.java | 104 ------- .../language/validation/ProblemValidator.java | 62 ---- .../language/tests/ProblemParsingTest.xtend | 64 ---- .../tests/formatting2/ProblemFormatterTest.java | 235 --------------- .../tests/rules/DirectRuleParsingTest.xtend | 96 ------ .../language/tests/scoping/NodeScopingTest.xtend | 322 --------------------- .../tests/serializer/ProblemSerializerTest.java | 229 --------------- 27 files changed, 2599 deletions(-) delete mode 100644 language/build.gradle delete mode 100644 language/src/main/java/tools/refinery/language/GenerateProblem.mwe2 delete mode 100644 language/src/main/java/tools/refinery/language/Problem.xtext delete mode 100644 language/src/main/java/tools/refinery/language/ProblemRuntimeModule.java delete mode 100644 language/src/main/java/tools/refinery/language/ProblemStandaloneSetup.java delete mode 100644 language/src/main/java/tools/refinery/language/ProblemXmiRuntimeModule.java delete mode 100644 language/src/main/java/tools/refinery/language/conversion/ProblemValueConverterService.java delete mode 100644 language/src/main/java/tools/refinery/language/conversion/UpperBoundValueConverter.java delete mode 100644 language/src/main/java/tools/refinery/language/formatting2/ProblemFormatter.java delete mode 100644 language/src/main/java/tools/refinery/language/naming/NamingUtil.java delete mode 100644 language/src/main/java/tools/refinery/language/naming/ProblemQualifiedNameConverter.java delete mode 100644 language/src/main/java/tools/refinery/language/resource/DerivedVariableComputer.java delete mode 100644 language/src/main/java/tools/refinery/language/resource/NodeNameCollector.java delete mode 100644 language/src/main/java/tools/refinery/language/resource/ProblemDerivedStateComputer.java delete mode 100644 language/src/main/java/tools/refinery/language/resource/ProblemLocationInFileProvider.java delete mode 100644 language/src/main/java/tools/refinery/language/resource/ProblemResourceDescriptionStrategy.java delete mode 100644 language/src/main/java/tools/refinery/language/resource/ProblemXmiResourceFactory.java delete mode 100644 language/src/main/java/tools/refinery/language/resource/ReferenceCounter.java delete mode 100644 language/src/main/java/tools/refinery/language/scoping/ProblemGlobalScopeProvider.java delete mode 100644 language/src/main/java/tools/refinery/language/scoping/ProblemLocalScopeProvider.java delete mode 100644 language/src/main/java/tools/refinery/language/scoping/ProblemScopeProvider.java delete mode 100644 language/src/main/java/tools/refinery/language/validation/ProblemValidator.java delete mode 100644 language/src/test/java/tools/refinery/language/tests/ProblemParsingTest.xtend delete mode 100644 language/src/test/java/tools/refinery/language/tests/formatting2/ProblemFormatterTest.java delete mode 100644 language/src/test/java/tools/refinery/language/tests/rules/DirectRuleParsingTest.xtend delete mode 100644 language/src/test/java/tools/refinery/language/tests/scoping/NodeScopingTest.xtend delete mode 100644 language/src/test/java/tools/refinery/language/tests/serializer/ProblemSerializerTest.java (limited to 'language') diff --git a/language/build.gradle b/language/build.gradle deleted file mode 100644 index f7574ecc..00000000 --- a/language/build.gradle +++ /dev/null @@ -1,66 +0,0 @@ -plugins { - id 'java-test-fixtures' - id 'refinery-java-library' - id 'refinery-mwe2' - id 'refinery-sonarqube' - id 'refinery-xtend' - id 'refinery-xtext-conventions' -} - -dependencies { - api platform(libs.xtext.bom) - api libs.ecore - api libs.xtext.core - 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 -} - -sourceSets { - testFixtures { - java.srcDirs += ['src/testFixtures/xtext-gen'] - resources.srcDirs += ['src/testFixtures/xtext-gen'] - } -} - -tasks.named('jar') { - from(sourceSets.main.allSource) { - include '**/*.xtext' - } -} - -def generateXtextLanguage = tasks.register('generateXtextLanguage', JavaExec) { - mainClass = 'org.eclipse.emf.mwe2.launch.runtime.Mwe2Launcher' - classpath = configurations.mwe2 - inputs.file 'src/main/java/tools/refinery/language/GenerateProblem.mwe2' - inputs.file 'src/main/java/tools/refinery/language/Problem.xtext' - outputs.dir 'src/main/xtext-gen' - outputs.dir 'src/testFixtures/xtext-gen' - outputs.dir '../language-ide/src/main/xtext-gen' - outputs.dir '../language-web/src/main/xtext-gen' - args += 'src/main/java/tools/refinery/language/GenerateProblem.mwe2' - args += '-p' - args += "rootPath=/${projectDir}/.." -} - -for (taskName in ['compileJava', 'processResources', 'generateXtext', 'generateEclipseSourceFolders']) { - tasks.named(taskName) { - dependsOn generateXtextLanguage - } -} - -tasks.named('clean') { - delete 'src/main/xtext-gen' - delete 'src/testFixtures/xtext-gen' - delete '../language-ide/src/main/xtext-gen' - delete '../language-web/src/main/xtext-gen' -} - -sonarqube.properties { - properties['sonar.exclusions'] += [ - 'src/testFixtures/xtext-gen/**', - ] -} diff --git a/language/src/main/java/tools/refinery/language/GenerateProblem.mwe2 b/language/src/main/java/tools/refinery/language/GenerateProblem.mwe2 deleted file mode 100644 index 21ff456e..00000000 --- a/language/src/main/java/tools/refinery/language/GenerateProblem.mwe2 +++ /dev/null @@ -1,68 +0,0 @@ -module tools.refinery.language.GenerateProblem - -import org.eclipse.xtext.xtext.generator.* -import org.eclipse.xtext.xtext.generator.model.project.* - -var rootPath = '..' - -Workflow { - component = XtextGenerator { - configuration = { - project = StandardProjectConfig { - baseName = 'language' - rootPath = rootPath - runtimeTest = { - enabled = true - srcGen = 'src/testFixtures/xtext-gen' - } - genericIde = { - name = 'language-ide' - } - web = { - enabled = true - name = 'language-web' - } - mavenLayout = true - } - code = { - encoding = 'UTF-8' - lineDelimiter = '\n' - fileHeader = '/*\n * generated by Xtext \${version}\n */' - preferXtendStubs = false - } - } - - language = StandardLanguage { - name = 'tools.refinery.language.Problem' - fileExtensions = 'problem' - referencedResource = 'platform:/resource/tools.refinery.refinery-language-model/model/problem.genmodel' - serializer = { - generateStub = false - } - formatter = { - generateStub = true - } - validator = { - generateDeprecationValidation = true - } - generator = { - generateStub = false - } - junitSupport = { - generateStub = false - skipXbaseTestingPackage = true - junitVersion = '5' - } - webSupport = { - // We only generate the {@code AbstractProblemWebModule}, - // because we write our own integration code for CodeMirror 6. - framework = 'codemirror' - generateHtmlExample = false - generateJettyLauncher = false - generateJsHighlighting = false - generateServlet = false - generateWebXml = false - } - } - } -} diff --git a/language/src/main/java/tools/refinery/language/Problem.xtext b/language/src/main/java/tools/refinery/language/Problem.xtext deleted file mode 100644 index c94d40ab..00000000 --- a/language/src/main/java/tools/refinery/language/Problem.xtext +++ /dev/null @@ -1,205 +0,0 @@ -grammar tools.refinery.language.Problem with org.eclipse.xtext.common.Terminals - -import "http://www.eclipse.org/emf/2002/Ecore" as ecore -import "https://refinery.tools/emf/2021/Problem" - -Problem: - ("problem" name=Identifier ".")? - statements+=Statement*; - -Statement: - ClassDeclaration | EnumDeclaration | PredicateDefinition | RuleDefinition | Assertion | NodeValueAssertion | - ScopeDeclaration | - IndividualDeclaration; - -ClassDeclaration: - abstract?="abstract"? "class" - name=Identifier - ("extends" superTypes+=[Relation|QualifiedName] ("," superTypes+=[Relation|QualifiedName])*)? - ("{" (referenceDeclarations+=ReferenceDeclaration ";"?)* "}" | "."); - -EnumDeclaration: - "enum" - name=Identifier - ("{" (literals+=EnumLiteral ("," literals+=EnumLiteral)* ("," | ";")?)? "}" | "."); - -EnumLiteral returns Node: - name=Identifier; - -ReferenceDeclaration: - (containment?="contains" | "refers")? - referenceType=[Relation|QualifiedName] - ("[" multiplicity=Multiplicity "]")? - name=Identifier - ("opposite" opposite=[ReferenceDeclaration|QualifiedName])?; - -enum PredicateKind: - DIRECT="direct"; - -PredicateDefinition: - (error?="error" "pred"? | kind=PredicateKind? "pred") - name=Identifier - "(" (parameters+=Parameter ("," parameters+=Parameter)*)? ")" - ("<->" bodies+=Conjunction (";" bodies+=Conjunction)*)? - "."; - -enum RuleKind: - DIRECT="direct"; - -RuleDefinition: - kind=RuleKind "rule" - name=Identifier - "(" (parameters+=Parameter ("," parameters+=Parameter)*)? ")" - (":" bodies+=Conjunction (";" bodies+=Conjunction)* - "~>" action=Action)? - "."; - -Parameter: - parameterType=[Relation|QualifiedName]? name=Identifier; - -Conjunction: - literals+=Literal ("," literals+=Literal)*; - -Action: - actionLiterals+=ActionLiteral ("," actionLiterals+=ActionLiteral)*; - -Literal: - Atom | ValueLiteral | NegativeLiteral; - -ValueLiteral: - atom=Atom - (refinement?=":" | "=") - values+=LogicConstant ("|" values+=LogicConstant)*; - -NegativeLiteral: - "!" atom=Atom; - -ActionLiteral: - ValueActionLiteral | DeleteActionLiteral | NewActionLiteral; - -ValueActionLiteral: - atom=Atom - (refinement?=":" | "=") - value=LogicValue; - -DeleteActionLiteral: - "delete" variableOrNode=[VariableOrNode|QualifiedName]; - -NewActionLiteral: - "new" variable=NewVariable; - -NewVariable: - name=Identifier; - -Atom: - relation=[Relation|QualifiedName] - transitiveClosure?="+"? - "(" (arguments+=Argument ("," arguments+=Argument)*)? ")"; - -LogicConstant: - value=LogicValue; - -Argument: - VariableOrNodeArgument | ConstantArgument; - -VariableOrNodeArgument: - variableOrNode=[VariableOrNode|QualifiedName]; - -ConstantArgument: - constant=Constant; - -Assertion: - default?="default"? - (value=ShortLogicValue? - relation=[Relation|QualifiedName] - "(" (arguments+=AssertionArgument ("," arguments+=AssertionArgument)*)? ")" - | relation=[Relation|QualifiedName] - "(" (arguments+=AssertionArgument ("," arguments+=AssertionArgument)*)? ")" - ":" value=LogicValue) - "."; - -AssertionArgument: - NodeAssertionArgument | WildcardAssertionArgument | ConstantAssertionArgument; - -NodeAssertionArgument: - node=[Node|QualifiedName]; - -WildcardAssertionArgument: - {WildcardAssertionArgument} "*"; - -ConstantAssertionArgument: - constant=Constant; - -enum LogicValue: - TRUE="true" | FALSE="false" | UNKNOWN="unknown" | ERROR="error"; - -enum ShortLogicValue returns LogicValue: - FALSE="!" | UNKNOWN="?"; - -NodeValueAssertion: - node=[Node|QualifiedName] ":" value=Constant "."; - -Constant: - RealConstant | IntConstant | StringConstant; - -IntConstant: - intValue=Integer; - -RealConstant: - realValue=Real; - -StringConstant: - stringValue=STRING; - -ScopeDeclaration: - "scope" typeScopes+=TypeScope ("," typeScopes+=TypeScope)* "."; - -TypeScope: - targetType=[ClassDeclaration|QualifiedName] - (increment?="+=" | "=") - multiplicity=DefiniteMultiplicity; - -Multiplicity: - UnboundedMultiplicity | DefiniteMultiplicity; - -DefiniteMultiplicity returns Multiplicity: - RangeMultiplicity | ExactMultiplicity; - -UnboundedMultiplicity: - {UnboundedMultiplicity}; - -RangeMultiplicity: - lowerBound=INT ".." upperBound=UpperBound; - -ExactMultiplicity: - exactValue=INT; - -IndividualDeclaration: - "indiv" nodes+=EnumLiteral ("," nodes+=EnumLiteral)* "."; - -UpperBound returns ecore::EInt: - INT | "*"; - -QualifiedName hidden(): - Identifier ("::" Identifier)*; - -Identifier: - ID | "true" | "false" | "unknown" | "error" | "class" | "abstract" | "extends" | "enum" | "pred" | - "indiv" | "problem" | "new" | "delete" | "direct" | "rule"; - -Integer returns ecore::EInt hidden(): - "-"? INT; - -Real returns ecore::EDouble: - "-"? (EXPONENTIAL | INT "." (INT | EXPONENTIAL)); - -@Override -terminal ID: - ('a'..'z' | 'A'..'Z' | '_') ('a'..'z' | 'A'..'Z' | '_' | '0'..'9')*; - -terminal EXPONENTIAL: - INT ("e" | "E") ("+" | "-")? INT; - -@Override -terminal SL_COMMENT: - ('%' | '//') !('\n' | '\r')* ('\r'? '\n')?; diff --git a/language/src/main/java/tools/refinery/language/ProblemRuntimeModule.java b/language/src/main/java/tools/refinery/language/ProblemRuntimeModule.java deleted file mode 100644 index dd7731b4..00000000 --- a/language/src/main/java/tools/refinery/language/ProblemRuntimeModule.java +++ /dev/null @@ -1,84 +0,0 @@ -/* - * generated by Xtext 2.25.0 - */ -package tools.refinery.language; - -import org.eclipse.xtext.conversion.IValueConverterService; -import org.eclipse.xtext.naming.IQualifiedNameConverter; -import org.eclipse.xtext.resource.DerivedStateAwareResource; -import org.eclipse.xtext.resource.DerivedStateAwareResourceDescriptionManager; -import org.eclipse.xtext.resource.IDefaultResourceDescriptionStrategy; -import org.eclipse.xtext.resource.IDerivedStateComputer; -import org.eclipse.xtext.resource.ILocationInFileProvider; -import org.eclipse.xtext.resource.IResourceDescription; -import org.eclipse.xtext.resource.XtextResource; -import org.eclipse.xtext.scoping.IGlobalScopeProvider; -import org.eclipse.xtext.scoping.IScopeProvider; -import org.eclipse.xtext.scoping.impl.AbstractDeclarativeScopeProvider; -import org.eclipse.xtext.validation.IResourceValidator; -import org.eclipse.xtext.xbase.annotations.validation.DerivedStateAwareResourceValidator; - -import com.google.inject.Binder; -import com.google.inject.name.Names; - -import tools.refinery.language.conversion.ProblemValueConverterService; -import tools.refinery.language.naming.ProblemQualifiedNameConverter; -import tools.refinery.language.resource.ProblemDerivedStateComputer; -import tools.refinery.language.resource.ProblemLocationInFileProvider; -import tools.refinery.language.resource.ProblemResourceDescriptionStrategy; -import tools.refinery.language.scoping.ProblemGlobalScopeProvider; -import tools.refinery.language.scoping.ProblemLocalScopeProvider; - -/** - * Use this class to register components to be used at runtime / without the - * Equinox extension registry. - */ -public class ProblemRuntimeModule extends AbstractProblemRuntimeModule { - public Class bindIQualifiedNameConverter() { - return ProblemQualifiedNameConverter.class; - } - - public Class bindIDefaultResourceDescriptionStrategy() { - return ProblemResourceDescriptionStrategy.class; - } - - @Override - public Class bindIValueConverterService() { - return ProblemValueConverterService.class; - } - - @Override - public Class bindIGlobalScopeProvider() { - return ProblemGlobalScopeProvider.class; - } - - @Override - public void configureIScopeProviderDelegate(Binder binder) { - binder.bind(IScopeProvider.class).annotatedWith(Names.named(AbstractDeclarativeScopeProvider.NAMED_DELEGATE)) - .to(ProblemLocalScopeProvider.class); - } - - @Override - public Class bindXtextResource() { - return DerivedStateAwareResource.class; - } - - // Method name follows Xtext convention. - @SuppressWarnings("squid:S100") - public Class bindIResourceDescription$Manager() { - return DerivedStateAwareResourceDescriptionManager.class; - } - - public Class bindIResourceValidator() { - return DerivedStateAwareResourceValidator.class; - } - - public Class bindIDerivedStateComputer() { - return ProblemDerivedStateComputer.class; - } - - @Override - public Class bindILocationInFileProvider() { - return ProblemLocationInFileProvider.class; - } -} diff --git a/language/src/main/java/tools/refinery/language/ProblemStandaloneSetup.java b/language/src/main/java/tools/refinery/language/ProblemStandaloneSetup.java deleted file mode 100644 index d753a119..00000000 --- a/language/src/main/java/tools/refinery/language/ProblemStandaloneSetup.java +++ /dev/null @@ -1,44 +0,0 @@ -/* - * generated by Xtext 2.25.0 - */ -package tools.refinery.language; - -import org.eclipse.emf.ecore.resource.Resource; -import org.eclipse.xtext.resource.IResourceFactory; -import org.eclipse.xtext.resource.IResourceServiceProvider; - -import com.google.inject.Guice; -import com.google.inject.Injector; - -import tools.refinery.language.model.ProblemEMFSetup; - -/** - * Initialization support for running Xtext languages without Equinox extension - * registry. - */ -public class ProblemStandaloneSetup extends ProblemStandaloneSetupGenerated { - - public static void doSetup() { - new ProblemStandaloneSetup().createInjectorAndDoEMFRegistration(); - } - - @Override - public Injector createInjectorAndDoEMFRegistration() { - ProblemEMFSetup.doEMFRegistration(); - var xmiInjector = createXmiInjector(); - registerXmiInjector(xmiInjector); - 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/language/src/main/java/tools/refinery/language/ProblemXmiRuntimeModule.java b/language/src/main/java/tools/refinery/language/ProblemXmiRuntimeModule.java deleted file mode 100644 index 03a33bee..00000000 --- a/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/language/src/main/java/tools/refinery/language/conversion/ProblemValueConverterService.java b/language/src/main/java/tools/refinery/language/conversion/ProblemValueConverterService.java deleted file mode 100644 index 508688ed..00000000 --- a/language/src/main/java/tools/refinery/language/conversion/ProblemValueConverterService.java +++ /dev/null @@ -1,19 +0,0 @@ -package tools.refinery.language.conversion; - -import org.eclipse.xtext.common.services.DefaultTerminalConverters; -import org.eclipse.xtext.conversion.IValueConverter; -import org.eclipse.xtext.conversion.ValueConverter; - -import com.google.inject.Inject; - -public class ProblemValueConverterService extends DefaultTerminalConverters { - @Inject - private UpperBoundValueConverter upperBoundValueConverter; - - @ValueConverter(rule = "UpperBound") - // Method name follows Xtext convention. - @SuppressWarnings("squid:S100") - public IValueConverter UpperBound() { - return upperBoundValueConverter; - } -} diff --git a/language/src/main/java/tools/refinery/language/conversion/UpperBoundValueConverter.java b/language/src/main/java/tools/refinery/language/conversion/UpperBoundValueConverter.java deleted file mode 100644 index be0d15ad..00000000 --- a/language/src/main/java/tools/refinery/language/conversion/UpperBoundValueConverter.java +++ /dev/null @@ -1,35 +0,0 @@ -package tools.refinery.language.conversion; - -import org.eclipse.xtext.conversion.ValueConverterException; -import org.eclipse.xtext.conversion.impl.AbstractValueConverter; -import org.eclipse.xtext.conversion.impl.INTValueConverter; -import org.eclipse.xtext.nodemodel.INode; - -import com.google.inject.Inject; -import com.google.inject.Singleton; - -@Singleton -public class UpperBoundValueConverter extends AbstractValueConverter { - public static final String INFINITY = "*"; - - @Inject - private INTValueConverter intValueConverter; - - @Override - public Integer toValue(String string, INode node) throws ValueConverterException { - if (INFINITY.equals(string)) { - return -1; - } else { - return intValueConverter.toValue(string, node); - } - } - - @Override - public String toString(Integer value) throws ValueConverterException { - if (value < 0) { - return INFINITY; - } else { - return intValueConverter.toString(value); - } - } -} diff --git a/language/src/main/java/tools/refinery/language/formatting2/ProblemFormatter.java b/language/src/main/java/tools/refinery/language/formatting2/ProblemFormatter.java deleted file mode 100644 index 903347f7..00000000 --- a/language/src/main/java/tools/refinery/language/formatting2/ProblemFormatter.java +++ /dev/null @@ -1,183 +0,0 @@ -/* - * generated by Xtext 2.26.0.M2 - */ -package tools.refinery.language.formatting2; - -import org.eclipse.emf.ecore.EObject; -import org.eclipse.xtext.formatting2.AbstractJavaFormatter; -import org.eclipse.xtext.formatting2.IFormattableDocument; -import org.eclipse.xtext.formatting2.IHiddenRegionFormatter; -import org.eclipse.xtext.formatting2.regionaccess.ISemanticRegionsFinder; -import org.eclipse.xtext.formatting2.regionaccess.ISequentialRegion; -import org.eclipse.xtext.xbase.lib.Procedures.Procedure1; - -import tools.refinery.language.model.problem.Assertion; -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.IndividualDeclaration; -import tools.refinery.language.model.problem.NegativeLiteral; -import tools.refinery.language.model.problem.Parameter; -import tools.refinery.language.model.problem.PredicateDefinition; -import tools.refinery.language.model.problem.Problem; -import tools.refinery.language.model.problem.ProblemPackage; - -public class ProblemFormatter extends AbstractJavaFormatter { - - protected void format(Problem problem, IFormattableDocument doc) { - doc.prepend(problem, this::noSpace); - var region = regionFor(problem); - doc.append(region.keyword("problem"), this::oneSpace); - doc.prepend(region.keyword("."), this::noSpace); - appendNewLines(doc, region.keyword("."), this::twoNewLines); - for (var statement : problem.getStatements()) { - doc.format(statement); - } - } - - protected void format(Assertion assertion, IFormattableDocument doc) { - surroundNewLines(doc, assertion, this::singleNewLine); - var region = regionFor(assertion); - doc.append(region.feature(ProblemPackage.Literals.ASSERTION__DEFAULT), this::oneSpace); - doc.append(region.feature(ProblemPackage.Literals.ASSERTION__VALUE), this::noSpace); - doc.append(region.feature(ProblemPackage.Literals.ASSERTION__RELATION), this::noSpace); - formatParenthesizedList(region, doc); - doc.prepend(region.keyword(":"), this::noSpace); - doc.append(region.keyword(":"), this::oneSpace); - doc.prepend(region.keyword("."), this::noSpace); - for (var argument : assertion.getArguments()) { - doc.format(argument); - } - } - - protected void format(ClassDeclaration classDeclaration, IFormattableDocument doc) { - surroundNewLines(doc, classDeclaration, this::twoNewLines); - var region = regionFor(classDeclaration); - doc.append(region.feature(ProblemPackage.Literals.CLASS_DECLARATION__ABSTRACT), this::oneSpace); - doc.append(region.keyword("class"), this::oneSpace); - doc.surround(region.keyword("extends"), this::oneSpace); - formatList(region, ",", doc); - doc.prepend(region.keyword("{"), this::oneSpace); - doc.append(region.keyword("{"), it -> it.setNewLines(1, 1, 2)); - doc.prepend(region.keyword("}"), it -> it.setNewLines(1, 1, 2)); - doc.prepend(region.keyword("."), this::noSpace); - for (var referenceDeclaration : classDeclaration.getReferenceDeclarations()) { - doc.format(referenceDeclaration); - } - } - - protected void format(PredicateDefinition predicateDefinition, IFormattableDocument doc) { - surroundNewLines(doc, predicateDefinition, this::twoNewLines); - var region = regionFor(predicateDefinition); - doc.append(region.feature(ProblemPackage.Literals.PREDICATE_DEFINITION__KIND), this::oneSpace); - doc.append(region.keyword("pred"), this::oneSpace); - doc.append(region.feature(ProblemPackage.Literals.NAMED_ELEMENT__NAME), this::noSpace); - formatParenthesizedList(region, doc); - doc.surround(region.keyword("<->"), this::oneSpace); - formatList(region, ";", doc); - doc.prepend(region.keyword("."), this::noSpace); - for (var parameter : predicateDefinition.getParameters()) { - doc.format(parameter); - } - for (var body : predicateDefinition.getBodies()) { - doc.format(body); - } - } - - protected void format(Parameter parameter, IFormattableDocument doc) { - doc.append(regionFor(parameter).feature(ProblemPackage.Literals.PARAMETER__PARAMETER_TYPE), this::oneSpace); - } - - protected void format(Conjunction conjunction, IFormattableDocument doc) { - var region = regionFor(conjunction); - formatList(region, ",", doc); - for (var literal : conjunction.getLiterals()) { - doc.format(literal); - } - } - - protected void format(NegativeLiteral literal, IFormattableDocument doc) { - var region = regionFor(literal); - doc.append(region.keyword("!"), this::noSpace); - doc.format(literal.getAtom()); - } - - protected void format(Atom atom, IFormattableDocument doc) { - var region = regionFor(atom); - doc.append(region.feature(ProblemPackage.Literals.ATOM__RELATION), this::noSpace); - doc.append(region.feature(ProblemPackage.Literals.ATOM__TRANSITIVE_CLOSURE), this::noSpace); - formatParenthesizedList(region, doc); - for (var argument : atom.getArguments()) { - doc.format(argument); - } - } - - protected void format(IndividualDeclaration individualDeclaration, IFormattableDocument doc) { - surroundNewLines(doc, individualDeclaration, this::singleNewLine); - var region = regionFor(individualDeclaration); - doc.append(region.keyword("indiv"), this::oneSpace); - formatList(region, ",", doc); - doc.prepend(region.keyword("."), this::noSpace); - } - - protected void formatParenthesizedList(ISemanticRegionsFinder region, IFormattableDocument doc) { - doc.append(region.keyword("("), this::noSpace); - doc.prepend(region.keyword(")"), this::noSpace); - formatList(region, ",", doc); - } - - protected void formatList(ISemanticRegionsFinder region, String separator, IFormattableDocument doc) { - for (var comma : region.keywords(separator)) { - doc.prepend(comma, this::noSpace); - doc.append(comma, this::oneSpace); - } - } - - protected void singleNewLine(IHiddenRegionFormatter it) { - it.setNewLines(1, 1, 2); - } - - protected void twoNewLines(IHiddenRegionFormatter it) { - it.highPriority(); - it.setNewLines(2); - } - - protected void surroundNewLines(IFormattableDocument doc, EObject eObject, - Procedure1 init) { - var region = doc.getRequest().getTextRegionAccess().regionForEObject(eObject); - preprendNewLines(doc, region, init); - appendNewLines(doc, region, init); - } - - protected void preprendNewLines(IFormattableDocument doc, ISequentialRegion region, - Procedure1 init) { - if (region == null) { - return; - } - var previousHiddenRegion = region.getPreviousHiddenRegion(); - if (previousHiddenRegion == null) { - return; - } - if (previousHiddenRegion.getPreviousSequentialRegion() == null) { - doc.set(previousHiddenRegion, it -> it.setNewLines(0)); - } else { - doc.set(previousHiddenRegion, init); - } - } - - protected void appendNewLines(IFormattableDocument doc, ISequentialRegion region, - Procedure1 init) { - if (region == null) { - return; - } - var nextHiddenRegion = region.getNextHiddenRegion(); - if (nextHiddenRegion == null) { - return; - } - if (nextHiddenRegion.getNextSequentialRegion() == null) { - doc.set(nextHiddenRegion, it -> it.setNewLines(1)); - } else { - doc.set(nextHiddenRegion, init); - } - } -} diff --git a/language/src/main/java/tools/refinery/language/naming/NamingUtil.java b/language/src/main/java/tools/refinery/language/naming/NamingUtil.java deleted file mode 100644 index e959be74..00000000 --- a/language/src/main/java/tools/refinery/language/naming/NamingUtil.java +++ /dev/null @@ -1,25 +0,0 @@ -package tools.refinery.language.naming; - -import java.util.regex.Pattern; - -public final class NamingUtil { - private static final String SINGLETON_VARIABLE_PREFIX = "_"; - - private static final Pattern ID_REGEX = Pattern.compile("[_a-zA-Z][_0-9a-zA-Z]*"); - - private NamingUtil() { - throw new IllegalStateException("This is a static utility class and should not be instantiated directly"); - } - - public static boolean isNullOrEmpty(String name) { - return name == null || name.isEmpty(); - } - - public static boolean isSingletonVariableName(String name) { - return name != null && name.startsWith(SINGLETON_VARIABLE_PREFIX); - } - - public static boolean isValidId(String name) { - return name != null && ID_REGEX.matcher(name).matches(); - } -} diff --git a/language/src/main/java/tools/refinery/language/naming/ProblemQualifiedNameConverter.java b/language/src/main/java/tools/refinery/language/naming/ProblemQualifiedNameConverter.java deleted file mode 100644 index 5453906f..00000000 --- a/language/src/main/java/tools/refinery/language/naming/ProblemQualifiedNameConverter.java +++ /dev/null @@ -1,15 +0,0 @@ -package tools.refinery.language.naming; - -import org.eclipse.xtext.naming.IQualifiedNameConverter; - -import com.google.inject.Singleton; - -@Singleton -public class ProblemQualifiedNameConverter extends IQualifiedNameConverter.DefaultImpl { - public static final String DELIMITER = "::"; - - @Override - public String getDelimiter() { - return DELIMITER; - } -} diff --git a/language/src/main/java/tools/refinery/language/resource/DerivedVariableComputer.java b/language/src/main/java/tools/refinery/language/resource/DerivedVariableComputer.java deleted file mode 100644 index bb1226c4..00000000 --- a/language/src/main/java/tools/refinery/language/resource/DerivedVariableComputer.java +++ /dev/null @@ -1,194 +0,0 @@ -package tools.refinery.language.resource; - -import java.util.HashSet; -import java.util.List; -import java.util.Set; - -import org.eclipse.xtext.linking.impl.LinkingHelper; -import org.eclipse.xtext.naming.IQualifiedNameConverter; -import org.eclipse.xtext.nodemodel.INode; -import org.eclipse.xtext.nodemodel.util.NodeModelUtils; -import org.eclipse.xtext.scoping.IScope; -import org.eclipse.xtext.scoping.IScopeProvider; -import org.eclipse.xtext.scoping.impl.AbstractDeclarativeScopeProvider; - -import com.google.inject.Inject; -import com.google.inject.Singleton; -import com.google.inject.name.Named; - -import tools.refinery.language.model.problem.Argument; -import tools.refinery.language.model.problem.Atom; -import tools.refinery.language.model.problem.Conjunction; -import tools.refinery.language.model.problem.ExistentialQuantifier; -import tools.refinery.language.model.problem.ImplicitVariable; -import tools.refinery.language.model.problem.Literal; -import tools.refinery.language.model.problem.NegativeLiteral; -import tools.refinery.language.model.problem.Parameter; -import tools.refinery.language.model.problem.ParametricDefinition; -import tools.refinery.language.model.problem.Problem; -import tools.refinery.language.model.problem.ProblemFactory; -import tools.refinery.language.model.problem.ProblemPackage; -import tools.refinery.language.model.problem.Statement; -import tools.refinery.language.model.problem.ValueLiteral; -import tools.refinery.language.model.problem.VariableOrNodeArgument; -import tools.refinery.language.naming.NamingUtil; - -@Singleton -public class DerivedVariableComputer { - @Inject - private LinkingHelper linkingHelper; - - @Inject - private IQualifiedNameConverter qualifiedNameConverter; - - @Inject - @Named(AbstractDeclarativeScopeProvider.NAMED_DELEGATE) - private IScopeProvider scopeProvider; - - public void installDerivedVariables(Problem problem, Set nodeNames) { - for (Statement statement : problem.getStatements()) { - if (statement instanceof ParametricDefinition definition) { - installDerivedParametricDefinitionState(definition, nodeNames); - } - } - } - - protected void installDerivedParametricDefinitionState(ParametricDefinition definition, Set nodeNames) { - Set knownVariables = new HashSet<>(); - knownVariables.addAll(nodeNames); - for (Parameter parameter : definition.getParameters()) { - String name = parameter.getName(); - if (name != null) { - knownVariables.add(name); - } - } - for (Conjunction body : definition.getBodies()) { - installDeriveConjunctionState(body, knownVariables); - } - } - - protected void installDeriveConjunctionState(Conjunction conjunction, Set knownVariables) { - Set newVariables = new HashSet<>(); - for (Literal literal : conjunction.getLiterals()) { - if (literal instanceof Atom atom) { - createSigletonVariablesAndCollectVariables(atom, knownVariables, newVariables); - } else - if (literal instanceof ValueLiteral valueLiteral) { - createSigletonVariablesAndCollectVariables(valueLiteral.getAtom(), knownVariables, newVariables); - } - } - createVariables(conjunction, newVariables); - newVariables.addAll(knownVariables); - for (Literal literal : conjunction.getLiterals()) { - if (literal instanceof NegativeLiteral negativeLiteral) { - installDeriveNegativeLiteralState(negativeLiteral, newVariables); - } - } - } - - protected void installDeriveNegativeLiteralState(NegativeLiteral negativeLiteral, Set knownVariables) { - Set newVariables = new HashSet<>(); - createSigletonVariablesAndCollectVariables(negativeLiteral.getAtom(), knownVariables, newVariables); - createVariables(negativeLiteral, newVariables); - } - - protected void createSigletonVariablesAndCollectVariables(Atom atom, Set knownVariables, - Set newVariables) { - for (Argument argument : atom.getArguments()) { - if (argument instanceof VariableOrNodeArgument variableOrNodeArgument) { - IScope scope = scopeProvider.getScope(variableOrNodeArgument, - ProblemPackage.Literals.VARIABLE_OR_NODE_ARGUMENT__VARIABLE_OR_NODE); - List nodes = NodeModelUtils.findNodesForFeature(variableOrNodeArgument, - ProblemPackage.Literals.VARIABLE_OR_NODE_ARGUMENT__VARIABLE_OR_NODE); - for (INode node : nodes) { - var variableName = linkingHelper.getCrossRefNodeAsString(node, true); - var created = tryCreateVariableForArgument(variableOrNodeArgument, variableName, scope, - knownVariables, newVariables); - if (created) { - break; - } - } - } - } - } - - protected boolean tryCreateVariableForArgument(VariableOrNodeArgument variableOrNodeArgument, String variableName, - IScope scope, Set knownVariables, Set newVariables) { - if (!NamingUtil.isValidId(variableName)) { - return false; - } - var qualifiedName = qualifiedNameConverter.toQualifiedName(variableName); - if (scope.getSingleElement(qualifiedName) != null) { - return false; - } - if (NamingUtil.isSingletonVariableName(variableName)) { - createSingletonVariable(variableOrNodeArgument, variableName); - return true; - } - if (!knownVariables.contains(variableName)) { - newVariables.add(variableName); - return true; - } - return false; - } - - protected void createVariables(ExistentialQuantifier quantifier, Set newVariables) { - for (String variableName : newVariables) { - createVariable(quantifier, variableName); - } - } - - protected void createVariable(ExistentialQuantifier quantifier, String variableName) { - if (NamingUtil.isValidId(variableName)) { - ImplicitVariable variable = createNamedVariable(variableName); - quantifier.getImplicitVariables().add(variable); - } - } - - protected void createSingletonVariable(VariableOrNodeArgument argument, String variableName) { - if (NamingUtil.isValidId(variableName)) { - ImplicitVariable variable = createNamedVariable(variableName); - argument.setSingletonVariable(variable); - } - } - - protected ImplicitVariable createNamedVariable(String variableName) { - var variable = ProblemFactory.eINSTANCE.createImplicitVariable(); - variable.setName(variableName); - return variable; - } - - public void discardDerivedVariables(Problem problem) { - for (Statement statement : problem.getStatements()) { - if (statement instanceof ParametricDefinition parametricDefinition) { - discardParametricDefinitionState(parametricDefinition); - } - } - } - - protected void discardParametricDefinitionState(ParametricDefinition definition) { - for (Conjunction body : definition.getBodies()) { - body.getImplicitVariables().clear(); - for (Literal literal : body.getLiterals()) { - if (literal instanceof Atom atom) { - discardDerivedAtomState(atom); - } - if (literal instanceof NegativeLiteral negativeLiteral) { - negativeLiteral.getImplicitVariables().clear(); - discardDerivedAtomState(negativeLiteral.getAtom()); - } - } - } - } - - protected void discardDerivedAtomState(Atom atom) { - if (atom == null) { - return; - } - for (Argument argument : atom.getArguments()) { - if (argument instanceof VariableOrNodeArgument variableOrNodeArgument) { - variableOrNodeArgument.setSingletonVariable(null); - } - } - } -} diff --git a/language/src/main/java/tools/refinery/language/resource/NodeNameCollector.java b/language/src/main/java/tools/refinery/language/resource/NodeNameCollector.java deleted file mode 100644 index 99bf9b64..00000000 --- a/language/src/main/java/tools/refinery/language/resource/NodeNameCollector.java +++ /dev/null @@ -1,88 +0,0 @@ -package tools.refinery.language.resource; - -import java.util.List; -import java.util.Set; - -import org.eclipse.emf.ecore.EObject; -import org.eclipse.emf.ecore.EStructuralFeature; -import org.eclipse.xtext.linking.impl.LinkingHelper; -import org.eclipse.xtext.naming.IQualifiedNameConverter; -import org.eclipse.xtext.nodemodel.INode; -import org.eclipse.xtext.nodemodel.util.NodeModelUtils; -import org.eclipse.xtext.scoping.IScope; -import org.eclipse.xtext.scoping.IScopeProvider; -import org.eclipse.xtext.scoping.impl.AbstractDeclarativeScopeProvider; - -import com.google.common.collect.ImmutableSet; -import com.google.inject.Inject; -import com.google.inject.name.Named; - -import tools.refinery.language.model.problem.Assertion; -import tools.refinery.language.model.problem.AssertionArgument; -import tools.refinery.language.model.problem.NodeAssertionArgument; -import tools.refinery.language.model.problem.NodeValueAssertion; -import tools.refinery.language.model.problem.Problem; -import tools.refinery.language.model.problem.ProblemPackage; -import tools.refinery.language.model.problem.Statement; -import tools.refinery.language.naming.NamingUtil; - -public class NodeNameCollector { - @Inject - private LinkingHelper linkingHelper; - - @Inject - private IQualifiedNameConverter qualifiedNameConverter; - - @Inject - @Named(AbstractDeclarativeScopeProvider.NAMED_DELEGATE) - private IScopeProvider scopeProvider; - - private final ImmutableSet.Builder nodeNames = ImmutableSet.builder(); - - private IScope nodeScope; - - public Set getNodeNames() { - return nodeNames.build(); - } - - public void collectNodeNames(Problem problem) { - nodeScope = scopeProvider.getScope(problem, ProblemPackage.Literals.NODE_ASSERTION_ARGUMENT__NODE); - for (Statement statement : problem.getStatements()) { - collectStatementNodeNames(statement); - } - } - - protected void collectStatementNodeNames(Statement statement) { - if (statement instanceof Assertion assertion) { - collectAssertionNodeNames(assertion); - } else if (statement instanceof NodeValueAssertion nodeValueAssertion) { - collectNodeValueAssertionNodeNames(nodeValueAssertion); - } - } - - protected void collectAssertionNodeNames(Assertion assertion) { - for (AssertionArgument argument : assertion.getArguments()) { - if (argument instanceof NodeAssertionArgument) { - collectNodeNames(argument, ProblemPackage.Literals.NODE_ASSERTION_ARGUMENT__NODE); - } - } - } - - protected void collectNodeValueAssertionNodeNames(NodeValueAssertion nodeValueAssertion) { - collectNodeNames(nodeValueAssertion, ProblemPackage.Literals.NODE_VALUE_ASSERTION__NODE); - } - - private void collectNodeNames(EObject eObject, EStructuralFeature feature) { - List nodes = NodeModelUtils.findNodesForFeature(eObject, feature); - for (INode node : nodes) { - var nodeName = linkingHelper.getCrossRefNodeAsString(node, true); - if (!NamingUtil.isValidId(nodeName)) { - continue; - } - var qualifiedName = qualifiedNameConverter.toQualifiedName(nodeName); - if (nodeScope.getSingleElement(qualifiedName) == null) { - nodeNames.add(nodeName); - } - } - } -} \ No newline at end of file diff --git a/language/src/main/java/tools/refinery/language/resource/ProblemDerivedStateComputer.java b/language/src/main/java/tools/refinery/language/resource/ProblemDerivedStateComputer.java deleted file mode 100644 index 275feca3..00000000 --- a/language/src/main/java/tools/refinery/language/resource/ProblemDerivedStateComputer.java +++ /dev/null @@ -1,163 +0,0 @@ -package tools.refinery.language.resource; - -import java.util.Collection; -import java.util.HashMap; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Set; -import java.util.function.Function; - -import org.eclipse.emf.common.notify.impl.AdapterImpl; -import org.eclipse.emf.ecore.EObject; -import org.eclipse.emf.ecore.resource.Resource; -import org.eclipse.emf.ecore.util.EcoreUtil; -import org.eclipse.xtext.Constants; -import org.eclipse.xtext.resource.DerivedStateAwareResource; -import org.eclipse.xtext.resource.IDerivedStateComputer; -import org.eclipse.xtext.resource.XtextResource; -import org.eclipse.xtext.scoping.IScopeProvider; -import org.eclipse.xtext.scoping.impl.AbstractDeclarativeScopeProvider; - -import com.google.inject.Inject; -import com.google.inject.Provider; -import com.google.inject.Singleton; -import com.google.inject.name.Named; - -import tools.refinery.language.model.problem.ClassDeclaration; -import tools.refinery.language.model.problem.Node; -import tools.refinery.language.model.problem.Problem; -import tools.refinery.language.model.problem.ProblemFactory; -import tools.refinery.language.model.problem.Statement; - -@Singleton -public class ProblemDerivedStateComputer implements IDerivedStateComputer { - public static final String NEW_NODE = "new"; - - @Inject - @Named(Constants.LANGUAGE_NAME) - private String languageName; - - @Inject - @Named(AbstractDeclarativeScopeProvider.NAMED_DELEGATE) - private IScopeProvider scopeProvider; - - @Inject - private Provider nodeNameCollectorProvider; - - @Inject - private DerivedVariableComputer derivedVariableComputer; - - @Override - public void installDerivedState(DerivedStateAwareResource resource, boolean preLinkingPhase) { - var problem = getProblem(resource); - if (problem != null) { - var adapter = getOrInstallAdapter(resource); - installDerivedProblemState(problem, adapter, preLinkingPhase); - } - } - - protected Problem getProblem(Resource resource) { - List contents = resource.getContents(); - if (contents.isEmpty()) { - return null; - } - EObject object = contents.get(0); - if (object instanceof Problem problem) { - return problem; - } - return null; - } - - protected void installDerivedProblemState(Problem problem, Adapter adapter, boolean preLinkingPhase) { - installNewNodes(problem, adapter); - if (preLinkingPhase) { - return; - } - Set nodeNames = installDerivedNodes(problem); - derivedVariableComputer.installDerivedVariables(problem, nodeNames); - } - - protected void installNewNodes(Problem problem, Adapter adapter) { - for (Statement statement : problem.getStatements()) { - if (statement instanceof ClassDeclaration declaration && !declaration.isAbstract() - && declaration.getNewNode() == null) { - var newNode = adapter.createNodeIfAbsent(declaration, key -> createNode(NEW_NODE)); - declaration.setNewNode(newNode); - } - } - } - - protected Set installDerivedNodes(Problem problem) { - var collector = nodeNameCollectorProvider.get(); - collector.collectNodeNames(problem); - Set nodeNames = collector.getNodeNames(); - List grapNodes = problem.getNodes(); - for (String nodeName : nodeNames) { - var graphNode = createNode(nodeName); - grapNodes.add(graphNode); - } - return nodeNames; - } - - protected Node createNode(String name) { - var node = ProblemFactory.eINSTANCE.createNode(); - node.setName(name); - return node; - } - - @Override - public void discardDerivedState(DerivedStateAwareResource resource) { - var problem = getProblem(resource); - if (problem != null) { - var adapter = getOrInstallAdapter(resource); - discardDerivedProblemState(problem, adapter); - } - } - - protected void discardDerivedProblemState(Problem problem, Adapter adapter) { - Set classDeclarations = new HashSet<>(); - problem.getNodes().clear(); - for (Statement statement : problem.getStatements()) { - if (statement instanceof ClassDeclaration classDeclaration) { - classDeclaration.setNewNode(null); - classDeclarations.add(classDeclaration); - } - } - adapter.retainAll(classDeclarations); - derivedVariableComputer.discardDerivedVariables(problem); - } - - protected Adapter getOrInstallAdapter(Resource resource) { - if (!(resource instanceof XtextResource)) { - return new Adapter(); - } - String resourceLanguageName = ((XtextResource) resource).getLanguageName(); - if (!languageName.equals(resourceLanguageName)) { - return new Adapter(); - } - var adapter = (Adapter) EcoreUtil.getAdapter(resource.eAdapters(), Adapter.class); - if (adapter == null) { - adapter = new Adapter(); - resource.eAdapters().add(adapter); - } - return adapter; - } - - protected static class Adapter extends AdapterImpl { - private Map newNodes = new HashMap<>(); - - public Node createNodeIfAbsent(ClassDeclaration classDeclaration, Function createNode) { - return newNodes.computeIfAbsent(classDeclaration, createNode); - } - - public void retainAll(Collection classDeclarations) { - newNodes.keySet().retainAll(classDeclarations); - } - - @Override - public boolean isAdapterForType(Object type) { - return Adapter.class == type; - } - } -} diff --git a/language/src/main/java/tools/refinery/language/resource/ProblemLocationInFileProvider.java b/language/src/main/java/tools/refinery/language/resource/ProblemLocationInFileProvider.java deleted file mode 100644 index 7aa75833..00000000 --- a/language/src/main/java/tools/refinery/language/resource/ProblemLocationInFileProvider.java +++ /dev/null @@ -1,33 +0,0 @@ -package tools.refinery.language.resource; - -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.model.problem.ImplicitVariable; -import tools.refinery.language.model.problem.Node; - -public class ProblemLocationInFileProvider extends DefaultLocationInFileProvider { - @Override - protected ITextRegion doGetTextRegion(EObject obj, RegionDescription query) { - if (obj instanceof Node node) { - return getNodeTextRegion(node, query); - } - if (obj instanceof ImplicitVariable) { - return ITextRegion.EMPTY_REGION; - } - return super.doGetTextRegion(obj, query); - } - - protected ITextRegion getNodeTextRegion(Node node, RegionDescription query) { - if (ProblemUtil.isIndividualNode(node)) { - return super.doGetTextRegion(node, query); - } - if (ProblemUtil.isNewNode(node)) { - EObject container = node.eContainer(); - return doGetTextRegion(container, query); - } - return ITextRegion.EMPTY_REGION; - } -} diff --git a/language/src/main/java/tools/refinery/language/resource/ProblemResourceDescriptionStrategy.java b/language/src/main/java/tools/refinery/language/resource/ProblemResourceDescriptionStrategy.java deleted file mode 100644 index f86ebd38..00000000 --- a/language/src/main/java/tools/refinery/language/resource/ProblemResourceDescriptionStrategy.java +++ /dev/null @@ -1,103 +0,0 @@ -package tools.refinery.language.resource; - -import org.eclipse.emf.ecore.EObject; -import org.eclipse.xtext.EcoreUtil2; -import org.eclipse.xtext.naming.IQualifiedNameConverter; -import org.eclipse.xtext.naming.QualifiedName; -import org.eclipse.xtext.resource.EObjectDescription; -import org.eclipse.xtext.resource.IEObjectDescription; -import org.eclipse.xtext.resource.impl.DefaultResourceDescriptionStrategy; -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.model.problem.NamedElement; -import tools.refinery.language.model.problem.Node; -import tools.refinery.language.model.problem.Problem; -import tools.refinery.language.model.problem.Variable; -import tools.refinery.language.naming.NamingUtil; - -@Singleton -public class ProblemResourceDescriptionStrategy extends DefaultResourceDescriptionStrategy { - @Inject - private IQualifiedNameConverter qualifiedNameConverter; - - @Override - public boolean createEObjectDescriptions(EObject eObject, IAcceptor acceptor) { - if (!shouldExport(eObject)) { - return false; - } - var qualifiedName = getNameAsQualifiedName(eObject); - if (qualifiedName == null) { - return true; - } - var problem = EcoreUtil2.getContainerOfType(eObject, Problem.class); - var problemQualifiedName = getNameAsQualifiedName(problem); - boolean nameExported; - if (shouldExportSimpleName(eObject)) { - acceptEObjectDescription(eObject, problemQualifiedName, qualifiedName, acceptor); - nameExported = true; - } else { - nameExported = false; - } - var parent = eObject.eContainer(); - while (parent != null && parent != problem) { - var parentQualifiedName = getNameAsQualifiedName(parent); - if (parentQualifiedName == null) { - parent = parent.eContainer(); - continue; - } - qualifiedName = parentQualifiedName.append(qualifiedName); - if (shouldExportSimpleName(parent)) { - acceptEObjectDescription(eObject, problemQualifiedName, qualifiedName, acceptor); - nameExported = true; - } else { - nameExported = false; - } - parent = parent.eContainer(); - } - if (!nameExported) { - acceptEObjectDescription(eObject, problemQualifiedName, qualifiedName, acceptor); - } - return true; - } - - protected QualifiedName getNameAsQualifiedName(EObject eObject) { - if (!(eObject instanceof NamedElement)) { - return null; - } - var namedElement = (NamedElement) eObject; - var name = namedElement.getName(); - if (NamingUtil.isNullOrEmpty(name)) { - return null; - } - return qualifiedNameConverter.toQualifiedName(name); - } - - protected boolean shouldExport(EObject eObject) { - if (eObject instanceof Variable) { - // Variables are always private to the containing predicate definition. - return false; - } - if (eObject instanceof Node node) { - // Only enum literals and new nodes are visible across problem files. - return ProblemUtil.isIndividualNode(node) || ProblemUtil.isNewNode(node); - } - return true; - } - - protected boolean shouldExportSimpleName(EObject eObject) { - if (eObject instanceof Node node) { - return !ProblemUtil.isNewNode(node); - } - return true; - } - - private void acceptEObjectDescription(EObject eObject, QualifiedName prefix, QualifiedName qualifiedName, - IAcceptor acceptor) { - var qualifiedNameWithPrefix = prefix == null ? qualifiedName : prefix.append(qualifiedName); - acceptor.accept(EObjectDescription.create(qualifiedNameWithPrefix, eObject)); - } -} diff --git a/language/src/main/java/tools/refinery/language/resource/ProblemXmiResourceFactory.java b/language/src/main/java/tools/refinery/language/resource/ProblemXmiResourceFactory.java deleted file mode 100644 index 68aa6016..00000000 --- a/language/src/main/java/tools/refinery/language/resource/ProblemXmiResourceFactory.java +++ /dev/null @@ -1,16 +0,0 @@ -package tools.refinery.language.resource; - -import org.eclipse.emf.common.util.URI; -import org.eclipse.emf.ecore.resource.Resource; -import org.eclipse.xtext.resource.IResourceFactory; - -import tools.refinery.language.model.problem.util.ProblemResourceFactoryImpl; - -public class ProblemXmiResourceFactory implements IResourceFactory { - private Resource.Factory problemResourceFactory = new ProblemResourceFactoryImpl(); - - @Override - public Resource createResource(URI uri) { - return problemResourceFactory.createResource(uri); - } -} diff --git a/language/src/main/java/tools/refinery/language/resource/ReferenceCounter.java b/language/src/main/java/tools/refinery/language/resource/ReferenceCounter.java deleted file mode 100644 index 7525dfc6..00000000 --- a/language/src/main/java/tools/refinery/language/resource/ReferenceCounter.java +++ /dev/null @@ -1,51 +0,0 @@ -package tools.refinery.language.resource; - -import java.util.HashMap; -import java.util.Map; - -import org.eclipse.emf.ecore.EObject; -import org.eclipse.xtext.util.IResourceScopeCache; - -import com.google.inject.Inject; -import com.google.inject.Singleton; - -import tools.refinery.language.model.problem.Problem; - -@Singleton -public class ReferenceCounter { - @Inject - private IResourceScopeCache cache; - - public int countReferences(Problem problem, EObject eObject) { - var count = getReferenceCounts(problem).get(eObject); - if (count == null) { - return 0; - } - return count; - } - - protected Map getReferenceCounts(Problem problem) { - var resource = problem.eResource(); - if (resource == null) { - return doGetReferenceCounts(problem); - } - return cache.get(problem, resource, () -> doGetReferenceCounts(problem)); - } - - protected Map doGetReferenceCounts(Problem problem) { - var map = new HashMap(); - countCrossReferences(problem, map); - var iterator = problem.eAllContents(); - while (iterator.hasNext()) { - var eObject = iterator.next(); - countCrossReferences(eObject, map); - } - return map; - } - - protected void countCrossReferences(EObject eObject, Map map) { - for (var referencedObject : eObject.eCrossReferences()) { - map.compute(referencedObject, (key, currentValue) -> currentValue == null ? 1 : currentValue + 1); - } - } -} diff --git a/language/src/main/java/tools/refinery/language/scoping/ProblemGlobalScopeProvider.java b/language/src/main/java/tools/refinery/language/scoping/ProblemGlobalScopeProvider.java deleted file mode 100644 index b582d16b..00000000 --- a/language/src/main/java/tools/refinery/language/scoping/ProblemGlobalScopeProvider.java +++ /dev/null @@ -1,18 +0,0 @@ -package tools.refinery.language.scoping; - -import java.util.LinkedHashSet; - -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; - -public class ProblemGlobalScopeProvider extends ImportUriGlobalScopeProvider { - @Override - protected LinkedHashSet getImportedUris(Resource resource) { - LinkedHashSet importedUris = new LinkedHashSet<>(); - importedUris.add(ProblemUtil.BUILTIN_LIBRARY_URI); - return importedUris; - } -} diff --git a/language/src/main/java/tools/refinery/language/scoping/ProblemLocalScopeProvider.java b/language/src/main/java/tools/refinery/language/scoping/ProblemLocalScopeProvider.java deleted file mode 100644 index 85797025..00000000 --- a/language/src/main/java/tools/refinery/language/scoping/ProblemLocalScopeProvider.java +++ /dev/null @@ -1,42 +0,0 @@ -package tools.refinery.language.scoping; - -import java.util.List; - -import org.eclipse.emf.ecore.EObject; -import org.eclipse.emf.ecore.resource.Resource; -import org.eclipse.xtext.naming.QualifiedName; -import org.eclipse.xtext.resource.IResourceDescriptions; -import org.eclipse.xtext.resource.IResourceDescriptionsProvider; -import org.eclipse.xtext.resource.ISelectable; -import org.eclipse.xtext.scoping.impl.ImportNormalizer; -import org.eclipse.xtext.scoping.impl.ImportedNamespaceAwareLocalScopeProvider; - -import com.google.inject.Inject; - -import tools.refinery.language.model.ProblemUtil; - -public class ProblemLocalScopeProvider extends ImportedNamespaceAwareLocalScopeProvider { - private static final QualifiedName BUILTIN_LIBRARY_QUALIFIED_NAME = QualifiedName - .create(ProblemUtil.BUILTIN_LIBRARY_NAME); - - @Inject - private IResourceDescriptionsProvider resourceDescriptionsProvider; - - @Override - protected List getImplicitImports(boolean ignoreCase) { - return List.of(doCreateImportNormalizer(BUILTIN_LIBRARY_QUALIFIED_NAME, true, ignoreCase)); - } - - @Override - protected List getImportedNamespaceResolvers(EObject context, boolean ignoreCase) { - return List.of(); - } - - @Override - protected ISelectable internalGetAllDescriptions(Resource resource) { - // Force the use of ProblemResourceDescriptionStrategy to include all QualifiedNames of objects. - IResourceDescriptions resourceDescriptions = resourceDescriptionsProvider - .getResourceDescriptions(resource.getResourceSet()); - return resourceDescriptions.getResourceDescription(resource.getURI()); - } -} diff --git a/language/src/main/java/tools/refinery/language/scoping/ProblemScopeProvider.java b/language/src/main/java/tools/refinery/language/scoping/ProblemScopeProvider.java deleted file mode 100644 index d31a5308..00000000 --- a/language/src/main/java/tools/refinery/language/scoping/ProblemScopeProvider.java +++ /dev/null @@ -1,104 +0,0 @@ -/* - * generated by Xtext 2.25.0 - */ -package tools.refinery.language.scoping; - -import java.util.ArrayList; -import java.util.List; - -import org.eclipse.emf.ecore.EObject; -import org.eclipse.emf.ecore.EReference; -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.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; -import tools.refinery.language.model.problem.Variable; -import tools.refinery.language.model.problem.VariableOrNodeArgument; - -/** - * This class contains custom scoping description. - * - * See - * https://www.eclipse.org/Xtext/documentation/303_runtime_concepts.html#scoping - * on how and when to use it. - */ -public class ProblemScopeProvider extends AbstractProblemScopeProvider { - - @Override - public IScope getScope(EObject context, EReference reference) { - var scope = super.getScope(context, reference); - if (reference == ProblemPackage.Literals.NODE_ASSERTION_ARGUMENT__NODE - || reference == ProblemPackage.Literals.NODE_VALUE_ASSERTION__NODE) { - return getNodesScope(context, scope); - } - if (reference == ProblemPackage.Literals.VARIABLE_OR_NODE_ARGUMENT__VARIABLE_OR_NODE - || reference == ProblemPackage.Literals.DELETE_ACTION_LITERAL__VARIABLE_OR_NODE) { - return getVariableScope(context, scope); - } - if (reference == ProblemPackage.Literals.REFERENCE_DECLARATION__OPPOSITE) { - return getOppositeScope(context, scope); - } - return scope; - } - - protected IScope getNodesScope(EObject context, IScope delegateScope) { - var problem = EcoreUtil2.getContainerOfType(context, Problem.class); - if (problem == null) { - return delegateScope; - } - return Scopes.scopeFor(problem.getNodes(), delegateScope); - } - - protected IScope getVariableScope(EObject context, IScope delegateScope) { - List variables = new ArrayList<>(); - EObject currentContext = context; - if (context instanceof VariableOrNodeArgument argument) { - Variable singletonVariable = argument.getSingletonVariable(); - if (singletonVariable != null) { - variables.add(singletonVariable); - } - } - while (currentContext != null && !(currentContext instanceof ParametricDefinition)) { - if (currentContext instanceof ExistentialQuantifier quantifier) { - variables.addAll(quantifier.getImplicitVariables()); - } else - if(currentContext instanceof Action action) { - for (var literal : action.getActionLiterals()) { - if(literal instanceof NewActionLiteral newActionLiteral && newActionLiteral.getVariable() != null) { - variables.add(newActionLiteral.getVariable()); - } - } - } - currentContext = currentContext.eContainer(); - } - IScope parentScope = getNodesScope(context, delegateScope); - if (currentContext != null) { - ParametricDefinition definition = (ParametricDefinition) currentContext; - parentScope = Scopes.scopeFor(definition.getParameters(),parentScope); - } - return Scopes.scopeFor(variables,parentScope); - } - - protected IScope getOppositeScope(EObject context, IScope delegateScope) { - var referenceDeclaration = EcoreUtil2.getContainerOfType(context, ReferenceDeclaration.class); - if (referenceDeclaration == null) { - return delegateScope; - } - var relation = referenceDeclaration.getReferenceType(); - if (!(relation instanceof ClassDeclaration)) { - return delegateScope; - } - var classDeclaration = (ClassDeclaration) relation; - var referenceDeclarations = ProblemUtil.getAllReferenceDeclarations(classDeclaration); - return Scopes.scopeFor(referenceDeclarations, delegateScope); - } -} diff --git a/language/src/main/java/tools/refinery/language/validation/ProblemValidator.java b/language/src/main/java/tools/refinery/language/validation/ProblemValidator.java deleted file mode 100644 index 975fdca2..00000000 --- a/language/src/main/java/tools/refinery/language/validation/ProblemValidator.java +++ /dev/null @@ -1,62 +0,0 @@ -/* - * generated by Xtext 2.25.0 - */ -package tools.refinery.language.validation; - -import org.eclipse.xtext.EcoreUtil2; -import org.eclipse.xtext.validation.Check; - -import com.google.inject.Inject; - -import tools.refinery.language.model.ProblemUtil; -import tools.refinery.language.model.problem.Node; -import tools.refinery.language.model.problem.Problem; -import tools.refinery.language.model.problem.ProblemPackage; -import tools.refinery.language.model.problem.Variable; -import tools.refinery.language.model.problem.VariableOrNodeArgument; -import tools.refinery.language.resource.ReferenceCounter; - -/** - * This class contains custom validation rules. - * - * See - * https://www.eclipse.org/Xtext/documentation/303_runtime_concepts.html#validation - */ -public class ProblemValidator extends AbstractProblemValidator { - private static final String ISSUE_PREFIX = "tools.refinery.language.validation.ProblemValidator."; - - public static final String SINGLETON_VARIABLE_ISSUE = ISSUE_PREFIX + "SINGLETON_VARIABLE"; - - public static final String NON_INDIVIDUAL_NODE_ISSUE = ISSUE_PREFIX + "NON_INDIVIDUAL_NODE"; - - @Inject - private ReferenceCounter referenceCounter; - - @Check - public void checkUniqueVariable(VariableOrNodeArgument argument) { - var variableOrNode = argument.getVariableOrNode(); - if (variableOrNode instanceof Variable variable && ProblemUtil.isImplicitVariable(variable) - && !ProblemUtil.isSingletonVariable(variable)) { - var problem = EcoreUtil2.getContainerOfType(variable, Problem.class); - if (problem != null && referenceCounter.countReferences(problem, variable) <= 1) { - var name = variable.getName(); - var message = "Variable '%s' has only a single reference. Add another reference or mark is as a singleton variable: '_%s'" - .formatted(name, name); - warning(message, argument, ProblemPackage.Literals.VARIABLE_OR_NODE_ARGUMENT__VARIABLE_OR_NODE, - INSIGNIFICANT_INDEX, SINGLETON_VARIABLE_ISSUE); - } - } - } - - @Check - public void checkNonUniqueNode(VariableOrNodeArgument argument) { - var variableOrNode = argument.getVariableOrNode(); - if (variableOrNode instanceof Node node && !ProblemUtil.isIndividualNode(node)) { - var name = node.getName(); - var message = "Only individual nodes can be referenced in predicates. Mark '%s' as individual with the declaration 'indiv %s.'" - .formatted(name, name); - error(message, argument, ProblemPackage.Literals.VARIABLE_OR_NODE_ARGUMENT__VARIABLE_OR_NODE, - INSIGNIFICANT_INDEX, NON_INDIVIDUAL_NODE_ISSUE); - } - } -} diff --git a/language/src/test/java/tools/refinery/language/tests/ProblemParsingTest.xtend b/language/src/test/java/tools/refinery/language/tests/ProblemParsingTest.xtend deleted file mode 100644 index 53d31a6c..00000000 --- a/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/language/src/test/java/tools/refinery/language/tests/formatting2/ProblemFormatterTest.java b/language/src/test/java/tools/refinery/language/tests/formatting2/ProblemFormatterTest.java deleted file mode 100644 index 41ad2d31..00000000 --- a/language/src/test/java/tools/refinery/language/tests/formatting2/ProblemFormatterTest.java +++ /dev/null @@ -1,235 +0,0 @@ -package tools.refinery.language.tests.formatting2; - -import static org.hamcrest.MatcherAssert.assertThat; -import static org.hamcrest.Matchers.equalTo; - -import java.util.List; - -import org.eclipse.xtext.formatting2.FormatterRequest; -import org.eclipse.xtext.formatting2.IFormatter2; -import org.eclipse.xtext.formatting2.regionaccess.ITextRegionAccess; -import org.eclipse.xtext.formatting2.regionaccess.ITextReplacement; -import org.eclipse.xtext.formatting2.regionaccess.TextRegionAccessBuilder; -import org.eclipse.xtext.resource.XtextResource; -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 com.google.inject.Inject; -import com.google.inject.Provider; - -import tools.refinery.language.model.problem.Problem; -import tools.refinery.language.tests.ProblemInjectorProvider; - -@ExtendWith(InjectionExtension.class) -@InjectWith(ProblemInjectorProvider.class) -class ProblemFormatterTest { - @Inject - private ParseHelper parseHelper; - - @Inject - private Provider formatterRequestProvider; - - @Inject - private TextRegionAccessBuilder regionBuilder; - - @Inject - private IFormatter2 formatter2; - - @Test - void problemNameTest() { - testFormatter(" problem problem . ", "problem problem.\n"); - } - - @Test - void assertionTest() { - testFormatter(" equals ( a , b , * ) : true . ", "equals(a, b, *): true.\n"); - } - - @Test - void defaultAssertionTest() { - testFormatter(" default equals ( a , b , * ) : true . ", "default equals(a, b, *): true.\n"); - } - - @Test - void assertionShortTrueTest() { - testFormatter(" equals ( a , b , * ) . ", "equals(a, b, *).\n"); - } - - @Test - void defaultAssertionShortTrueTest() { - testFormatter(" default equals ( a , b , * ) . ", "default equals(a, b, *).\n"); - } - - @Test - void assertionShortFalseTest() { - testFormatter(" ! equals ( a , b , * ) . ", "!equals(a, b, *).\n"); - } - - @Test - void defaultAssertionShortFalseTest() { - testFormatter(" default ! equals ( a , b , * ) . ", "default !equals(a, b, *).\n"); - } - - @Test - void assertionShortUnknownTest() { - testFormatter(" ? equals ( a , b , * ) . ", "?equals(a, b, *).\n"); - } - - @Test - void defaultAssertionShortUnknownTest() { - testFormatter(" default ? equals ( a , b , * ) . ", "default ?equals(a, b, *).\n"); - } - - @Test - void multipleAssertionsTest() { - testFormatter(" exists ( a ) . ? equals ( a , a ).", """ - exists(a). - ?equals(a, a). - """); - } - - @Test - void multipleAssertionsNamedProblemTest() { - testFormatter(" problem foo . exists ( a ) . ? equals ( a , a ).", """ - problem foo. - - exists(a). - ?equals(a, a). - """); - } - - @Test - void classWithoutBodyTest() { - testFormatter(" class Foo . ", "class Foo.\n"); - } - - @Test - void abstractClassWithoutBodyTest() { - testFormatter(" abstract class Foo . ", "abstract class Foo.\n"); - } - - @Test - void classExtendsWithoutBodyTest() { - testFormatter(" class Foo. class Bar . class Quux extends Foo , Bar . ", """ - class Foo. - - class Bar. - - class Quux extends Foo, Bar. - """); - } - - @Test - void classWithEmptyBodyTest() { - testFormatter(" class Foo { } ", """ - class Foo { - } - """); - } - - @Test - void classExtendsWithBodyTest() { - testFormatter(" class Foo. class Bar . class Quux extends Foo , Bar { } ", """ - class Foo. - - class Bar. - - class Quux extends Foo, Bar { - } - """); - } - - @Test - void predicateWithoutBodyTest() { - testFormatter(" pred foo ( node a , b ) . ", "pred foo(node a, b).\n"); - } - - @Test - void predicateWithBodyTest() { - testFormatter( - " pred foo ( node a , b ) <-> equal (a , _c ) , ! equal ( a , b ) ; equal+( a , b ) . ", - "pred foo(node a, b) <-> equal(a, _c), !equal(a, b); equal+(a, b).\n"); - } - - @Test - void predicatesWithoutBodyTest() { - testFormatter(" pred foo ( node a , b ) . pred bar ( node c ) . ", """ - pred foo(node a, b). - - pred bar(node c). - """); - } - - @Test - void predicateCommentsTest() { - testFormatter(""" - % Some foo - pred foo ( node a , b ) . - % Some bar - pred bar ( node c ) . - """, """ - % Some foo - pred foo(node a, b). - - % Some bar - pred bar(node c). - """); - } - - @Test - void individualDeclarationTest() { - testFormatter(" indiv a , b . ", "indiv a, b.\n"); - } - - @Test - void mixedDeclarationsTest() { - testFormatter(""" - problem test. - pred foo(node a). - class Foo. - foo(n1, n2). - indiv i1. - !foo(i1, n1). - pred bar(node a, node b). - pred quux(). - default !bar(*, *). - """, """ - problem test. - - pred foo(node a). - - class Foo. - - foo(n1, n2). - indiv i1. - !foo(i1, n1). - - pred bar(node a, node b). - - pred quux(). - - default !bar(*, *). - """); - } - - private void testFormatter(String toFormat, String expected) { - Problem problem; - try { - problem = parseHelper.parse(toFormat); - } catch (Exception e) { - throw new RuntimeException("Failed to parse document", e); - } - var resource = (XtextResource) problem.eResource(); - FormatterRequest request = formatterRequestProvider.get(); - request.setAllowIdentityEdits(false); - request.setFormatUndefinedHiddenRegionsOnly(false); - ITextRegionAccess regionAccess = regionBuilder.forNodeModel(resource).create(); - request.setTextRegionAccess(regionAccess); - List replacements = formatter2.format(request); - var formattedString = regionAccess.getRewriter().renderToString(replacements); - assertThat(formattedString, equalTo(expected)); - } -} diff --git a/language/src/test/java/tools/refinery/language/tests/rules/DirectRuleParsingTest.xtend b/language/src/test/java/tools/refinery/language/tests/rules/DirectRuleParsingTest.xtend deleted file mode 100644 index d60651a0..00000000 --- a/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/language/src/test/java/tools/refinery/language/tests/scoping/NodeScopingTest.xtend b/language/src/test/java/tools/refinery/language/tests/scoping/NodeScopingTest.xtend deleted file mode 100644 index 3a046341..00000000 --- a/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/language/src/test/java/tools/refinery/language/tests/serializer/ProblemSerializerTest.java b/language/src/test/java/tools/refinery/language/tests/serializer/ProblemSerializerTest.java deleted file mode 100644 index ba3aaeb7..00000000 --- a/language/src/test/java/tools/refinery/language/tests/serializer/ProblemSerializerTest.java +++ /dev/null @@ -1,229 +0,0 @@ -package tools.refinery.language.tests.serializer; - -import static org.hamcrest.MatcherAssert.assertThat; -import static org.hamcrest.Matchers.equalTo; - -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.util.Map; -import java.util.stream.Stream; - -import org.eclipse.emf.common.util.URI; -import org.eclipse.emf.ecore.resource.Resource; -import org.eclipse.emf.ecore.resource.ResourceSet; -import org.eclipse.xtext.testing.InjectWith; -import org.eclipse.xtext.testing.extensions.InjectionExtension; -import org.junit.jupiter.api.BeforeEach; -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 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; -import tools.refinery.language.model.problem.PredicateDefinition; -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.tests.ProblemInjectorProvider; - -@ExtendWith(InjectionExtension.class) -@InjectWith(ProblemInjectorProvider.class) -class ProblemSerializerTest { - @Inject - private ResourceSet resourceSet; - - @Inject - private ProblemTestUtil testUtil; - - private Resource resource; - - private Problem problem; - - private Problem builtin; - - @BeforeEach - void beforeEach() { - problem = ProblemFactory.eINSTANCE.createProblem(); - resource = resourceSet.createResource(URI.createFileURI("test.problem")); - resource.getContents().add(problem); - builtin = ProblemUtil.getBuiltInLibrary(problem).get(); - } - - @ParameterizedTest - @MethodSource - void assertionTest(LogicValue value, String serializedAssertion) { - var pred = createPred(); - var node = ProblemFactory.eINSTANCE.createNode(); - node.setName("a"); - var individualDeclaration = ProblemFactory.eINSTANCE.createIndividualDeclaration(); - individualDeclaration.getNodes().add(node); - problem.getStatements().add(individualDeclaration); - createAssertion(pred, node, value); - - assertSerializedResult(""" - pred foo(node p). - - indiv a. - """ + serializedAssertion + "\n"); - } - - static Stream assertionTest() { - return Stream.of(Arguments.of(LogicValue.TRUE, "foo(a)."), Arguments.of(LogicValue.FALSE, "!foo(a)."), - Arguments.of(LogicValue.UNKNOWN, "?foo(a)."), Arguments.of(LogicValue.ERROR, "foo(a): error.")); - } - - @Test - void implicitNodeTest() { - var pred = createPred(); - var node = ProblemFactory.eINSTANCE.createNode(); - node.setName("a"); - problem.getNodes().add(node); - createAssertion(pred, node); - - assertSerializedResult(""" - pred foo(node p). - - foo(a). - """); - } - - private PredicateDefinition createPred() { - var pred = ProblemFactory.eINSTANCE.createPredicateDefinition(); - pred.setName("foo"); - var parameter = ProblemFactory.eINSTANCE.createParameter(); - var nodeType = testUtil.findClass(builtin, "node"); - parameter.setParameterType(nodeType); - parameter.setName("p"); - pred.getParameters().add(parameter); - problem.getStatements().add(pred); - return pred; - } - - @Test - void newNodeTest() { - var classDeclaration = ProblemFactory.eINSTANCE.createClassDeclaration(); - classDeclaration.setName("Foo"); - var newNode = ProblemFactory.eINSTANCE.createNode(); - newNode.setName("new"); - classDeclaration.setNewNode(newNode); - problem.getStatements().add(classDeclaration); - createAssertion(classDeclaration, newNode); - - assertSerializedResult(""" - class Foo. - - Foo(Foo::new). - """); - } - - private void createAssertion(Relation relation, Node node) { - createAssertion(relation, node, LogicValue.TRUE); - } - - private void createAssertion(Relation relation, Node node, LogicValue value) { - var assertion = ProblemFactory.eINSTANCE.createAssertion(); - assertion.setRelation(relation); - var argument = ProblemFactory.eINSTANCE.createNodeAssertionArgument(); - argument.setNode(node); - assertion.getArguments().add(argument); - assertion.setValue(value); - problem.getStatements().add(assertion); - } - - @Test - void implicitVariableTest() { - var pred = ProblemFactory.eINSTANCE.createPredicateDefinition(); - pred.setName("foo"); - var nodeType = testUtil.findClass(builtin, "node"); - var parameter1 = ProblemFactory.eINSTANCE.createParameter(); - parameter1.setParameterType(nodeType); - parameter1.setName("p1"); - pred.getParameters().add(parameter1); - var parameter2 = ProblemFactory.eINSTANCE.createParameter(); - parameter2.setParameterType(nodeType); - 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"); - conjunction.getLiterals().add(createAtom(equals, parameter1, variable)); - conjunction.getLiterals().add(createAtom(equals, variable, parameter2)); - pred.getBodies().add(conjunction); - problem.getStatements().add(pred); - - assertSerializedResult(""" - pred foo(node p1, node p2) <-> equals(p1, q), equals(q, p2). - """); - } - - private Atom createAtom(Relation relation, VariableOrNode variable1, VariableOrNode variable2) { - var atom = ProblemFactory.eINSTANCE.createAtom(); - atom.setRelation(relation); - var arg1 = ProblemFactory.eINSTANCE.createVariableOrNodeArgument(); - arg1.setVariableOrNode(variable1); - atom.getArguments().add(arg1); - var arg2 = ProblemFactory.eINSTANCE.createVariableOrNodeArgument(); - arg2.setVariableOrNode(variable2); - atom.getArguments().add(arg2); - return atom; - } - - @Test - void singletonVariableTest() { - var pred = ProblemFactory.eINSTANCE.createPredicateDefinition(); - pred.setName("foo"); - var nodeType = testUtil.findClass(builtin, "node"); - var parameter = ProblemFactory.eINSTANCE.createParameter(); - parameter.setParameterType(nodeType); - parameter.setName("p"); - pred.getParameters().add(parameter); - var conjunction = ProblemFactory.eINSTANCE.createConjunction(); - var atom = ProblemFactory.eINSTANCE.createAtom(); - var equals = testUtil.reference(nodeType, "equals"); - atom.setRelation(equals); - var arg1 = ProblemFactory.eINSTANCE.createVariableOrNodeArgument(); - arg1.setVariableOrNode(parameter); - atom.getArguments().add(arg1); - var arg2 = ProblemFactory.eINSTANCE.createVariableOrNodeArgument(); - var variable = ProblemFactory.eINSTANCE.createImplicitVariable(); - variable.setName("_q"); - arg2.setSingletonVariable(variable); - arg2.setVariableOrNode(variable); - atom.getArguments().add(arg2); - conjunction.getLiterals().add(atom); - pred.getBodies().add(conjunction); - problem.getStatements().add(pred); - - assertSerializedResult(""" - pred foo(node p) <-> equals(p, _q). - """); - } - - private void assertSerializedResult(String expected) { - var outputStream = new ByteArrayOutputStream(); - try { - resource.save(outputStream, Map.of()); - } catch (IOException e) { - throw new AssertionError("Failed to serialize problem", e); - } finally { - try { - outputStream.close(); - } catch (IOException e) { - // Nothing to handle in a test. - } - } - var problemString = outputStream.toString(); - - assertThat(problemString, equalTo(expected)); - } -} -- cgit v1.2.3-54-g00ecf