[ 
https://issues.apache.org/jira/browse/GROOVY-12448?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
 ]

Daniel Sun updated GROOVY-12448:
--------------------------------
    Description: 
h2. Context

GROOVY-12411 added groovy-lsp and the in-process GroovyLanguageEngine. Groovy 
Console and groovysh were left unconnected. This change attaches both hosts to 
that engine. Diagnostics and completion for an unsaved buffer do not generate 
class files.

Scripts still run through GroovyShell in the console and through GroovyEngine 
in groovysh.

h2. User-visible behavior

* *Groovy Console.* The editor compiles the unsaved buffer in the background 
and highlights compiler diagnostics. {{Alt+/}} offers compiler-backed 
completions. {{Ctrl+Space}} is left free, because that chord switches the input 
method on Chinese desktops and on macOS. {{Ctrl+/}} is still comment and 
uncomment. A multiline string keeps the color of its opening delimiter: single 
quote, double quote, or slashy. The dollar sign that opens a GString expression 
is not colored as part of the string. A jar or directory added from the Script 
menu is picked up on the next background compile. The compile uses the console 
compiler configuration, including imports and AST customizers. Turning Allow 
interruption on or off edits that configuration, and the next compile sees the 
edit.
* *groovysh.* Tab completion and tail tips consult the compiler for the current 
buffer: imports, types, methods, and binding variables. A syntax tail tip 
reports diagnostics and does not evaluate the line. A method tail tip asks for 
signatures on the full line, so an unclosed opening parenthesis is visible, and 
uses the previous inspector only when the compiler has none. {{/grab}} is still 
how Maven artifacts are added. The next completion or tail tip notices the 
loader change. Customizers on the compiler configuration given to the engine at 
construction apply to completion and tail tips as well as to evaluation. An 
import typed at the prompt is buffer text, so the next completion sees it as 
part of the script.

h2. Design

* groovy-console and groovy-groovysh depend on groovy-lsp with an 
{{implementation}} dependency, not an {{api}} dependency. LSP4J is not part of 
either module's published API. groovy-lsp stays an optional module and is not 
listed directly by groovy-all. Consumers of the console or groovysh still 
receive it transitively.
* Each host keeps its own adapter and talks to the engine with JDK records. 
Host source does not import LSP4J. The console adapter owns the buffer name 
{{groovy-buffer:console}}. The groovysh adapter owns {{groovy-buffer:repl}}. 
The engine does not assign those names. Both adapters are internal 
implementation details, not an embedding API.
* Positions are 0-based UTF-16. CR, LF, and CRLF are line breaks. A character 
past the end of a line stays on that line. A zero-width diagnostic at the end 
of the text is painted on the last character.
* A query that is given the buffer text replaces that text first. Identical 
text keeps the document version, so the snapshot can be reused. Publishing the 
host compiler configuration copies the script base class and the compilation 
customizers into the tooling compile, and drops the cached compile on every 
call, including a repeat of the same instance. Hosts do that when the 
configuration is replaced or edited, not before every query.
* The console publishes its configuration when the host is created and again 
when the host rebinds. Rebinding covers classpath changes and the Allow 
interruption toggle. Later queries publish the parent loader only.
* groovysh publishes the engine configuration at construction, and again only 
when the configuration instance itself changes. That field is final. 
Interactive imports are buffer snippets, not edits to an import customizer.
* The compile fingerprint includes the URLs of a URLClassLoader, so an in-place 
addURL is visible on the next compile.
* groovysh builds one script for each question: the remembered buffer, a 
declaration for each binding name the buffer does not already introduce, then 
the current line. Those names come from the compiled AST. The walk does not 
enter a closure or a lambda. It skips the generated no-arg run method and a 
static main method whose only parameter is an array.
* Console coloring uses one lenient lexer walk on the editor thread. It does 
not paint the compiled name-kind overlay, because those kinds share the 
identifier style. Brace matching still reads that lexer token list. groovysh 
keeps its existing nanorc highlighter.
* Snippet placeholders are removed from completion text before it is inserted. 
groovysh keeps only the first line of that text.

