Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit 69b0db5

Browse files
committed
Rework InlayHints to use a visitor
1 parent 66f6155 commit 69b0db5

File tree

1 file changed

+80
-38
lines changed

1 file changed

+80
-38
lines changed

lib/syntax_tree/language_server/inlay_hints.rb

Lines changed: 80 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,72 @@
22

33
module SyntaxTree
44
class LanguageServer
5-
class InlayHints
6-
attr_reader :before, :after
5+
class InlayHints < Visitor
6+
attr_reader :stack, :before, :after
77

88
def initialize
9+
@stack = []
910
@before = Hash.new { |hash, key| hash[key] = +"" }
1011
@after = Hash.new { |hash, key| hash[key] = +"" }
1112
end
1213

14+
def visit(node)
15+
stack << node
16+
result = super
17+
stack.pop
18+
result
19+
end
20+
21+
# Adds parentheses around assignments contained within the default values
22+
# of parameters. For example,
23+
#
24+
# def foo(a = b = c)
25+
# end
26+
#
27+
# becomes
28+
#
29+
# def foo(a = ₍b = c₎)
30+
# end
31+
#
32+
def visit_assign(node)
33+
parentheses(node.location) if stack[-2].is_a?(Params)
34+
end
35+
36+
# Adds parentheses around binary expressions to make it clear which
37+
# subexpression will be evaluated first. For example,
38+
#
39+
# a + b * c
40+
#
41+
# becomes
42+
#
43+
# a + ₍b * c₎
44+
#
45+
def visit_binary(node)
46+
case stack[-2]
47+
in Assign | OpAssign
48+
parentheses(node.location)
49+
in Binary[operator: operator] if operator != node.operator
50+
parentheses(node.location)
51+
else
52+
end
53+
end
54+
55+
# Adds parentheses around ternary operators contained within certain
56+
# expressions where it could be confusing which subexpression will get
57+
# evaluated first. For example,
58+
#
59+
# a ? b : c ? d : e
60+
#
61+
# becomes
62+
#
63+
# a ? b : ₍c ? d : e₎
64+
#
65+
def visit_if_op(node)
66+
if stack[-2] in Assign | Binary | IfOp | OpAssign
67+
parentheses(node.location)
68+
end
69+
end
70+
1371
# Adds the implicitly rescued StandardError into a bare rescue clause. For
1472
# example,
1573
#
@@ -23,54 +81,38 @@ def initialize
2381
# rescue StandardError
2482
# end
2583
#
26-
def bare_rescue(location)
27-
after[location.start_char + "rescue".length] << " StandardError"
84+
def visit_rescue(node)
85+
if node.exception.nil?
86+
after[node.location.start_char + "rescue".length] << " StandardError"
87+
end
2888
end
2989

30-
# Adds implicit parentheses around certain expressions to make it clear
31-
# which subexpression will be evaluated first. For example,
90+
# Adds parentheses around unary statements using the - operator that are
91+
# contained within Binary nodes. For example,
3292
#
33-
# a + b * c
93+
# -a + b
3494
#
3595
# becomes
3696
#
37-
# a + ₍b * c₎
97+
# ₍-a₎ + b
3898
#
39-
def precedence_parentheses(location)
40-
before[location.start_char] << "₍"
41-
after[location.end_char] << "₎"
99+
def visit_unary(node)
100+
if stack[-2].is_a?(Binary) && (node.operator == "-")
101+
parentheses(node.location)
102+
end
42103
end
43104

44105
def self.find(program)
45-
inlay_hints = new
46-
queue = [[nil, program]]
47-
48-
until queue.empty?
49-
parent_node, child_node = queue.shift
50-
51-
child_node.child_nodes.each do |grand_child_node|
52-
queue << [child_node, grand_child_node] if grand_child_node
53-
end
106+
visitor = new
107+
visitor.visit(program)
108+
visitor
109+
end
54110

55-
case [parent_node, child_node]
56-
in _, Rescue[exception: nil, location:]
57-
inlay_hints.bare_rescue(location)
58-
in Assign | Binary | IfOp | OpAssign, IfOp[location:]
59-
inlay_hints.precedence_parentheses(location)
60-
in Assign | OpAssign, Binary[location:]
61-
inlay_hints.precedence_parentheses(location)
62-
in Binary[operator: parent_oper], Binary[operator: child_oper, location:] if parent_oper != child_oper
63-
inlay_hints.precedence_parentheses(location)
64-
in Binary, Unary[operator: "-", location:]
65-
inlay_hints.precedence_parentheses(location)
66-
in Params, Assign[location:]
67-
inlay_hints.precedence_parentheses(location)
68-
else
69-
# do nothing
70-
end
71-
end
111+
private
72112

73-
inlay_hints
113+
def parentheses(location)
114+
before[location.start_char] << "₍"
115+
after[location.end_char] << "₎"
74116
end
75117
end
76118
end

0 commit comments

Comments
 (0)