parser 2.2.2.3 → 2.2.2.5
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +13 -0
- data/lib/parser/ast/processor.rb +1 -0
- data/lib/parser/source/comment/associator.rb +37 -46
- data/lib/parser/source/map.rb +18 -0
- data/lib/parser/source/range.rb +20 -0
- data/lib/parser/version.rb +1 -1
- data/test/test_source_comment_associator.rb +108 -58
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 710e70cbd335c48e5d33828e22465ed144bb89e1
|
4
|
+
data.tar.gz: f7b154226cd171fc3d7290a83636e292631c961a
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: f675cb69ce293a7f6787c6b08ce38d545393a7ca776a999f5c37cb607425a22aee2d2d2f24474792927e8bbc36e86125b8bcbe3c366cebb2c3fc785e2eaa5675
|
7
|
+
data.tar.gz: 02fb79c07b4473351667a166383345a235a756cea3ff7b0b718683fe5b6fab13c5f67ffc484e60f72402cf8c0b6e5130305157e1dac96a5d57353efe41d1af3c
|
data/CHANGELOG.md
CHANGED
@@ -1,6 +1,19 @@
|
|
1
1
|
Changelog
|
2
2
|
=========
|
3
3
|
|
4
|
+
v2.2.2.5 (2015-05-25)
|
5
|
+
---------------------
|
6
|
+
|
7
|
+
API modifications:
|
8
|
+
* Source::Comment::Associator: rework entirely; fixes #194 (Oleg Zubchenko)
|
9
|
+
|
10
|
+
Features implemented:
|
11
|
+
* Source::Map: add last_line, last_column delegation (Oleg Zubchenko)
|
12
|
+
* Source::Range: add last_line, last_column methods (Oleg Zubchenko)
|
13
|
+
|
14
|
+
Bugs fixed:
|
15
|
+
* AST::Processor: add missing on_block_pass (fixes #196) (whitequark)
|
16
|
+
|
4
17
|
v2.2.2.3 (2015-05-17)
|
5
18
|
---------------------
|
6
19
|
|
data/lib/parser/ast/processor.rb
CHANGED
@@ -108,6 +108,7 @@ module Parser
|
|
108
108
|
alias on_arg_expr process_regular_node
|
109
109
|
alias on_restarg_expr process_regular_node
|
110
110
|
alias on_blockarg_expr process_regular_node
|
111
|
+
alias on_block_pass process_regular_node
|
111
112
|
|
112
113
|
alias on_module process_regular_node
|
113
114
|
alias on_class process_regular_node
|
@@ -54,11 +54,12 @@ module Parser
|
|
54
54
|
end
|
55
55
|
|
56
56
|
##
|
57
|
-
# Compute a mapping between AST nodes and comments.
|
57
|
+
# Compute a mapping between AST nodes and comments. Comment is
|
58
|
+
# associated with the node, if it is one of the following types:
|
58
59
|
#
|
59
|
-
#
|
60
|
-
#
|
61
|
-
# the
|
60
|
+
# - preceding comment, it ends before the node start
|
61
|
+
# - sparse comment, it is located inside the node, after all child nodes
|
62
|
+
# - decorating comment, it starts at the same line, where the node ends
|
62
63
|
#
|
63
64
|
# This rule is unambiguous and produces the result
|
64
65
|
# one could reasonably expect; for example, this code
|
@@ -76,6 +77,9 @@ module Parser
|
|
76
77
|
# [#<Parser::Source::Comment (string):3:8 "# bar">]
|
77
78
|
# }
|
78
79
|
#
|
80
|
+
# Note that comments after the end of the end of a passed tree range are
|
81
|
+
# ignored (except root decorating comment).
|
82
|
+
#
|
79
83
|
# Note that {associate} produces unexpected result for nodes which are
|
80
84
|
# equal but have distinct locations; comments for these nodes are merged.
|
81
85
|
#
|
@@ -108,39 +112,35 @@ module Parser
|
|
108
112
|
|
109
113
|
advance_through_directives if @skip_directives
|
110
114
|
|
111
|
-
@
|
112
|
-
visit(@ast)
|
115
|
+
visit(@ast) if @ast
|
113
116
|
|
114
117
|
@mapping
|
115
118
|
end
|
116
119
|
|
117
120
|
def visit(node)
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
visit(child)
|
124
|
-
end
|
125
|
-
process_trailing_comments(node)
|
126
|
-
@prev_node = node
|
121
|
+
process_leading_comments(node)
|
122
|
+
|
123
|
+
node.children.each do |child|
|
124
|
+
next unless child.is_a?(AST::Node) && child.loc && child.loc.expression
|
125
|
+
visit(child)
|
127
126
|
end
|
127
|
+
|
128
|
+
process_trailing_comments(node)
|
128
129
|
end
|
129
130
|
|
130
|
-
def
|
131
|
-
return
|
132
|
-
while
|
133
|
-
associate_and_advance_comment(
|
131
|
+
def process_leading_comments(node)
|
132
|
+
return if node.type == :begin
|
133
|
+
while current_comment_before?(node) # preceding comment
|
134
|
+
associate_and_advance_comment(node)
|
134
135
|
end
|
135
|
-
@prev_node = node
|
136
136
|
end
|
137
137
|
|
138
|
-
def process_trailing_comments(
|
139
|
-
while
|
140
|
-
associate_and_advance_comment(
|
138
|
+
def process_trailing_comments(node)
|
139
|
+
while current_comment_before_end?(node)
|
140
|
+
associate_and_advance_comment(node) # sparse comment
|
141
141
|
end
|
142
|
-
while
|
143
|
-
associate_and_advance_comment(
|
142
|
+
while current_comment_decorates?(node)
|
143
|
+
associate_and_advance_comment(node) # decorating comment
|
144
144
|
end
|
145
145
|
end
|
146
146
|
|
@@ -149,40 +149,31 @@ module Parser
|
|
149
149
|
@current_comment = @comments[@comment_num]
|
150
150
|
end
|
151
151
|
|
152
|
-
def
|
152
|
+
def current_comment_before?(node)
|
153
153
|
return false if !@current_comment
|
154
154
|
comment_loc = @current_comment.location.expression
|
155
155
|
|
156
|
-
if
|
157
|
-
|
158
|
-
return false if comment_loc.end_pos >
|
159
|
-
end
|
160
|
-
if prev_node
|
161
|
-
prev_loc = prev_node.location.expression
|
162
|
-
return false if comment_loc.begin_pos < prev_loc.begin_pos
|
156
|
+
if node
|
157
|
+
node_loc = node.location.expression
|
158
|
+
return false if comment_loc.end_pos > node_loc.begin_pos
|
163
159
|
end
|
164
160
|
true
|
165
161
|
end
|
166
162
|
|
167
|
-
def
|
163
|
+
def current_comment_before_end?(node)
|
168
164
|
return false if !@current_comment
|
169
|
-
@current_comment.location.
|
165
|
+
comment_loc = @current_comment.location.expression
|
166
|
+
node_loc = node.location.expression
|
167
|
+
comment_loc.end_pos <= node_loc.end_pos
|
170
168
|
end
|
171
169
|
|
172
|
-
def
|
170
|
+
def current_comment_decorates?(node)
|
173
171
|
return false if !@current_comment
|
174
|
-
|
175
|
-
parent_loc = parent.location.expression
|
176
|
-
comment_loc.end_pos <= parent_loc.end_pos
|
172
|
+
@current_comment.location.line == node.location.last_line
|
177
173
|
end
|
178
174
|
|
179
|
-
def associate_and_advance_comment(
|
180
|
-
|
181
|
-
owner_node = (@current_comment.location.line == prev_node.location.line) ? prev_node : node
|
182
|
-
else
|
183
|
-
owner_node = prev_node ? prev_node : node
|
184
|
-
end
|
185
|
-
key = @map_using_locations ? owner_node.location : owner_node
|
175
|
+
def associate_and_advance_comment(node)
|
176
|
+
key = @map_using_locations ? node.location : node
|
186
177
|
@mapping[key] << @current_comment
|
187
178
|
advance_comment
|
188
179
|
end
|
data/lib/parser/source/map.rb
CHANGED
@@ -98,6 +98,8 @@ module Parser
|
|
98
98
|
@expression.line
|
99
99
|
end
|
100
100
|
|
101
|
+
alias_method :first_line, :line
|
102
|
+
|
101
103
|
##
|
102
104
|
# A shortcut for `self.expression.column`.
|
103
105
|
# @return [Integer]
|
@@ -106,6 +108,22 @@ module Parser
|
|
106
108
|
@expression.column
|
107
109
|
end
|
108
110
|
|
111
|
+
##
|
112
|
+
# A shortcut for `self.expression.last_line`.
|
113
|
+
# @return [Integer]
|
114
|
+
#
|
115
|
+
def last_line
|
116
|
+
@expression.last_line
|
117
|
+
end
|
118
|
+
|
119
|
+
##
|
120
|
+
# A shortcut for `self.expression.last_column`.
|
121
|
+
# @return [Integer]
|
122
|
+
#
|
123
|
+
def last_column
|
124
|
+
@expression.last_column
|
125
|
+
end
|
126
|
+
|
109
127
|
##
|
110
128
|
# @api private
|
111
129
|
#
|
data/lib/parser/source/range.rb
CHANGED
@@ -75,6 +75,8 @@ module Parser
|
|
75
75
|
line
|
76
76
|
end
|
77
77
|
|
78
|
+
alias_method :first_line, :line
|
79
|
+
|
78
80
|
##
|
79
81
|
# @return [Integer] zero-based column number of the beginning of this range.
|
80
82
|
#
|
@@ -84,6 +86,24 @@ module Parser
|
|
84
86
|
column
|
85
87
|
end
|
86
88
|
|
89
|
+
##
|
90
|
+
# @return [Integer] line number of the end of this range.
|
91
|
+
#
|
92
|
+
def last_line
|
93
|
+
line, _ = @source_buffer.decompose_position(@end_pos)
|
94
|
+
|
95
|
+
line
|
96
|
+
end
|
97
|
+
|
98
|
+
##
|
99
|
+
# @return [Integer] zero-based column number of the end of this range.
|
100
|
+
#
|
101
|
+
def last_column
|
102
|
+
_, column = @source_buffer.decompose_position(@end_pos)
|
103
|
+
|
104
|
+
column
|
105
|
+
end
|
106
|
+
|
87
107
|
##
|
88
108
|
# @return [::Range] a range of columns spanned by this range.
|
89
109
|
# @raise RangeError
|
data/lib/parser/version.rb
CHANGED
@@ -29,39 +29,56 @@ class TestSourceCommentAssociator < Minitest::Test
|
|
29
29
|
ast, associations = associate(<<-END)
|
30
30
|
#!/usr/bin/env ruby
|
31
31
|
# coding: utf-8
|
32
|
-
#
|
33
|
-
# another class
|
34
|
-
class Foo
|
35
|
-
#
|
36
|
-
|
37
|
-
|
38
|
-
# method
|
32
|
+
# class preceeding
|
33
|
+
# another class preceeding
|
34
|
+
class Foo # class keyword line
|
35
|
+
# method foo preceeding
|
36
|
+
def foo
|
37
|
+
puts 'foo'
|
38
|
+
end # method foo decorating
|
39
|
+
# method bar preceeding
|
39
40
|
def bar
|
40
|
-
#
|
41
|
-
1 + #
|
41
|
+
# expression preceeding
|
42
|
+
1 + # 1 decorating
|
42
43
|
2
|
43
|
-
#
|
44
|
-
end
|
45
|
-
|
44
|
+
# method bar sparse
|
45
|
+
end # method bar decorating
|
46
|
+
# class sparse
|
47
|
+
end # class decorating
|
46
48
|
END
|
47
49
|
|
48
|
-
klass_node
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
assert_equal
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
50
|
+
klass_node = ast
|
51
|
+
klass_name_node = klass_node.children[0]
|
52
|
+
foo_node = klass_node.children[2].children[0] # def foo
|
53
|
+
bar_node = klass_node.children[2].children[1] # def bar
|
54
|
+
expr_node = bar_node.children[2] # 1 + 2
|
55
|
+
one_node = expr_node.children[0] # 1
|
56
|
+
|
57
|
+
assert_equal 6, associations.size
|
58
|
+
assert_equal [
|
59
|
+
'# class preceeding',
|
60
|
+
'# another class preceeding',
|
61
|
+
'# class sparse',
|
62
|
+
'# class decorating'
|
63
|
+
], associations[klass_node].map(&:text)
|
64
|
+
assert_equal [
|
65
|
+
'# class keyword line'
|
66
|
+
], associations[klass_name_node].map(&:text)
|
67
|
+
assert_equal [
|
68
|
+
'# method foo preceeding',
|
69
|
+
'# method foo decorating'
|
70
|
+
], associations[foo_node].map(&:text)
|
71
|
+
assert_equal [
|
72
|
+
'# method bar preceeding',
|
73
|
+
'# method bar sparse',
|
74
|
+
'# method bar decorating'
|
75
|
+
], associations[bar_node].map(&:text)
|
76
|
+
assert_equal [
|
77
|
+
'# expression preceeding'
|
78
|
+
], associations[expr_node].map(&:text)
|
79
|
+
assert_equal [
|
80
|
+
'# 1 decorating'
|
81
|
+
], associations[one_node].map(&:text)
|
65
82
|
end
|
66
83
|
|
67
84
|
# The bug below is fixed by using associate_locations
|
@@ -93,39 +110,56 @@ end
|
|
93
110
|
ast, associations = associate_locations(<<-END)
|
94
111
|
#!/usr/bin/env ruby
|
95
112
|
# coding: utf-8
|
96
|
-
#
|
97
|
-
# another class
|
98
|
-
class Foo
|
99
|
-
#
|
100
|
-
|
101
|
-
|
102
|
-
# method
|
113
|
+
# class preceeding
|
114
|
+
# another class preceeding
|
115
|
+
class Foo # class keyword line
|
116
|
+
# method foo preceeding
|
117
|
+
def foo
|
118
|
+
puts 'foo'
|
119
|
+
end # method foo decorating
|
120
|
+
# method bar preceeding
|
103
121
|
def bar
|
104
|
-
#
|
105
|
-
1 + #
|
122
|
+
# expression preceeding
|
123
|
+
1 + # 1 decorating
|
106
124
|
2
|
107
|
-
#
|
108
|
-
end
|
109
|
-
|
125
|
+
# method bar sparse
|
126
|
+
end # method bar decorating
|
127
|
+
# class sparse
|
128
|
+
end # class decorating
|
110
129
|
END
|
111
130
|
|
112
|
-
klass_node
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
assert_equal
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
131
|
+
klass_node = ast
|
132
|
+
klass_name_node = klass_node.children[0]
|
133
|
+
foo_node = klass_node.children[2].children[0] # def foo
|
134
|
+
bar_node = klass_node.children[2].children[1] # def bar
|
135
|
+
expr_node = bar_node.children[2] # 1 + 2
|
136
|
+
one_node = expr_node.children[0] # 1
|
137
|
+
|
138
|
+
assert_equal 6, associations.size
|
139
|
+
assert_equal [
|
140
|
+
'# class preceeding',
|
141
|
+
'# another class preceeding',
|
142
|
+
'# class sparse',
|
143
|
+
'# class decorating'
|
144
|
+
], associations[klass_node.loc].map(&:text)
|
145
|
+
assert_equal [
|
146
|
+
'# class keyword line'
|
147
|
+
], associations[klass_name_node.loc].map(&:text)
|
148
|
+
assert_equal [
|
149
|
+
'# method foo preceeding',
|
150
|
+
'# method foo decorating'
|
151
|
+
], associations[foo_node.loc].map(&:text)
|
152
|
+
assert_equal [
|
153
|
+
'# method bar preceeding',
|
154
|
+
'# method bar sparse',
|
155
|
+
'# method bar decorating'
|
156
|
+
], associations[bar_node.loc].map(&:text)
|
157
|
+
assert_equal [
|
158
|
+
'# expression preceeding'
|
159
|
+
], associations[expr_node.loc].map(&:text)
|
160
|
+
assert_equal [
|
161
|
+
'# 1 decorating'
|
162
|
+
], associations[one_node.loc].map(&:text)
|
129
163
|
end
|
130
164
|
|
131
165
|
def test_associate_locations_dupe_statement
|
@@ -164,6 +198,11 @@ end
|
|
164
198
|
associations[ast].map(&:text)
|
165
199
|
end
|
166
200
|
|
201
|
+
def test_associate_empty_tree
|
202
|
+
ast, associations = associate("")
|
203
|
+
assert_equal 0, associations.size
|
204
|
+
end
|
205
|
+
|
167
206
|
def test_associate_shebang_only
|
168
207
|
ast, associations = associate(<<-END)
|
169
208
|
#!ruby
|
@@ -183,6 +222,17 @@ end
|
|
183
222
|
assert_equal 0, associations.size
|
184
223
|
end
|
185
224
|
|
225
|
+
def test_associate_comments_after_root_node
|
226
|
+
ast, associations = associate(<<-END)
|
227
|
+
class Foo
|
228
|
+
end
|
229
|
+
# not associated
|
230
|
+
END
|
231
|
+
|
232
|
+
assert_equal 0, associations.size
|
233
|
+
end
|
234
|
+
|
235
|
+
|
186
236
|
def test_associate_stray_comment
|
187
237
|
ast, associations = associate(<<-END)
|
188
238
|
def foo
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: parser
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.2.2.
|
4
|
+
version: 2.2.2.5
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Peter Zotov
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-05-
|
11
|
+
date: 2015-05-25 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: ast
|