Skip to content

Commit ae88127

Browse files
authored
Merge pull request #805 from Shopify/vs/add_show_syntax_tree
Add show syntax tree request
2 parents 1ad3200 + 2cf2d59 commit ae88127

File tree

5 files changed

+78
-0
lines changed

5 files changed

+78
-0
lines changed

lib/ruby_lsp/executor.rb

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -169,6 +169,8 @@ def run(request)
169169
completion(uri, request.dig(:params, :position))
170170
when "textDocument/definition"
171171
definition(uri, request.dig(:params, :position))
172+
when "rubyLsp/textDocument/showSyntaxTree"
173+
{ ast: Requests::ShowSyntaxTree.new(@store.get(uri)).run }
172174
end
173175
end
174176

lib/ruby_lsp/requests.rb

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ module RubyLsp
2020
# - [PathCompletion](rdoc-ref:RubyLsp::Requests::PathCompletion)
2121
# - [CodeLens](rdoc-ref:RubyLsp::Requests::CodeLens)
2222
# - [Definition](rdoc-ref:RubyLsp::Requests::Definition)
23+
# - [ShowSyntaxTree](rdoc-ref:RubyLsp::Requests::ShowSyntaxTree)
2324

2425
module Requests
2526
autoload :BaseRequest, "ruby_lsp/requests/base_request"
@@ -39,6 +40,7 @@ module Requests
3940
autoload :PathCompletion, "ruby_lsp/requests/path_completion"
4041
autoload :CodeLens, "ruby_lsp/requests/code_lens"
4142
autoload :Definition, "ruby_lsp/requests/definition"
43+
autoload :ShowSyntaxTree, "ruby_lsp/requests/show_syntax_tree"
4244

4345
# :nodoc:
4446
module Support
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
# typed: strict
2+
# frozen_string_literal: true
3+
4+
module RubyLsp
5+
module Requests
6+
# ![Show syntax tree demo](../../show_syntax_tree.gif)
7+
#
8+
# Show syntax tree is a custom [LSP
9+
# request](https://microsoft.github.io/language-server-protocol/specification#requestMessage) that displays the AST
10+
# for the current document in a new tab.
11+
#
12+
# # Example
13+
#
14+
# ```ruby
15+
# # Executing the Ruby LSP: Show syntax tree command will display the AST for the document
16+
# 1 + 1
17+
# # (program (statements ((binary (int "1") + (int "1")))))
18+
# ```
19+
#
20+
class ShowSyntaxTree < BaseRequest
21+
extend T::Sig
22+
23+
sig { override.returns(String) }
24+
def run
25+
return "Document contains syntax error" if @document.syntax_error?
26+
27+
output_string = +""
28+
PP.pp(@document.tree, output_string)
29+
output_string
30+
end
31+
end
32+
end
33+
end

misc/show_syntax_tree.gif

314 KB
Loading
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
# typed: true
2+
# frozen_string_literal: true
3+
4+
require "test_helper"
5+
6+
class ShowSyntaxTreeTest < Minitest::Test
7+
def setup
8+
@message_queue = Thread::Queue.new
9+
end
10+
11+
def teardown
12+
@message_queue.close
13+
end
14+
15+
def test_returns_nil_if_document_has_syntax_error
16+
store = RubyLsp::Store.new
17+
store.set(uri: "file:///fake.rb", source: "foo do", version: 1)
18+
response = RubyLsp::Executor.new(store, @message_queue).execute({
19+
method: "rubyLsp/textDocument/showSyntaxTree",
20+
params: { textDocument: { uri: "file:///fake.rb" } },
21+
}).response
22+
23+
assert_equal("Document contains syntax error", response[:ast])
24+
end
25+
26+
def test_returns_ast_if_document_is_parsed
27+
store = RubyLsp::Store.new
28+
store.set(uri: "file:///fake.rb", source: "foo = 123", version: 1)
29+
document = store.get("file:///fake.rb")
30+
document.parse
31+
32+
response = RubyLsp::Executor.new(store, @message_queue).execute({
33+
method: "rubyLsp/textDocument/showSyntaxTree",
34+
params: { textDocument: { uri: "file:///fake.rb" } },
35+
}).response
36+
37+
assert_equal(<<~AST, response[:ast])
38+
(program (statements ((assign (var_field (ident "foo")) (int "123")))))
39+
AST
40+
end
41+
end

0 commit comments

Comments
 (0)