From 2c25dbd0164351257bcbd015cbbcbf6211c2ae32 Mon Sep 17 00:00:00 2001 From: Gerlof Fokkema Date: Tue, 21 Jun 2016 13:00:31 +0200 Subject: [PATCH] Add a stylefunction. --- .../metaborg/spoofax/shell/ReplModule.java | 4 ++ .../shell/commands/CommandBuilder.java | 9 +++ .../shell/commands/LanguageCommand.java | 1 + .../shell/functions/IFunctionFactory.java | 3 + .../shell/functions/StyleFunction.java | 43 ++++++++++++ .../spoofax/shell/output/IResultFactory.java | 4 ++ .../spoofax/shell/output/StyleResult.java | 67 +++++++++++++++++++ .../client/eclipse/impl/EclipseEditor.java | 5 +- 8 files changed, 135 insertions(+), 1 deletion(-) create mode 100644 org.metaborg.spoofax.shell.core/src/main/java/org/metaborg/spoofax/shell/functions/StyleFunction.java create mode 100644 org.metaborg.spoofax.shell.core/src/main/java/org/metaborg/spoofax/shell/output/StyleResult.java 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 4e8ac4ed..6980d32e 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 @@ -27,6 +27,7 @@ import org.metaborg.spoofax.shell.functions.InputFunction; import org.metaborg.spoofax.shell.functions.PTransformFunction; import org.metaborg.spoofax.shell.functions.ParseFunction; +import org.metaborg.spoofax.shell.functions.StyleFunction; import org.metaborg.spoofax.shell.invoker.ICommandInvoker; import org.metaborg.spoofax.shell.invoker.SpoofaxCommandInvoker; import org.metaborg.spoofax.shell.output.AnalyzeResult; @@ -37,6 +38,7 @@ import org.metaborg.spoofax.shell.output.ISpoofaxTermResult; import org.metaborg.spoofax.shell.output.InputResult; import org.metaborg.spoofax.shell.output.ParseResult; +import org.metaborg.spoofax.shell.output.StyleResult; import org.metaborg.spoofax.shell.output.TransformResult; import com.google.common.io.Files; @@ -107,6 +109,8 @@ protected void bindFactories() { PTransformFunction.class) .implement(new TypeLiteral>() { }, ATransformFunction.class) + .implement(new TypeLiteral>() { }, + StyleFunction.class) .implement(new TypeLiteral, EvaluateResult, IResult>>() { }, EvaluateFunction.class) diff --git a/org.metaborg.spoofax.shell.core/src/main/java/org/metaborg/spoofax/shell/commands/CommandBuilder.java b/org.metaborg.spoofax.shell.core/src/main/java/org/metaborg/spoofax/shell/commands/CommandBuilder.java index 89762c7e..d997de15 100644 --- a/org.metaborg.spoofax.shell.core/src/main/java/org/metaborg/spoofax/shell/commands/CommandBuilder.java +++ b/org.metaborg.spoofax.shell.core/src/main/java/org/metaborg/spoofax/shell/commands/CommandBuilder.java @@ -15,6 +15,7 @@ import org.metaborg.spoofax.shell.output.IResult; import org.metaborg.spoofax.shell.output.InputResult; import org.metaborg.spoofax.shell.output.ParseResult; +import org.metaborg.spoofax.shell.output.StyleResult; import org.metaborg.spoofax.shell.output.TransformResult; import com.google.inject.assistedinject.Assisted; @@ -127,6 +128,10 @@ private FailableFunction aEvaluateFunction() { .kleisliCompose(functionFactory.createEvaluateFunction(project, lang)); } + private FailableFunction styleFunction() { + return parseFunction().kleisliCompose(functionFactory.createStyleFunction(project, lang)); + } + /** * Returns a function that creates an {@link InputResult} from a String. * @@ -194,6 +199,10 @@ public CommandBuilder evalAnalyzed() { return function(aEvaluateFunction()); } + public CommandBuilder styleParsed() { + return function(styleFunction()); + } + /** * Set the function for a new builder with the current parameters. Discards the current function * of this builder. 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 83d29c69..8d5fb7b3 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 @@ -112,6 +112,7 @@ private void loadCommands(ILanguageImpl lang) { invoker.resetCommands(); invoker.addCommand("parse", builder.parse().description("Parse the expression").build()); + invoker.addCommand("style", builder.styleParsed().description("Style the expression").build()); if (analyze) { invoker.addCommand("analyze", builder.analyze() .description("Analyze the expression").build()); diff --git a/org.metaborg.spoofax.shell.core/src/main/java/org/metaborg/spoofax/shell/functions/IFunctionFactory.java b/org.metaborg.spoofax.shell.core/src/main/java/org/metaborg/spoofax/shell/functions/IFunctionFactory.java index 7e4bdf73..ef28bc97 100644 --- a/org.metaborg.spoofax.shell.core/src/main/java/org/metaborg/spoofax/shell/functions/IFunctionFactory.java +++ b/org.metaborg.spoofax.shell.core/src/main/java/org/metaborg/spoofax/shell/functions/IFunctionFactory.java @@ -11,6 +11,7 @@ import org.metaborg.spoofax.shell.output.ISpoofaxTermResult; import org.metaborg.spoofax.shell.output.InputResult; import org.metaborg.spoofax.shell.output.ParseResult; +import org.metaborg.spoofax.shell.output.StyleResult; import org.metaborg.spoofax.shell.output.TransformResult; /** @@ -92,4 +93,6 @@ public interface IFunctionFactory { * @return an {@link CommandBuilder} */ CommandBuilder createBuilder(IProject project, ILanguageImpl lang); + + FailableFunction createStyleFunction(IProject project, ILanguageImpl lang); } diff --git a/org.metaborg.spoofax.shell.core/src/main/java/org/metaborg/spoofax/shell/functions/StyleFunction.java b/org.metaborg.spoofax.shell.core/src/main/java/org/metaborg/spoofax/shell/functions/StyleFunction.java new file mode 100644 index 00000000..c8dd77e6 --- /dev/null +++ b/org.metaborg.spoofax.shell.core/src/main/java/org/metaborg/spoofax/shell/functions/StyleFunction.java @@ -0,0 +1,43 @@ +package org.metaborg.spoofax.shell.functions; + +import org.metaborg.core.language.ILanguageImpl; +import org.metaborg.core.project.IProject; +import org.metaborg.core.style.IRegionCategory; +import org.metaborg.core.style.IRegionStyle; +import org.metaborg.core.syntax.ParseException; +import org.metaborg.spoofax.core.style.ISpoofaxCategorizerService; +import org.metaborg.spoofax.core.style.ISpoofaxStylerService; +import org.metaborg.spoofax.core.unit.ISpoofaxParseUnit; +import org.metaborg.spoofax.shell.output.FailOrSuccessResult; +import org.metaborg.spoofax.shell.output.IResult; +import org.metaborg.spoofax.shell.output.IResultFactory; +import org.metaborg.spoofax.shell.output.ParseResult; +import org.metaborg.spoofax.shell.output.StyleResult; +import org.spoofax.interpreter.terms.IStrategoTerm; + +import com.google.inject.Inject; +import com.google.inject.assistedinject.Assisted; + +public class StyleFunction extends AbstractSpoofaxFunction { + private ISpoofaxCategorizerService categorizerService; + private ISpoofaxStylerService stylerService; + + @Inject + public StyleFunction(ISpoofaxCategorizerService categorizerService, ISpoofaxStylerService stylerService, + IResultFactory resultFactory, @Assisted IProject project, + @Assisted ILanguageImpl lang) { + super(resultFactory, project, lang); + this.categorizerService = categorizerService; + this.stylerService = stylerService; + } + + @Override + protected FailOrSuccessResult applyThrowing(ParseResult a) + throws ParseException { + ISpoofaxParseUnit unit = a.unit(); + Iterable> categorized = categorizerService.categorize(lang, unit); + Iterable> styled = stylerService.styleParsed(lang, categorized); + + return FailOrSuccessResult.ofSpoofaxResult(resultFactory.createStyleResult(unit, styled)); + } +} diff --git a/org.metaborg.spoofax.shell.core/src/main/java/org/metaborg/spoofax/shell/output/IResultFactory.java b/org.metaborg.spoofax.shell.core/src/main/java/org/metaborg/spoofax/shell/output/IResultFactory.java index 6de00b5f..e4ef1351 100644 --- a/org.metaborg.spoofax.shell.core/src/main/java/org/metaborg/spoofax/shell/output/IResultFactory.java +++ b/org.metaborg.spoofax.shell.core/src/main/java/org/metaborg/spoofax/shell/output/IResultFactory.java @@ -2,6 +2,7 @@ import org.apache.commons.vfs2.FileObject; import org.metaborg.core.language.ILanguageImpl; +import org.metaborg.core.style.IRegionStyle; import org.metaborg.core.syntax.IInputUnit; import org.metaborg.spoofax.core.syntax.JSGLRParserConfiguration; import org.metaborg.spoofax.core.unit.ISpoofaxAnalyzeUnit; @@ -84,4 +85,7 @@ InputResult createInputResult(ILanguageImpl lang, FileObject file, String source EvaluateResult createEvaluateResult(ISpoofaxTermResult inputTermResult, IStrategoTerm result); + StyleResult createStyleResult(ISpoofaxParseUnit unit, + Iterable> styled); + } diff --git a/org.metaborg.spoofax.shell.core/src/main/java/org/metaborg/spoofax/shell/output/StyleResult.java b/org.metaborg.spoofax.shell.core/src/main/java/org/metaborg/spoofax/shell/output/StyleResult.java new file mode 100644 index 00000000..88e134e4 --- /dev/null +++ b/org.metaborg.spoofax.shell.core/src/main/java/org/metaborg/spoofax/shell/output/StyleResult.java @@ -0,0 +1,67 @@ +package org.metaborg.spoofax.shell.output; + +import java.util.List; +import java.util.Optional; +import java.util.stream.Collectors; +import java.util.stream.StreamSupport; + +import org.metaborg.core.context.IContext; +import org.metaborg.core.messages.IMessage; +import org.metaborg.core.style.IRegionStyle; +import org.metaborg.core.style.RegionStyle; +import org.metaborg.spoofax.core.stratego.IStrategoCommon; +import org.metaborg.spoofax.core.unit.ISpoofaxParseUnit; +import org.spoofax.interpreter.terms.IStrategoTerm; + +import com.google.inject.Inject; +import com.google.inject.assistedinject.Assisted; + +public class StyleResult extends ParseResult { + + private Iterable> styled; + + @Inject + public StyleResult(IStrategoCommon common, @Assisted ISpoofaxParseUnit unit, + @Assisted Iterable> styled) { + super(common, unit); + this.styled = styled; + } + + @Override + public Optional context() { + return Optional.empty(); + } + + @Override + public List messages() { + return StreamSupport.stream(unit().messages().spliterator(), false) + .collect(Collectors.toList()); + } + + @Override + public StyledText styled() { + Iterable> collect = StreamSupport.stream(styled.spliterator(), false) + .map(e -> new RegionStyle(e.region(), e.style(), + sourceText().substring(e.region().startOffset(), + e.region().endOffset() + 1))) + .collect(Collectors.toList()); + + return new StyledText(collect); + } + + @Override + public String sourceText() { + return unit().input().text(); + } + + @Override + public boolean valid() { + return unit().valid() && unit().success(); + } + + @Override + public void accept(IResultVisitor visitor) { + visitor.visitTermResult(this); + } + +} 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 6201170c..919e55a6 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 @@ -140,7 +140,10 @@ public void keyPressed(KeyEvent event) { @Override public void modifyText(ModifyEvent event) { - // TODO: text has been modified, send it to get syntax highlighting. + String doc = document.get(); + observers.forEach(e -> { + e.onNext(String.format(":style %s", doc)); + }); } }