2
2
3
3
module SyntaxTree
4
4
class LanguageServer
5
- class InlayHints
6
- attr_reader :before , :after
5
+ class InlayHints < Visitor
6
+ attr_reader :stack , : before, :after
7
7
8
8
def initialize
9
+ @stack = [ ]
9
10
@before = Hash . new { |hash , key | hash [ key ] = +"" }
10
11
@after = Hash . new { |hash , key | hash [ key ] = +"" }
11
12
end
12
13
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
+
13
71
# Adds the implicitly rescued StandardError into a bare rescue clause. For
14
72
# example,
15
73
#
@@ -23,54 +81,38 @@ def initialize
23
81
# rescue StandardError
24
82
# end
25
83
#
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
28
88
end
29
89
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,
32
92
#
33
- # a + b * c
93
+ # - a + b
34
94
#
35
95
# becomes
36
96
#
37
- # a + ₍b * c₎
97
+ # ₍-a₎ + b
38
98
#
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
42
103
end
43
104
44
105
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
54
110
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
72
112
73
- inlay_hints
113
+ def parentheses ( location )
114
+ before [ location . start_char ] << "₍"
115
+ after [ location . end_char ] << "₎"
74
116
end
75
117
end
76
118
end
0 commit comments