parser 2.7.1.2 → 2.7.1.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.travis.yml +4 -6
- data/CHANGELOG.md +17 -1
- data/README.md +1 -2
- data/Rakefile +1 -1
- data/doc/AST_FORMAT.md +22 -0
- data/lib/parser/ast/processor.rb +3 -0
- data/lib/parser/builders/default.rb +9 -0
- data/lib/parser/diagnostic.rb +1 -1
- data/lib/parser/diagnostic/engine.rb +1 -2
- data/lib/parser/lexer.rl +7 -0
- data/lib/parser/messages.rb +15 -0
- data/lib/parser/meta.rb +1 -1
- data/lib/parser/ruby28.y +62 -20
- data/lib/parser/runner.rb +21 -2
- data/lib/parser/runner/ruby_rewrite.rb +2 -2
- data/lib/parser/source/buffer.rb +3 -1
- data/lib/parser/source/comment/associator.rb +14 -4
- data/lib/parser/source/range.rb +7 -0
- data/lib/parser/source/tree_rewriter.rb +1 -1
- data/lib/parser/tree_rewriter.rb +1 -2
- data/lib/parser/version.rb +1 -1
- data/parser.gemspec +1 -1
- data/test/helper.rb +24 -6
- data/test/parse_helper.rb +9 -16
- data/test/test_ast_processor.rb +32 -0
- data/test/test_base.rb +1 -1
- data/test/test_diagnostic.rb +6 -7
- data/test/test_diagnostic_engine.rb +5 -8
- data/test/test_lexer.rb +5 -8
- data/test/test_meta.rb +12 -0
- data/test/test_parser.rb +84 -13
- data/test/test_runner_parse.rb +22 -1
- data/test/test_runner_rewrite.rb +1 -1
- data/test/test_source_buffer.rb +4 -1
- data/test/test_source_comment.rb +2 -2
- data/test/test_source_comment_associator.rb +47 -15
- data/test/test_source_map.rb +1 -2
- data/test/test_source_range.rb +16 -11
- data/test/test_source_rewriter.rb +4 -4
- data/test/test_source_rewriter_action.rb +2 -2
- data/test/test_source_tree_rewriter.rb +3 -3
- metadata +11 -7
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: bab855c4abc633b9ba13f855d816f20948ee539f27bea7878b574f4d0b3232f7
|
4
|
+
data.tar.gz: 929aa201a2c06738c6202c8efb2afd2dda77e630805738007c39f3b8274fa717
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 78e2e37d1ef61d2c125c1462ecb2e48ab8f76a06fd97bcba28ea4acd5fa60f77a296f859fd6ad67a787027b7a9e62d0fc34bedc8c23522bce21213d1ca49d780
|
7
|
+
data.tar.gz: 07fa5ad8fe63b8503ced8fa0143062385f1d2f99e542f80cc32375269a9ad75f07cc2b0e00838232a71a9e797ba5cab28b661d8a58765f558e29353462641f06
|
data/.travis.yml
CHANGED
@@ -19,10 +19,10 @@ matrix:
|
|
19
19
|
script: bundle exec rake test_cov
|
20
20
|
- name: jruby-9.1.15.0 / Parser tests
|
21
21
|
rvm: jruby-9.1.15.0
|
22
|
-
script: bundle exec rake
|
23
|
-
- name:
|
24
|
-
rvm:
|
25
|
-
script: bundle exec rake
|
22
|
+
script: bundle exec rake test
|
23
|
+
- name: truffleruby / Parser tests
|
24
|
+
rvm: truffleruby
|
25
|
+
script: bundle exec rake test
|
26
26
|
- name: 2.5.8 / Rubocop tests
|
27
27
|
rvm: 2.5.8
|
28
28
|
script: ./ci/run_rubocop_specs
|
@@ -34,9 +34,7 @@ matrix:
|
|
34
34
|
script: ./ci/run_rubocop_specs
|
35
35
|
allow_failures:
|
36
36
|
- rvm: ruby-head
|
37
|
-
- rvm: rbx-2
|
38
37
|
- script: ./ci/run_rubocop_specs
|
39
38
|
before_install:
|
40
|
-
- gem install bundler -v '< 2'
|
41
39
|
- bundle --version
|
42
40
|
- gem --version
|
data/CHANGELOG.md
CHANGED
@@ -1,9 +1,25 @@
|
|
1
1
|
Changelog
|
2
2
|
=========
|
3
3
|
|
4
|
-
Not released (2020-
|
4
|
+
Not released (2020-05-26)
|
5
5
|
-------------------------
|
6
6
|
|
7
|
+
API modifications:
|
8
|
+
* fixed all warnings. tests are running in verbose mode now. (#685) (Ilya Bylich)
|
9
|
+
|
10
|
+
Features implemented:
|
11
|
+
* ruby-[parse, rewrite]: add legacy switches (#699) (Marc-André Lafortune)
|
12
|
+
* Added Parser::Source::Range#to_range. (#697) (Ilya Bylich)
|
13
|
+
* ruby28.y: support rescue modifier in endless method definition. (#696) (Ilya Bylich)
|
14
|
+
* ruby28.y: unify kwrest and no-kwrest rules. (#694) (Ilya Bylich)
|
15
|
+
* ruby28.y: add right hand assignment (#682) (Vladimir Dementyev)
|
16
|
+
|
17
|
+
Bugs fixed:
|
18
|
+
* fix Comment.associate for postfix conditions/loops (#688) (Marc-André Lafortune)
|
19
|
+
|
20
|
+
v2.7.1.2 (2020-04-30)
|
21
|
+
---------------------
|
22
|
+
|
7
23
|
Features implemented:
|
8
24
|
* ruby28.y: endless method definition (#676) (Vladimir Dementyev)
|
9
25
|
* ruby28.y: branch parser (#677) (Vladimir Dementyev)
|
data/README.md
CHANGED
@@ -59,8 +59,7 @@ Parse a chunk of code and display all diagnostics:
|
|
59
59
|
puts diag.render
|
60
60
|
end
|
61
61
|
|
62
|
-
buffer = Parser::Source::Buffer.new('(string)')
|
63
|
-
buffer.source = "foo *bar"
|
62
|
+
buffer = Parser::Source::Buffer.new('(string)', source: "foo *bar")
|
64
63
|
|
65
64
|
p parser.parse(buffer)
|
66
65
|
# (string):1:5: warning: `*' interpreted as argument prefix
|
data/Rakefile
CHANGED
data/doc/AST_FORMAT.md
CHANGED
@@ -730,6 +730,28 @@ Format:
|
|
730
730
|
|
731
731
|
~~~
|
732
732
|
|
733
|
+
### Right-hand assignment
|
734
|
+
|
735
|
+
Format:
|
736
|
+
|
737
|
+
~~~
|
738
|
+
(rasgn (int 1) (lvasgn :a))
|
739
|
+
"1 => a"
|
740
|
+
~~~~~~ expression
|
741
|
+
~~ operator
|
742
|
+
~~~
|
743
|
+
|
744
|
+
#### Multiple right-hand assignment
|
745
|
+
|
746
|
+
Format:
|
747
|
+
|
748
|
+
~~~
|
749
|
+
(mrasgn (send (int 13) :divmod (int 5)) (mlhs (lvasgn :a) (lvasgn :b)))
|
750
|
+
"13.divmod(5) => a,b"
|
751
|
+
~~~~~~~~~~~~~~~~~~~ expression
|
752
|
+
^^ operator
|
753
|
+
~~~
|
754
|
+
|
733
755
|
## Class and module definition
|
734
756
|
|
735
757
|
### Module
|
data/lib/parser/ast/processor.rb
CHANGED
@@ -619,6 +619,15 @@ module Parser
|
|
619
619
|
binary_op_map(lhs, eql_t, rhs))
|
620
620
|
end
|
621
621
|
|
622
|
+
def rassign(lhs, assoc_t, rhs)
|
623
|
+
n(:rasgn, [lhs, rhs], binary_op_map(lhs, assoc_t, rhs))
|
624
|
+
end
|
625
|
+
|
626
|
+
def multi_rassign(lhs, assoc_t, rhs)
|
627
|
+
n(:mrasgn, [ lhs, rhs ],
|
628
|
+
binary_op_map(lhs, assoc_t, rhs))
|
629
|
+
end
|
630
|
+
|
622
631
|
#
|
623
632
|
# Class and module definition
|
624
633
|
#
|
data/lib/parser/diagnostic.rb
CHANGED
@@ -7,8 +7,7 @@ module Parser
|
|
7
7
|
# diagnostics by delegating them to registered consumers.
|
8
8
|
#
|
9
9
|
# @example
|
10
|
-
# buffer = Parser::Source::Buffer.new(__FILE__)
|
11
|
-
# buffer.code = 'foobar'
|
10
|
+
# buffer = Parser::Source::Buffer.new(__FILE__, source: 'foobar')
|
12
11
|
#
|
13
12
|
# consumer = lambda do |diagnostic|
|
14
13
|
# puts diagnostic.message
|
data/lib/parser/lexer.rl
CHANGED
@@ -283,6 +283,13 @@ class Parser::Lexer
|
|
283
283
|
%% write exec;
|
284
284
|
# %
|
285
285
|
|
286
|
+
# Ragel creates a local variable called `testEof` but it doesn't use
|
287
|
+
# it in any assignment. This dead code is here to swallow the warning.
|
288
|
+
# It has no runtime cost because Ruby doesn't produce any instructions from it.
|
289
|
+
if false
|
290
|
+
testEof
|
291
|
+
end
|
292
|
+
|
286
293
|
@p = p
|
287
294
|
|
288
295
|
if @token_queue.any?
|
data/lib/parser/messages.rb
CHANGED
@@ -93,4 +93,19 @@ module Parser
|
|
93
93
|
:crossing_insertions => 'the rewriting action on:',
|
94
94
|
:crossing_insertions_conflict => 'is crossing that on:',
|
95
95
|
}.freeze
|
96
|
+
|
97
|
+
# @api private
|
98
|
+
module Messages
|
99
|
+
# Formats the message, returns a raw template if there's nothing to interpolate
|
100
|
+
#
|
101
|
+
# Code like `format("", {})` gives a warning, and so this method tries interpolating
|
102
|
+
# only if `arguments` hash is not empty.
|
103
|
+
#
|
104
|
+
# @api private
|
105
|
+
def self.compile(reason, arguments)
|
106
|
+
template = MESSAGES[reason]
|
107
|
+
return template if Hash === arguments && arguments.empty?
|
108
|
+
format(template, arguments)
|
109
|
+
end
|
110
|
+
end
|
96
111
|
end
|
data/lib/parser/meta.rb
CHANGED
@@ -12,7 +12,7 @@ module Parser
|
|
12
12
|
sym dsym xstr regopt regexp array splat
|
13
13
|
pair kwsplat hash irange erange self
|
14
14
|
lvar ivar cvar gvar const defined? lvasgn
|
15
|
-
ivasgn cvasgn gvasgn casgn mlhs masgn
|
15
|
+
ivasgn cvasgn gvasgn casgn mlhs masgn rasgn mrasgn
|
16
16
|
op_asgn and_asgn ensure rescue arg_expr
|
17
17
|
or_asgn back_ref nth_ref
|
18
18
|
match_with_lvasgn match_current_line
|
data/lib/parser/ruby28.y
CHANGED
@@ -206,8 +206,26 @@ rule
|
|
206
206
|
{
|
207
207
|
result = @builder.multi_assign(val[0], val[1], val[2])
|
208
208
|
}
|
209
|
+
| rassign
|
209
210
|
| expr
|
210
211
|
|
212
|
+
rassign: arg_value tASSOC lhs
|
213
|
+
{
|
214
|
+
result = @builder.rassign(val[0], val[1], val[2])
|
215
|
+
}
|
216
|
+
| arg_value tASSOC mlhs
|
217
|
+
{
|
218
|
+
result = @builder.multi_rassign(val[0], val[1], val[2])
|
219
|
+
}
|
220
|
+
| rassign tASSOC lhs
|
221
|
+
{
|
222
|
+
result = @builder.rassign(val[0], val[1], val[2])
|
223
|
+
}
|
224
|
+
| rassign tASSOC mlhs
|
225
|
+
{
|
226
|
+
result = @builder.multi_rassign(val[0], val[1], val[2])
|
227
|
+
}
|
228
|
+
|
211
229
|
command_asgn: lhs tEQL command_rhs
|
212
230
|
{
|
213
231
|
result = @builder.assign(val[0], val[1], val[2])
|
@@ -851,6 +869,23 @@ rule
|
|
851
869
|
result = @builder.def_endless_method(*val[0],
|
852
870
|
val[1], val[2], val[3])
|
853
871
|
|
872
|
+
@lexer.cmdarg.pop
|
873
|
+
@lexer.cond.pop
|
874
|
+
@static_env.unextend
|
875
|
+
@context.pop
|
876
|
+
@current_arg_stack.pop
|
877
|
+
}
|
878
|
+
| defn_head f_paren_args tEQL arg kRESCUE_MOD arg
|
879
|
+
{
|
880
|
+
rescue_body = @builder.rescue_body(val[4],
|
881
|
+
nil, nil, nil,
|
882
|
+
nil, val[5])
|
883
|
+
|
884
|
+
method_body = @builder.begin_body(val[3], [ rescue_body ])
|
885
|
+
|
886
|
+
result = @builder.def_endless_method(*val[0],
|
887
|
+
val[1], val[2], method_body)
|
888
|
+
|
854
889
|
@lexer.cmdarg.pop
|
855
890
|
@lexer.cond.pop
|
856
891
|
@static_env.unextend
|
@@ -862,6 +897,23 @@ rule
|
|
862
897
|
result = @builder.def_endless_singleton(*val[0],
|
863
898
|
val[1], val[2], val[3])
|
864
899
|
|
900
|
+
@lexer.cmdarg.pop
|
901
|
+
@lexer.cond.pop
|
902
|
+
@static_env.unextend
|
903
|
+
@context.pop
|
904
|
+
@current_arg_stack.pop
|
905
|
+
}
|
906
|
+
| defs_head f_paren_args tEQL arg kRESCUE_MOD arg
|
907
|
+
{
|
908
|
+
rescue_body = @builder.rescue_body(val[4],
|
909
|
+
nil, nil, nil,
|
910
|
+
nil, val[5])
|
911
|
+
|
912
|
+
method_body = @builder.begin_body(val[3], [ rescue_body ])
|
913
|
+
|
914
|
+
result = @builder.def_endless_singleton(*val[0],
|
915
|
+
val[1], val[2], method_body)
|
916
|
+
|
865
917
|
@lexer.cmdarg.pop
|
866
918
|
@lexer.cond.pop
|
867
919
|
@static_env.unextend
|
@@ -1401,6 +1453,9 @@ rule
|
|
1401
1453
|
result = @builder.restarg(val[0])
|
1402
1454
|
}
|
1403
1455
|
|
1456
|
+
f_any_kwrest: f_kwrest
|
1457
|
+
| f_no_kwarg
|
1458
|
+
|
1404
1459
|
block_args_tail: f_block_kwarg tCOMMA f_kwrest opt_f_block_arg
|
1405
1460
|
{
|
1406
1461
|
result = val[0].concat(val[2]).concat(val[3])
|
@@ -1409,11 +1464,7 @@ rule
|
|
1409
1464
|
{
|
1410
1465
|
result = val[0].concat(val[1])
|
1411
1466
|
}
|
1412
|
-
|
|
1413
|
-
{
|
1414
|
-
result = val[0].concat(val[1])
|
1415
|
-
}
|
1416
|
-
| f_no_kwarg opt_f_block_arg
|
1467
|
+
| f_any_kwrest opt_f_block_arg
|
1417
1468
|
{
|
1418
1469
|
result = val[0].concat(val[1])
|
1419
1470
|
}
|
@@ -2012,7 +2063,7 @@ opt_block_args_tail:
|
|
2012
2063
|
|
2013
2064
|
p_arg: p_expr
|
2014
2065
|
|
2015
|
-
p_kwargs: p_kwarg tCOMMA
|
2066
|
+
p_kwargs: p_kwarg tCOMMA p_any_kwrest
|
2016
2067
|
{
|
2017
2068
|
result = [ *val[0], *val[2] ]
|
2018
2069
|
}
|
@@ -2024,18 +2075,10 @@ opt_block_args_tail:
|
|
2024
2075
|
{
|
2025
2076
|
result = val[0]
|
2026
2077
|
}
|
2027
|
-
|
|
2078
|
+
| p_any_kwrest
|
2028
2079
|
{
|
2029
2080
|
result = val[0]
|
2030
2081
|
}
|
2031
|
-
| p_kwarg tCOMMA p_kwnorest
|
2032
|
-
{
|
2033
|
-
result = [ *val[0], *val[2] ]
|
2034
|
-
}
|
2035
|
-
| p_kwnorest
|
2036
|
-
{
|
2037
|
-
result = [ *val[0], *val[2] ]
|
2038
|
-
}
|
2039
2082
|
|
2040
2083
|
p_kwarg: p_kw
|
2041
2084
|
{
|
@@ -2079,6 +2122,9 @@ opt_block_args_tail:
|
|
2079
2122
|
result = [ @builder.match_nil_pattern(val[0], val[1]) ]
|
2080
2123
|
}
|
2081
2124
|
|
2125
|
+
p_any_kwrest: p_kwrest
|
2126
|
+
| p_kwnorest
|
2127
|
+
|
2082
2128
|
p_value: p_primitive
|
2083
2129
|
| p_primitive tDOT2 p_primitive
|
2084
2130
|
{
|
@@ -2579,11 +2625,7 @@ keyword_variable: kNIL
|
|
2579
2625
|
{
|
2580
2626
|
result = val[0].concat(val[1])
|
2581
2627
|
}
|
2582
|
-
|
|
2583
|
-
{
|
2584
|
-
result = val[0].concat(val[1])
|
2585
|
-
}
|
2586
|
-
| f_no_kwarg opt_f_block_arg
|
2628
|
+
| f_any_kwrest opt_f_block_arg
|
2587
2629
|
{
|
2588
2630
|
result = val[0].concat(val[1])
|
2589
2631
|
}
|
data/lib/parser/runner.rb
CHANGED
@@ -14,9 +14,8 @@ module Parser
|
|
14
14
|
end
|
15
15
|
|
16
16
|
def initialize
|
17
|
-
Parser::Builders::Default.modernize
|
18
|
-
|
19
17
|
@option_parser = OptionParser.new { |opts| setup_option_parsing(opts) }
|
18
|
+
@legacy = {}
|
20
19
|
@parser_class = nil
|
21
20
|
@parser = nil
|
22
21
|
@files = []
|
@@ -30,6 +29,7 @@ module Parser
|
|
30
29
|
|
31
30
|
def execute(options)
|
32
31
|
parse_options(options)
|
32
|
+
setup_builder_default
|
33
33
|
prepare_parser
|
34
34
|
|
35
35
|
process_all_input
|
@@ -37,6 +37,8 @@ module Parser
|
|
37
37
|
|
38
38
|
private
|
39
39
|
|
40
|
+
LEGACY_MODES = %i[lambda procarg0 encoding index arg_inside_procarg0].freeze
|
41
|
+
|
40
42
|
def runner_name
|
41
43
|
raise NotImplementedError, "implement #{self.class}##{__callee__}"
|
42
44
|
end
|
@@ -126,6 +128,17 @@ module Parser
|
|
126
128
|
@parser_class = Parser::RubyMotion
|
127
129
|
end
|
128
130
|
|
131
|
+
opts.on '--legacy', "Parse with all legacy modes" do
|
132
|
+
@legacy = Hash.new(true)
|
133
|
+
end
|
134
|
+
|
135
|
+
LEGACY_MODES.each do |mode|
|
136
|
+
opt_name = "--legacy-#{mode.to_s.gsub('_', '-')}"
|
137
|
+
opts.on opt_name, "Parse with legacy mode for emit_#{mode}" do
|
138
|
+
@legacy[mode] = true
|
139
|
+
end
|
140
|
+
end
|
141
|
+
|
129
142
|
opts.on '-w', '--warnings', 'Enable warnings' do |w|
|
130
143
|
@warnings = w
|
131
144
|
end
|
@@ -164,6 +177,12 @@ module Parser
|
|
164
177
|
end
|
165
178
|
end
|
166
179
|
|
180
|
+
def setup_builder_default
|
181
|
+
LEGACY_MODES.each do |mode|
|
182
|
+
Parser::Builders::Default.send(:"emit_#{mode}=", !@legacy[mode])
|
183
|
+
end
|
184
|
+
end
|
185
|
+
|
167
186
|
def prepare_parser
|
168
187
|
@parser = @parser_class.new
|
169
188
|
|
@@ -55,8 +55,8 @@ module Parser
|
|
55
55
|
new_source = rewriter.rewrite(buffer, ast)
|
56
56
|
|
57
57
|
new_buffer = Source::Buffer.new(initial_buffer.name +
|
58
|
-
'|after ' + rewriter_class.name
|
59
|
-
|
58
|
+
'|after ' + rewriter_class.name,
|
59
|
+
source: new_source)
|
60
60
|
|
61
61
|
@parser.reset
|
62
62
|
new_ast = @parser.parse(new_buffer)
|
data/lib/parser/source/buffer.rb
CHANGED
@@ -102,7 +102,7 @@ module Parser
|
|
102
102
|
end
|
103
103
|
end
|
104
104
|
|
105
|
-
def initialize(name, first_line = 1)
|
105
|
+
def initialize(name, first_line = 1, source: nil)
|
106
106
|
@name = name.to_s
|
107
107
|
@source = nil
|
108
108
|
@first_line = first_line
|
@@ -116,6 +116,8 @@ module Parser
|
|
116
116
|
# Cache for fast lookup
|
117
117
|
@line_for_position = {}
|
118
118
|
@column_for_position = {}
|
119
|
+
|
120
|
+
self.source = source if source
|
119
121
|
end
|
120
122
|
|
121
123
|
##
|
@@ -107,6 +107,19 @@ module Parser
|
|
107
107
|
|
108
108
|
private
|
109
109
|
|
110
|
+
POSTFIX_TYPES = Set[:if, :while, :while_post, :until, :until_post].freeze
|
111
|
+
def children_in_source_order(node)
|
112
|
+
if POSTFIX_TYPES.include?(node.type)
|
113
|
+
# All these types have either nodes with expressions, or `nil`
|
114
|
+
# so a compact will do, but they need to be sorted.
|
115
|
+
node.children.compact.sort_by { |child| child.loc.expression.begin_pos }
|
116
|
+
else
|
117
|
+
node.children.select do |child|
|
118
|
+
child.is_a?(AST::Node) && child.loc && child.loc.expression
|
119
|
+
end
|
120
|
+
end
|
121
|
+
end
|
122
|
+
|
110
123
|
def do_associate
|
111
124
|
@mapping = Hash.new { |h, k| h[k] = [] }
|
112
125
|
@comment_num = -1
|
@@ -131,10 +144,7 @@ module Parser
|
|
131
144
|
node_loc = node.location
|
132
145
|
if @current_comment.location.line <= node_loc.last_line ||
|
133
146
|
node_loc.is_a?(Map::Heredoc)
|
134
|
-
node.
|
135
|
-
next unless child.is_a?(AST::Node) && child.loc && child.loc.expression
|
136
|
-
visit(child)
|
137
|
-
end
|
147
|
+
children_in_source_order(node).each { |child| visit(child) }
|
138
148
|
|
139
149
|
process_trailing_comments(node)
|
140
150
|
end
|