h2. Out of scope

* Driving the AST browser from a language-engine snapshot.
* A public embedding API for either adapter.
* A separate engine jar that does not contain LSP4J. Feature services inside 
groovy-lsp still use those types, so LSP4J remains a runtime dependency of both 
hosts.
* Noticing an in-place edit of a customizer that groovysh has already 
published. The shell does not edit that object after construction. The console 
does, and it publishes the configuration again after the edit.


  was:
h2. Context

GROOVY-12411 added {{groovy-lsp}} and an in-process 
{{{}GroovyLanguageEngine{}}}. That work left Groovy Console and groovysh 
unconnected. This change attaches those two hosts to the same engine so an 
unsaved buffer can be queried for diagnostics, completion, hover, and 
signatures without generating class files.

Scripts still run through {{GroovyShell}} in the console and {{GroovyEngine}} 
in groovysh.
h2. User-visible behavior
 * *Groovy Console.* The editor compiles the unsaved buffer in the background 
and highlights compiler diagnostics. {{Ctrl+Space}} offers compiler-backed 
completions. Adding a jar or directory to the classpath is picked up on the 
next compile.
 * *groovysh.* Tab completion and tail-tip descriptions consult the compiler 
for the current buffer (imports, types, methods, and binding variables). Syntax 
tail-tips report diagnostics and do not evaluate the line. {{/grab}} remains 
the way to add Maven artifacts; the next completion or tail-tip notices the 
loader change.

h2. Design
 * {{groovy-console}} and {{groovy-groovysh}} take an {{implementation}} 
dependency on {{{}groovy-lsp{}}}.
 * Adapters stay in the host trees: {{ConsoleLanguageHost}} (buffer URI 
{{{}groovy-buffer:console{}}}) and {{GroovyshLanguageSession}} (buffer URI 
{{{}groovy-buffer:repl{}}}). The engine does not assign those names. Both 
adapters are {{@Internal}} and are not an embedding API.
 * Queries return JDK records. Host source does not import LSP4J. Feature 
services inside {{groovy-lsp}} still use LSP4J types, so LSP4J remains a 
runtime dependency of these hosts.
 * Positions are 0-based UTF-16.
 * The compile fingerprint includes {{URLClassLoader}} URLs, so an in-place 
{{addURL}} (console classpath menu, groovysh {{{}/grab{}}}) is visible on the 
next compile.
 * groovysh composes {{{}GroovyEngine.getBuffer(){}}}, declaration-only binding 
types for names the buffer does not already introduce, and the current line. 
Those names come from the compiled AST 
({{{}GroovyLanguageEngine.declaredNames{}}}).
 * groovysh {{SYNTAX}} tail-tips return compiler diagnostics and do not fall 
through to Inspector {{{}checkSyntax{}}}, which evaluates. {{METHOD}} 
signatures use the full {{CmdLine.line}} so an unclosed opening parenthesis is 
visible. Inspector is used only when the compiler has no signatures.

h2. Out of scope
 * Driving AstBrowser from an LSP snapshot.
 * A public embedding API for the adapters.
 * Splitting a protocol-free engine module out of {{{}groovy-lsp{}}}.


