Search code examples
rascal

Creating an outliner and a summariser to register a language


I am trying to update the registering of my language and with the new specifications I need to define an Outliner and a Summariser

Here is the example project for the pico dsl file here and the language specification (i assume) here

module lang::pico::LanguageServer

import util::LanguageServer;
import util::IDEServices;
import ParseTree;
import util::Reflective;
import lang::pico::\syntax::Main;
import IO;

// a minimal implementation of a DSL in rascal
// users can add support for more advanced features
set[LanguageService] picoContributions() = {
    parser(parser(#start[Program])), // register the parser function for the Pico language
    outliner(picoOutliner),
    summarizer(picoSummarizer, providesImplementations = false)
  };


// we build a simple outline based on the grammar
list[DocumentSymbol] picoOutliner(start[Program] input)
  = [symbol("<input.src>", DocumentSymbolKind::\file(), input.src, children=[
      *[symbol("<var.id>", \variable(), var.src) | /IdType var := input]
  ])];

// normally you would import the typechecker and run it here
// for brevity we've inlined the implementation here
Summary picoSummarizer(loc l, start[Program] input) {
    rel[str, loc] defs = {<"<var.id>", var.src> | /IdType var  := input};
    rel[loc, str] uses = {<id.src, "<id>"> | /Id id := input};
    rel[loc, str] docs = {<var.src, "*variable* <var>"> | /IdType var := input};


    return summary(l,
        messages = {<src, error("<id> is not defined", src)> | <src, id> <- uses, id notin defs<0>},
        references = (uses o defs)<1,0>,
        definitions = uses o defs,
        documentation = (uses o defs) o docs
    );
}

// run this from a REPL while developing the DSL
int main() {
    // we register a new language to Rascal's LSP multiplexer
    // the multiplexer starts a new evaluator and loads this module and function
    registerLanguage(
        language(
            pathConfig(srcs=[|project://pico-dsl-lsp/src/main/rascal|]),
            "Pico", // name of the language
            "pico", // extension
            "lang::pico::LanguageServer", // module to import
            "picoContributions"
        )
    );
    return 0;
}

I am trying to build both an Outliner and a Summarizer for my language (AST here).

data Pipeline
    = pipeline(
    Alphabet alphabet,
    Options options,
    list[Module] modules,
    list[Constraint] constraints,
    list[Handler] handlers
    );
 
data Alphabet
    = alphabet(
    list[SymbolInfo] symbols);

Here is what I have for the outliner so far, I cant find further documentation on their structure:

list[DocumentSymbol] ldOutliner(start[Pipeline] pipeline) {
    return [
        symbol("Pipeline", DocumentSymbolKind::Namespace, pipeline.src, children=[
            *[symbol("Alphabet"
            
                {...}
            ]
        ])
    ];
}

Additionally, the contributions style were defined as following, how can i define the style now?

Contribution STYLE =
  categories
  (
    (
      "Name" : {bold()},
      "String" : {foregroundColor(color("purple"))},
      "Boolean" : {foregroundColor(color("DarkRed"))},
      "ColorCode" : {foregroundColor(color("Violet"))},
      "Character" :{foregroundColor(color("dimgray"))},
      "ConstraintKeywords" :{foregroundColor(color("Olive"))},
      "Integer" : {foregroundColor(color("orange")), bold()}
    )
    );

Any help would be appreciated, thanks!


Solution

    • the new outliner is missing () for the DocumentSymbolKind constructor. That makes it a reference to the function instead of an instance of the datatype. It could be that this error is printed in a different view than where you are looking! It should be DocumentSymbolKind::Namespace()
    • The LSP outline is much more limited than what we had in Eclipse, on the other hand all outlines now look the same and behave the same for usability's sake.
    • We lost the ability to define our own syntax categories too, going from eclipse IMP to VScode, however, now theming works nicely and you'll have a darkmode DSL for free 🤓 It means the contribution for registering categories simply does not exist anymore.