Skip to content

Commit 4f8aa69

Browse files
authored
Merge pull request #184 from ruby-syntax-tree/style
Style, pattern matching, rake exit status
2 parents 999292b + 15514e5 commit 4f8aa69

12 files changed

+379
-245
lines changed

.rubocop.yml

+3
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,9 @@ Naming/MethodParameterName:
4646
Naming/RescuedExceptionsVariableName:
4747
PreferredName: error
4848

49+
Style/CaseEquality:
50+
Enabled: false
51+
4952
Style/ExplicitBlockArgument:
5053
Enabled: false
5154

Rakefile

+1-7
Original file line numberDiff line numberDiff line change
@@ -7,13 +7,7 @@ require "syntax_tree/rake_tasks"
77
Rake::TestTask.new(:test) do |t|
88
t.libs << "test"
99
t.libs << "lib"
10-
test_files = FileList["test/**/*_test.rb"]
11-
if RUBY_ENGINE == "truffleruby"
12-
# language_server.rb uses pattern matching
13-
test_files -= FileList["test/language_server/*_test.rb"]
14-
test_files -= FileList["test/language_server_test.rb"]
15-
end
16-
t.test_files = test_files
10+
t.test_files = FileList["test/**/*_test.rb"]
1711
end
1812

1913
task default: :test

lib/syntax_tree/cli.rb

+2-2
Original file line numberDiff line numberDiff line change
@@ -193,8 +193,8 @@ def run(item)
193193
class Expr < Action
194194
def run(item)
195195
program = item.handler.parse(item.source)
196-
if Program === program and expressions = program.statements.body and
197-
expressions.size == 1
196+
197+
if (expressions = program.statements.body) && expressions.size == 1
198198
puts expressions.first.construct_keys
199199
else
200200
warn("The input to `stree expr` must be a single expression.")

lib/syntax_tree/language_server.rb

+64-17
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,50 @@ module SyntaxTree
1313
# stree lsp
1414
#
1515
class LanguageServer
16+
# This is a small module that effectively mirrors pattern matching. We're
17+
# using it so that we can support truffleruby without having to ignore the
18+
# language server.
19+
module Request
20+
# Represents a hash pattern.
21+
class Shape
22+
attr_reader :values
23+
24+
def initialize(values)
25+
@values = values
26+
end
27+
28+
def ===(other)
29+
values.all? do |key, value|
30+
value == :any ? other.key?(key) : value === other[key]
31+
end
32+
end
33+
end
34+
35+
# Represents an array pattern.
36+
class Tuple
37+
attr_reader :values
38+
39+
def initialize(values)
40+
@values = values
41+
end
42+
43+
def ===(other)
44+
values.each_with_index.all? { |value, index| value === other[index] }
45+
end
46+
end
47+
48+
def self.[](value)
49+
case value
50+
when Array
51+
Tuple.new(value.map { |child| self[child] })
52+
when Hash
53+
Shape.new(value.transform_values { |child| self[child] })
54+
else
55+
value
56+
end
57+
end
58+
end
59+
1660
attr_reader :input, :output, :print_width
1761

1862
def initialize(
@@ -39,30 +83,33 @@ def run
3983

4084
# stree-ignore
4185
case request
42-
in { method: "initialize", id: }
86+
when Request[method: "initialize", id: :any]
4387
store.clear
44-
write(id: id, result: { capabilities: capabilities })
45-
in { method: "initialized" }
88+
write(id: request[:id], result: { capabilities: capabilities })
89+
when Request[method: "initialized"]
4690
# ignored
47-
in { method: "shutdown" } # tolerate missing ID to be a good citizen
91+
when Request[method: "shutdown"] # tolerate missing ID to be a good citizen
4892
store.clear
4993
write(id: request[:id], result: {})
5094
return
51-
in { method: "textDocument/didChange", params: { textDocument: { uri: }, contentChanges: [{ text: }, *] } }
52-
store[uri] = text
53-
in { method: "textDocument/didOpen", params: { textDocument: { uri:, text: } } }
54-
store[uri] = text
55-
in { method: "textDocument/didClose", params: { textDocument: { uri: } } }
56-
store.delete(uri)
57-
in { method: "textDocument/formatting", id:, params: { textDocument: { uri: } } }
95+
when Request[method: "textDocument/didChange", params: { textDocument: { uri: :any }, contentChanges: [{ text: :any }] }]
96+
store[request.dig(:params, :textDocument, :uri)] = request.dig(:params, :contentChanges, 0, :text)
97+
when Request[method: "textDocument/didOpen", params: { textDocument: { uri: :any, text: :any } }]
98+
store[request.dig(:params, :textDocument, :uri)] = request.dig(:params, :textDocument, :text)
99+
when Request[method: "textDocument/didClose", params: { textDocument: { uri: :any } }]
100+
store.delete(request.dig(:params, :textDocument, :uri))
101+
when Request[method: "textDocument/formatting", id: :any, params: { textDocument: { uri: :any } }]
102+
uri = request.dig(:params, :textDocument, :uri)
58103
contents = store[uri]
59-
write(id: id, result: contents ? format(contents, uri.split(".").last) : nil)
60-
in { method: "textDocument/inlayHint", id:, params: { textDocument: { uri: } } }
104+
write(id: request[:id], result: contents ? format(contents, uri.split(".").last) : nil)
105+
when Request[method: "textDocument/inlayHint", id: :any, params: { textDocument: { uri: :any } }]
106+
uri = request.dig(:params, :textDocument, :uri)
61107
contents = store[uri]
62-
write(id: id, result: contents ? inlay_hints(contents) : nil)
63-
in { method: "syntaxTree/visualizing", id:, params: { textDocument: { uri: } } }
64-
write(id: id, result: PP.pp(SyntaxTree.parse(store[uri]), +""))
65-
in { method: %r{\$/.+} }
108+
write(id: request[:id], result: contents ? inlay_hints(contents) : nil)
109+
when Request[method: "syntaxTree/visualizing", id: :any, params: { textDocument: { uri: :any } }]
110+
uri = request.dig(:params, :textDocument, :uri)
111+
write(id: request[:id], result: PP.pp(SyntaxTree.parse(store[uri]), +""))
112+
when Request[method: %r{\$/.+}]
66113
# ignored
67114
else
68115
raise ArgumentError, "Unhandled: #{request}"

lib/syntax_tree/language_server/inlay_hints.rb

+4-6
Original file line numberDiff line numberDiff line change
@@ -69,11 +69,10 @@ def visit_assign(node)
6969
#
7070
def visit_binary(node)
7171
case stack[-2]
72-
in Assign | OpAssign
72+
when Assign, OpAssign
7373
parentheses(node.location)
74-
in Binary[operator: operator] if operator != node.operator
75-
parentheses(node.location)
76-
else
74+
when Binary
75+
parentheses(node.location) if stack[-2].operator != node.operator
7776
end
7877

7978
super
@@ -91,9 +90,8 @@ def visit_binary(node)
9190
#
9291
def visit_if_op(node)
9392
case stack[-2]
94-
in Assign | Binary | IfOp | OpAssign
93+
when Assign, Binary, IfOp, OpAssign
9594
parentheses(node.location)
96-
else
9795
end
9896

9997
super

0 commit comments

Comments
 (0)