diff --git a/org.metaborg.spoofax.shell.console/src/main/java/org/metaborg/spoofax/shell/client/ConsoleReplModule.java b/org.metaborg.spoofax.shell.console/src/main/java/org/metaborg/spoofax/shell/client/ConsoleReplModule.java index 68729e4d..ca6667f5 100644 --- a/org.metaborg.spoofax.shell.console/src/main/java/org/metaborg/spoofax/shell/client/ConsoleReplModule.java +++ b/org.metaborg.spoofax.shell.console/src/main/java/org/metaborg/spoofax/shell/client/ConsoleReplModule.java @@ -1,6 +1,5 @@ package org.metaborg.spoofax.shell.client; -import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; @@ -12,10 +11,8 @@ import org.metaborg.spoofax.shell.client.console.impl.history.JLine2PersistentInputHistory; import org.metaborg.spoofax.shell.commands.IReplCommand; -import com.google.inject.Provides; import com.google.inject.Singleton; import com.google.inject.multibindings.MapBinder; -import com.google.inject.name.Named; import com.google.inject.name.Names; /** @@ -54,24 +51,4 @@ protected void configure() { super.configure(); bindUserInterface(); } - - /** - * TODO: Replace with "CheckedProvides" because IO in Provider method is bad practice, see: - * https://github.com/google/guice/wiki/ThrowingProviders. - * - * @param in - * The {@link InputStream}. - * @param out - * The {@link OutputStream}. - * @return A {@link jline.console.ConsoleReader} with the given streams. - * @throws IOException - * When an IO error occurs upon construction. - */ - @Provides - @Singleton - protected jline.console.ConsoleReader provideConsoleReader(@Named("in") InputStream in, - @Named("out") OutputStream out) - throws IOException { - return new jline.console.ConsoleReader(in, out); - } } diff --git a/org.metaborg.spoofax.shell.console/src/main/java/org/metaborg/spoofax/shell/client/console/Main.java b/org.metaborg.spoofax.shell.console/src/main/java/org/metaborg/spoofax/shell/client/console/Main.java index 5c066f2a..9c563fd6 100644 --- a/org.metaborg.spoofax.shell.console/src/main/java/org/metaborg/spoofax/shell/client/console/Main.java +++ b/org.metaborg.spoofax.shell.console/src/main/java/org/metaborg/spoofax/shell/client/console/Main.java @@ -15,18 +15,30 @@ * This class launches a {@link ConsoleRepl}, a console based REPL. */ public final class Main { + private static final String ERROR = "Invalid commandline parameters: %s%nThe only argument " + + "accepted is the path to a language implementation " + + "location, using any filesystem supported by Apache VFS"; private Main() { } + private static StyledText error(String[] args) { + StringBuilder invalidArgs = new StringBuilder(); + for (String arg : args) { + invalidArgs.append(arg).append(", "); + } + // Remove the appended ", " from the string. + invalidArgs.delete(invalidArgs.length() - 2, invalidArgs.length()); + return new StyledText(Color.RED, String.format(ERROR, invalidArgs.toString())); + } + /** * Instantiates and runs a new {@link ConsoleRepl}. * * @param args - * The path to a language implementation location, using any URI supported by Apache - * VFS. + * The path to a language implementation location, using any filesystem supported by + * Apache VFS. */ - // TODO: make the argument work again. public static void main(String[] args) { Injector injector = Guice.createInjector(new ConsoleReplModule()); IDisplay display = injector.getInstance(IDisplay.class); @@ -37,6 +49,12 @@ public static void main(String[] args) { display.displayStyledText(message); ConsoleRepl repl = injector.getInstance(ConsoleRepl.class); + if (args.length == 1) { + repl.runOnce(":load " + args[0]); + } else if (args.length > 1) { + display.displayStyledText(error(args)); + } + repl.run(); } } diff --git a/org.metaborg.spoofax.shell.console/src/main/java/org/metaborg/spoofax/shell/client/console/commands/ExitCommand.java b/org.metaborg.spoofax.shell.console/src/main/java/org/metaborg/spoofax/shell/client/console/commands/ExitCommand.java index d04e4b31..45da994e 100644 --- a/org.metaborg.spoofax.shell.console/src/main/java/org/metaborg/spoofax/shell/client/console/commands/ExitCommand.java +++ b/org.metaborg.spoofax.shell.console/src/main/java/org/metaborg/spoofax/shell/client/console/commands/ExitCommand.java @@ -33,8 +33,6 @@ public String description() { @Override public IResult execute(String... args) { ConsoleRepl repl = replProvider.get(); - return (visitor) -> { - repl.setRunning(false); - }; + return (visitor) -> repl.setRunning(false); } } diff --git a/org.metaborg.spoofax.shell.console/src/main/java/org/metaborg/spoofax/shell/client/console/impl/ConsoleRepl.java b/org.metaborg.spoofax.shell.console/src/main/java/org/metaborg/spoofax/shell/client/console/impl/ConsoleRepl.java index 57ef8c97..d8fd9152 100644 --- a/org.metaborg.spoofax.shell.console/src/main/java/org/metaborg/spoofax/shell/client/console/impl/ConsoleRepl.java +++ b/org.metaborg.spoofax.shell.console/src/main/java/org/metaborg/spoofax/shell/client/console/impl/ConsoleRepl.java @@ -52,6 +52,21 @@ public void setRunning(boolean running) { this.running = running; } + /** + * Evaluate {@code input}, without having to enter the main loop in {@link #run()}. This is + * useful to initialize some state before control is handed to the user. + * + * @param input + * The input to evaluate. + */ + public void runOnce(String input) { + try { + eval(input).accept(display); + } catch (CommandNotFoundException e) { + this.display.displayStyledText(new StyledText(Color.RED, e.getMessage())); + } + } + /** * Run {@link IRepl#eval(String)} in a loop, for as long as {@code running} is {@code true}. * @@ -65,11 +80,7 @@ public void run() { String input; setRunning(true); while (running && (input = this.iface.getInput()) != null) { - try { - eval(input).accept(display); - } catch (CommandNotFoundException e) { - this.display.displayStyledText(new StyledText(Color.RED, e.getMessage())); - } + runOnce(input); } this.iface.history().persistToDisk(); diff --git a/org.metaborg.spoofax.shell.console/src/main/java/org/metaborg/spoofax/shell/client/console/impl/TerminalUserInterface.java b/org.metaborg.spoofax.shell.console/src/main/java/org/metaborg/spoofax/shell/client/console/impl/TerminalUserInterface.java index 24c9be8a..3e7f609f 100644 --- a/org.metaborg.spoofax.shell.console/src/main/java/org/metaborg/spoofax/shell/client/console/impl/TerminalUserInterface.java +++ b/org.metaborg.spoofax.shell.console/src/main/java/org/metaborg/spoofax/shell/client/console/impl/TerminalUserInterface.java @@ -48,13 +48,10 @@ public class TerminalUserInterface implements IDisplay { * The {@link PrintStream} to write errors to. * @param hist * The input history adapter for JLine2. - * @throws IOException - * When an IO error occurs. */ @Inject public TerminalUserInterface(ConsoleReader reader, @Named("out") OutputStream out, - @Named("err") OutputStream err, IInputHistory hist) - throws IOException { + @Named("err") OutputStream err, IInputHistory hist) { this.reader = reader; this.hist = hist; reader.setExpandEvents(false); diff --git a/org.metaborg.spoofax.shell.console/src/main/java/org/metaborg/spoofax/shell/client/console/impl/history/JLine2PersistentInputHistory.java b/org.metaborg.spoofax.shell.console/src/main/java/org/metaborg/spoofax/shell/client/console/impl/history/JLine2PersistentInputHistory.java index e4bbc1d6..ddf1f420 100644 --- a/org.metaborg.spoofax.shell.console/src/main/java/org/metaborg/spoofax/shell/client/console/impl/history/JLine2PersistentInputHistory.java +++ b/org.metaborg.spoofax.shell.console/src/main/java/org/metaborg/spoofax/shell/client/console/impl/history/JLine2PersistentInputHistory.java @@ -3,10 +3,13 @@ import java.io.File; import java.io.IOException; import java.util.Optional; +import java.util.function.Function; import com.google.inject.Inject; import com.google.inject.name.Named; +import jline.console.history.History; + /** * An extension to the adapter for JLine2's History implementation. This adapter implementation * maintains two versions of JLine2's History classes: one that is initially used in-memory, and @@ -49,10 +52,10 @@ public JLine2PersistentInputHistory(@Named("historyPath") String filePath, * used instead. */ @Override - protected jline.console.history.History delegate() { + protected History delegate() { // orElse does not work on a subtype, but it does if you put flatMap in between. return delegateFileHist - .flatMap((jline.console.history.History fileHist) -> Optional.of(fileHist)) + .flatMap((Function>) Optional::of) .orElse(super.delegate()); } diff --git a/org.metaborg.spoofax.shell.console/src/main/java/org/metaborg/spoofax/shell/client/console/impl/history/package-info.java b/org.metaborg.spoofax.shell.console/src/main/java/org/metaborg/spoofax/shell/client/console/impl/history/package-info.java index cc4a242b..eabd299f 100644 --- a/org.metaborg.spoofax.shell.console/src/main/java/org/metaborg/spoofax/shell/client/console/impl/history/package-info.java +++ b/org.metaborg.spoofax.shell.console/src/main/java/org/metaborg/spoofax/shell/client/console/impl/history/package-info.java @@ -1,5 +1,5 @@ /** * This package contains implementations (one volatile, one persistent) of - * {@link org.metaborg.spoofax.shell.client.console.IInputHistory}. + * {@link org.metaborg.spoofax.shell.client.IInputHistory}. */ package org.metaborg.spoofax.shell.client.console.impl.history; \ No newline at end of file diff --git a/org.metaborg.spoofax.shell.console/src/test/java/org/metaborg/spoofax/shell/client/console/impl/ConsoleReplTest.java b/org.metaborg.spoofax.shell.console/src/test/java/org/metaborg/spoofax/shell/client/console/impl/ConsoleReplTest.java index 5a019d41..a1257737 100644 --- a/org.metaborg.spoofax.shell.console/src/test/java/org/metaborg/spoofax/shell/client/console/impl/ConsoleReplTest.java +++ b/org.metaborg.spoofax.shell.console/src/test/java/org/metaborg/spoofax/shell/client/console/impl/ConsoleReplTest.java @@ -1,6 +1,5 @@ package org.metaborg.spoofax.shell.client.console.impl; -import static org.junit.Assert.fail; import static org.metaborg.spoofax.shell.client.console.impl.TerminalUserInterfaceTest.C_D; import static org.metaborg.spoofax.shell.client.console.impl.TerminalUserInterfaceTest.ENTER; import static org.mockito.Matchers.anyString; @@ -91,19 +90,41 @@ private void setUpCtrlD() throws IOException { createRepl(new UserInputSimulationModule(in, out), new MockModule(invokerMock)); } + /** + * Test {@link ConsoleRepl#runOnce(String)}. + * + * @throws IOException + * Should not happen. + * @throws CommandNotFoundException + * Should not happen. + */ + @Test + public void testRunOnce() throws IOException, CommandNotFoundException { + String fake = ":fakecommand foo"; + setUp(fake); + invokerMock = mock(ICommandInvoker.class, RETURNS_MOCKS); + + // Create a user input simulated ConsoleRepl with the mock invoker. + createRepl(new UserInputSimulationModule(in, out), new MockModule(invokerMock)); + + repl.runOnce(fake); + verify(invokerMock, times(1)).execute(fake); + } + /** * Test whether the REPl exits when Control-D is pressed. + * + * @throws IOException + * Should not happen. + * @throws CommandNotFoundException + * Should not happen. */ @Test - public void testCtrlDDoesExit() { - try { - setUpCtrlD(); - repl.run(); - // Ensure that the command invoker is never called with any command. - verify(invokerMock, never()).execute(anyString()); - } catch (IOException | CommandNotFoundException e) { - fail("Should not happen"); - } + public void testCtrlDDoesExit() throws CommandNotFoundException, IOException { + setUpCtrlD(); + repl.run(); + // Ensure that the command invoker is never called with any command. + verify(invokerMock, never()).execute(anyString()); } private void setUpExit() throws IOException { @@ -118,28 +139,29 @@ private void setUpExit() throws IOException { /** * Tests the {@link ExitCommand}. + * + * @throws IOException + * Should not happen. + * @throws CommandNotFoundException + * Should not happen. */ @Test - public void testExitCommand() { - try { - setUpExit(); + public void testExitCommand() throws IOException, CommandNotFoundException { + setUpExit(); - // Stub the invoker so that it returns an exit command which we can spy on. - ExitCommand exitCommandMock = spy(new ExitCommand(() -> repl)); - when(invokerMock.commandFromName("exit")).thenReturn(exitCommandMock); + // Stub the invoker so that it returns an exit command which we can spy on. + ExitCommand exitCommandMock = spy(new ExitCommand(() -> repl)); + when(invokerMock.commandFromName("exit")).thenReturn(exitCommandMock); - repl.run(); + repl.run(); - // Ensure that the command was given to the invoker just once. - verify(invokerMock, times(1)).execute(":exit"); + // Ensure that the command was given to the invoker just once. + verify(invokerMock, times(1)).execute(":exit"); - // Ensure that exitCommand was executed once. - verify(exitCommandMock, times(1)).execute(); + // Ensure that exitCommand was executed once. + verify(exitCommandMock, times(1)).execute(); - // Verify that the Editor was not asked for input after the exit command was executed. - verify(ifaceSpy, times(1)).getInput(); - } catch (IOException | CommandNotFoundException e) { - fail("Should not happen"); - } + // Verify that the Editor was not asked for input after the exit command was executed. + verify(ifaceSpy, times(1)).getInput(); } } diff --git a/org.metaborg.spoofax.shell.console/src/test/java/org/metaborg/spoofax/shell/client/console/impl/TerminalUserInterfaceTest.java b/org.metaborg.spoofax.shell.console/src/test/java/org/metaborg/spoofax/shell/client/console/impl/TerminalUserInterfaceTest.java index 806c53f1..bfc57eac 100644 --- a/org.metaborg.spoofax.shell.console/src/test/java/org/metaborg/spoofax/shell/client/console/impl/TerminalUserInterfaceTest.java +++ b/org.metaborg.spoofax.shell.console/src/test/java/org/metaborg/spoofax/shell/client/console/impl/TerminalUserInterfaceTest.java @@ -11,7 +11,6 @@ import java.io.OutputStream; import org.junit.Test; -import org.metaborg.spoofax.shell.client.console.impl.TerminalUserInterface; import org.metaborg.spoofax.shell.output.StyledText; import com.google.inject.Guice; @@ -37,7 +36,6 @@ public class TerminalUserInterfaceTest { /* >>> */ + "qwerty" + ENTER /* ... */ + ENTER; private TerminalUserInterface ui; - private ByteArrayInputStream in; private ByteArrayOutputStream out; /** @@ -49,7 +47,7 @@ public class TerminalUserInterfaceTest { * When an IO error occurs upon construction of the {@link ConsoleReader}. */ public void setUp(String inputString) throws IOException { - in = new ByteArrayInputStream(inputString.getBytes("UTF-8")); + ByteArrayInputStream in = new ByteArrayInputStream(inputString.getBytes("UTF-8")); out = new ByteArrayOutputStream(); Injector injector = Guice.createInjector(new UserInputSimulationModule(in, out)); diff --git a/org.metaborg.spoofax.shell.core/src/main/java/org/metaborg/spoofax/shell/ReplModule.java b/org.metaborg.spoofax.shell.core/src/main/java/org/metaborg/spoofax/shell/ReplModule.java index 7400f11a..af5154ad 100644 --- a/org.metaborg.spoofax.shell.core/src/main/java/org/metaborg/spoofax/shell/ReplModule.java +++ b/org.metaborg.spoofax.shell.core/src/main/java/org/metaborg/spoofax/shell/ReplModule.java @@ -9,7 +9,9 @@ import org.metaborg.core.resource.IResourceService; import org.metaborg.core.resource.ResourceService; import org.metaborg.spoofax.core.SpoofaxModule; +import org.metaborg.spoofax.shell.client.IDisplay; import org.metaborg.spoofax.shell.client.IRepl; +import org.metaborg.spoofax.shell.commands.DefaultCommand; import org.metaborg.spoofax.shell.commands.HelpCommand; import org.metaborg.spoofax.shell.commands.IReplCommand; import org.metaborg.spoofax.shell.commands.LanguageCommand; @@ -61,7 +63,8 @@ public abstract class ReplModule extends SpoofaxModule { protected void bindCommands(MapBinder commandBinder) { commandBinder.addBinding("help").to(HelpCommand.class); commandBinder.addBinding("load").to(LanguageCommand.class); - + bind(IReplCommand.class).annotatedWith(Names.named("default_command")) + .to(DefaultCommand.class); bind(ICommandInvoker.class).to(SpoofaxCommandInvoker.class); } diff --git a/org.metaborg.spoofax.shell.core/src/main/java/org/metaborg/spoofax/shell/client/IDisplay.java b/org.metaborg.spoofax.shell.core/src/main/java/org/metaborg/spoofax/shell/client/IDisplay.java index 2fd3374c..107c948e 100644 --- a/org.metaborg.spoofax.shell.core/src/main/java/org/metaborg/spoofax/shell/client/IDisplay.java +++ b/org.metaborg.spoofax.shell.core/src/main/java/org/metaborg/spoofax/shell/client/IDisplay.java @@ -49,7 +49,7 @@ default void visitFailure(FailResult errorResult) { StyledText styled = highlightMessagesInSource(sourceText, messages); String concat = - messages.stream().map(message -> message.message()).collect(Collectors.joining("\n")); + messages.stream().map(IMessage::message).collect(Collectors.joining("\n")); visitMessage(styled.append("\n").append(Color.RED, concat)); } @@ -64,7 +64,7 @@ default void visitFailure(FailResult errorResult) { * @return The highlighted {@link StyledText} */ default StyledText highlightMessagesInSource(String sourceText, List messages) { - List regions = messages.stream().map(message -> message.region()) + List regions = messages.stream().map(IMessage::region) .filter(Objects::nonNull).collect(Collectors.toList()); StyledText styled = new StyledText(); IStyle style = new Style(Color.RED, null, true, false, false); diff --git a/org.metaborg.spoofax.shell.core/src/main/java/org/metaborg/spoofax/shell/commands/DefaultCommand.java b/org.metaborg.spoofax.shell.core/src/main/java/org/metaborg/spoofax/shell/commands/DefaultCommand.java new file mode 100644 index 00000000..27bf928c --- /dev/null +++ b/org.metaborg.spoofax.shell.core/src/main/java/org/metaborg/spoofax/shell/commands/DefaultCommand.java @@ -0,0 +1,19 @@ +package org.metaborg.spoofax.shell.commands; + +import org.metaborg.spoofax.shell.output.IResult; +import org.metaborg.spoofax.shell.output.StyledText; + +/** + * Dummy class returned only when no language is loaded. + */ +public class DefaultCommand implements IReplCommand { + @Override + public String description() { + return "No language is loaded yet, type :help for more information."; + } + + @Override + public IResult execute(String... args) { + return (visitor) -> visitor.visitMessage(new StyledText(description())); + } +} \ No newline at end of file diff --git a/org.metaborg.spoofax.shell.core/src/main/java/org/metaborg/spoofax/shell/commands/HelpCommand.java b/org.metaborg.spoofax.shell.core/src/main/java/org/metaborg/spoofax/shell/commands/HelpCommand.java index 9ad66bd0..4acf146a 100644 --- a/org.metaborg.spoofax.shell.core/src/main/java/org/metaborg/spoofax/shell/commands/HelpCommand.java +++ b/org.metaborg.spoofax.shell.core/src/main/java/org/metaborg/spoofax/shell/commands/HelpCommand.java @@ -20,7 +20,7 @@ public class HelpCommand implements IReplCommand { private final ICommandInvoker invoker; /** - * Instantiates a new HelpCommand. + * Instantiates a new {@link HelpCommand}. * * @param invoker * The {@link ICommandInvoker}. @@ -41,7 +41,7 @@ public String description() { * @return a formatted string */ public String formathelp(Map commands) { - int longestCommand = commands.keySet().stream().mapToInt(a -> a.length()).max().orElse(0); + int longestCommand = commands.keySet().stream().mapToInt(String::length).max().orElse(0); String format = "%-" + longestCommand + "s %s"; return commands.keySet().stream().flatMap(name -> { diff --git a/org.metaborg.spoofax.shell.core/src/main/java/org/metaborg/spoofax/shell/commands/LanguageCommand.java b/org.metaborg.spoofax.shell.core/src/main/java/org/metaborg/spoofax/shell/commands/LanguageCommand.java index 9104e405..83d29c69 100644 --- a/org.metaborg.spoofax.shell.core/src/main/java/org/metaborg/spoofax/shell/commands/LanguageCommand.java +++ b/org.metaborg.spoofax.shell.core/src/main/java/org/metaborg/spoofax/shell/commands/LanguageCommand.java @@ -29,6 +29,7 @@ * Represents a command that loads a Spoofax language. */ public class LanguageCommand implements IReplCommand { + private static final String[] ARCHIVES = { "zip", "jar", "tar", "tgz", "tbz2", }; private final ILanguageDiscoveryService langDiscoveryService; private final IResourceService resourceService; private final IMenuService menuService; @@ -72,9 +73,12 @@ public String description() { /** * Load a {@link ILanguageImpl} from a {@link FileObject}. - * @param langloc the {@link FileObject} containing the {@link ILanguageImpl} - * @return the {@link ILanguageImpl} - * @throws MetaborgException when loading fails + * + * @param langloc + * the {@link FileObject} containing the {@link ILanguageImpl} + * @return the {@link ILanguageImpl} + * @throws MetaborgException + * when loading fails */ public ILanguageImpl load(FileObject langloc) throws MetaborgException { Iterable requests = langDiscoveryService.request(langloc); @@ -89,11 +93,12 @@ public ILanguageImpl load(FileObject langloc) throws MetaborgException { return lang; } - // FIXME: there really should be a better way to go about this. Perhaps Apache Tika? private FileObject resolveLanguage(String path) { String extension = resourceService.resolveToName(path).getExtension(); - if (extension.equals("zip")) { - return resourceService.resolve(extension + ":" + path + "!/"); + for (String archive : ARCHIVES) { + if (extension.equals(archive)) { + return resourceService.resolve(extension + ":" + path + "!/"); + } } return resourceService.resolve(path); } @@ -101,25 +106,28 @@ private FileObject resolveLanguage(String path) { private void loadCommands(ILanguageImpl lang) { boolean analyze = lang.hasFacet(AnalyzerFacet.class); CommandBuilder builder = factory.createBuilder(project, lang); + + IReplCommand eval; Function> transform; invoker.resetCommands(); invoker.addCommand("parse", builder.parse().description("Parse the expression").build()); if (analyze) { invoker.addCommand("analyze", builder.analyze() - .description("Analyze the expression").build()); - invoker.addCommand("eval", builder.evalAnalyzed() - .description("Evaluate an analyzed expression").build()); - transform = (action) -> builder.transformAnalyzed(action); + .description("Analyze the expression").build()); + + eval = builder.evalAnalyzed().description("Evaluate an analyzed expression").build(); + transform = builder::transformAnalyzed; } else { - invoker.addCommand("eval", builder.evalParsed() - .description("Evaluate a parsed expression").build()); - transform = (action) -> builder.transformParsed(action); + eval = builder.evalParsed().description("Evaluate a parsed expression").build(); + transform = builder::transformParsed; } + invoker.addCommand("eval", eval); + invoker.setDefault(eval); - new TransformVisitor(menuService).getActions(lang).forEach((key, action) -> { - invoker.addCommand(key, transform.apply(action).description(action.name()).build()); - }); + new TransformVisitor(menuService).getActions(lang).forEach((key, action) -> + invoker.addCommand(key, transform.apply(action).description(action.name()) + .build())); } @Override @@ -132,8 +140,7 @@ public IResult execute(String... args) { ILanguageImpl lang = load(resolveLanguage(args[0])); loadCommands(lang); - return (visitor) -> visitor - .visitMessage(new StyledText("Loaded language " + lang)); + return (visitor) -> visitor.visitMessage(new StyledText("Loaded language " + lang)); } catch (MetaborgException e) { return new ExceptionResult(e); } diff --git a/org.metaborg.spoofax.shell.core/src/main/java/org/metaborg/spoofax/shell/commands/TransformVisitor.java b/org.metaborg.spoofax.shell.core/src/main/java/org/metaborg/spoofax/shell/commands/TransformVisitor.java index 4492a564..599cfb7f 100644 --- a/org.metaborg.spoofax.shell.core/src/main/java/org/metaborg/spoofax/shell/commands/TransformVisitor.java +++ b/org.metaborg.spoofax.shell.core/src/main/java/org/metaborg/spoofax/shell/commands/TransformVisitor.java @@ -15,11 +15,12 @@ import com.google.inject.Inject; /** - * An {@link IMenuItemVisitor} implementation to create one {@link TransformCommand} per menu item. + * An {@link IMenuItemVisitor} implementation that traverses over all {@link IMenuItem}s. + * This class then creates a map of all defined {@link ITransformAction}s. */ public class TransformVisitor implements IMenuItemVisitor { + private final IMenuService menuService; private Map actions; - private IMenuService menuService; /** * Instantiates a new {@link TransformVisitor}. @@ -33,7 +34,7 @@ public TransformVisitor(IMenuService menuService) { } /** - * Retrieve all the actions from the {@link IMenuService} that belong to the given + * Retrieve all actions from the {@link IMenuService} that are defined for the given * {@link ILanguageImpl language}. * * @param lang diff --git a/org.metaborg.spoofax.shell.core/src/main/java/org/metaborg/spoofax/shell/core/ClassPathInterpreterLoader.java b/org.metaborg.spoofax.shell.core/src/main/java/org/metaborg/spoofax/shell/core/ClassPathInterpreterLoader.java index e9f4d180..08b93b7e 100644 --- a/org.metaborg.spoofax.shell.core/src/main/java/org/metaborg/spoofax/shell/core/ClassPathInterpreterLoader.java +++ b/org.metaborg.spoofax.shell.core/src/main/java/org/metaborg/spoofax/shell/core/ClassPathInterpreterLoader.java @@ -27,9 +27,9 @@ /** * Loads an interpreter that is present in the class path. This {@link IInterpreterLoader} uses - * reflection to load the generated {@link DynSemEntryPoint} and {@link DynSemLanguage} subclasses. - * It instantiates a {@link PolyglotEngine} with the {@link NonParser} that is provided, by using - * the supported {@link DynSemLanguage#PARSER configuration parameter}. + * reflection to load the generated {@link DynSemEntryPoint} subclass. It instantiates a + * {@link PolyglotEngine} and initializes the interpreter by evaluating the DynSem specification + * term. */ public class ClassPathInterpreterLoader implements IInterpreterLoader { private String langName; @@ -88,7 +88,7 @@ public ITermTransformer getTransformer() { private DynSemEntryPoint getEntryPoint() throws InterpreterLoadException { try { Class entryPointClass = - this. getGeneratedClass("EntryPoint"); + this.getGeneratedClass("EntryPoint"); return ConstructorUtils.invokeConstructor(entryPointClass); } catch (InstantiationException | IllegalAccessException | NoSuchMethodException | InvocationTargetException e) { diff --git a/org.metaborg.spoofax.shell.core/src/main/java/org/metaborg/spoofax/shell/core/DynSemEvaluationStrategy.java b/org.metaborg.spoofax.shell.core/src/main/java/org/metaborg/spoofax/shell/core/DynSemEvaluationStrategy.java index 691a9b8e..8968db2e 100644 --- a/org.metaborg.spoofax.shell.core/src/main/java/org/metaborg/spoofax/shell/core/DynSemEvaluationStrategy.java +++ b/org.metaborg.spoofax.shell.core/src/main/java/org/metaborg/spoofax/shell/core/DynSemEvaluationStrategy.java @@ -136,15 +136,13 @@ private Value lookupRuleForInput(IStrategoTerm input) throws MetaborgException { String ctorName = inputCtor.getName(); int arity = inputCtor.getArity(); - Value rule = - polyglotEngine.findGlobalSymbol(RuleRegistry.makeKey("shell", ctorName, arity)); - return rule; + return polyglotEngine.findGlobalSymbol(RuleRegistry.makeKey("shell", ctorName, arity)); } private IStrategoTerm invoke(Value rule, ITerm programTerm) throws MetaborgException { try { // Add the arguments. - List arguments = new ArrayList(1 + rwSemanticComponents.length); + List arguments = new ArrayList<>(1 + rwSemanticComponents.length); arguments.add(programTerm); arguments.addAll(Arrays.asList(rwSemanticComponents)); diff --git a/org.metaborg.spoofax.shell.core/src/main/java/org/metaborg/spoofax/shell/functions/AEvalFunction.java b/org.metaborg.spoofax.shell.core/src/main/java/org/metaborg/spoofax/shell/functions/AEvalFunction.java index 841c2eb2..cc1c2a92 100644 --- a/org.metaborg.spoofax.shell.core/src/main/java/org/metaborg/spoofax/shell/functions/AEvalFunction.java +++ b/org.metaborg.spoofax.shell.core/src/main/java/org/metaborg/spoofax/shell/functions/AEvalFunction.java @@ -2,6 +2,7 @@ import java.util.Map; +import org.metaborg.core.MetaborgException; import org.metaborg.core.context.IContext; import org.metaborg.core.context.IContextService; import org.metaborg.core.language.ILanguageImpl; @@ -50,9 +51,12 @@ public AEvalFunction(Map evaluationStrategies, protected FailOrSuccessResult applyThrowing(IContext context, AnalyzeResult a) throws Exception { ShellFacet facet = context.language().facet(ShellFacet.class); + if (facet == null) { + throw new MetaborgException("Cannot find the shell facet."); + } + IEvaluationStrategy evalStrategy = evaluationStrategies.get(facet.getEvaluationMethod()); IStrategoTerm result = evalStrategy.evaluate(a, context); - return FailOrSuccessResult.ofSpoofaxResult(resultFactory.createEvaluateResult(a, result)); } } diff --git a/org.metaborg.spoofax.shell.core/src/main/java/org/metaborg/spoofax/shell/functions/ATransformFunction.java b/org.metaborg.spoofax.shell.core/src/main/java/org/metaborg/spoofax/shell/functions/ATransformFunction.java index 69f3a51a..5a6b94f9 100644 --- a/org.metaborg.spoofax.shell.core/src/main/java/org/metaborg/spoofax/shell/functions/ATransformFunction.java +++ b/org.metaborg.spoofax.shell.core/src/main/java/org/metaborg/spoofax/shell/functions/ATransformFunction.java @@ -35,7 +35,7 @@ public class ATransformFunction extends ContextualSpoofaxFunction - * The argument type of the {@link #apply(In)} method. + * The argument type of the {@link #apply(Object)} method. * @param * The type of a successful {@link ISpoofaxResult}. */ @@ -30,11 +30,11 @@ public abstract class AbstractSpoofaxFunction - * The argument type of the {@link #apply(In)} method. + * The argument type of the {@link #apply(Object)} method. * @param * The type of a successful {@link ISpoofaxResult}. */ @@ -37,7 +37,7 @@ public abstract class ContextualSpoofaxFunction, * The {@link IContextService} with which to create a new {@link IContext} if * necessary. * @param resultFactory - * The {@link ResulFactory}. + * The {@link IResultFactory}. * @param project * The project in which this command should operate. * @param lang diff --git a/org.metaborg.spoofax.shell.core/src/main/java/org/metaborg/spoofax/shell/functions/FailableFunction.java b/org.metaborg.spoofax.shell.core/src/main/java/org/metaborg/spoofax/shell/functions/FailableFunction.java index 455f8fd9..3d1e987d 100644 --- a/org.metaborg.spoofax.shell.core/src/main/java/org/metaborg/spoofax/shell/functions/FailableFunction.java +++ b/org.metaborg.spoofax.shell.core/src/main/java/org/metaborg/spoofax/shell/functions/FailableFunction.java @@ -7,7 +7,7 @@ import org.metaborg.spoofax.shell.output.IResult; /** - * A {@link java.util.Function} that may result in a failure. This is our domain-specific equivalent + * A {@link Function} that may result in a failure. This is our domain-specific equivalent * of a Kleisli arrow in Haskell. * * @param diff --git a/org.metaborg.spoofax.shell.core/src/main/java/org/metaborg/spoofax/shell/functions/InputFunction.java b/org.metaborg.spoofax.shell.core/src/main/java/org/metaborg/spoofax/shell/functions/InputFunction.java index 96c8342a..a81632ec 100644 --- a/org.metaborg.spoofax.shell.core/src/main/java/org/metaborg/spoofax/shell/functions/InputFunction.java +++ b/org.metaborg.spoofax.shell.core/src/main/java/org/metaborg/spoofax/shell/functions/InputFunction.java @@ -1,7 +1,7 @@ package org.metaborg.spoofax.shell.functions; import org.apache.commons.vfs2.FileObject; -import org.apache.commons.vfs2.FileSystemException; +import org.metaborg.core.MetaborgException; import org.metaborg.core.language.ILanguageImpl; import org.metaborg.core.project.IProject; import org.metaborg.spoofax.core.shell.ShellFacet; @@ -37,8 +37,12 @@ public InputFunction(IResultFactory resultFactory, @Assisted IProject project, @Override protected FailOrSuccessResult applyThrowing(String source) - throws FileSystemException { + throws Exception { ShellFacet shellFacet = lang.facet(ShellFacet.class); + if (shellFacet == null) { + throw new MetaborgException("Cannot find the shell facet."); + } + FileObject file = project.location().resolveFile("temp"); return FailOrSuccessResult.ofSpoofaxResult(resultFactory .createInputResult(lang, file, source, diff --git a/org.metaborg.spoofax.shell.core/src/main/java/org/metaborg/spoofax/shell/functions/PEvalFunction.java b/org.metaborg.spoofax.shell.core/src/main/java/org/metaborg/spoofax/shell/functions/PEvalFunction.java index ce1cceb1..1e2a2cfa 100644 --- a/org.metaborg.spoofax.shell.core/src/main/java/org/metaborg/spoofax/shell/functions/PEvalFunction.java +++ b/org.metaborg.spoofax.shell.core/src/main/java/org/metaborg/spoofax/shell/functions/PEvalFunction.java @@ -2,6 +2,7 @@ import java.util.Map; +import org.metaborg.core.MetaborgException; import org.metaborg.core.context.IContext; import org.metaborg.core.context.IContextService; import org.metaborg.core.language.ILanguageImpl; @@ -50,9 +51,12 @@ public PEvalFunction(Map evaluationStrategies, protected FailOrSuccessResult applyThrowing(IContext context, ParseResult a) throws Exception { ShellFacet facet = context.language().facet(ShellFacet.class); + if (facet == null) { + throw new MetaborgException("Cannot find the shell facet."); + } + IEvaluationStrategy evalStrategy = evaluationStrategies.get(facet.getEvaluationMethod()); IStrategoTerm result = evalStrategy.evaluate(a, context); - return FailOrSuccessResult.ofSpoofaxResult(resultFactory.createEvaluateResult(a, result)); } } diff --git a/org.metaborg.spoofax.shell.core/src/main/java/org/metaborg/spoofax/shell/functions/PTransformFunction.java b/org.metaborg.spoofax.shell.core/src/main/java/org/metaborg/spoofax/shell/functions/PTransformFunction.java index c6e406d5..23d7b098 100644 --- a/org.metaborg.spoofax.shell.core/src/main/java/org/metaborg/spoofax/shell/functions/PTransformFunction.java +++ b/org.metaborg.spoofax.shell.core/src/main/java/org/metaborg/spoofax/shell/functions/PTransformFunction.java @@ -35,7 +35,7 @@ public class PTransformFunction extends ContextualSpoofaxFunction 1 ? Arrays.copyOfRange(split, 1, split.length) : new String[0]; return commandFromName(commandName).execute(argument); } else { - // FIXME: create sensible way to set default - return commandFromName("eval").execute(optionallyPrefixedCommandName); + return getDefault().execute(optionallyPrefixedCommandName); } } diff --git a/org.metaborg.spoofax.shell.core/src/main/java/org/metaborg/spoofax/shell/invoker/SpoofaxCommandInvoker.java b/org.metaborg.spoofax.shell.core/src/main/java/org/metaborg/spoofax/shell/invoker/SpoofaxCommandInvoker.java index 5f974c23..5c7dc874 100644 --- a/org.metaborg.spoofax.shell.core/src/main/java/org/metaborg/spoofax/shell/invoker/SpoofaxCommandInvoker.java +++ b/org.metaborg.spoofax.shell.core/src/main/java/org/metaborg/spoofax/shell/invoker/SpoofaxCommandInvoker.java @@ -6,6 +6,7 @@ import com.google.common.collect.Maps; import com.google.inject.Inject; +import com.google.inject.name.Named; /** * Default implementation of an {@link ICommandInvoker}. @@ -13,16 +14,21 @@ public class SpoofaxCommandInvoker implements ICommandInvoker { private final Map defaults; private final Map commands; + private IReplCommand defaultCommand; /** * Instantiates a new SpoofaxCommandInvoker. * * @param defaults * The commands, with their command names as key (without prefix). + * @param defaultCommand + * The command that will be executed by default. */ @Inject - public SpoofaxCommandInvoker(Map defaults) { + public SpoofaxCommandInvoker(Map defaults, + @Named("default_command") IReplCommand defaultCommand) { this.defaults = defaults; + this.defaultCommand = defaultCommand; this.commands = Maps.newConcurrentMap(); this.resetCommands(); } @@ -40,6 +46,16 @@ public String commandPrefix() { return ":"; } + @Override + public IReplCommand getDefault() { + return defaultCommand; + } + + @Override + public void setDefault(IReplCommand defaultCommand) { + this.defaultCommand = defaultCommand; + } + @Override public void addCommand(String name, IReplCommand command) { commands.put(name, command); diff --git a/org.metaborg.spoofax.shell.core/src/main/java/org/metaborg/spoofax/shell/invoker/package-info.java b/org.metaborg.spoofax.shell.core/src/main/java/org/metaborg/spoofax/shell/invoker/package-info.java index 3ef376a3..16f1d982 100644 --- a/org.metaborg.spoofax.shell.core/src/main/java/org/metaborg/spoofax/shell/invoker/package-info.java +++ b/org.metaborg.spoofax.shell.core/src/main/java/org/metaborg/spoofax/shell/invoker/package-info.java @@ -1,5 +1,5 @@ /** - * The {@link ICommandInvoker} is called by {@link org.metaborg.spoofax.shell.client.IRepl} to - * execute expressions and commands. + * The {@link org.metaborg.spoofax.shell.invoker.ICommandInvoker} is called by + * {@link org.metaborg.spoofax.shell.client.IRepl} to execute expressions and commands. */ package org.metaborg.spoofax.shell.invoker; \ No newline at end of file diff --git a/org.metaborg.spoofax.shell.core/src/main/java/org/metaborg/spoofax/shell/output/AbstractSpoofaxResult.java b/org.metaborg.spoofax.shell.core/src/main/java/org/metaborg/spoofax/shell/output/AbstractSpoofaxResult.java index 8ef0a756..c9d212b6 100644 --- a/org.metaborg.spoofax.shell.core/src/main/java/org/metaborg/spoofax/shell/output/AbstractSpoofaxResult.java +++ b/org.metaborg.spoofax.shell.core/src/main/java/org/metaborg/spoofax/shell/output/AbstractSpoofaxResult.java @@ -3,19 +3,20 @@ import org.apache.commons.vfs2.FileObject; import org.metaborg.core.unit.IUnit; import org.metaborg.spoofax.core.stratego.IStrategoCommon; +import org.metaborg.spoofax.shell.commands.IReplCommand; import org.spoofax.interpreter.terms.IStrategoTerm; /** - * Represents an {@link AbstractResult} as returned by the {@link SpoofaxCommand}. + * Represents an {@link AbstractSpoofaxResult} as returned by the {@link IReplCommand}. * Wraps Spoofax {@link IUnit} of various types. * @param the wrapped subtype of {@link IUnit} */ public abstract class AbstractSpoofaxResult implements ISpoofaxResult { - private IStrategoCommon common; - private T unit; + private final IStrategoCommon common; + private final T unit; /** - * Constructor for an {@link AbstractResult}. + * Constructor for an {@link AbstractSpoofaxResult}. * @param common the {@link IStrategoCommon} service * @param unit the wrapped {@link IUnit} */ diff --git a/org.metaborg.spoofax.shell.core/src/main/java/org/metaborg/spoofax/shell/output/AnalyzeResult.java b/org.metaborg.spoofax.shell.core/src/main/java/org/metaborg/spoofax/shell/output/AnalyzeResult.java index abb4d5f9..d55e7e1c 100644 --- a/org.metaborg.spoofax.shell.core/src/main/java/org/metaborg/spoofax/shell/output/AnalyzeResult.java +++ b/org.metaborg.spoofax.shell.core/src/main/java/org/metaborg/spoofax/shell/output/AnalyzeResult.java @@ -9,13 +9,14 @@ import org.metaborg.core.messages.IMessage; import org.metaborg.spoofax.core.stratego.IStrategoCommon; import org.metaborg.spoofax.core.unit.ISpoofaxAnalyzeUnit; +import org.metaborg.spoofax.shell.commands.IReplCommand; import org.spoofax.interpreter.terms.IStrategoTerm; import com.google.inject.assistedinject.Assisted; import com.google.inject.assistedinject.AssistedInject; /** - * Represents an {@link AnalyzeResult} as returned by the {@link SpoofaxCommand}. + * Represents an {@link AnalyzeResult} as returned by the {@link IReplCommand}. * Wraps a {@link ISpoofaxAnalyzeUnit}. */ public class AnalyzeResult extends AbstractSpoofaxResult { diff --git a/org.metaborg.spoofax.shell.core/src/main/java/org/metaborg/spoofax/shell/output/EvaluateResult.java b/org.metaborg.spoofax.shell.core/src/main/java/org/metaborg/spoofax/shell/output/EvaluateResult.java index d309aed9..b71a93fb 100644 --- a/org.metaborg.spoofax.shell.core/src/main/java/org/metaborg/spoofax/shell/output/EvaluateResult.java +++ b/org.metaborg.spoofax.shell.core/src/main/java/org/metaborg/spoofax/shell/output/EvaluateResult.java @@ -18,8 +18,8 @@ * The result of the execution of an {@link AEvalFunction} or a {@link PEvalFunction}. */ public abstract class EvaluateResult extends AbstractSpoofaxResult { - private AbstractSpoofaxResult wrappedDelegate; - private IStrategoTerm result; + private final AbstractSpoofaxResult wrappedDelegate; + private final IStrategoTerm result; /** * The result of the evaluation of an analyzed AST. diff --git a/org.metaborg.spoofax.shell.core/src/main/java/org/metaborg/spoofax/shell/output/ExceptionResult.java b/org.metaborg.spoofax.shell.core/src/main/java/org/metaborg/spoofax/shell/output/ExceptionResult.java index 6f27a766..04ef9e59 100644 --- a/org.metaborg.spoofax.shell.core/src/main/java/org/metaborg/spoofax/shell/output/ExceptionResult.java +++ b/org.metaborg.spoofax.shell.core/src/main/java/org/metaborg/spoofax/shell/output/ExceptionResult.java @@ -4,7 +4,7 @@ * Represents a command that has resulted in a {@link Throwable}. */ public class ExceptionResult implements IResult { - private Throwable thrown; + private final Throwable thrown; /** * Create an {@link ExceptionResult} from a {@link Throwable}. diff --git a/org.metaborg.spoofax.shell.core/src/main/java/org/metaborg/spoofax/shell/output/FailOrSuccessResult.java b/org.metaborg.spoofax.shell.core/src/main/java/org/metaborg/spoofax/shell/output/FailOrSuccessResult.java index 512267e7..543b1824 100644 --- a/org.metaborg.spoofax.shell.core/src/main/java/org/metaborg/spoofax/shell/output/FailOrSuccessResult.java +++ b/org.metaborg.spoofax.shell.core/src/main/java/org/metaborg/spoofax/shell/output/FailOrSuccessResult.java @@ -84,7 +84,7 @@ public void accept(IResultVisitor visitor) { */ public static FailOrSuccessResult successful(S successfulResult) { - return new Successful(successfulResult); + return new Successful<>(successfulResult); } /** @@ -100,7 +100,7 @@ public void accept(IResultVisitor visitor) { */ public static FailOrSuccessResult failed(F failedResult) { - return new Failed(failedResult); + return new Failed<>(failedResult); } /** diff --git a/org.metaborg.spoofax.shell.core/src/main/java/org/metaborg/spoofax/shell/output/ISpoofaxResult.java b/org.metaborg.spoofax.shell.core/src/main/java/org/metaborg/spoofax/shell/output/ISpoofaxResult.java index 003ddc31..b27a76a8 100644 --- a/org.metaborg.spoofax.shell.core/src/main/java/org/metaborg/spoofax/shell/output/ISpoofaxResult.java +++ b/org.metaborg.spoofax.shell.core/src/main/java/org/metaborg/spoofax/shell/output/ISpoofaxResult.java @@ -7,10 +7,11 @@ import org.metaborg.core.context.IContext; import org.metaborg.core.messages.IMessage; import org.metaborg.core.unit.IUnit; +import org.metaborg.spoofax.shell.commands.IReplCommand; import org.spoofax.interpreter.terms.IStrategoTerm; /** - * Represents an {@link ISpoofaxResult} as returned by the {@link SpoofaxCommand} (TODO). + * Represents an {@link ISpoofaxResult} as returned by the {@link IReplCommand}. * Wraps Spoofax {@link IUnit} of various types. * @param the wrapped subtype of {@link IUnit} */ diff --git a/org.metaborg.spoofax.shell.core/src/main/java/org/metaborg/spoofax/shell/output/InputResult.java b/org.metaborg.spoofax.shell.core/src/main/java/org/metaborg/spoofax/shell/output/InputResult.java index 37b50a54..1fb1c5e2 100644 --- a/org.metaborg.spoofax.shell.core/src/main/java/org/metaborg/spoofax/shell/output/InputResult.java +++ b/org.metaborg.spoofax.shell.core/src/main/java/org/metaborg/spoofax/shell/output/InputResult.java @@ -11,6 +11,7 @@ import org.metaborg.spoofax.core.syntax.JSGLRParserConfiguration; import org.metaborg.spoofax.core.unit.ISpoofaxInputUnit; import org.metaborg.spoofax.core.unit.ISpoofaxUnitService; +import org.metaborg.spoofax.shell.commands.IReplCommand; import org.spoofax.interpreter.terms.IStrategoTerm; import com.google.common.collect.Lists; @@ -18,7 +19,7 @@ import com.google.inject.assistedinject.AssistedInject; /** - * Represents a {@link InputResult} as returned by the {@link SpoofaxCommand}. Wraps a + * Represents a {@link InputResult} as returned by the {@link IReplCommand}. Wraps a * {@link ISpoofaxInputUnit}. */ public class InputResult extends AbstractSpoofaxResult { diff --git a/org.metaborg.spoofax.shell.core/src/main/java/org/metaborg/spoofax/shell/output/ParseResult.java b/org.metaborg.spoofax.shell.core/src/main/java/org/metaborg/spoofax/shell/output/ParseResult.java index bf150538..bc2b25c4 100644 --- a/org.metaborg.spoofax.shell.core/src/main/java/org/metaborg/spoofax/shell/output/ParseResult.java +++ b/org.metaborg.spoofax.shell.core/src/main/java/org/metaborg/spoofax/shell/output/ParseResult.java @@ -9,13 +9,14 @@ import org.metaborg.core.messages.IMessage; import org.metaborg.spoofax.core.stratego.IStrategoCommon; import org.metaborg.spoofax.core.unit.ISpoofaxParseUnit; +import org.metaborg.spoofax.shell.commands.IReplCommand; import org.spoofax.interpreter.terms.IStrategoTerm; import com.google.inject.assistedinject.Assisted; import com.google.inject.assistedinject.AssistedInject; /** - * Represents a {@link ParseResult} as returned by the {@link SpoofaxCommand}. + * Represents a {@link ParseResult} as returned by the {@link IReplCommand}. * Wraps a {@link ISpoofaxParseUnit}. */ public class ParseResult extends AbstractSpoofaxResult { diff --git a/org.metaborg.spoofax.shell.core/src/main/java/org/metaborg/spoofax/shell/output/StyledText.java b/org.metaborg.spoofax.shell.core/src/main/java/org/metaborg/spoofax/shell/output/StyledText.java index 39259347..a845aae3 100644 --- a/org.metaborg.spoofax.shell.core/src/main/java/org/metaborg/spoofax/shell/output/StyledText.java +++ b/org.metaborg.spoofax.shell.core/src/main/java/org/metaborg/spoofax/shell/output/StyledText.java @@ -206,12 +206,13 @@ public boolean equals(Object obj) { @Override public int hashCode() { return source.stream() - .map(e -> e.fragment().hashCode() * e.style().hashCode()) - .reduce(1, (a, b) -> a * b); + .map(e -> (e.fragment() == null ? 1 : e.fragment().hashCode()) + * (e.style() == null ? 1 : e.style().hashCode())) + .reduce(1, (a, b) -> a * b); } @Override public String toString() { - return source.stream().map(e -> e.fragment()).collect(Collectors.joining()); + return source.stream().map(IRegionStyle::fragment).collect(Collectors.joining()); } } diff --git a/org.metaborg.spoofax.shell.core/src/main/java/org/metaborg/spoofax/shell/output/TransformResult.java b/org.metaborg.spoofax.shell.core/src/main/java/org/metaborg/spoofax/shell/output/TransformResult.java index 8112e367..ef698187 100644 --- a/org.metaborg.spoofax.shell.core/src/main/java/org/metaborg/spoofax/shell/output/TransformResult.java +++ b/org.metaborg.spoofax.shell.core/src/main/java/org/metaborg/spoofax/shell/output/TransformResult.java @@ -12,6 +12,7 @@ import org.metaborg.spoofax.core.unit.ISpoofaxAnalyzeUnit; import org.metaborg.spoofax.core.unit.ISpoofaxParseUnit; import org.metaborg.spoofax.core.unit.ISpoofaxTransformUnit; +import org.metaborg.spoofax.shell.commands.IReplCommand; import org.spoofax.interpreter.terms.IStrategoTerm; import com.google.inject.Inject; @@ -19,7 +20,7 @@ import com.google.inject.assistedinject.AssistedInject; /** - * Represents a {@link TransformResult} as returned by the {@link SpoofaxCommand}. Wraps a + * Represents a {@link TransformResult} as returned by the {@link IReplCommand}. Wraps a * {@link ISpoofaxTransformUnit}. */ public abstract class TransformResult diff --git a/org.metaborg.spoofax.shell.core/src/main/java/org/metaborg/spoofax/shell/output/package-info.java b/org.metaborg.spoofax.shell.core/src/main/java/org/metaborg/spoofax/shell/output/package-info.java index 38c48806..be38529f 100644 --- a/org.metaborg.spoofax.shell.core/src/main/java/org/metaborg/spoofax/shell/output/package-info.java +++ b/org.metaborg.spoofax.shell.core/src/main/java/org/metaborg/spoofax/shell/output/package-info.java @@ -1,6 +1,5 @@ /** - * This package defines result classes, which are passed on to hooks. - * - * @see {@link org.metaborg.spoofax.shell.hooks} + * This package defines result classes, that can be visited by an + * {@link org.metaborg.spoofax.shell.output.IResultVisitor}. */ package org.metaborg.spoofax.shell.output; \ No newline at end of file diff --git a/org.metaborg.spoofax.shell.core/src/test/java/org/metaborg/spoofax/shell/client/InputHistoryTest.java b/org.metaborg.spoofax.shell.core/src/test/java/org/metaborg/spoofax/shell/client/InputHistoryTest.java index 0e6f3b01..a55d33a1 100644 --- a/org.metaborg.spoofax.shell.core/src/test/java/org/metaborg/spoofax/shell/client/InputHistoryTest.java +++ b/org.metaborg.spoofax.shell.core/src/test/java/org/metaborg/spoofax/shell/client/InputHistoryTest.java @@ -45,7 +45,7 @@ public void testAppend() { } /** - * Test {@link IInputHistory@get(int)}. + * Test {@link IInputHistory#get(int)}. */ @Test(expected = IndexOutOfBoundsException.class) public void testGet() { @@ -56,7 +56,7 @@ public void testGet() { /** * Test the stateful {@link IInputHistory#getPrevious()}, {@link IInputHistory#getNext()} and - * {@link IInputHisytory#reset()} methods. + * {@link IInputHistory#reset()} methods. */ @Test public void testGetStateful() { diff --git a/org.metaborg.spoofax.shell.core/src/test/java/org/metaborg/spoofax/shell/commands/HelpCommandTest.java b/org.metaborg.spoofax.shell.core/src/test/java/org/metaborg/spoofax/shell/commands/HelpCommandTest.java index ad2a6ca9..5a5d4abc 100644 --- a/org.metaborg.spoofax.shell.core/src/test/java/org/metaborg/spoofax/shell/commands/HelpCommandTest.java +++ b/org.metaborg.spoofax.shell.core/src/test/java/org/metaborg/spoofax/shell/commands/HelpCommandTest.java @@ -41,7 +41,6 @@ public class HelpCommandTest { @Mock private IReplCommand multiLineComment; private HelpCommand helpCommand; - private Map commands; /** * Set up mocks used in the test case. @@ -49,7 +48,7 @@ public class HelpCommandTest { */ @Before public void setup() throws CommandNotFoundException { - commands = Maps.newHashMap(); + Map commands = Maps.newHashMap(); commands.put("name-1", singleLineComment); commands.put("name-2", multiLineComment); diff --git a/org.metaborg.spoofax.shell.core/src/test/java/org/metaborg/spoofax/shell/commands/LanguageCommandTest.java b/org.metaborg.spoofax.shell.core/src/test/java/org/metaborg/spoofax/shell/commands/LanguageCommandTest.java index 1b5bedf3..c42fa88a 100644 --- a/org.metaborg.spoofax.shell.core/src/test/java/org/metaborg/spoofax/shell/commands/LanguageCommandTest.java +++ b/org.metaborg.spoofax.shell.core/src/test/java/org/metaborg/spoofax/shell/commands/LanguageCommandTest.java @@ -11,6 +11,10 @@ import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; +import static org.mockito.MockitoAnnotations.initMocks; + +import java.util.Arrays; +import java.util.Collection; import org.apache.commons.vfs2.FileObject; import org.apache.commons.vfs2.FileSystemException; @@ -18,6 +22,8 @@ import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; +import org.junit.runners.Parameterized; +import org.junit.runners.Parameterized.Parameters; import org.metaborg.core.MetaborgException; import org.metaborg.core.analysis.AnalyzerFacet; import org.metaborg.core.language.ILanguageComponent; @@ -37,15 +43,15 @@ import org.mockito.Captor; import org.mockito.Mock; import org.mockito.Mockito; -import org.mockito.runners.MockitoJUnitRunner; import com.google.common.collect.Lists; /** * Test creating and using the {@link LanguageCommand}. */ -@RunWith(MockitoJUnitRunner.class) +@RunWith(Parameterized.class) public class LanguageCommandTest { + private final String extension; // Constructor mocks @Mock private ILanguageDiscoveryService langDiscoveryService; @@ -66,14 +72,46 @@ public class LanguageCommandTest { private FileObject langloc; private LanguageCommand langCommand; + /** + * List the archive types that are tested. + * + * @return An array of archive extensions. + */ + @Parameters + public static Collection archives() { + // @formatter.off + return Arrays.asList(new Object[][] { + { "zip" }, + { "jar" }, + { "tar" }, + { "tgz" }, + { "tbz2" } + }); + // @formatter.on + } + + /** + * Instantiate a new {@link LanguageCommandTest}. + * + * @param archiveExtension + * The archive extension to run the tests with, see {@link #archives()}. + */ + public LanguageCommandTest(String archiveExtension) { + this.extension = archiveExtension; + } + /** * Set up mocks used in the test case. - * @throws FileSystemException when resolving the temp file fails - * @throws ParseException when parsing fails + * + * @throws FileSystemException + * when resolving the temp file fails + * @throws ParseException + * when parsing fails */ @Before - public void setup() throws FileSystemException, ParseException { - langloc = VFS.getManager().resolveFile("res:paplj.zip"); + public void setUp() throws FileSystemException, ParseException { + initMocks(this); + langloc = VFS.getManager().resolveFile("res:paplj." + this.extension); Mockito.>when(langcomp.contributesTo()) .thenReturn(Lists.newArrayList(lang)); when(resourceService.resolveToName(anyString())).thenReturn(langloc.getName()); diff --git a/org.metaborg.spoofax.shell.core/src/test/java/org/metaborg/spoofax/shell/core/ClassPathInterpreterLoaderTest.java b/org.metaborg.spoofax.shell.core/src/test/java/org/metaborg/spoofax/shell/core/ClassPathInterpreterLoaderTest.java index 5bd6975c..2d9b1d98 100644 --- a/org.metaborg.spoofax.shell.core/src/test/java/org/metaborg/spoofax/shell/core/ClassPathInterpreterLoaderTest.java +++ b/org.metaborg.spoofax.shell.core/src/test/java/org/metaborg/spoofax/shell/core/ClassPathInterpreterLoaderTest.java @@ -58,16 +58,16 @@ public class ClassPathInterpreterLoaderTest { private static final String NO_EXCEPTION = "No exception should be thrown"; protected static final String SPEC_TERM_CONSTANT = "specification term"; - protected ClassPathInterpreterLoader cpInterpLoader = new ClassPathInterpreterLoader(); + protected final ClassPathInterpreterLoader cpInterpLoader = new ClassPathInterpreterLoader(); protected static final RuleRoot MOCK_RULE_ROOT = Mockito.mock(RuleRoot.class); protected ILanguageImpl mockLangImpl; @SuppressWarnings("unused") private static final TestCPLoaderLanguage LANG = TestCPLoaderLanguage.INSTANCE; private static boolean reachedLanguageParse = false; - private Iterable langImplLocations; - private String expectedExceptionMessage; - private Class expectedExceptionCauseClass; + private final Iterable langImplLocations; + private final String expectedExceptionMessage; + private final Class expectedExceptionCauseClass; /** * @param langImplLocations @@ -136,8 +136,7 @@ public static Collection languageLocationsParameters() throws FileSyst } - private static Supplier> goodWeatherLocations(FileObject rootDir) - throws FileSystemException { + private static Supplier> goodWeatherLocations(FileObject rootDir) { return () -> { try { rootDir.createFolder(); @@ -151,7 +150,7 @@ private static Supplier> goodWeatherLocations(FileObject rootDi printWriter.flush(); printWriter.close(); dynSemProperties.close(); - List res = new ArrayList(1); + List res = new ArrayList<>(1); res.add(rootDir); return res; } catch (FileSystemException e) { @@ -161,8 +160,7 @@ private static Supplier> goodWeatherLocations(FileObject rootDi }; } - private static Supplier> missingDynSemProperties(FileObject rootDir) - throws FileSystemException { + private static Supplier> missingDynSemProperties(FileObject rootDir) { return () -> { try { rootDir.createFolder(); @@ -174,7 +172,7 @@ private static Supplier> missingDynSemProperties(FileObject roo printWriter.flush(); printWriter.close(); noDynSemProperties.close(); - List res = new ArrayList(1); + List res = new ArrayList<>(1); res.add(rootDir); return res; } catch (FileSystemException e) { @@ -184,8 +182,7 @@ private static Supplier> missingDynSemProperties(FileObject roo }; } - private static Supplier> multipleLocations(FileObject rootDir) - throws FileSystemException { + private static Supplier> multipleLocations(FileObject rootDir) { return () -> { try { rootDir.createFolder(); @@ -219,7 +216,7 @@ private static Supplier> badWeatherLocations(FileObject rootDir printWriter.flush(); printWriter.close(); dynSemProperties.close(); - List res = new ArrayList(1); + List res = new ArrayList<>(1); res.add(rootDir); return res; } catch (FileSystemException e) { diff --git a/org.metaborg.spoofax.shell.core/src/test/java/org/metaborg/spoofax/shell/core/DynSemEvaluationStrategyTest.java b/org.metaborg.spoofax.shell.core/src/test/java/org/metaborg/spoofax/shell/core/DynSemEvaluationStrategyTest.java index 010db9fa..53f7d7cb 100644 --- a/org.metaborg.spoofax.shell.core/src/test/java/org/metaborg/spoofax/shell/core/DynSemEvaluationStrategyTest.java +++ b/org.metaborg.spoofax.shell.core/src/test/java/org/metaborg/spoofax/shell/core/DynSemEvaluationStrategyTest.java @@ -48,7 +48,7 @@ @RunWith(Parameterized.class) public class DynSemEvaluationStrategyTest { private final DynSemEvaluationStrategy evalStrategy; - private IStrategoTerm input; + private final IStrategoTerm input; private static final int DEFAULT_SHELL_RULE_ANSWER = 42; private static final String NO_EXCEPTION = "No exception should be thrown"; private final String expectedExceptionMessage; @@ -132,7 +132,7 @@ public void testEnvironmentPropagation() { * An {@link IInterpreterLoader} that returns a mock interpreter. */ static final class MockInterpreterLoader implements IInterpreterLoader { - private String ruleKey; + private final String ruleKey; private MockInterpreterLoader(String ruleKey) { this.ruleKey = ruleKey; diff --git a/org.metaborg.spoofax.shell.core/src/test/java/org/metaborg/spoofax/shell/functions/AnalyzeFunctionTest.java b/org.metaborg.spoofax.shell.core/src/test/java/org/metaborg/spoofax/shell/functions/AnalyzeFunctionTest.java index d5a90ee6..8943ebdb 100644 --- a/org.metaborg.spoofax.shell.core/src/test/java/org/metaborg/spoofax/shell/functions/AnalyzeFunctionTest.java +++ b/org.metaborg.spoofax.shell.core/src/test/java/org/metaborg/spoofax/shell/functions/AnalyzeFunctionTest.java @@ -26,8 +26,6 @@ import org.metaborg.spoofax.core.unit.ISpoofaxAnalyzeUnit; import org.metaborg.spoofax.shell.commands.CommandBuilder; import org.metaborg.spoofax.shell.commands.IReplCommand; -import org.metaborg.spoofax.shell.functions.AnalyzeFunction; -import org.metaborg.spoofax.shell.functions.IFunctionFactory; import org.metaborg.spoofax.shell.output.AnalyzeResult; import org.metaborg.spoofax.shell.output.FailOrSuccessResult; import org.metaborg.spoofax.shell.output.FailResult; @@ -71,7 +69,6 @@ public class AnalyzeFunctionTest { @Captor private ArgumentCaptor> resultCaptor; @Captor private ArgumentCaptor exceptionCaptor; - private FileObject sourceFile; private IReplCommand analyzeCommand; /** @@ -81,7 +78,7 @@ public class AnalyzeFunctionTest { */ @Before public void setup() throws FileSystemException, MetaborgException { - sourceFile = VFS.getManager().resolveFile("ram://junit-temp"); + FileObject sourceFile = VFS.getManager().resolveFile("ram://junit-temp"); when(project.location()).thenReturn(sourceFile); AnalyzeFunction analyzeFunction = new AnalyzeFunction(contextService, analysisService, diff --git a/org.metaborg.spoofax.shell.core/src/test/java/org/metaborg/spoofax/shell/functions/EvaluateFunctionTest.java b/org.metaborg.spoofax.shell.core/src/test/java/org/metaborg/spoofax/shell/functions/EvaluateFunctionTest.java index ffdbf74b..cfe1dffc 100644 --- a/org.metaborg.spoofax.shell.core/src/test/java/org/metaborg/spoofax/shell/functions/EvaluateFunctionTest.java +++ b/org.metaborg.spoofax.shell.core/src/test/java/org/metaborg/spoofax/shell/functions/EvaluateFunctionTest.java @@ -92,11 +92,10 @@ public class EvaluateFunctionTest { @Captor private ArgumentCaptor exceptionCaptor; - private FileObject sourceFile; - private String description; - private EvaluateResult result; - private IReplCommand command; - private Function check; + private final String description; + private final EvaluateResult result; + private final IReplCommand command; + private final Function check; /** * Parameters to test {@link AEvalFunction} and {@link PEvalFunction}. @@ -105,10 +104,8 @@ public class EvaluateFunctionTest { */ @Parameters(name = "{index}: {0}") public static List functions() { - Function, CommandBuilder> parsedEval = - (builder) -> builder.evalParsed(); - Function, CommandBuilder> analyzedEval = - (builder) -> builder.evalAnalyzed(); + Function, CommandBuilder> parsedEval = CommandBuilder::evalParsed; + Function, CommandBuilder> analyzedEval = CommandBuilder::evalAnalyzed; Function checkParsed = (factory) -> factory.createEvaluateResult(any(ParseResult.class), any()); Function checkAnalyzed = @@ -165,7 +162,7 @@ private void mockContext() { } private void mockServices() throws FileSystemException, MetaborgException { - sourceFile = VFS.getManager().resolveFile("ram://junit-temp"); + FileObject sourceFile = VFS.getManager().resolveFile("ram://junit-temp"); when(project.location()).thenReturn(sourceFile); when(parseResult.context()).thenReturn(Optional.empty()); when(analyzeResult.context()).thenReturn(Optional.empty()); diff --git a/org.metaborg.spoofax.shell.core/src/test/java/org/metaborg/spoofax/shell/functions/InputFunctionTest.java b/org.metaborg.spoofax.shell.core/src/test/java/org/metaborg/spoofax/shell/functions/InputFunctionTest.java index a2880846..fc17c96b 100644 --- a/org.metaborg.spoofax.shell.core/src/test/java/org/metaborg/spoofax/shell/functions/InputFunctionTest.java +++ b/org.metaborg.spoofax.shell.core/src/test/java/org/metaborg/spoofax/shell/functions/InputFunctionTest.java @@ -59,7 +59,6 @@ public class InputFunctionTest { @Captor private ArgumentCaptor> resultCaptor; @Captor private ArgumentCaptor exceptionCaptor; - private FileObject sourceFile; private IReplCommand inputCommand; /** @@ -68,7 +67,7 @@ public class InputFunctionTest { */ @Before public void setup() throws FileSystemException { - sourceFile = VFS.getManager().resolveFile("ram://junit-temp"); + FileObject sourceFile = VFS.getManager().resolveFile("ram://junit-temp"); when(project.location()).thenReturn(sourceFile); InputFunction inputFunction = new InputFunction(resultFactory, project, lang); diff --git a/org.metaborg.spoofax.shell.core/src/test/java/org/metaborg/spoofax/shell/functions/ParseFunctionTest.java b/org.metaborg.spoofax.shell.core/src/test/java/org/metaborg/spoofax/shell/functions/ParseFunctionTest.java index a9bc085c..c585bd27 100644 --- a/org.metaborg.spoofax.shell.core/src/test/java/org/metaborg/spoofax/shell/functions/ParseFunctionTest.java +++ b/org.metaborg.spoofax.shell.core/src/test/java/org/metaborg/spoofax/shell/functions/ParseFunctionTest.java @@ -63,7 +63,6 @@ public class ParseFunctionTest { @Captor private ArgumentCaptor> resultCaptor; @Captor private ArgumentCaptor exceptionCaptor; - private FileObject sourceFile; private IReplCommand parseCommand; /** @@ -73,7 +72,7 @@ public class ParseFunctionTest { */ @Before public void setup() throws FileSystemException, ParseException { - sourceFile = VFS.getManager().resolveFile("ram://junit-temp"); + FileObject sourceFile = VFS.getManager().resolveFile("ram://junit-temp"); when(project.location()).thenReturn(sourceFile); ParseFunction parseFunction = new ParseFunction(syntaxService, unitService, diff --git a/org.metaborg.spoofax.shell.core/src/test/java/org/metaborg/spoofax/shell/functions/TransformFunctionTest.java b/org.metaborg.spoofax.shell.core/src/test/java/org/metaborg/spoofax/shell/functions/TransformFunctionTest.java index 1f20d452..533f5dfd 100644 --- a/org.metaborg.spoofax.shell.core/src/test/java/org/metaborg/spoofax/shell/functions/TransformFunctionTest.java +++ b/org.metaborg.spoofax.shell.core/src/test/java/org/metaborg/spoofax/shell/functions/TransformFunctionTest.java @@ -52,7 +52,8 @@ import org.mockito.Mock; /** - * Test creating and using a {@link IReplCommand} created from the {@link TransformFunction}. + * Test creating and using a {@link IReplCommand} created from the {@link PTransformFunction} and + * the {@link ATransformFunction}. */ @RunWith(Parameterized.class) public class TransformFunctionTest { @@ -82,11 +83,10 @@ public class TransformFunctionTest { @Captor private ArgumentCaptor> resultCaptor; @Captor private ArgumentCaptor exceptionCaptor; - private FileObject sourceFile; - private String description; - private TransformResult result; + private final String description; + private final TransformResult result; + private final Function check; private IReplCommand command; - private Function check; /** * Parameters to test {@link ATransformFunction} and {@link PTransformFunction}. @@ -95,9 +95,9 @@ public class TransformFunctionTest { @Parameters(name = "{index}: {0}") public static List functions() { BiFunction, ITransformAction, CommandBuilder> parsedTransform - = (builder, action) -> builder.transformParsed(action); + = CommandBuilder::transformParsed; BiFunction, ITransformAction, CommandBuilder> analyzedTransform - = (builder, action) -> builder.transformAnalyzed(action); + = CommandBuilder::transformAnalyzed; Function checkParsed = (factory) -> factory.createPTransformResult(any()); Function checkAnalyzed @@ -137,7 +137,7 @@ public TransformFunctionTest(String description, } private void mockServices() throws FileSystemException, MetaborgException { - sourceFile = VFS.getManager().resolveFile("ram://junit-temp"); + FileObject sourceFile = VFS.getManager().resolveFile("ram://junit-temp"); when(project.location()).thenReturn(sourceFile); when(parseResult.context()).thenReturn(Optional.empty()); when(analyzeResult.context()).thenReturn(Optional.empty()); diff --git a/org.metaborg.spoofax.shell.core/src/test/java/org/metaborg/spoofax/shell/invoker/SpoofaxCommandInvokerTest.java b/org.metaborg.spoofax.shell.core/src/test/java/org/metaborg/spoofax/shell/invoker/SpoofaxCommandInvokerTest.java index ec799502..1e72d3ff 100644 --- a/org.metaborg.spoofax.shell.core/src/test/java/org/metaborg/spoofax/shell/invoker/SpoofaxCommandInvokerTest.java +++ b/org.metaborg.spoofax.shell.core/src/test/java/org/metaborg/spoofax/shell/invoker/SpoofaxCommandInvokerTest.java @@ -2,9 +2,11 @@ import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; +import static org.mockito.Mockito.mock; import org.junit.Before; import org.junit.Test; +import org.metaborg.spoofax.shell.commands.IReplCommand; import com.google.common.collect.Maps; @@ -19,7 +21,7 @@ public class SpoofaxCommandInvokerTest { */ @Before public void setUp() { - invoker = new SpoofaxCommandInvoker(Maps.newHashMap()); + invoker = new SpoofaxCommandInvoker(Maps.newHashMap(), mock(IReplCommand.class)); } /** diff --git a/org.metaborg.spoofax.shell.core/src/test/java/org/metaborg/spoofax/shell/output/SpoofaxResultsTest.java b/org.metaborg.spoofax.shell.core/src/test/java/org/metaborg/spoofax/shell/output/SpoofaxResultsTest.java index 599c89ab..29b1a411 100644 --- a/org.metaborg.spoofax.shell.core/src/test/java/org/metaborg/spoofax/shell/output/SpoofaxResultsTest.java +++ b/org.metaborg.spoofax.shell.core/src/test/java/org/metaborg/spoofax/shell/output/SpoofaxResultsTest.java @@ -40,13 +40,13 @@ public class SpoofaxResultsTest { private static final String ACTUAL_TO_STRING = "actual"; private static final String ACTUAL_SOURCE = "actual source"; - private AbstractSpoofaxResult abstractResult; - private List expectedMessages; - private Optional expectedAst; - private Optional expectedContext; - private FileObject expectedSource; - private boolean expectedValid; - private String expectedString; + private final AbstractSpoofaxResult abstractResult; + private final List expectedMessages; + private final Optional expectedAst; + private final Optional expectedContext; + private final FileObject expectedSource; + private final boolean expectedValid; + private final String expectedString; /** * Instantiate parameters. diff --git a/org.metaborg.spoofax.shell.core/src/test/resources/paplj.jar b/org.metaborg.spoofax.shell.core/src/test/resources/paplj.jar new file mode 100644 index 00000000..67f32d2a Binary files /dev/null and b/org.metaborg.spoofax.shell.core/src/test/resources/paplj.jar differ diff --git a/org.metaborg.spoofax.shell.core/src/test/resources/paplj.tar b/org.metaborg.spoofax.shell.core/src/test/resources/paplj.tar new file mode 100644 index 00000000..67f32d2a Binary files /dev/null and b/org.metaborg.spoofax.shell.core/src/test/resources/paplj.tar differ diff --git a/org.metaborg.spoofax.shell.core/src/test/resources/paplj.tbz2 b/org.metaborg.spoofax.shell.core/src/test/resources/paplj.tbz2 new file mode 100644 index 00000000..67f32d2a Binary files /dev/null and b/org.metaborg.spoofax.shell.core/src/test/resources/paplj.tbz2 differ diff --git a/org.metaborg.spoofax.shell.core/src/test/resources/paplj.tgz b/org.metaborg.spoofax.shell.core/src/test/resources/paplj.tgz new file mode 100644 index 00000000..67f32d2a Binary files /dev/null and b/org.metaborg.spoofax.shell.core/src/test/resources/paplj.tgz differ diff --git a/org.metaborg.spoofax.shell.eclipse/src/main/java/org/metaborg/spoofax/shell/client/eclipse/ColorManager.java b/org.metaborg.spoofax.shell.eclipse/src/main/java/org/metaborg/spoofax/shell/client/eclipse/ColorManager.java index 11b4c939..6aef3b6a 100644 --- a/org.metaborg.spoofax.shell.eclipse/src/main/java/org/metaborg/spoofax/shell/client/eclipse/ColorManager.java +++ b/org.metaborg.spoofax.shell.eclipse/src/main/java/org/metaborg/spoofax/shell/client/eclipse/ColorManager.java @@ -18,25 +18,13 @@ * Note that the ColorManager is not thread-safe. */ public class ColorManager { - private Map colors = new HashMap(); - - /** - * Return the default foreground color, which is all black. - * - * @return A new {@link RGB}. - */ - public static RGB getDefault() { - return new RGB(0, 0, 0); - } + private final Map colors = new HashMap<>(); /** * Dispose all created colors. */ public void dispose() { - for (Color color : colors.values()) { - color.dispose(); - } - + colors.values().stream().forEach(Color::dispose); colors.clear(); } diff --git a/org.metaborg.spoofax.shell.eclipse/src/main/java/org/metaborg/spoofax/shell/client/eclipse/impl/EclipseDisplay.java b/org.metaborg.spoofax.shell.eclipse/src/main/java/org/metaborg/spoofax/shell/client/eclipse/impl/EclipseDisplay.java index b3c82d0b..d6f8f49e 100644 --- a/org.metaborg.spoofax.shell.eclipse/src/main/java/org/metaborg/spoofax/shell/client/eclipse/impl/EclipseDisplay.java +++ b/org.metaborg.spoofax.shell.eclipse/src/main/java/org/metaborg/spoofax/shell/client/eclipse/impl/EclipseDisplay.java @@ -27,6 +27,9 @@ * Note that this class should always be run in and accessed from the UI thread! */ public class EclipseDisplay implements IDisplay { + // TODO: Use ReplDocument to provide custom partitioning? Perhaps more something for the output + // as opposed to input. Should be relatively easy for output to at least partition different + // input/output combinations. private final ITextViewer output; private final ColorManager colorManager; @@ -111,8 +114,6 @@ public void displayStyledText(StyledText text) { style(e.style(), offset, e.region().length()); }); - // TODO: this always append a newline, which means there will be an empty line between input - // (which has its newline appended) and output. append(doc, doc.getLength(), "\n"); scrollText(); } diff --git a/org.metaborg.spoofax.shell.eclipse/src/main/java/org/metaborg/spoofax/shell/client/eclipse/impl/EclipseEditor.java b/org.metaborg.spoofax.shell.eclipse/src/main/java/org/metaborg/spoofax/shell/client/eclipse/impl/EclipseEditor.java index 1024627f..6201170c 100644 --- a/org.metaborg.spoofax.shell.eclipse/src/main/java/org/metaborg/spoofax/shell/client/eclipse/impl/EclipseEditor.java +++ b/org.metaborg.spoofax.shell.eclipse/src/main/java/org/metaborg/spoofax/shell/client/eclipse/impl/EclipseEditor.java @@ -3,6 +3,7 @@ import java.util.List; import java.util.Observer; +import org.eclipse.jface.resource.JFaceResources; import org.eclipse.jface.text.Document; import org.eclipse.jface.text.IDocument; import org.eclipse.jface.text.source.SourceViewer; @@ -24,7 +25,7 @@ import rx.Subscriber; /** - * A multiline input editor for the {@link EclipseRepl}, with a {@link Sourceviewer} backend. It + * A multiline input editor for the {@link EclipseRepl}, with a {@link SourceViewer} backend. It * attaches itself as a {@link KeyListener} to listen for certain keypresses. When the Return key * (e.g. linefeed or carriage return) is pressed, the {@link Observer}s are notified with the text * typed so far. @@ -37,9 +38,6 @@ public class EclipseEditor extends KeyAdapter implements ModifyListener { private final IInputHistory history; private final SourceViewer input; - // TODO: Use ReplDocument to provide custom partitioning? Perhaps more something for the output - // as opposed to input. Should be relatively easy for output to at least partition different - // input/output combinations. private final IDocument document; private final List> observers; @@ -57,6 +55,8 @@ public EclipseEditor(IInputHistory history, @Assisted Composite parent) { this.history = history; this.document = new Document(); this.input = new SourceViewer(parent, null, SWT.BORDER | SWT.MULTI); + this.input.getTextWidget().setFont(JFaceResources.getFont(JFaceResources.TEXT_FONT)); + this.input.getTextWidget().setAlwaysShowScrollBars(false); this.input.setDocument(document); this.input.getTextWidget().addKeyListener(this); this.observers = Lists.newArrayList(); @@ -77,9 +77,8 @@ public void setFocus() { * @return A new {@link Observable} from this editor. */ public Observable asObservable() { - return Observable.create(s -> { - EclipseEditor.this.observers.add(s); - }); + return Observable + .create((Observable.OnSubscribe) EclipseEditor.this.observers::add); } /** @@ -110,9 +109,6 @@ private void enterPressed() { this.document.set(""); } - private void offerCompletions() { - } - private void setTextFromHistory(String text) { document.set(text); input.setSelectedRange(text.length(), 0); @@ -127,11 +123,6 @@ public void keyPressed(KeyEvent event) { enterPressed(); } break; - case SWT.SPACE: - if ((event.stateMask & SWT.CTRL) == SWT.CTRL) { - offerCompletions(); - } - break; case SWT.PAGE_DOWN: if ((event.stateMask & (SWT.CTRL | SWT.SHIFT)) == 0) { setTextFromHistory(history.getNext()); diff --git a/org.metaborg.spoofax.shell.eclipse/src/main/java/org/metaborg/spoofax/shell/client/eclipse/impl/EclipseRepl.java b/org.metaborg.spoofax.shell.eclipse/src/main/java/org/metaborg/spoofax/shell/client/eclipse/impl/EclipseRepl.java index c559a650..410d8610 100644 --- a/org.metaborg.spoofax.shell.eclipse/src/main/java/org/metaborg/spoofax/shell/client/eclipse/impl/EclipseRepl.java +++ b/org.metaborg.spoofax.shell.eclipse/src/main/java/org/metaborg/spoofax/shell/client/eclipse/impl/EclipseRepl.java @@ -8,8 +8,8 @@ import org.eclipse.core.runtime.jobs.Job; import org.eclipse.ui.progress.UIJob; import org.metaborg.core.style.Style; -import org.metaborg.spoofax.shell.client.IRepl; import org.metaborg.spoofax.shell.client.IDisplay; +import org.metaborg.spoofax.shell.client.IRepl; import org.metaborg.spoofax.shell.invoker.CommandNotFoundException; import org.metaborg.spoofax.shell.invoker.ICommandInvoker; import org.metaborg.spoofax.shell.output.IResult; @@ -29,9 +29,6 @@ * Note that this class evaluates input in a separate thread. */ public class EclipseRepl implements IRepl, Observer { - private static final int INPUT_RED = 232; - private static final int INPUT_GREEN = 242; - private static final int INPUT_BLUE = 254; private final IDisplay display; private final ICommandInvoker invoker; @@ -79,8 +76,7 @@ private void appendInputToDisplay(String input) { // TODO: Style input! Output cannot be styled since there is no way to "pretty-prettyprint" // it back to a format of the language currently being used. As such, it cannot be // highlighted. - Color inputBackgroundColor = new Color(INPUT_RED, INPUT_GREEN, INPUT_BLUE); - Style style = new Style(null, inputBackgroundColor, false, false, false); + Style style = new Style(null, null, true, false, false); this.display.displayStyledText(new StyledText(style, input)); }