[
https://issues.apache.org/jira/browse/GROOVY-12411?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=18115609#comment-18115609
]
ASF GitHub Bot commented on GROOVY-12411:
-----------------------------------------
daniellansun commented on PR #2936:
URL: https://github.com/apache/groovy/pull/2936#issuecomment-5681332181
> I am wondering about a few things in this:
>
> * is the change to 1-base in columns not a breaking change?
> * I need a more clear answer to what this is not supposed to solve and
what it is supposed to solve. So far I understand only that it does not want to
be a complete workspace/IDE solution and it does not support anything but
Groovy itself. What it is trying to solve seems to be that the other
implementations are lagging behind. But those implementations also implement
much more of the IDE concept... especially for specific modes, GDSL support,
joint compilation, cross language renames, ... So I am not yet clear what the
intended scope and differentiator of this implementation are.
> * Let me extend the renames point ... In dynamically typed Groovy, where
MethodCallExpression.methodTarget is normally not available, what semantic
guarantees are intended for definition, references and rename? The current
fallback in NavigationService.resolveMethod() appears to select a method based
on receiver type, name and argument count. Is this intentionally a best-effort
heuristic, and if so, should operations such as rename avoid making potentially
incorrect edits when the target cannot be uniquely determined? A heuristic is
good enough for Hover I think, but in case of rename this can be a problem.
> * You mention `groovy-language-server`, what about
`tomaszrup/groovy-language-server-edt` and `trustytrojan/groovyls`? How do you
see this implementation in relation to those?
> * What do **you** actually want to use this for? And how should others use
it? And more from the IDE-side how are IDEs supposed to use this? Is it even
intended for direct use in a IDE?
> * What is the **vision** for this? Are other LSP implementations supposed
to use this as base, or is this intended to be a standalone Groovy language
server?
>
> Yeah, I know, a wild mix of specific and very broad questions. I am not
against the idea at all; I just want to understand more clearly why this PR
came into existence in the first place and what you see its role being.
Thanks for taking the time to unpack this — the mix of questions is fair,
and I should have been clearer about scope from the start.
**1-based columns.** That is GROOVY-12085 in the *compiler* AST (1-based
Unicode code points). It is not an LSP coordinate change. The protocol stays
0-based in the encoding negotiated at `initialize`; the server converts, and
clients never see AST columns. Existing LSP clients do not need to change how
they send positions. This module also does not add name-span fields to
`AnnotatedNode`; identifier selection for rename/highlight is done in
groovy-lsp from the node’s existing source span.
**What this is for, and what it is not.** It is a Groovy *language core* for
LSP, not a workspace/IDE. It is meant to stay current with the in-tree compiler
so editors (and later AI tools) get diagnostics, completion, hover, navigation,
and conservative rename on `.groovy` sources. It does not try to match the
IDE-shaped servers on GDSL, joint Groovy+Java compilation, cross-language
rename, Gradle/Maven invocation, a debugger, or a test runner. Those are real
strengths of the other implementations; they are out of scope here on purpose.
The differentiator is “same compiler as the language, small surface, safe
edits,” not “more IDE features.”
**Rename vs hover when `methodTarget` is missing.** You are right that a
name-and-arity fallback is a heuristic, and that it is a problem for rename.
That is now the policy: hover may show a unique arity match and mark it
`_inferred_`; definition lists every such candidate rather than picking the
first; **prepare-rename and rename refuse** unbound dynamic calls. They only
run on declarations (by owner + name + descriptor) and on calls/properties the
compiler actually bound. A wrong edit is worse than a refused rename.
**The other servers.** Prominic `groovy-language-server` is the earlier
community server; this is a new implementation, not a fork.
`trustytrojan/groovyls` (Apache 2.0) is the natural place for Jenkins GDSL and
a forced STC pass — those can sit on this compile/protocol loop later via the
incubating `GroovyLspExtension` SPI, without living in this module.
`tomaszrup/groovy-language-server-edt` (EPL, JDT + groovy-eclipse) is
complementary: joint compilation and Java interop need that stack. We do not
copy it, and we do not use its identifier-scan rename fallback.
**How to use it.** Yes, it is intended for direct use in an IDE or editor:
start `groovylsp` and speak stdio JSON-RPC. The client supplies
`groovy.classpath` (we never invoke Gradle or Maven). The same process is the
semantic backend for Groovy-aware AI; a later `groovy-mcp` is expected to wrap
it so a model can ask what an identifier is without embedding the compiler.
**Vision.** Both: a standalone first-party Groovy language server that an
editor can run today, and a small compile + protocol loop that other
*Apache-2.0* Groovy LSPs (and groovy-mcp) can extend instead of forking. It is
not a replacement for the JDT/groovy-eclipse stack, and it will not grow into a
full IDE.
Happy to go further on any of these if that still feels thin.
> Add a first-party Language Server Protocol implementation (groovy-lsp)
> ----------------------------------------------------------------------
>
> Key: GROOVY-12411
> URL: https://issues.apache.org/jira/browse/GROOVY-12411
> Project: Groovy
> Issue Type: Improvement
> Reporter: Daniel Sun
> Priority: Major
>
> Ship an optional first-party language server so editors can offer Groovy
> completion, navigation, diagnostics, and refactorings against the in-tree
> compiler rather than a community fork.
> h3. Why
> Community servers ({{groovy-language-server}}, {{gvy}}/{{gls}}) lag language
> changes. A module in this repository compiles with the same
> {{CompilationUnit}} the rest of Groovy uses, so parser and type-system work
> land in the IDE automatically.
> h3. What to ship
> * New optional subproject {{groovy-lsp}} (not part of {{groovy-all}})
> * {{groovylsp}} / {{groovylsp.bat}} launchers (stdio JSON-RPC; optional
> {{--socket}})
> * LSP 3.18 over Eclipse LSP4J 1.0; unknown 3.19 fields ignored
> * Compile open buffers through {{SEMANTIC_ANALYSIS}} (no class generation)
> * Identifier name spans on {{AnnotatedNode}} so rename/highlight select the
> name, not the whole declaration (same 1-based code-point columns as
> GROOVY-12085)
> h3. Language features (advertise only what is implemented)
> * Incremental sync, push/pull diagnostics
> * Completion (keywords, snippets, members, workspace types with auto-import,
> GDK with a prefix) and {{completionItem/resolve}}
> * Hover, signature help, document highlight
> * Definition, type definition, implementation, declaration, references (by
> declaration identity)
> * Prepare-rename / rename (rename the file when the class name matches the
> file stem)
> * Document and workspace symbols, folding, selection range, semantic tokens,
> inlay hints
> * Organize imports (star, static, alias); unused-import hints
> * Code actions: add import, implement abstracts, insert inferred field type,
> add package from path, create missing class stub, generate accessors /
> {{toString}} / {{equals}}/{{hashCode}} / constructor, add {{@Override}}
> * Call hierarchy and type hierarchy
> * Reference-count code lenses
> h3. Safety and classpath
> * {{@Grab}} and {{@ASTTest}} off unless the client sets {{grapeEnabled}} /
> {{astTestEnabled}}
> * Diagnostics scoped to the owning source unit (shared {{ErrorCollector}})
> * No Gradle or Maven Tooling API; the client supplies {{classpath}} /
> {{sourcePaths}}. If those are empty, fall back to {{src/main/groovy}} (and
> friends) and jars under {{lib}} / {{libs}}
> * Unchanged inputs skip recompilation; {{GroovyClassLoader}} is reused and
> closed on shutdown
> h3. Out of scope
> * Debugger (DAP)
> * Test runner
> * Invoking Gradle or Maven to resolve the project
> h3. How to run
> {code}
> groovylsp
> {code}
> Optional flags: {{\-\-stdio}} (default), {{\-\-socket port}}, {{\-\-help}},
> {{\-\-version}}.
--
This message was sent by Atlassian Jira
(v8.20.10#820010)