Skip to content

Commit

Permalink
fix(language): singleton variable warnings
Browse files Browse the repository at this point in the history
  • Loading branch information
kris7t committed Dec 16, 2024
1 parent 4e3428f commit daa2cef
Show file tree
Hide file tree
Showing 2 changed files with 109 additions and 2 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
import com.google.inject.Inject;
import com.google.inject.Singleton;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.util.EContentsEList;
import org.eclipse.xtext.util.IResourceScopeCache;
import org.eclipse.xtext.util.Tuples;
import tools.refinery.language.model.problem.Problem;
Expand Down Expand Up @@ -51,8 +52,14 @@ public static Map<EObject, Integer> computeReferenceCounts(EObject root) {
}

private static void countCrossReferences(EObject eObject, Map<EObject, Integer> map) {
for (var referencedObject : eObject.eCrossReferences()) {
map.compute(referencedObject, (key, currentValue) -> currentValue == null ? 1 : currentValue + 1);
var featureIterator = (EContentsEList.FeatureIterator<EObject>) eObject.eCrossReferences().iterator();
while (featureIterator.hasNext()) {
var referencedObject = featureIterator.next();
// Avoid double-counting the derived reference {@code variableOrNode} of {@code VariableOrNodeExpression},
// as the original reference is just {@code element}.
if (!featureIterator.feature().isDerived()) {
map.compute(referencedObject, (key, currentValue) -> currentValue == null ? 1 : currentValue + 1);
}
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
/*
* SPDX-FileCopyrightText: 2024 The Refinery Authors <https://refinery.tools/>
*
* SPDX-License-Identifier: EPL-2.0
*/
package tools.refinery.language.tests.validation;

import com.google.inject.Inject;
import org.eclipse.emf.common.util.Diagnostic;
import org.junit.jupiter.api.Test;
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.tests.InjectWithRefinery;
import tools.refinery.language.tests.utils.ProblemParseHelper;
import tools.refinery.language.validation.ProblemValidator;

import java.util.stream.Stream;

import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.*;

@InjectWithRefinery
class VariableValidationTest {
@Inject
private ProblemParseHelper parseHelper;

@Test
void shouldBeSingletonVariableTest() {
var problem = parseHelper.parse("""
pred foo(a, b).
pred bar(a) <-> foo(a, shouldBeSingleton).
""");
var issues = problem.validate();
assertThat(issues, hasItem(allOf(
hasProperty("severity", is(Diagnostic.WARNING)),
hasProperty("issueCode", is(ProblemValidator.SINGLETON_VARIABLE_ISSUE)),
hasProperty("message", containsString("shouldBeSingleton"))
)));
}

@ParameterizedTest
@ValueSource(strings = {"_shouldBeSingleton", "_"})
void singletonVariableTest(String variableName) {
var problem = parseHelper.parse("""
pred foo(a, b).
pred bar(a) <-> foo(a, %s).
""".formatted(variableName));
var issues = problem.validate();
assertThat(issues, not(hasItem(
hasProperty("issueCode", is(ProblemValidator.SINGLETON_VARIABLE_ISSUE)))));
}

@ParameterizedTest
@MethodSource
void shouldBeAtomNodeTest(String declaration) {
var problem = parseHelper.parse("""
pred foo(a, b).
pred bar(a) <-> foo(a, shouldBeAtom).
%s
""".formatted(declaration));
var issues = problem.validate();
assertThat(issues, hasItem(allOf(
hasProperty("severity", is(Diagnostic.ERROR)),
hasProperty("issueCode", is(ProblemValidator.NODE_CONSTANT_ISSUE)),
hasProperty("message", containsString("shouldBeAtom"))
)));
}

public static Stream<Arguments> shouldBeAtomNodeTest() {
return Stream.of(
Arguments.of("node(shouldBeAtom)."),
Arguments.of("declare shouldBeAtom."),
Arguments.of("multi shouldBeAtom.")
);
}

@ParameterizedTest
@MethodSource("shouldBeAtomNodeTest")
void shouldBeAtomNodeRuleTest(String declaration) {
var problem = parseHelper.parse("""
pred foo(a, b).
rule bar(a) ==> foo(a, shouldBeAtom).
%s
""".formatted(declaration));
var issues = problem.validate();
assertThat(issues, hasItem(allOf(
hasProperty("severity", is(Diagnostic.ERROR)),
hasProperty("issueCode", is(ProblemValidator.NODE_CONSTANT_ISSUE)),
hasProperty("message", containsString("shouldBeAtom"))
)));
}
}

0 comments on commit daa2cef

Please sign in to comment.