zazuko / xrm

A friendly language for mappings to RDF
MIT License
1 stars 0 forks source link

explore impact of refactoring on LSP functionality #92

Closed mchlrch closed 3 years ago

mchlrch commented 4 years ago

Explore if the proposed refactoring (recommended setup) would solve some of the issues we encountered in the LSP backed vscode plugin.

https://github.com/zazuko/rdf-mapping-dsl/wiki/VS-Code-extension,-Theia https://github.com/zazuko/expressive-rdf-mapper-vscode/issues/1

IMO a good one to investigate would be the "code assist rules implemented in the DSL are neglected, semantically inappropriate proposals are shown". Is this because of the way we build the proposals in XRM? Or is it something that is not customizable in LSP? Maybe pushing more of the mapping language variability in the grammar could help here.

Setting-up a new simple xtext project, dedicated to explore LSP related (dis-)functionality probably makes sense here. Also in regard to consulting with TypeFox afterwards. It could be a public repo

mchlrch commented 4 years ago

Playground repo: https://github.com/zazuko/xrm-lsp-playground

nnamtug commented 3 years ago

Xtext uses *.ui XOR *.ide package, ui for eclipse, ide for vs-code. This means all functionality impemented in *.ui will not have any effect in the vs case. Typical functionality in *.ui is

There is a lot of domain logic based on the concrete syntax implemented in RealRdfMappingProposalProvider.java, e.g. rules like "only offer the keyword 'parent-map' on a RML based output type". In other words: ParentTriplesMapTerm is a RML-ish feature. This kind of tuning is required since we are using the same elements in the grammar for any generic kind of mapping but having semantic code completion in place. Now the DSL statically covers all the variation and on runtime parts of the grammar will be ommitted/disabled depending on values dynamically provided by the user. Technically it is possible to do so, but dynamically controlling static parts of the grammar is somehow hacky.

An alternative is writing specific grammar rules for RML and CSV based mapping. This makes the DSL technically much simpler and the amount of rules implemented in a ProposalProvider will be reduced: This now allowes to write the grammar rules optimized in order to get the editors up, running, and working (less dependencies to domain knowledge). Of course this will result in redundant implementation of the common part in the rules. This is where the impact of the refactoring will take action: By introducing a domain model which is independent of the DSL, the redundancy is limited to the DSL and converters.

Side note: When using *.ide, there seems not really to exist possibilities to customize parsing. It looks pretty technical and based on static information only. Here is a snippet of the generated, grammar based ContentAssistParser:

public class RdfMappingParser extends AbstractContentAssistParser {

    @Singleton
    public static final class NameMappings {

        private final Map<AbstractElement, String> mappings;

        @Inject
        public NameMappings(RdfMappingGrammarAccess grammarAccess) {
            ImmutableMap.Builder<AbstractElement, String> builder = ImmutableMap.builder();
            init(builder, grammarAccess);
            this.mappings = builder.build();
        }
    // ...
        private static void init(ImmutableMap.Builder<AbstractElement, String> builder, RdfMappingGrammarAccess grammarAccess) {
            builder.put(grammarAccess.getElementAccess().getAlternatives(), "rule__Element__Alternatives");
            builder.put(grammarAccess.getBooleanLiteralAccess().getAlternatives(), "rule__BooleanLiteral__Alternatives");
            builder.put(grammarAccess.getTemplateValueAccess().getAlternatives(), "rule__TemplateValue__Alternatives");
            builder.put(grammarAccess.getValuedTermAccess().getAlternatives(), "rule__ValuedTerm__Alternatives");
            builder.put(grammarAccess.getReferenceValuedTermAccess().getAlternatives_2(), "rule__ReferenceValuedTerm__Alternatives_2");
            builder.put(grammarAccess.getMultiReferenceValuedTermAccess().getAlternatives_3(), "rule__MultiReferenceValuedTerm__Alternatives_3");
// ...

Maybe the package *.ide might become more customizable in future - this could be a thing to ask the Xtext pros?

Next steps:

nnamtug commented 3 years ago

since the mentioned git-repo does not exist in the account of zazuko, I temporary created a new one https://github.com/nnamtug/xrm-lsp-playground and invited @mchlrch as collaborator. please (re-?)provide a repository that belongs to zazuko.

nnamtug commented 3 years ago

So I created a variation of the DSL with specific mapping rules. It basically boils down to introduce three partitions in the language, one could actually think about splitting this in three different DSLs. The examples in the inner eclipse actually support the idea of these three partitions. Splitting would allow to isolate their different lifecycle and the more specific grammar rules simplify life for the editor including VS Code. By introducing a common domainmodel (independent of the concrete syntax), one could still share the business logic. The three partitions including the grammar elements are:

In a domainmodel, one would represent these three partitions by e.g. using packages. When converting, values would be normalized so most of the resolve*-operations are superfluous.

Symptoms pointing in the direction for separating common, csv, rmlish:

So the working assumptions for xrm-lsp-playground are:

Finally the result of the investigation:

Introducing a domainmodel and specific grammar rules drop a lot of technical code within the editor. But only of the missing feature in the VS Code plugin can be compensated by the refactoring.

nnamtug commented 3 years ago

Update 1.12.2020:

Xtext 2.24 released - it should support quickixes in LSP now

https://www.eclipse.org/Xtext/releasenotes.html#/releasenotes/2020/12/01/version-2-24-0

nnamtug commented 3 years ago

since the mentioned git-repo does not exist in the account of zazuko, I temporary created a new one https://github.com/nnamtug/xrm-lsp-playground and invited @mchlrch as collaborator. please (re-?)provide a repository that belongs to zazuko.

@mchlrch : thank you. code is now in https://github.com/zazuko/xrm-lsp-playground

mchlrch commented 3 years ago

Xtext uses .ui XOR .ide package, ui for eclipse, ide for vs-code. This means all functionality impemented in .ui will not have any effect in the vs case. Typical functionality in .ui is

modified proposal provider quickfix labels, tooltips outlines

proposal provider: It seems that there is a way to implement IDE content proposal provider and delegate from UI using UiToIdeContentProposalProvider

https://github.com/eclipse/xtext-eclipse/blob/master/org.eclipse.xtext.ui/src/org/eclipse/xtext/ui/editor/contentassist/UiToIdeContentProposalProvider.java https://stackoverflow.com/questions/47005235/customizing-content-proposal-in-xtext-for-web-editors https://github.com/eclipse/xtext-eclipse/issues/139

And for tooltips/hover, I found the following open issue: https://github.com/eclipse/xtext/issues/2602

mchlrch commented 3 years ago

I pushed the changes to build the vscode plugin with the playground on branch xrm-lsp-playground

https://github.com/zazuko/expressive-rdf-mapper-vscode/tree/xrm-lsp-playground

nnamtug commented 3 years ago

Reminder: example DSL snippet to try the code completion

known-languages: English German;
known-books: 
    LordOfTheRings (English)
    HerrDerRinge (German)
    Xtext4Dummies (English)

libraries:
LondonLibrary English {
    LordOfTheRings
    // do code-completion here, get only proposals related to English
}