22
33module 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