parser 2.7.1.2 → 2.7.1.3
Sign up to get free protection for your applications and to get access to all the features.
- 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
|