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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: ab4cd18ca1c0a175a8631f5b33b00d1b74a87138
4
- data.tar.gz: 84d9cd1a7216ab854b704080977bfec9dcd86023
3
+ metadata.gz: 710e70cbd335c48e5d33828e22465ed144bb89e1
4
+ data.tar.gz: f7b154226cd171fc3d7290a83636e292631c961a
5
5
  SHA512:
6
- metadata.gz: cdf15aa367699423e2b475cc9e90c90eb52e6fdbd0c8560e63ea9f3e85ed8dd0963052f2413363460dda0b2adfde1738abf059cba398983c2937f3c5860fd4ac
7
- data.tar.gz: 6be794d016744e9d7a0ffab004983bb6af6030c88ba1ccd11c31776d1108d8f45391fa2455d82fc14ca30b89d2c25951648ae3cf186111fc5397f6721978d17c
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
 
@@ -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
- # A comment belongs to a certain node if it begins after end
60
- # of the previous node (if one exists) and ends before beginning of
61
- # the current node.
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
- @prev_node = nil
112
- visit(@ast)
115
+ visit(@ast) if @ast
113
116
 
114
117
  @mapping
115
118
  end
116
119
 
117
120
  def visit(node)
118
- process_node(node)
119
-
120
- if node.children.length > 0
121
- node.children.each do |child|
122
- next unless child.is_a?(AST::Node) && child.loc && child.loc.expression
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 process_node(node)
131
- return unless node.type != :begin
132
- while current_comment_between?(@prev_node, node)
133
- associate_and_advance_comment(@prev_node, node)
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(parent)
139
- while current_comment_decorates?(@prev_node)
140
- associate_and_advance_comment(@prev_node, nil)
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 current_comment_before_end?(parent)
143
- associate_and_advance_comment(@prev_node, nil)
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 current_comment_between?(prev_node, next_node)
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 next_node
157
- next_loc = next_node.location.expression
158
- return false if comment_loc.end_pos > next_loc.begin_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 current_comment_decorates?(prev_node)
163
+ def current_comment_before_end?(node)
168
164
  return false if !@current_comment
169
- @current_comment.location.line == prev_node.location.line
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 current_comment_before_end?(parent)
170
+ def current_comment_decorates?(node)
173
171
  return false if !@current_comment
174
- comment_loc = @current_comment.location.expression
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(prev_node, node)
180
- if prev_node && node
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
@@ -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
  #
@@ -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
@@ -1,3 +1,3 @@
1
1
  module Parser
2
- VERSION = '2.2.2.3'
2
+ VERSION = '2.2.2.5'
3
3
  end
@@ -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
- # Class comment
33
- # another class comment
34
- class Foo
35
- # attr_accessor comment
36
- attr_accessor :foo
37
-
38
- # method comment
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
- # expr comment
41
- 1 + # intermediate comment
41
+ # expression preceeding
42
+ 1 + # 1 decorating
42
43
  2
43
- # stray comment
44
- end
45
- end
44
+ # method bar sparse
45
+ end # method bar decorating
46
+ # class sparse
47
+ end # class decorating
46
48
  END
47
49
 
48
- klass_node = ast
49
- attr_accessor_node = ast.children[2].children[0]
50
- method_node = ast.children[2].children[1] # def bar
51
- expr_node = method_node.children[2] # 1 + 2
52
- intermediate_node = expr_node.children[0] # 1
53
-
54
- assert_equal 5, associations.size
55
- assert_equal ['# Class comment', '# another class comment'],
56
- associations[klass_node].map(&:text)
57
- assert_equal ['# attr_accessor comment'],
58
- associations[attr_accessor_node].map(&:text)
59
- assert_equal ['# method comment'],
60
- associations[method_node].map(&:text)
61
- assert_equal ['# expr comment', "# stray comment"],
62
- associations[expr_node].map(&:text)
63
- assert_equal ['# intermediate comment'],
64
- associations[intermediate_node].map(&:text)
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
- # Class comment
97
- # another class comment
98
- class Foo
99
- # attr_accessor comment
100
- attr_accessor :foo
101
-
102
- # method comment
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
- # expr comment
105
- 1 + # intermediate comment
122
+ # expression preceeding
123
+ 1 + # 1 decorating
106
124
  2
107
- # stray comment
108
- end
109
- end
125
+ # method bar sparse
126
+ end # method bar decorating
127
+ # class sparse
128
+ end # class decorating
110
129
  END
111
130
 
112
- klass_node = ast
113
- attr_accessor_node = ast.children[2].children[0]
114
- method_node = ast.children[2].children[1]
115
- expr_node = method_node.children[2]
116
- intermediate_node = expr_node.children[0]
117
-
118
- assert_equal 5, associations.size
119
- assert_equal ['# Class comment', '# another class comment'],
120
- associations[klass_node.loc].map(&:text)
121
- assert_equal ['# attr_accessor comment'],
122
- associations[attr_accessor_node.loc].map(&:text)
123
- assert_equal ['# method comment'],
124
- associations[method_node.loc].map(&:text)
125
- assert_equal ['# expr comment', '# stray comment'],
126
- associations[expr_node.loc].map(&:text)
127
- assert_equal ['# intermediate comment'],
128
- associations[intermediate_node.loc].map(&:text)
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.3
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-17 00:00:00.000000000 Z
11
+ date: 2015-05-25 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: ast