parser 2.6.0.0 → 3.1.0.0
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/lib/parser/all.rb +3 -0
- data/lib/parser/ast/processor.rb +48 -1
- data/lib/parser/base.rb +30 -6
- data/lib/parser/builders/default.rb +670 -38
- data/lib/parser/context.rb +24 -26
- data/lib/parser/current.rb +36 -9
- data/lib/parser/current_arg_stack.rb +46 -0
- data/lib/parser/diagnostic/engine.rb +1 -2
- data/lib/parser/diagnostic.rb +1 -1
- data/lib/parser/lexer/dedenter.rb +58 -49
- data/lib/parser/lexer/explanation.rb +1 -1
- data/lib/parser/lexer.rb +13837 -11893
- data/lib/parser/macruby.rb +2544 -2489
- data/lib/parser/max_numparam_stack.rb +56 -0
- data/lib/parser/messages.rb +78 -44
- data/lib/parser/meta.rb +13 -3
- data/lib/parser/ruby18.rb +2313 -2259
- data/lib/parser/ruby19.rb +2537 -2488
- data/lib/parser/ruby20.rb +2724 -2673
- data/lib/parser/ruby21.rb +2766 -2727
- data/lib/parser/ruby22.rb +2683 -2628
- data/lib/parser/ruby23.rb +2796 -2755
- data/lib/parser/ruby24.rb +2812 -2771
- data/lib/parser/ruby25.rb +2703 -2670
- data/lib/parser/ruby26.rb +2794 -2747
- data/lib/parser/ruby27.rb +7914 -0
- data/lib/parser/ruby28.rb +8047 -0
- data/lib/parser/ruby30.rb +8096 -0
- data/lib/parser/ruby31.rb +8354 -0
- data/lib/parser/rubymotion.rb +2527 -2485
- data/lib/parser/runner/ruby_parse.rb +2 -2
- data/lib/parser/runner/ruby_rewrite.rb +2 -2
- data/lib/parser/runner.rb +36 -2
- data/lib/parser/source/buffer.rb +53 -28
- data/lib/parser/source/comment/associator.rb +31 -8
- data/lib/parser/source/comment.rb +14 -1
- data/lib/parser/source/map/method_definition.rb +25 -0
- data/lib/parser/source/range.rb +19 -3
- data/lib/parser/source/tree_rewriter/action.rb +137 -28
- data/lib/parser/source/tree_rewriter.rb +144 -14
- data/lib/parser/static_environment.rb +23 -0
- data/lib/parser/tree_rewriter.rb +3 -3
- data/lib/parser/variables_stack.rb +36 -0
- data/lib/parser/version.rb +1 -1
- data/lib/parser.rb +4 -0
- data/parser.gemspec +12 -19
- metadata +34 -99
- data/.gitignore +0 -32
- data/.travis.yml +0 -45
- data/.yardopts +0 -21
- data/CHANGELOG.md +0 -943
- data/CONTRIBUTING.md +0 -17
- data/Gemfile +0 -10
- data/README.md +0 -301
- data/Rakefile +0 -165
- data/ci/run_rubocop_specs +0 -14
- data/doc/AST_FORMAT.md +0 -1735
- data/doc/CUSTOMIZATION.md +0 -37
- data/doc/INTERNALS.md +0 -21
- data/doc/css/.gitkeep +0 -0
- data/doc/css/common.css +0 -68
- data/lib/parser/lexer.rl +0 -2383
- data/lib/parser/macruby.y +0 -2198
- data/lib/parser/ruby18.y +0 -1934
- data/lib/parser/ruby19.y +0 -2175
- data/lib/parser/ruby20.y +0 -2353
- data/lib/parser/ruby21.y +0 -2357
- data/lib/parser/ruby22.y +0 -2364
- data/lib/parser/ruby23.y +0 -2370
- data/lib/parser/ruby24.y +0 -2408
- data/lib/parser/ruby25.y +0 -2405
- data/lib/parser/ruby26.y +0 -2413
- data/lib/parser/rubymotion.y +0 -2182
- data/test/bug_163/fixtures/input.rb +0 -5
- data/test/bug_163/fixtures/output.rb +0 -5
- data/test/bug_163/rewriter.rb +0 -20
- data/test/helper.rb +0 -52
- data/test/parse_helper.rb +0 -315
- data/test/racc_coverage_helper.rb +0 -133
- data/test/test_base.rb +0 -31
- data/test/test_current.rb +0 -27
- data/test/test_diagnostic.rb +0 -96
- data/test/test_diagnostic_engine.rb +0 -62
- data/test/test_encoding.rb +0 -99
- data/test/test_lexer.rb +0 -3543
- data/test/test_lexer_stack_state.rb +0 -78
- data/test/test_parse_helper.rb +0 -80
- data/test/test_parser.rb +0 -7087
- data/test/test_runner_rewrite.rb +0 -47
- data/test/test_source_buffer.rb +0 -162
- data/test/test_source_comment.rb +0 -36
- data/test/test_source_comment_associator.rb +0 -367
- data/test/test_source_map.rb +0 -15
- data/test/test_source_range.rb +0 -172
- data/test/test_source_rewriter.rb +0 -541
- data/test/test_source_rewriter_action.rb +0 -46
- data/test/test_source_tree_rewriter.rb +0 -173
- data/test/test_static_environment.rb +0 -45
- data/test/using_tree_rewriter/fixtures/input.rb +0 -3
- data/test/using_tree_rewriter/fixtures/output.rb +0 -3
- data/test/using_tree_rewriter/using_tree_rewriter.rb +0 -9
data/lib/parser/context.rb
CHANGED
@@ -5,47 +5,45 @@ module Parser
|
|
5
5
|
#
|
6
6
|
# Supported states:
|
7
7
|
# + :class - in the class body (class A; end)
|
8
|
+
# + :module - in the module body (module M; end)
|
8
9
|
# + :sclass - in the singleton class body (class << obj; end)
|
9
10
|
# + :def - in the method body (def m; end)
|
10
11
|
# + :defs - in the singleton method body (def self.m; end)
|
12
|
+
# + :def_open_args - in the arglist of the method definition
|
13
|
+
# keep in mind that it's set **only** after reducing the first argument,
|
14
|
+
# if you need to handle the first argument check `lex_state == expr_fname`
|
11
15
|
# + :block - in the block body (tap {})
|
12
16
|
# + :lambda - in the lambda body (-> {})
|
13
17
|
#
|
14
18
|
class Context
|
15
|
-
|
19
|
+
FLAGS = %i[
|
20
|
+
in_defined
|
21
|
+
in_kwarg
|
22
|
+
in_argdef
|
23
|
+
in_def
|
24
|
+
in_class
|
25
|
+
in_block
|
26
|
+
in_lambda
|
27
|
+
]
|
16
28
|
|
17
29
|
def initialize
|
18
|
-
|
19
|
-
freeze
|
20
|
-
end
|
21
|
-
|
22
|
-
def push(state)
|
23
|
-
@stack << state
|
24
|
-
end
|
25
|
-
|
26
|
-
def pop
|
27
|
-
@stack.pop
|
30
|
+
reset
|
28
31
|
end
|
29
32
|
|
30
33
|
def reset
|
31
|
-
@
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
@
|
36
|
-
|
37
|
-
|
38
|
-
def indirectly_in_def?
|
39
|
-
@stack.include?(:def) || @stack.include?(:defs)
|
34
|
+
@in_defined = false
|
35
|
+
@in_kwarg = false
|
36
|
+
@in_argdef = false
|
37
|
+
@in_def = false
|
38
|
+
@in_class = false
|
39
|
+
@in_block = false
|
40
|
+
@in_lambda = false
|
40
41
|
end
|
41
42
|
|
42
|
-
|
43
|
-
def_index = stack.rindex { |item| [:def, :defs].include?(item) }
|
44
|
-
sclass_index = stack.rindex(:sclass)
|
43
|
+
attr_accessor(*FLAGS)
|
45
44
|
|
46
|
-
|
45
|
+
def in_dynamic_block?
|
46
|
+
in_block || in_lambda
|
47
47
|
end
|
48
|
-
alias module_definition_allowed? class_definition_allowed?
|
49
|
-
alias dynamic_const_definition_allowed? class_definition_allowed?
|
50
48
|
end
|
51
49
|
end
|
data/lib/parser/current.rb
CHANGED
@@ -3,9 +3,9 @@
|
|
3
3
|
module Parser
|
4
4
|
class << self
|
5
5
|
def warn_syntax_deviation(feature, version)
|
6
|
-
warn "warning: parser/current is loading #{feature}, which recognizes"
|
7
|
-
|
8
|
-
|
6
|
+
warn "warning: parser/current is loading #{feature}, which recognizes" \
|
7
|
+
"#{version}-compliant syntax, but you are running #{RUBY_VERSION}.\n" \
|
8
|
+
"Please see https://github.com/whitequark/parser#compatibility-with-ruby-mri."
|
9
9
|
end
|
10
10
|
private :warn_syntax_deviation
|
11
11
|
end
|
@@ -48,7 +48,7 @@ module Parser
|
|
48
48
|
CurrentRuby = Ruby23
|
49
49
|
|
50
50
|
when /^2\.4\./
|
51
|
-
current_version = '2.4.
|
51
|
+
current_version = '2.4.10'
|
52
52
|
if RUBY_VERSION != current_version
|
53
53
|
warn_syntax_deviation 'parser/ruby24', current_version
|
54
54
|
end
|
@@ -57,7 +57,7 @@ module Parser
|
|
57
57
|
CurrentRuby = Ruby24
|
58
58
|
|
59
59
|
when /^2\.5\./
|
60
|
-
current_version = '2.5.
|
60
|
+
current_version = '2.5.9'
|
61
61
|
if RUBY_VERSION != current_version
|
62
62
|
warn_syntax_deviation 'parser/ruby25', current_version
|
63
63
|
end
|
@@ -66,7 +66,7 @@ module Parser
|
|
66
66
|
CurrentRuby = Ruby25
|
67
67
|
|
68
68
|
when /^2\.6\./
|
69
|
-
current_version = '2.6.
|
69
|
+
current_version = '2.6.9'
|
70
70
|
if RUBY_VERSION != current_version
|
71
71
|
warn_syntax_deviation 'parser/ruby26', current_version
|
72
72
|
end
|
@@ -74,10 +74,37 @@ module Parser
|
|
74
74
|
require 'parser/ruby26'
|
75
75
|
CurrentRuby = Ruby26
|
76
76
|
|
77
|
+
when /^2\.7\./
|
78
|
+
current_version = '2.7.5'
|
79
|
+
if RUBY_VERSION != current_version
|
80
|
+
warn_syntax_deviation 'parser/ruby27', current_version
|
81
|
+
end
|
82
|
+
|
83
|
+
require 'parser/ruby27'
|
84
|
+
CurrentRuby = Ruby27
|
85
|
+
|
86
|
+
when /^3\.0\./
|
87
|
+
current_version = '3.0.3'
|
88
|
+
if RUBY_VERSION != current_version
|
89
|
+
warn_syntax_deviation 'parser/ruby30', current_version
|
90
|
+
end
|
91
|
+
|
92
|
+
require 'parser/ruby30'
|
93
|
+
CurrentRuby = Ruby30
|
94
|
+
|
95
|
+
when /^3\.1\./
|
96
|
+
current_version = '3.1.0'
|
97
|
+
if RUBY_VERSION != current_version
|
98
|
+
warn_syntax_deviation 'parser/ruby31', current_version
|
99
|
+
end
|
100
|
+
|
101
|
+
require 'parser/ruby31'
|
102
|
+
CurrentRuby = Ruby31
|
103
|
+
|
77
104
|
else # :nocov:
|
78
105
|
# Keep this in sync with released Ruby.
|
79
|
-
warn_syntax_deviation 'parser/
|
80
|
-
require 'parser/
|
81
|
-
CurrentRuby =
|
106
|
+
warn_syntax_deviation 'parser/ruby31', '3.1.x'
|
107
|
+
require 'parser/ruby31'
|
108
|
+
CurrentRuby = Ruby31
|
82
109
|
end
|
83
110
|
end
|
@@ -0,0 +1,46 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Parser
|
4
|
+
# Stack that holds names of current arguments,
|
5
|
+
# i.e. while parsing
|
6
|
+
# def m1(a = (def m2(b = def m3(c = 1); end); end)); end
|
7
|
+
# ^
|
8
|
+
# stack is [:a, :b, :c]
|
9
|
+
#
|
10
|
+
# Emulates `p->cur_arg` in MRI's parse.y
|
11
|
+
#
|
12
|
+
# @api private
|
13
|
+
#
|
14
|
+
class CurrentArgStack
|
15
|
+
attr_reader :stack
|
16
|
+
|
17
|
+
def initialize
|
18
|
+
@stack = []
|
19
|
+
freeze
|
20
|
+
end
|
21
|
+
|
22
|
+
def empty?
|
23
|
+
@stack.size == 0
|
24
|
+
end
|
25
|
+
|
26
|
+
def push(value)
|
27
|
+
@stack << value
|
28
|
+
end
|
29
|
+
|
30
|
+
def set(value)
|
31
|
+
@stack[@stack.length - 1] = value
|
32
|
+
end
|
33
|
+
|
34
|
+
def pop
|
35
|
+
@stack.pop
|
36
|
+
end
|
37
|
+
|
38
|
+
def reset
|
39
|
+
@stack.clear
|
40
|
+
end
|
41
|
+
|
42
|
+
def top
|
43
|
+
@stack.last
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
@@ -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/diagnostic.rb
CHANGED
@@ -3,72 +3,81 @@
|
|
3
3
|
module Parser
|
4
4
|
|
5
5
|
class Lexer::Dedenter
|
6
|
+
# Tab (\t) counts as 8 spaces
|
7
|
+
TAB_WIDTH = 8
|
8
|
+
|
6
9
|
def initialize(dedent_level)
|
7
10
|
@dedent_level = dedent_level
|
8
11
|
@at_line_begin = true
|
9
12
|
@indent_level = 0
|
10
13
|
end
|
11
14
|
|
15
|
+
# For a heredoc like
|
16
|
+
# <<-HERE
|
17
|
+
# a
|
18
|
+
# b
|
19
|
+
# HERE
|
20
|
+
# this method gets called with " a\n" and " b\n"
|
21
|
+
#
|
22
|
+
# However, the following heredoc:
|
23
|
+
#
|
24
|
+
# <<-HERE
|
25
|
+
# a\
|
26
|
+
# b
|
27
|
+
# HERE
|
28
|
+
# calls this method only once with a string " a\\\n b\n"
|
29
|
+
#
|
30
|
+
# This is important because technically it's a single line,
|
31
|
+
# but it has to be concatenated __after__ dedenting.
|
32
|
+
#
|
33
|
+
# It has no effect for non-squiggly heredocs, i.e. it simply removes "\\\n"
|
34
|
+
# Of course, lexer could do it but once again: it's all because of dedenting.
|
35
|
+
#
|
12
36
|
def dedent(string)
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
37
|
+
original_encoding = string.encoding
|
38
|
+
# Prevent the following error when processing binary encoded source.
|
39
|
+
# "\xC0".split # => ArgumentError (invalid byte sequence in UTF-8)
|
40
|
+
lines = string.force_encoding(Encoding::BINARY).split("\\\n")
|
41
|
+
if lines.length == 1
|
42
|
+
# If the line continuation sequence was found but there is no second
|
43
|
+
# line, it was not really a line continuation and must be ignored.
|
44
|
+
lines = [string.force_encoding(original_encoding)]
|
45
|
+
else
|
46
|
+
lines.map! {|s| s.force_encoding(original_encoding) }
|
47
|
+
end
|
17
48
|
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
if char == ?\n
|
28
|
-
# trimming \n, starting a new line
|
29
|
-
string.slice!(index - offset)
|
30
|
-
offset += 1
|
31
|
-
@at_line_begin = true
|
32
|
-
space_begin = space_end = index - offset
|
33
|
-
@indent_level = 0
|
34
|
-
elsif char == ?n
|
35
|
-
# replacing \\n to \n
|
36
|
-
string.slice!(index - offset)
|
37
|
-
string.insert(index - offset, ?\n)
|
38
|
-
else
|
39
|
-
# exiting escape mode as it's not an escape sequence
|
40
|
-
@at_line_begin = _at_line_begin
|
41
|
-
escape = false
|
42
|
-
redo
|
43
|
-
end
|
44
|
-
escape = false
|
45
|
-
elsif @at_line_begin
|
46
|
-
if char == ?\n || @indent_level >= @dedent_level
|
47
|
-
string.slice!(space_begin...space_end)
|
48
|
-
offset += space_end - space_begin
|
49
|
-
@at_line_begin = false
|
50
|
-
end
|
49
|
+
if @at_line_begin
|
50
|
+
lines_to_dedent = lines
|
51
|
+
else
|
52
|
+
_first, *lines_to_dedent = lines
|
53
|
+
end
|
54
|
+
|
55
|
+
lines_to_dedent.each do |line|
|
56
|
+
left_to_remove = @dedent_level
|
57
|
+
remove = 0
|
51
58
|
|
59
|
+
line.each_char do |char|
|
60
|
+
break if left_to_remove <= 0
|
52
61
|
case char
|
53
62
|
when ?\s
|
54
|
-
|
55
|
-
|
63
|
+
remove += 1
|
64
|
+
left_to_remove -= 1
|
56
65
|
when ?\t
|
57
|
-
|
58
|
-
|
66
|
+
break if TAB_WIDTH * (remove / TAB_WIDTH + 1) > @dedent_level
|
67
|
+
remove += 1
|
68
|
+
left_to_remove -= TAB_WIDTH
|
69
|
+
else
|
70
|
+
# no more spaces or tabs
|
71
|
+
break
|
59
72
|
end
|
60
|
-
elsif char == ?\n && index == last_index
|
61
|
-
@at_line_begin = true
|
62
|
-
@indent_level = 0
|
63
|
-
space_begin = space_end = index - offset + 1
|
64
73
|
end
|
65
|
-
end
|
66
74
|
|
67
|
-
|
68
|
-
string.slice!(space_begin..space_end)
|
75
|
+
line.slice!(0, remove)
|
69
76
|
end
|
70
77
|
|
71
|
-
|
78
|
+
string.replace(lines.join)
|
79
|
+
|
80
|
+
@at_line_begin = string.end_with?("\n")
|
72
81
|
end
|
73
82
|
|
74
83
|
def interrupt
|