> Wire Groovy Console and groovysh to the in-process language engine
> ------------------------------------------------------------------
>
>                 Key: GROOVY-12448
>                 URL: https://issues.apache.org/jira/browse/GROOVY-12448
>             Project: Groovy
>          Issue Type: Improvement
>            Reporter: Daniel Sun
>            Priority: Major
>
> h2. Context
> GROOVY-12411 added groovy-lsp and the in-process GroovyLanguageEngine. Groovy 
> Console and groovysh were left unconnected. This change attaches both hosts 
> to that engine. Diagnostics and completion for an unsaved buffer do not 
> generate class files.
> Scripts still run through GroovyShell in the console and through GroovyEngine 
> in groovysh.
> h2. User-visible behavior
> * *Groovy Console.* The editor compiles the unsaved buffer in the background 
> and highlights compiler diagnostics. {{Alt+/}} offers compiler-backed 
> completions. {{Ctrl+Space}} is left free, because that chord switches the 
> input method on Chinese desktops and on macOS. {{Ctrl+/}} is still comment 
> and uncomment. A multiline string keeps the color of its opening delimiter: 
> single quote, double quote, or slashy. The dollar sign that opens a GString 
> expression is not colored as part of the string. A jar or directory added 
> from the Script menu is picked up on the next background compile. The compile 
> uses the console compiler configuration, including imports and AST 
> customizers. Turning Allow interruption on or off edits that configuration, 
> and the next compile sees the edit.
> * *groovysh.* Tab completion and tail tips consult the compiler for the 
> current buffer: imports, types, methods, and binding variables. A syntax tail 
> tip reports diagnostics and does not evaluate the line. A method tail tip 
> asks for signatures on the full line, so an unclosed opening parenthesis is 
> visible, and uses the previous inspector only when the compiler has none. 
> {{/grab}} is still how Maven artifacts are added. The next completion or tail 
> tip notices the loader change. Customizers on the compiler configuration 
> given to the engine at construction apply to completion and tail tips as well 
> as to evaluation. An import typed at the prompt is buffer text, so the next 
> completion sees it as part of the script.
> h2. Design
> * groovy-console and groovy-groovysh depend on groovy-lsp with an 
> {{implementation}} dependency, not an {{api}} dependency. LSP4J is not part 
> of either module's published API. groovy-lsp stays an optional module and is 
> not listed directly by groovy-all. Consumers of the console or groovysh still 
> receive it transitively.
> * Each host keeps its own adapter and talks to the engine with JDK records. 
> Host source does not import LSP4J. The console adapter owns the buffer name 
> {{groovy-buffer:console}}. The groovysh adapter owns {{groovy-buffer:repl}}. 
> The engine does not assign those names. Both adapters are internal 
> implementation details, not an embedding API.
> * Positions are 0-based UTF-16. CR, LF, and CRLF are line breaks. A character 
> past the end of a line stays on that line. A zero-width diagnostic at the end 
> of the text is painted on the last character.
> * A query that is given the buffer text replaces that text first. Identical 
> text keeps the document version, so the snapshot can be reused. Publishing 
> the host compiler configuration copies the script base class and the 
> compilation customizers into the tooling compile, and drops the cached 
> compile on every call, including a repeat of the same instance. Hosts do that 
> when the configuration is replaced or edited, not before every query.
> * The console publishes its configuration when the host is created and again 
> when the host rebinds. Rebinding covers classpath changes and the Allow 
> interruption toggle. Later queries publish the parent loader only.
> * groovysh publishes the engine configuration at construction, and again only 
> when the configuration instance itself changes. That field is final. 
> Interactive imports are buffer snippets, not edits to an import customizer.
> * The compile fingerprint includes the URLs of a URLClassLoader, so an 
> in-place addURL is visible on the next compile.
> * groovysh builds one script for each question: the remembered buffer, a 
> declaration for each binding name the buffer does not already introduce, then 
> the current line. Those names come from the compiled AST. The walk does not 
> enter a closure or a lambda. It skips the generated no-arg run method and a 
> static main method whose only parameter is an array.
> * Console coloring uses one lenient lexer walk on the editor thread. It does 
> not paint the compiled name-kind overlay, because those kinds share the 
> identifier style. Brace matching still reads that lexer token list. groovysh 
> keeps its existing nanorc highlighter.
> * Snippet placeholders are removed from completion text before it is 
> inserted. groovysh keeps only the first line of that text.
> h2. Out of scope
> * Driving the AST browser from a language-engine snapshot.
> * A public embedding API for either adapter.
> * A separate engine jar that does not contain LSP4J. Feature services inside 
> groovy-lsp still use those types, so LSP4J remains a runtime dependency of 
> both hosts.
> * Noticing an in-place edit of a customizer that groovysh has already 
> published. The shell does not edit that object after construction. The 
> console does, and it publishes the configuration again after the edit.



--
This message was sent by Atlassian Jira
(v8.20.10#820010)

Reply via email to