From f3c4cf8d6ae236971a5789571471477f2f9dde2b Mon Sep 17 00:00:00 2001 From: Aron Zwaan Date: Mon, 16 Oct 2023 16:31:29 +0200 Subject: [PATCH 1/7] Treat spt test as file --- .../main/java/mb/spt/expectation/TransformExpectationUtil.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lwb/metalang/spt/spt/src/main/java/mb/spt/expectation/TransformExpectationUtil.java b/lwb/metalang/spt/spt/src/main/java/mb/spt/expectation/TransformExpectationUtil.java index f47f86779..3463d63ec 100644 --- a/lwb/metalang/spt/spt/src/main/java/mb/spt/expectation/TransformExpectationUtil.java +++ b/lwb/metalang/spt/spt/src/main/java/mb/spt/expectation/TransformExpectationUtil.java @@ -53,7 +53,7 @@ public class TransformExpectationUtil { @Nullable Region selection ) throws InterruptedException { try { - final CommandContext commandContext = CommandContext.ofReadableResource(resource, selection); + final CommandContext commandContext = CommandContext.ofFile(resource, selection); commandContext.setEnclosing(EnclosingCommandContextType.Directory, CommandContext.ofDirectory(resource)); commandContext.setEnclosing(EnclosingCommandContextType.Project, CommandContext.ofProject(resource)); final Task task = commandDef.createTask(CommandExecutionType.ManualOnce, commandContext, new ArgConverters(languageUnderTest.getResourceServiceComponent().getResourceService())); From e18f6360b0033e0590a1570bf1a50e9430c5d0c6 Mon Sep 17 00:00:00 2001 From: Aron Zwaan Date: Tue, 23 Jan 2024 09:22:19 +0100 Subject: [PATCH 2/7] Adaptions for AML --- .../java/mb/spoofax/eclipse/log/EclipseLoggerModule.java | 2 +- .../strategies/runtime/ExpandAllPredicatesStrategy.java | 1 + .../strategies/runtime/ExpandQueryStrategy.java | 6 +++++- .../java/mb/spt/expectation/CheckCountExpectation.java | 3 +++ .../java/mb/spt/expectation/CheckPatternExpectation.java | 3 +++ .../src/main/java/mb/spt/expectation/ParseExpectation.java | 3 +++ .../java/mb/spt/expectation/ParseToAtermExpectation.java | 4 ++++ .../mb/spt/expectation/ParseToFragmentExpectation.java | 2 ++ .../main/java/mb/spt/expectation/ResolveExpectation.java | 3 +++ .../java/mb/spt/expectation/RunStrategoExpectation.java | 3 +++ .../main/java/mb/spt/expectation/TransformExpectation.java | 4 +++- .../java/mb/spt/expectation/TransformExpectationUtil.java | 5 +++-- .../mb/spt/expectation/TransformToAtermExpectation.java | 4 +++- .../mb/spt/expectation/TransformToFragmentExpectation.java | 5 +++-- .../spt/src/main/java/mb/spt/model/TestExpectation.java | 4 ++++ .../spt/spt/src/main/java/mb/spt/task/SptCheck.java | 7 ++++--- .../spt/spt/src/main/java/mb/spt/task/SptRunTestSuite.java | 7 ++++--- 17 files changed, 52 insertions(+), 14 deletions(-) diff --git a/core/spoofax.eclipse/src/main/java/mb/spoofax/eclipse/log/EclipseLoggerModule.java b/core/spoofax.eclipse/src/main/java/mb/spoofax/eclipse/log/EclipseLoggerModule.java index b4546adca..96523ebed 100644 --- a/core/spoofax.eclipse/src/main/java/mb/spoofax/eclipse/log/EclipseLoggerModule.java +++ b/core/spoofax.eclipse/src/main/java/mb/spoofax/eclipse/log/EclipseLoggerModule.java @@ -8,7 +8,7 @@ @Module public class EclipseLoggerModule { @Provides @LoggerScope LoggerFactory provideLoggerFactory() { - return new EclipseLoggerFactory(); + return new EclipseLoggerFactory(mb.log.api.Level.Warn, mb.log.api.Level.Trace, "Spoofax"); } } diff --git a/core/statix.codecompletion/src/main/java/mb/statix/codecompletion/strategies/runtime/ExpandAllPredicatesStrategy.java b/core/statix.codecompletion/src/main/java/mb/statix/codecompletion/strategies/runtime/ExpandAllPredicatesStrategy.java index 266407387..7ccfad8f4 100644 --- a/core/statix.codecompletion/src/main/java/mb/statix/codecompletion/strategies/runtime/ExpandAllPredicatesStrategy.java +++ b/core/statix.codecompletion/src/main/java/mb/statix/codecompletion/strategies/runtime/ExpandAllPredicatesStrategy.java @@ -62,6 +62,7 @@ public static Seq eval( // An example where this happens is in this program, on the $Type placeholder: // let function $ID(): $Type = $Exp in 3 end // debugState(v, + final Strategy1, CCSolverState, CCSolverState> CCSolverState$withExpanded = StrategyExt.def("CCSolverState#withExpanded", "x", fun(CCSolverState::withExpanded)); diff --git a/core/statix.codecompletion/src/main/java/mb/statix/codecompletion/strategies/runtime/ExpandQueryStrategy.java b/core/statix.codecompletion/src/main/java/mb/statix/codecompletion/strategies/runtime/ExpandQueryStrategy.java index a81ca9aaf..8767c816c 100644 --- a/core/statix.codecompletion/src/main/java/mb/statix/codecompletion/strategies/runtime/ExpandQueryStrategy.java +++ b/core/statix.codecompletion/src/main/java/mb/statix/codecompletion/strategies/runtime/ExpandQueryStrategy.java @@ -150,7 +150,11 @@ public static Seq eval( if(!unifier.isGround(query.scopeTerm())) { // Delay final Delay delay = Delay.ofVars(unifier.getVars(query.scopeTerm())); - return Seq.of(input.withoutSelected().withDelay(query, delay)); + return Seq.of(input + .withoutSelected() + .withUpdatedConstraints(Collections.emptySet(), Collections.singleton(query)) + .withDelay(query, delay) + ); } @Nullable final Scope scope = Scope.matcher().match(query.scopeTerm(), unifier).orElse(null); assert scope != null; diff --git a/lwb/metalang/spt/spt/src/main/java/mb/spt/expectation/CheckCountExpectation.java b/lwb/metalang/spt/spt/src/main/java/mb/spt/expectation/CheckCountExpectation.java index c90adde3a..cf02c8504 100644 --- a/lwb/metalang/spt/spt/src/main/java/mb/spt/expectation/CheckCountExpectation.java +++ b/lwb/metalang/spt/spt/src/main/java/mb/spt/expectation/CheckCountExpectation.java @@ -10,12 +10,14 @@ import mb.pie.api.Session; import mb.pie.api.exec.CancelToken; import mb.resource.ResourceKey; +import mb.resource.hierarchical.ResourcePath; import mb.spt.lut.LanguageUnderTestProvider; import mb.spt.model.LanguageUnderTest; import mb.spt.model.SelectionReference; import mb.spt.model.TestCase; import mb.spt.model.TestExpectation; import mb.spt.util.SptMessageRemap; +import org.checkerframework.checker.nullness.qual.Nullable; import java.util.ArrayList; import java.util.stream.Collectors; @@ -77,6 +79,7 @@ public KeyedMessages evaluate( LanguageUnderTest languageUnderTest, Session languageUnderTestSession, LanguageUnderTestProvider languageUnderTestProvider, + @Nullable ResourcePath rootDirectoryHint, ExecContext context, CancelToken cancel ) throws InterruptedException { diff --git a/lwb/metalang/spt/spt/src/main/java/mb/spt/expectation/CheckPatternExpectation.java b/lwb/metalang/spt/spt/src/main/java/mb/spt/expectation/CheckPatternExpectation.java index 8457f1ce2..7e3b16981 100644 --- a/lwb/metalang/spt/spt/src/main/java/mb/spt/expectation/CheckPatternExpectation.java +++ b/lwb/metalang/spt/spt/src/main/java/mb/spt/expectation/CheckPatternExpectation.java @@ -10,12 +10,14 @@ import mb.pie.api.Session; import mb.pie.api.exec.CancelToken; import mb.resource.ResourceKey; +import mb.resource.hierarchical.ResourcePath; import mb.spt.lut.LanguageUnderTestProvider; import mb.spt.model.LanguageUnderTest; import mb.spt.model.SelectionReference; import mb.spt.model.TestCase; import mb.spt.model.TestExpectation; import mb.spt.util.SptMessageRemap; +import org.checkerframework.checker.nullness.qual.Nullable; import java.util.ArrayList; import java.util.stream.Collectors; @@ -39,6 +41,7 @@ public KeyedMessages evaluate( LanguageUnderTest languageUnderTest, Session languageUnderTestSession, LanguageUnderTestProvider languageUnderTestProvider, + @Nullable ResourcePath rootDirectoryHint, ExecContext context, CancelToken cancel ) throws InterruptedException { diff --git a/lwb/metalang/spt/spt/src/main/java/mb/spt/expectation/ParseExpectation.java b/lwb/metalang/spt/spt/src/main/java/mb/spt/expectation/ParseExpectation.java index be5bc87c9..959a2d5e3 100644 --- a/lwb/metalang/spt/spt/src/main/java/mb/spt/expectation/ParseExpectation.java +++ b/lwb/metalang/spt/spt/src/main/java/mb/spt/expectation/ParseExpectation.java @@ -9,6 +9,7 @@ import mb.pie.api.Session; import mb.pie.api.exec.CancelToken; import mb.resource.ResourceKey; +import mb.resource.hierarchical.ResourcePath; import mb.spoofax.core.language.LanguageInstance; import mb.spt.api.parse.ParseResult; import mb.spt.api.parse.TestableParse; @@ -17,6 +18,7 @@ import mb.spt.model.TestCase; import mb.spt.model.TestExpectation; import mb.spt.util.SptMessageRemap; +import org.checkerframework.checker.nullness.qual.Nullable; public class ParseExpectation implements TestExpectation { public enum Recovery { @@ -49,6 +51,7 @@ public KeyedMessages evaluate( LanguageUnderTest languageUnderTest, Session languageUnderTestSession, LanguageUnderTestProvider languageUnderTestProvider, + @Nullable ResourcePath rootDirectoryHint, ExecContext context, CancelToken cancel ) throws InterruptedException { diff --git a/lwb/metalang/spt/spt/src/main/java/mb/spt/expectation/ParseToAtermExpectation.java b/lwb/metalang/spt/spt/src/main/java/mb/spt/expectation/ParseToAtermExpectation.java index 25f147ae7..962f6b8f8 100644 --- a/lwb/metalang/spt/spt/src/main/java/mb/spt/expectation/ParseToAtermExpectation.java +++ b/lwb/metalang/spt/spt/src/main/java/mb/spt/expectation/ParseToAtermExpectation.java @@ -10,6 +10,7 @@ import mb.pie.api.Session; import mb.pie.api.exec.CancelToken; import mb.resource.ResourceKey; +import mb.resource.hierarchical.ResourcePath; import mb.spoofax.core.language.LanguageInstance; import mb.spt.lut.LanguageUnderTestProvider; import mb.spt.model.LanguageUnderTest; @@ -17,9 +18,11 @@ import mb.spt.api.parse.TestableParse; import mb.spt.model.TestExpectation; import mb.spt.util.SptAtermMatcher; +import org.checkerframework.checker.nullness.qual.Nullable; import org.spoofax.interpreter.terms.IStrategoTerm; import org.spoofax.terms.TermFactory; + public class ParseToAtermExpectation implements TestExpectation { private final IStrategoTerm expectedMatch; private final Region sourceRegion; @@ -35,6 +38,7 @@ public KeyedMessages evaluate( LanguageUnderTest languageUnderTest, Session languageUnderTestSession, LanguageUnderTestProvider languageUnderTestProvider, + @Nullable ResourcePath rootDirectoryHint, ExecContext context, CancelToken cancel ) throws InterruptedException { diff --git a/lwb/metalang/spt/spt/src/main/java/mb/spt/expectation/ParseToFragmentExpectation.java b/lwb/metalang/spt/spt/src/main/java/mb/spt/expectation/ParseToFragmentExpectation.java index 53d6860d0..ff6e34885 100644 --- a/lwb/metalang/spt/spt/src/main/java/mb/spt/expectation/ParseToFragmentExpectation.java +++ b/lwb/metalang/spt/spt/src/main/java/mb/spt/expectation/ParseToFragmentExpectation.java @@ -11,6 +11,7 @@ import mb.pie.api.Session; import mb.pie.api.exec.CancelToken; import mb.resource.ResourceKey; +import mb.resource.hierarchical.ResourcePath; import mb.spoofax.core.CoordinateRequirement; import mb.spoofax.core.language.LanguageInstance; import mb.spt.api.parse.TestableParse; @@ -38,6 +39,7 @@ public KeyedMessages evaluate( LanguageUnderTest languageUnderTest, Session languageUnderTestSession, LanguageUnderTestProvider languageUnderTestProvider, + @Nullable ResourcePath rootDirectoryHint, ExecContext context, CancelToken cancel ) throws InterruptedException { diff --git a/lwb/metalang/spt/spt/src/main/java/mb/spt/expectation/ResolveExpectation.java b/lwb/metalang/spt/spt/src/main/java/mb/spt/expectation/ResolveExpectation.java index 161d7addd..419783315 100644 --- a/lwb/metalang/spt/spt/src/main/java/mb/spt/expectation/ResolveExpectation.java +++ b/lwb/metalang/spt/spt/src/main/java/mb/spt/expectation/ResolveExpectation.java @@ -10,6 +10,7 @@ import mb.pie.api.Session; import mb.pie.api.exec.CancelToken; import mb.resource.ResourceKey; +import mb.resource.hierarchical.ResourcePath; import mb.spoofax.core.language.LanguageInstance; import mb.spt.api.resolve.TestableResolve; import mb.spt.lut.LanguageUnderTestProvider; @@ -18,6 +19,7 @@ import mb.spt.model.TestCase; import mb.spt.model.TestExpectation; import mb.spt.util.SptSelectionUtil; +import org.checkerframework.checker.nullness.qual.Nullable; public class ResolveExpectation implements TestExpectation { public final SelectionReference fromTerm; @@ -44,6 +46,7 @@ public KeyedMessages evaluate( LanguageUnderTest languageUnderTest, Session languageUnderTestSession, LanguageUnderTestProvider languageUnderTestProvider, + @Nullable ResourcePath rootDirectoryHint, ExecContext context, CancelToken cancel ) throws InterruptedException { diff --git a/lwb/metalang/spt/spt/src/main/java/mb/spt/expectation/RunStrategoExpectation.java b/lwb/metalang/spt/spt/src/main/java/mb/spt/expectation/RunStrategoExpectation.java index fccba81c2..1b1710ab6 100644 --- a/lwb/metalang/spt/spt/src/main/java/mb/spt/expectation/RunStrategoExpectation.java +++ b/lwb/metalang/spt/spt/src/main/java/mb/spt/expectation/RunStrategoExpectation.java @@ -11,6 +11,7 @@ import mb.pie.api.Session; import mb.pie.api.exec.CancelToken; import mb.resource.ResourceKey; +import mb.resource.hierarchical.ResourcePath; import mb.spoofax.core.language.LanguageInstance; import mb.spt.api.analyze.StrategoRunArgument; import mb.spt.api.stratego.TestableStratego; @@ -21,6 +22,7 @@ import mb.spt.model.TestCase; import mb.spt.model.TestExpectation; import mb.stratego.common.StrategoException; +import org.checkerframework.checker.nullness.qual.Nullable; import org.spoofax.interpreter.terms.IStrategoAppl; import org.spoofax.interpreter.terms.IStrategoInt; import org.spoofax.interpreter.terms.IStrategoString; @@ -62,6 +64,7 @@ public KeyedMessages evaluate( LanguageUnderTest languageUnderTest, Session languageUnderTestSession, LanguageUnderTestProvider languageUnderTestProvider, + @Nullable ResourcePath rootDirectoryHint, ExecContext context, CancelToken cancel ) throws InterruptedException { diff --git a/lwb/metalang/spt/spt/src/main/java/mb/spt/expectation/TransformExpectation.java b/lwb/metalang/spt/spt/src/main/java/mb/spt/expectation/TransformExpectation.java index ac434e758..71411fdde 100644 --- a/lwb/metalang/spt/spt/src/main/java/mb/spt/expectation/TransformExpectation.java +++ b/lwb/metalang/spt/spt/src/main/java/mb/spt/expectation/TransformExpectation.java @@ -9,6 +9,7 @@ import mb.pie.api.Session; import mb.pie.api.exec.CancelToken; import mb.resource.ResourceKey; +import mb.resource.hierarchical.ResourcePath; import mb.spoofax.core.language.command.CommandDef; import mb.spoofax.core.language.command.CommandFeedback; import mb.spt.lut.LanguageUnderTestProvider; @@ -37,6 +38,7 @@ public KeyedMessages evaluate( LanguageUnderTest languageUnderTest, Session languageUnderTestSession, LanguageUnderTestProvider languageUnderTestProvider, + @Nullable ResourcePath rootDirectoryHint, ExecContext context, CancelToken cancel ) throws InterruptedException { @@ -55,7 +57,7 @@ public KeyedMessages evaluate( final @Nullable Region selectionRegion = TransformExpectationUtil.getSelection(testCase, selectionReference); final @Nullable CommandFeedback feedback = TransformExpectationUtil.runCommand(testCase.resource, commandDef, - languageUnderTest, languageUnderTestSession, messagesBuilder, file, sourceRegion, selectionRegion); + languageUnderTest, languageUnderTestSession, messagesBuilder, file, rootDirectoryHint, sourceRegion, selectionRegion); if(feedback == null) { return messagesBuilder.build(file); } diff --git a/lwb/metalang/spt/spt/src/main/java/mb/spt/expectation/TransformExpectationUtil.java b/lwb/metalang/spt/spt/src/main/java/mb/spt/expectation/TransformExpectationUtil.java index 3463d63ec..20965a63d 100644 --- a/lwb/metalang/spt/spt/src/main/java/mb/spt/expectation/TransformExpectationUtil.java +++ b/lwb/metalang/spt/spt/src/main/java/mb/spt/expectation/TransformExpectationUtil.java @@ -49,13 +49,14 @@ public class TransformExpectationUtil { Session languageUnderTestSession, KeyedMessagesBuilder messagesBuilder, ResourceKey failMessageFile, + @Nullable ResourcePath rootDirectoryHint, Region fileMessageRegion, @Nullable Region selection ) throws InterruptedException { try { final CommandContext commandContext = CommandContext.ofFile(resource, selection); commandContext.setEnclosing(EnclosingCommandContextType.Directory, CommandContext.ofDirectory(resource)); - commandContext.setEnclosing(EnclosingCommandContextType.Project, CommandContext.ofProject(resource)); + commandContext.setEnclosing(EnclosingCommandContextType.Project, CommandContext.ofProject(rootDirectoryHint != null ? rootDirectoryHint : resource)); final Task task = commandDef.createTask(CommandExecutionType.ManualOnce, commandContext, new ArgConverters(languageUnderTest.getResourceServiceComponent().getResourceService())); return languageUnderTestSession.require(task); } catch(ExecException | ArgumentBuilderException e) { @@ -82,7 +83,7 @@ public static boolean isSelectionValid(TestCase testCase, Option availableSelections = testCase.testFragment.getInFragmentSelections(); + final ListView availableSelections = testCase.testFragment.getSelections(); return availableSelections.get(selectionReference.get().selection - 1); } } diff --git a/lwb/metalang/spt/spt/src/main/java/mb/spt/expectation/TransformToAtermExpectation.java b/lwb/metalang/spt/spt/src/main/java/mb/spt/expectation/TransformToAtermExpectation.java index 6ee4599b2..c616e3375 100644 --- a/lwb/metalang/spt/spt/src/main/java/mb/spt/expectation/TransformToAtermExpectation.java +++ b/lwb/metalang/spt/spt/src/main/java/mb/spt/expectation/TransformToAtermExpectation.java @@ -10,6 +10,7 @@ import mb.pie.api.Session; import mb.pie.api.exec.CancelToken; import mb.resource.ResourceKey; +import mb.resource.hierarchical.ResourcePath; import mb.spoofax.core.language.command.CommandDef; import mb.spoofax.core.language.command.CommandFeedback; import mb.spoofax.core.language.command.ShowFeedback; @@ -45,6 +46,7 @@ public KeyedMessages evaluate( LanguageUnderTest languageUnderTest, Session languageUnderTestSession, LanguageUnderTestProvider languageUnderTestProvider, + @Nullable ResourcePath rootDirectoryHint, ExecContext context, CancelToken cancel ) throws InterruptedException { @@ -63,7 +65,7 @@ public KeyedMessages evaluate( final @Nullable Region selectionRegion = TransformExpectationUtil.getSelection(testCase, selectionReference); final @Nullable CommandFeedback feedback = TransformExpectationUtil.runCommand(testCase.resource, commandDef, - languageUnderTest, languageUnderTestSession, messagesBuilder, file, sourceRegion, selectionRegion); + languageUnderTest, languageUnderTestSession, messagesBuilder, file, rootDirectoryHint, sourceRegion, selectionRegion); if(feedback == null) { return messagesBuilder.build(file); } diff --git a/lwb/metalang/spt/spt/src/main/java/mb/spt/expectation/TransformToFragmentExpectation.java b/lwb/metalang/spt/spt/src/main/java/mb/spt/expectation/TransformToFragmentExpectation.java index 6c446d45c..d1aeb582c 100644 --- a/lwb/metalang/spt/spt/src/main/java/mb/spt/expectation/TransformToFragmentExpectation.java +++ b/lwb/metalang/spt/spt/src/main/java/mb/spt/expectation/TransformToFragmentExpectation.java @@ -49,6 +49,7 @@ public KeyedMessages evaluate( LanguageUnderTest languageUnderTest, Session languageUnderTestSession, LanguageUnderTestProvider languageUnderTestProvider, + @Nullable ResourcePath rootDirectoryHint, ExecContext context, CancelToken cancel ) throws InterruptedException { @@ -67,7 +68,7 @@ public KeyedMessages evaluate( final @Nullable Region selectionRegion = TransformExpectationUtil.getSelection(testCase, selectionReference); final @Nullable CommandFeedback feedback = TransformExpectationUtil.runCommand(testCase.resource, commandDef, - languageUnderTest, languageUnderTestSession, messagesBuilder, file, sourceRegion, selectionRegion); + languageUnderTest, languageUnderTestSession, messagesBuilder, file, rootDirectoryHint, sourceRegion, selectionRegion); if(feedback == null) { return messagesBuilder.build(file); } @@ -83,7 +84,7 @@ public KeyedMessages evaluate( } final @Nullable CommandFeedback fragmentFeedback; try(final MixedSession session = fragmentLanguageUnderTest.getPieComponent().newSession() /* OPTO: share a single session for one test suite run. */) { - fragmentFeedback = TransformExpectationUtil.runCommand(fragmentResource, commandDef, fragmentLanguageUnderTest, session, messagesBuilder, file, sourceRegion, selectionRegion); + fragmentFeedback = TransformExpectationUtil.runCommand(fragmentResource, commandDef, fragmentLanguageUnderTest, session, messagesBuilder, file, rootDirectoryHint, sourceRegion, selectionRegion); } if(fragmentFeedback == null) { return messagesBuilder.build(file); diff --git a/lwb/metalang/spt/spt/src/main/java/mb/spt/model/TestExpectation.java b/lwb/metalang/spt/spt/src/main/java/mb/spt/model/TestExpectation.java index 90d5972e1..91aee60d5 100644 --- a/lwb/metalang/spt/spt/src/main/java/mb/spt/model/TestExpectation.java +++ b/lwb/metalang/spt/spt/src/main/java/mb/spt/model/TestExpectation.java @@ -4,14 +4,18 @@ import mb.pie.api.ExecContext; import mb.pie.api.Session; import mb.pie.api.exec.CancelToken; +import mb.resource.hierarchical.ResourcePath; import mb.spt.lut.LanguageUnderTestProvider; +import javax.annotation.Nullable; + public interface TestExpectation { KeyedMessages evaluate( TestCase testCase, LanguageUnderTest languageUnderTest, Session languageUnderTestSession, LanguageUnderTestProvider languageUnderTestProvider, + @Nullable ResourcePath rootDirectoryHint, ExecContext context, CancelToken cancel ) throws InterruptedException; diff --git a/lwb/metalang/spt/spt/src/main/java/mb/spt/task/SptCheck.java b/lwb/metalang/spt/spt/src/main/java/mb/spt/task/SptCheck.java index 9306eef66..d1015dc11 100644 --- a/lwb/metalang/spt/spt/src/main/java/mb/spt/task/SptCheck.java +++ b/lwb/metalang/spt/spt/src/main/java/mb/spt/task/SptCheck.java @@ -144,7 +144,7 @@ private void runTests( final Result languageUnderTestResult = languageUnderTestProvider.provide(context, file, rootDirectoryHint, testSuite.languageCoordinateRequirementHint); final CancelToken cancelToken = context.cancelToken(); languageUnderTestResult.ifThrowingElse( - languageUnderTest -> runTests(languageUnderTestProvider, context, languageUnderTest, cancelToken, messagesBuilder, testSuite), + languageUnderTest -> runTests(languageUnderTestProvider, context, languageUnderTest, cancelToken, messagesBuilder, testSuite, rootDirectoryHint), e -> messagesBuilder.addMessage("Cannot run tests, failed to get language under test", e, Severity.Error, file) ); } @@ -155,12 +155,13 @@ private void runTests( LanguageUnderTest languageUnderTest, CancelToken cancelToken, KeyedMessagesBuilder messagesBuilder, - TestSuite testSuite + TestSuite testSuite, + @Nullable ResourcePath rootDirectoryHint ) throws InterruptedException { try(final MixedSession languageUnderTestSession = languageUnderTest.getPieComponent().newSession()) { for(TestCase testCase : testSuite.testCases) { for(TestExpectation expectation : testCase.expectations) { - messagesBuilder.addMessages(expectation.evaluate(testCase, languageUnderTest, languageUnderTestSession, languageUnderTestProvider, context, cancelToken)); + messagesBuilder.addMessages(expectation.evaluate(testCase, languageUnderTest, languageUnderTestSession, languageUnderTestProvider, rootDirectoryHint, context, cancelToken)); } } } diff --git a/lwb/metalang/spt/spt/src/main/java/mb/spt/task/SptRunTestSuite.java b/lwb/metalang/spt/spt/src/main/java/mb/spt/task/SptRunTestSuite.java index c0a1bcc55..0ac6d8759 100644 --- a/lwb/metalang/spt/spt/src/main/java/mb/spt/task/SptRunTestSuite.java +++ b/lwb/metalang/spt/spt/src/main/java/mb/spt/task/SptRunTestSuite.java @@ -155,7 +155,7 @@ private TestSuiteResult runTests( final CancelToken cancelToken = context.cancelToken(); return languageUnderTestResult.mapThrowingOrElse( languageUnderTest -> { - ListView results = runTests(languageUnderTestProvider, context, languageUnderTest, cancelToken, testSuite); + ListView results = runTests(languageUnderTestProvider, context, languageUnderTest, cancelToken, testSuite, rootDirectoryHint); return new TestSuiteResult(messagesBuilder.build(), file, testSuite.name, results); }, (e) -> { @@ -170,7 +170,8 @@ private ListView runTests( ExecContext context, LanguageUnderTest languageUnderTest, CancelToken cancelToken, - TestSuite testSuite + TestSuite testSuite, + @Nullable ResourcePath rootDirectoryHint ) throws InterruptedException { List results = new ArrayList<>(); try(final MixedSession languageUnderTestSession = languageUnderTest.getPieComponent().newSession()) { @@ -180,7 +181,7 @@ private ListView runTests( final long startTime = System.currentTimeMillis(); for(TestExpectation expectation : testCase.expectations) { testMessageBuilder.addMessages( - expectation.evaluate(testCase, languageUnderTest, languageUnderTestSession, languageUnderTestProvider, context, cancelToken) + expectation.evaluate(testCase, languageUnderTest, languageUnderTestSession, languageUnderTestProvider, rootDirectoryHint, context, cancelToken) ); } final long duration = System.currentTimeMillis() - startTime; From c700f1ed18fe8dc517d721911ef3ef13f21e0e4a Mon Sep 17 00:00:00 2001 From: Aron Zwaan Date: Tue, 23 Jan 2024 11:30:09 +0100 Subject: [PATCH 3/7] Publish SPT CLI --- lwb/metalang/spt/spt.cli/build.gradle.kts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/lwb/metalang/spt/spt.cli/build.gradle.kts b/lwb/metalang/spt/spt.cli/build.gradle.kts index e316085df..9bda331ef 100644 --- a/lwb/metalang/spt/spt.cli/build.gradle.kts +++ b/lwb/metalang/spt/spt.cli/build.gradle.kts @@ -7,9 +7,11 @@ languageCliProject { adapterProject.set(project(":spt")) } +/* tasks { // Disable currently unused distribution tasks. distZip.configure { enabled = false } distTar.configure { enabled = false } startScripts.configure { enabled = false } } +*/ From 0721ee67d6b04560d165ebcd5d136983475043ca Mon Sep 17 00:00:00 2001 From: Aron Zwaan Date: Fri, 26 Jan 2024 10:11:50 +0100 Subject: [PATCH 4/7] CLI should have proper exit code --- .../java/mb/spoofax/cli/CommandRunner.java | 13 ++++++++---- .../mb/spoofax/cli/SpoofaxCliException.java | 14 +++++++++++++ .../compiler/adapter/data/CliParamRepr.java | 4 ++-- .../compiler/adapter/data/SeparatorRepr.java | 3 ++- lwb/build.gradle.kts | 2 +- lwb/metalang/spt/spt/build.gradle.kts | 21 +++++++++++++++++++ 6 files changed, 49 insertions(+), 8 deletions(-) create mode 100644 core/spoofax.cli/src/main/java/mb/spoofax/cli/SpoofaxCliException.java diff --git a/core/spoofax.cli/src/main/java/mb/spoofax/cli/CommandRunner.java b/core/spoofax.cli/src/main/java/mb/spoofax/cli/CommandRunner.java index 312809028..0d8320d47 100644 --- a/core/spoofax.cli/src/main/java/mb/spoofax/cli/CommandRunner.java +++ b/core/spoofax.cli/src/main/java/mb/spoofax/cli/CommandRunner.java @@ -70,8 +70,9 @@ void set(String paramId, @Nullable Object value) throws IllegalArgumentException System.out.println("The following messages were produced by command '" + commandDef.getDisplayName() + "':\n" + keyedMessages.toString()); } + boolean commandFailed = exception != null || keyedMessages.containsErrorOrHigher(); for(ShowFeedback showFeedback : feedback.getShowFeedbacks()) { - showFeedback.caseOf() + commandFailed |= showFeedback.caseOf() .showFile((file, region) -> { try { final ReadableResource resource = resourceService.getReadableResource(file); @@ -85,7 +86,7 @@ void set(String paramId, @Nullable Object value) throws IllegalArgumentException System.err.println("An exception occurred while showing file '" + file + "':"); e.printStackTrace(System.err); } - return Optional.empty(); + return false; }) .showText((text, name, region) -> { if(printFeedbackNames && !name.isEmpty()) { @@ -93,15 +94,19 @@ void set(String paramId, @Nullable Object value) throws IllegalArgumentException System.out.println(); } System.out.println(text); - return Optional.empty(); + return false; }) .showTestResults(((testResults, region) -> { StringBuilder builder = new StringBuilder(); testResults.addToStringBuilder(builder); System.out.print(builder); - return Optional.empty(); + return testResults.numFailed > 0; })); } + + if(commandFailed) { + throw new SpoofaxCliException("Command '" + commandDef.getDisplayName() + "' failed (see messages above).", exception); + } return null; } } diff --git a/core/spoofax.cli/src/main/java/mb/spoofax/cli/SpoofaxCliException.java b/core/spoofax.cli/src/main/java/mb/spoofax/cli/SpoofaxCliException.java new file mode 100644 index 000000000..c2658420b --- /dev/null +++ b/core/spoofax.cli/src/main/java/mb/spoofax/cli/SpoofaxCliException.java @@ -0,0 +1,14 @@ +package mb.spoofax.cli; + +import org.checkerframework.checker.nullness.qual.Nullable; + +public class SpoofaxCliException extends Exception { + + public SpoofaxCliException(String message) { + super(message); + } + + public SpoofaxCliException(String message, @Nullable Throwable cause) { + super(message, cause); + } +} diff --git a/core/spoofax.compiler/src/main/java/mb/spoofax/compiler/adapter/data/CliParamRepr.java b/core/spoofax.compiler/src/main/java/mb/spoofax/compiler/adapter/data/CliParamRepr.java index 044b38235..62e19862c 100644 --- a/core/spoofax.compiler/src/main/java/mb/spoofax/compiler/adapter/data/CliParamRepr.java +++ b/core/spoofax.compiler/src/main/java/mb/spoofax/compiler/adapter/data/CliParamRepr.java @@ -146,7 +146,7 @@ public String toJavaCode() { } - public static class Option { + public static class Option implements Serializable { public final ListView names; public final boolean negatable; public final @Nullable String label; @@ -187,7 +187,7 @@ public Option(ListView names, boolean negatable, @Nullable String label, } } - public static class Positional { + public static class Positional implements Serializable { public final int index; public final @Nullable String label; public final @Nullable String description; diff --git a/core/spoofax.compiler/src/main/java/mb/spoofax/compiler/adapter/data/SeparatorRepr.java b/core/spoofax.compiler/src/main/java/mb/spoofax/compiler/adapter/data/SeparatorRepr.java index 07aa050e1..cf7d876eb 100644 --- a/core/spoofax.compiler/src/main/java/mb/spoofax/compiler/adapter/data/SeparatorRepr.java +++ b/core/spoofax.compiler/src/main/java/mb/spoofax/compiler/adapter/data/SeparatorRepr.java @@ -2,10 +2,11 @@ import org.immutables.value.Value; +import java.io.Serializable; import java.util.Optional; @Value.Immutable -public interface SeparatorRepr { +public interface SeparatorRepr extends Serializable { class Builder extends ImmutableSeparatorRepr.Builder {} static Builder builder() { diff --git a/lwb/build.gradle.kts b/lwb/build.gradle.kts index 7309dae3c..4a5ddc376 100644 --- a/lwb/build.gradle.kts +++ b/lwb/build.gradle.kts @@ -24,7 +24,7 @@ plugins { subprojects { metaborg { configureSubProject() - if(name.contains(".cli") || (name.contains(".eclipse") && !isMetaLibThatShouldBePublished(name)) || name.contains(".intellij")) { + if((name.contains(".eclipse") && !isMetaLibThatShouldBePublished(name)) || name.contains(".intellij")) { // Do not publish CLI, Eclipse plugin, and IntelliJ plugin for now. javaCreatePublication = false javaCreateSourcesJar = false diff --git a/lwb/metalang/spt/spt/build.gradle.kts b/lwb/metalang/spt/spt/build.gradle.kts index 06a5142ab..48f10c35a 100644 --- a/lwb/metalang/spt/spt/build.gradle.kts +++ b/lwb/metalang/spt/spt/build.gradle.kts @@ -5,6 +5,7 @@ import mb.spoofax.core.language.command.CommandContextType import mb.spoofax.core.language.command.EnclosingCommandContextType import mb.spoofax.core.language.command.CommandExecutionType import mb.spoofax.common.* +import java.util.Optional plugins { id("org.metaborg.gradle.config.java-library") @@ -148,4 +149,24 @@ fun AdapterProjectCompiler.Input.Builder.configureCompilerInput() { CommandActionRepr.builder().manualOnce(showTestSuiteCommand).fileRequired().enclosingProjectRequired().buildItem(), CommandActionRepr.builder().manualOnce(showTestSuitesCommand).directoryRequired().enclosingProjectRequired().buildItem() ) + + cliCommand( + CliCommandRepr.of( + "spt", + CliCommandRepr.of( + "runTestSuite", + showTestSuiteCommand.description(), + showTestSuiteCommand.type(), + CliParamRepr.positional("file", 0, "FILE", "SPT test suite file to run") + // Enclosing project argument should be retrieved from context + ), + CliCommandRepr.of( + "runTestSuites", + showTestSuitesCommand.description(), + showTestSuitesCommand.type(), + CliParamRepr.positional("directory", 0, "DIRECTORY", "Directory with SPT test suites to run") + // Enclosing project argument should be retrieved from context + ) + ) + ) } From 61dadfee7ccf26f30d5479550b1a1e44a3d30aed Mon Sep 17 00:00:00 2001 From: Aron Zwaan Date: Mon, 29 Jan 2024 14:23:16 +0100 Subject: [PATCH 5/7] Polish changes --- .../core/language/testrunner/TestResults.java | 5 +++++ .../eclipse/log/EclipseLoggerModule.java | 2 +- .../runtime/ExpandAllPredicatesStrategy.java | 1 - lwb/build.gradle.kts | 2 +- lwb/metalang/spt/spt.cli/build.gradle.kts | 2 -- lwb/metalang/spt/spt/build.gradle.kts | 21 ------------------- 6 files changed, 7 insertions(+), 26 deletions(-) diff --git a/core/spoofax.core/src/main/java/mb/spoofax/core/language/testrunner/TestResults.java b/core/spoofax.core/src/main/java/mb/spoofax/core/language/testrunner/TestResults.java index 63f1f523d..69ba460d9 100644 --- a/core/spoofax.core/src/main/java/mb/spoofax/core/language/testrunner/TestResults.java +++ b/core/spoofax.core/src/main/java/mb/spoofax/core/language/testrunner/TestResults.java @@ -39,6 +39,11 @@ public void addToStringBuilder(StringBuilder builder) { for (TestSuiteResult suite : suites) { suite.addToStringBuilder(builder); } + builder + .append(numPassed) + .append(" test cases passed, ") + .append(numFailed) + .append(" test cases failed."); } @Override diff --git a/core/spoofax.eclipse/src/main/java/mb/spoofax/eclipse/log/EclipseLoggerModule.java b/core/spoofax.eclipse/src/main/java/mb/spoofax/eclipse/log/EclipseLoggerModule.java index 96523ebed..b4546adca 100644 --- a/core/spoofax.eclipse/src/main/java/mb/spoofax/eclipse/log/EclipseLoggerModule.java +++ b/core/spoofax.eclipse/src/main/java/mb/spoofax/eclipse/log/EclipseLoggerModule.java @@ -8,7 +8,7 @@ @Module public class EclipseLoggerModule { @Provides @LoggerScope LoggerFactory provideLoggerFactory() { - return new EclipseLoggerFactory(mb.log.api.Level.Warn, mb.log.api.Level.Trace, "Spoofax"); + return new EclipseLoggerFactory(); } } diff --git a/core/statix.codecompletion/src/main/java/mb/statix/codecompletion/strategies/runtime/ExpandAllPredicatesStrategy.java b/core/statix.codecompletion/src/main/java/mb/statix/codecompletion/strategies/runtime/ExpandAllPredicatesStrategy.java index 7ccfad8f4..266407387 100644 --- a/core/statix.codecompletion/src/main/java/mb/statix/codecompletion/strategies/runtime/ExpandAllPredicatesStrategy.java +++ b/core/statix.codecompletion/src/main/java/mb/statix/codecompletion/strategies/runtime/ExpandAllPredicatesStrategy.java @@ -62,7 +62,6 @@ public static Seq eval( // An example where this happens is in this program, on the $Type placeholder: // let function $ID(): $Type = $Exp in 3 end // debugState(v, - final Strategy1, CCSolverState, CCSolverState> CCSolverState$withExpanded = StrategyExt.def("CCSolverState#withExpanded", "x", fun(CCSolverState::withExpanded)); diff --git a/lwb/build.gradle.kts b/lwb/build.gradle.kts index 4a5ddc376..7309dae3c 100644 --- a/lwb/build.gradle.kts +++ b/lwb/build.gradle.kts @@ -24,7 +24,7 @@ plugins { subprojects { metaborg { configureSubProject() - if((name.contains(".eclipse") && !isMetaLibThatShouldBePublished(name)) || name.contains(".intellij")) { + if(name.contains(".cli") || (name.contains(".eclipse") && !isMetaLibThatShouldBePublished(name)) || name.contains(".intellij")) { // Do not publish CLI, Eclipse plugin, and IntelliJ plugin for now. javaCreatePublication = false javaCreateSourcesJar = false diff --git a/lwb/metalang/spt/spt.cli/build.gradle.kts b/lwb/metalang/spt/spt.cli/build.gradle.kts index 9bda331ef..e316085df 100644 --- a/lwb/metalang/spt/spt.cli/build.gradle.kts +++ b/lwb/metalang/spt/spt.cli/build.gradle.kts @@ -7,11 +7,9 @@ languageCliProject { adapterProject.set(project(":spt")) } -/* tasks { // Disable currently unused distribution tasks. distZip.configure { enabled = false } distTar.configure { enabled = false } startScripts.configure { enabled = false } } -*/ diff --git a/lwb/metalang/spt/spt/build.gradle.kts b/lwb/metalang/spt/spt/build.gradle.kts index 48f10c35a..06a5142ab 100644 --- a/lwb/metalang/spt/spt/build.gradle.kts +++ b/lwb/metalang/spt/spt/build.gradle.kts @@ -5,7 +5,6 @@ import mb.spoofax.core.language.command.CommandContextType import mb.spoofax.core.language.command.EnclosingCommandContextType import mb.spoofax.core.language.command.CommandExecutionType import mb.spoofax.common.* -import java.util.Optional plugins { id("org.metaborg.gradle.config.java-library") @@ -149,24 +148,4 @@ fun AdapterProjectCompiler.Input.Builder.configureCompilerInput() { CommandActionRepr.builder().manualOnce(showTestSuiteCommand).fileRequired().enclosingProjectRequired().buildItem(), CommandActionRepr.builder().manualOnce(showTestSuitesCommand).directoryRequired().enclosingProjectRequired().buildItem() ) - - cliCommand( - CliCommandRepr.of( - "spt", - CliCommandRepr.of( - "runTestSuite", - showTestSuiteCommand.description(), - showTestSuiteCommand.type(), - CliParamRepr.positional("file", 0, "FILE", "SPT test suite file to run") - // Enclosing project argument should be retrieved from context - ), - CliCommandRepr.of( - "runTestSuites", - showTestSuitesCommand.description(), - showTestSuitesCommand.type(), - CliParamRepr.positional("directory", 0, "DIRECTORY", "Directory with SPT test suites to run") - // Enclosing project argument should be retrieved from context - ) - ) - ) } From ead1c8d9c1cc1a7820bf9bd229e10a63d66b7a53 Mon Sep 17 00:00:00 2001 From: Aron Zwaan Date: Mon, 29 Jan 2024 14:37:00 +0100 Subject: [PATCH 6/7] Document some changes in inline comments --- .../src/main/java/mb/spoofax/cli/CommandRunner.java | 6 ++++-- .../strategies/runtime/ExpandQueryStrategy.java | 8 +++++++- .../java/mb/spt/expectation/TransformExpectationUtil.java | 5 +++++ 3 files changed, 16 insertions(+), 3 deletions(-) diff --git a/core/spoofax.cli/src/main/java/mb/spoofax/cli/CommandRunner.java b/core/spoofax.cli/src/main/java/mb/spoofax/cli/CommandRunner.java index 0d8320d47..bfa1ff0a1 100644 --- a/core/spoofax.cli/src/main/java/mb/spoofax/cli/CommandRunner.java +++ b/core/spoofax.cli/src/main/java/mb/spoofax/cli/CommandRunner.java @@ -1,6 +1,7 @@ package mb.spoofax.cli; import mb.common.message.KeyedMessages; +import mb.pie.api.ExecException; import mb.pie.api.MixedSession; import mb.pie.api.Task; import mb.resource.ReadableResource; @@ -53,7 +54,7 @@ void set(String paramId, @Nullable Object value) throws IllegalArgumentException rawArgsBuilder.setArg(paramId, (Serializable)value); } - @Override public @Nullable Object call() throws Exception { + @Override public @Nullable Object call() throws SpoofaxCliException, InterruptedException, ExecException { final RawArgs rawArgs = rawArgsBuilder.build(context); final A args = commandDef.fromRawArgs(rawArgs); final Task task = commandDef.createTask(args); @@ -67,7 +68,7 @@ void set(String paramId, @Nullable Object value) throws IllegalArgumentException final KeyedMessages keyedMessages = feedback.getMessages(); if(!keyedMessages.isEmpty()) { - System.out.println("The following messages were produced by command '" + commandDef.getDisplayName() + "':\n" + keyedMessages.toString()); + System.out.println("The following messages were produced by command '" + commandDef.getDisplayName() + "':\n" + keyedMessages); } boolean commandFailed = exception != null || keyedMessages.containsErrorOrHigher(); @@ -105,6 +106,7 @@ void set(String paramId, @Nullable Object value) throws IllegalArgumentException } if(commandFailed) { + // Exception is processed and turned into an exit code by picocli. throw new SpoofaxCliException("Command '" + commandDef.getDisplayName() + "' failed (see messages above).", exception); } return null; diff --git a/core/statix.codecompletion/src/main/java/mb/statix/codecompletion/strategies/runtime/ExpandQueryStrategy.java b/core/statix.codecompletion/src/main/java/mb/statix/codecompletion/strategies/runtime/ExpandQueryStrategy.java index 8767c816c..8ed785c7f 100644 --- a/core/statix.codecompletion/src/main/java/mb/statix/codecompletion/strategies/runtime/ExpandQueryStrategy.java +++ b/core/statix.codecompletion/src/main/java/mb/statix/codecompletion/strategies/runtime/ExpandQueryStrategy.java @@ -152,6 +152,7 @@ public static Seq eval( final Delay delay = Delay.ofVars(unifier.getVars(query.scopeTerm())); return Seq.of(input .withoutSelected() + // remove query from active constraint set, as it is delayed now .withUpdatedConstraints(Collections.emptySet(), Collections.singleton(query)) .withDelay(query, delay) ); @@ -359,7 +360,12 @@ public F1> caseCompiledQuery(CCompiledQuery q) { } catch(IncompleteException e) { // Delay final Delay delay = Delay.ofVars(unifier.getVars(query.scopeTerm())); - return Collections.singletonList(input.withoutSelected().withDelay(query, delay)); + return Collections.singletonList(input + .withoutSelected() + // remove query from active constraint set, as it is delayed now + .withUpdatedConstraints(Collections.emptySet(), Collections.singleton(query)) + .withDelay(query, delay) + ); } catch(ResolutionException e) { throw new RuntimeException("Unexpected ResolutionException: " + e.getMessage(), e); } catch(InterruptedException e) { diff --git a/lwb/metalang/spt/spt/src/main/java/mb/spt/expectation/TransformExpectationUtil.java b/lwb/metalang/spt/spt/src/main/java/mb/spt/expectation/TransformExpectationUtil.java index 20965a63d..0a091194a 100644 --- a/lwb/metalang/spt/spt/src/main/java/mb/spt/expectation/TransformExpectationUtil.java +++ b/lwb/metalang/spt/spt/src/main/java/mb/spt/expectation/TransformExpectationUtil.java @@ -54,8 +54,11 @@ public class TransformExpectationUtil { @Nullable Region selection ) throws InterruptedException { try { + // Using `ofFile` is required to make `transform` test expectations work. + // Otherwise, the argument provider `Context(File)` will not pick up this resource. final CommandContext commandContext = CommandContext.ofFile(resource, selection); commandContext.setEnclosing(EnclosingCommandContextType.Directory, CommandContext.ofDirectory(resource)); + // If no root directory hint is given, use the resource itself as the project context. commandContext.setEnclosing(EnclosingCommandContextType.Project, CommandContext.ofProject(rootDirectoryHint != null ? rootDirectoryHint : resource)); final Task task = commandDef.createTask(CommandExecutionType.ManualOnce, commandContext, new ArgConverters(languageUnderTest.getResourceServiceComponent().getResourceService())); return languageUnderTestSession.require(task); @@ -83,6 +86,8 @@ public static boolean isSelectionValid(TestCase testCase, Option availableSelections = testCase.testFragment.getSelections(); return availableSelections.get(selectionReference.get().selection - 1); } From 140c5efa6e26689b558d4fa0700588a7ba4eb860 Mon Sep 17 00:00:00 2001 From: Aron Zwaan Date: Fri, 9 Feb 2024 15:59:04 +0100 Subject: [PATCH 7/7] Update changelog --- CHANGELOG.md | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9f8699f09..06c5750d7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,15 @@ All notable changes to this project are documented in this file, based on [Keep ## [Unreleased] +### Changed +- Command Line Interface now returns a non-zero error code when the underlying command fails. +- Command Line Interface executing tests now prints the number of passed and failed test cases. +- SPT `transform` expectations support commands using the enclosing file and/or enclosing project. + +### Fixed +- Termination issues in Code Completion +- Serialization issues of meta-language configuration objects +- Region arguments to SPT `transform` expectations now correspond to the imploder attachments. ## [0.19.7] - 2024-02-09 ### Changed