parser 2.5.0.5 → 2.5.1.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/.gitignore +1 -0
- data/CHANGELOG.md +18 -0
- data/Rakefile +1 -0
- data/lib/parser/all.rb +1 -0
- data/lib/parser/builders/default.rb +1 -1
- data/lib/parser/context.rb +9 -0
- data/lib/parser/current.rb +13 -4
- data/lib/parser/lexer.rl +61 -19
- data/lib/parser/lexer/dedenter.rb +31 -3
- data/lib/parser/lexer/literal.rb +8 -0
- data/lib/parser/macruby.y +2 -2
- data/lib/parser/ruby18.y +2 -2
- data/lib/parser/ruby19.y +2 -2
- data/lib/parser/ruby20.y +2 -2
- data/lib/parser/ruby21.y +2 -2
- data/lib/parser/ruby22.y +2 -2
- data/lib/parser/ruby23.y +2 -2
- data/lib/parser/ruby24.y +20 -22
- data/lib/parser/ruby25.y +28 -30
- data/lib/parser/ruby26.y +2392 -0
- data/lib/parser/rubymotion.y +2 -2
- data/lib/parser/runner.rb +5 -0
- data/lib/parser/version.rb +1 -1
- data/parser.gemspec +1 -0
- data/test/helper.rb +13 -2
- data/test/parse_helper.rb +2 -1
- data/test/test_current.rb +2 -0
- data/test/test_lexer.rb +38 -2
- data/test/test_parser.rb +133 -10
- metadata +4 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 3d4445244332537a2a91b8b6f6a2d35b750ffb1dbc3869c91f1a4de840a89600
|
4
|
+
data.tar.gz: 800b3adeae6c64459f2b604c3c4b935eb728018bfe4136debae16c96df0384bf
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 99138e99f88e016a3da7cac3fe45c492068fe5fa5ecb6df640ade2f6890c05fdc2aff096d255e0fd57f75f4e5c3300c15f16fa9be177e9fdc56711c6e6ea29ac
|
7
|
+
data.tar.gz: 71504873b9c22a3adfd0d0ee304e69e3317b93d52a7e2506c6225e2c768cea2ddd9bf1a874a04c8b0706047f78dc97f49b7841307f64198678f03a3336ad2675
|
data/.gitignore
CHANGED
data/CHANGELOG.md
CHANGED
@@ -1,6 +1,24 @@
|
|
1
1
|
Changelog
|
2
2
|
=========
|
3
3
|
|
4
|
+
Not released (2018-04-12)
|
5
|
+
-------------------------
|
6
|
+
|
7
|
+
API modifications:
|
8
|
+
* Parser::Current: bump latest 2.2 branch to 2.2.10. (Ilya Bylich)
|
9
|
+
|
10
|
+
Features implemented:
|
11
|
+
* ruby26.y: Raise a syntax error on 'else' without 'rescue'. This commit tracks upstream commit ruby/ruby@140512d. (Ilya Bylich)
|
12
|
+
|
13
|
+
Bugs fixed:
|
14
|
+
* lexer.rl, Dedenter: Treat slash in heredocs as a line continuation. (Ilya Bylich)
|
15
|
+
* lexer.rl: Fix parsing of `a ? b + '': nil`. (Ilya Bylich)
|
16
|
+
* lexer.rl: Reject `m a: {} {}` and `m [] {}` since 25. (Ilya Bylich)
|
17
|
+
* builders/default: allow class/module/dynamic constant definition in the method body if there's a sclass between them. (bug #490) (Ilya Bylich)
|
18
|
+
* lexer.rl: Emit :!@ as :!, :~@ as :~. (Ilya Bylich)
|
19
|
+
* parse{23,24,25}.y: use only CMDARG/COND _PUSH/POP for cmdarg/cond management. (bug #481) (Ilya Bylich)
|
20
|
+
* lexer.rl: emit tSTRING_BEG and tSTRING_DBEG one by one to allow parser to properly manipulate cmdarg stack. (bug #480) (Ilya Bylich)
|
21
|
+
|
4
22
|
v2.5.0.4 (2018-03-13)
|
5
23
|
---------------------
|
6
24
|
|
data/Rakefile
CHANGED
data/lib/parser/all.rb
CHANGED
data/lib/parser/context.rb
CHANGED
@@ -38,5 +38,14 @@ module Parser
|
|
38
38
|
def indirectly_in_def?
|
39
39
|
@stack.include?(:def) || @stack.include?(:defs)
|
40
40
|
end
|
41
|
+
|
42
|
+
def class_definition_allowed?
|
43
|
+
def_index = stack.rindex { |item| [:def, :defs].include?(item) }
|
44
|
+
sclass_index = stack.rindex(:sclass)
|
45
|
+
|
46
|
+
def_index.nil? || (!sclass_index.nil? && sclass_index > def_index)
|
47
|
+
end
|
48
|
+
alias module_definition_allowed? class_definition_allowed?
|
49
|
+
alias dynamic_const_definition_allowed? class_definition_allowed?
|
41
50
|
end
|
42
51
|
end
|
data/lib/parser/current.rb
CHANGED
@@ -30,7 +30,7 @@ module Parser
|
|
30
30
|
CurrentRuby = Ruby21
|
31
31
|
|
32
32
|
when /^2\.2\./
|
33
|
-
current_version = '2.2.
|
33
|
+
current_version = '2.2.10'
|
34
34
|
if RUBY_VERSION != current_version
|
35
35
|
warn_syntax_deviation 'parser/ruby22', current_version
|
36
36
|
end
|
@@ -39,7 +39,7 @@ module Parser
|
|
39
39
|
CurrentRuby = Ruby22
|
40
40
|
|
41
41
|
when /^2\.3\./
|
42
|
-
current_version = '2.3.
|
42
|
+
current_version = '2.3.7'
|
43
43
|
if RUBY_VERSION != current_version
|
44
44
|
warn_syntax_deviation 'parser/ruby23', current_version
|
45
45
|
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.4'
|
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.1'
|
61
61
|
if RUBY_VERSION != current_version
|
62
62
|
warn_syntax_deviation 'parser/ruby25', current_version
|
63
63
|
end
|
@@ -65,6 +65,15 @@ module Parser
|
|
65
65
|
require 'parser/ruby25'
|
66
66
|
CurrentRuby = Ruby25
|
67
67
|
|
68
|
+
when /^2\.6\./
|
69
|
+
current_version = '2.6.0-dev'
|
70
|
+
if RUBY_VERSION != current_version
|
71
|
+
warn_syntax_deviation 'parser/ruby26', current_version
|
72
|
+
end
|
73
|
+
|
74
|
+
require 'parser/ruby26'
|
75
|
+
CurrentRuby = Ruby26
|
76
|
+
|
68
77
|
else # :nocov:
|
69
78
|
# Keep this in sync with released Ruby.
|
70
79
|
warn_syntax_deviation 'parser/ruby25', '2.5.x'
|
data/lib/parser/lexer.rl
CHANGED
@@ -379,27 +379,30 @@ class Parser::Lexer
|
|
379
379
|
def push_literal(*args)
|
380
380
|
new_literal = Literal.new(self, *args)
|
381
381
|
@literal_stack.push(new_literal)
|
382
|
+
next_state_for_literal(new_literal)
|
383
|
+
end
|
382
384
|
|
383
|
-
|
384
|
-
|
385
|
+
def next_state_for_literal(literal)
|
386
|
+
if literal.words? && literal.backslash_delimited?
|
387
|
+
if literal.interpolate?
|
385
388
|
self.class.lex_en_interp_backslash_delimited_words
|
386
389
|
else
|
387
390
|
self.class.lex_en_plain_backslash_delimited_words
|
388
391
|
end
|
389
|
-
elsif
|
390
|
-
if
|
392
|
+
elsif literal.words? && !literal.backslash_delimited?
|
393
|
+
if literal.interpolate?
|
391
394
|
self.class.lex_en_interp_words
|
392
395
|
else
|
393
396
|
self.class.lex_en_plain_words
|
394
397
|
end
|
395
|
-
elsif !
|
396
|
-
if
|
398
|
+
elsif !literal.words? && literal.backslash_delimited?
|
399
|
+
if literal.interpolate?
|
397
400
|
self.class.lex_en_interp_backslash_delimited
|
398
401
|
else
|
399
402
|
self.class.lex_en_plain_backslash_delimited
|
400
403
|
end
|
401
404
|
else
|
402
|
-
if
|
405
|
+
if literal.interpolate?
|
403
406
|
self.class.lex_en_interp_string
|
404
407
|
else
|
405
408
|
self.class.lex_en_plain_string
|
@@ -894,6 +897,23 @@ class Parser::Lexer
|
|
894
897
|
# Regular expressions should include escape sequences in their
|
895
898
|
# escaped form. On the other hand, escaped newlines are removed.
|
896
899
|
current_literal.extend_string(tok.gsub("\\\n".freeze, ''.freeze), @ts, @te)
|
900
|
+
elsif current_literal.heredoc? && escaped_char == "\n".freeze
|
901
|
+
if current_literal.squiggly_heredoc?
|
902
|
+
# Squiggly heredocs like
|
903
|
+
# <<~-HERE
|
904
|
+
# 1\
|
905
|
+
# 2
|
906
|
+
# HERE
|
907
|
+
# treat '\' as a line continuation, but still dedent the body, so the heredoc above becomes "12\n".
|
908
|
+
# This information is emitted as is, without escaping,
|
909
|
+
# later this escape sequence (\\n) gets handled manually in the Lexer::Dedenter
|
910
|
+
current_literal.extend_string(tok, @ts, @te)
|
911
|
+
else
|
912
|
+
# Plain heredocs also parse \\n as a line continuation,
|
913
|
+
# but they don't need to know that there was originally a newline in the
|
914
|
+
# code, so we escape it and emit as " 1 2\n"
|
915
|
+
current_literal.extend_string(tok.gsub("\\\n".freeze, ''.freeze), @ts, @te)
|
916
|
+
end
|
897
917
|
else
|
898
918
|
current_literal.extend_string(@escape || tok, @ts, @te)
|
899
919
|
end
|
@@ -1018,6 +1038,13 @@ class Parser::Lexer
|
|
1018
1038
|
if current_literal.end_interp_brace_and_try_closing
|
1019
1039
|
if version?(18, 19)
|
1020
1040
|
emit(:tRCURLY, '}'.freeze, p - 1, p)
|
1041
|
+
if @version < 24
|
1042
|
+
@cond.lexpop
|
1043
|
+
@cmdarg.lexpop
|
1044
|
+
else
|
1045
|
+
@cond.pop
|
1046
|
+
@cmdarg.pop
|
1047
|
+
end
|
1021
1048
|
else
|
1022
1049
|
emit(:tSTRING_DEND, '}'.freeze, p - 1, p)
|
1023
1050
|
end
|
@@ -1026,8 +1053,9 @@ class Parser::Lexer
|
|
1026
1053
|
@herebody_s = current_literal.saved_herebody_s
|
1027
1054
|
end
|
1028
1055
|
|
1056
|
+
|
1029
1057
|
fhold;
|
1030
|
-
fnext *
|
1058
|
+
fnext *next_state_for_literal(current_literal);
|
1031
1059
|
fbreak;
|
1032
1060
|
end
|
1033
1061
|
end
|
@@ -1046,7 +1074,8 @@ class Parser::Lexer
|
|
1046
1074
|
end
|
1047
1075
|
|
1048
1076
|
current_literal.start_interp_brace
|
1049
|
-
|
1077
|
+
fnext expr_value;
|
1078
|
+
fbreak;
|
1050
1079
|
}
|
1051
1080
|
|
1052
1081
|
# Actual string parsers are simply combined from the primitives defined
|
@@ -1748,6 +1777,14 @@ class Parser::Lexer
|
|
1748
1777
|
fgoto *push_literal(type, delimiter, @ts);
|
1749
1778
|
};
|
1750
1779
|
|
1780
|
+
# :!@ is :!
|
1781
|
+
# :~@ is :~
|
1782
|
+
':' [!~] '@'
|
1783
|
+
=> {
|
1784
|
+
emit(:tSYMBOL, tok(@ts + 1, @ts + 2))
|
1785
|
+
fnext expr_end; fbreak;
|
1786
|
+
};
|
1787
|
+
|
1751
1788
|
':' bareword ambiguous_symbol_suffix
|
1752
1789
|
=> {
|
1753
1790
|
emit(:tSYMBOL, tok(@ts + 1, tm), @ts, tm)
|
@@ -1775,7 +1812,7 @@ class Parser::Lexer
|
|
1775
1812
|
value = @escape || tok(@ts + 1)
|
1776
1813
|
|
1777
1814
|
if version?(18)
|
1778
|
-
emit(:tINTEGER, value.
|
1815
|
+
emit(:tINTEGER, value.getbyte(0))
|
1779
1816
|
else
|
1780
1817
|
emit(:tCHARACTER, value)
|
1781
1818
|
end
|
@@ -2206,10 +2243,16 @@ class Parser::Lexer
|
|
2206
2243
|
# OPERATORS
|
2207
2244
|
#
|
2208
2245
|
|
2209
|
-
|
2210
|
-
|
2211
|
-
|
2212
|
-
)
|
2246
|
+
# When '|', '~', '!', '=>' are used as operators
|
2247
|
+
# they do not accept any symbols (or quoted labels) after.
|
2248
|
+
# Other binary operators accept it.
|
2249
|
+
( operator_arithmetic | operator_rest ) - ( '|' | '~' | '!' )
|
2250
|
+
=> {
|
2251
|
+
emit_table(PUNCTUATION);
|
2252
|
+
fnext expr_value; fbreak;
|
2253
|
+
};
|
2254
|
+
|
2255
|
+
( e_lparen | '|' | '~' | '!' )
|
2213
2256
|
=> { emit_table(PUNCTUATION)
|
2214
2257
|
fnext expr_beg; fbreak; };
|
2215
2258
|
|
@@ -2217,17 +2260,16 @@ class Parser::Lexer
|
|
2217
2260
|
=> {
|
2218
2261
|
emit_table(PUNCTUATION)
|
2219
2262
|
|
2220
|
-
@cond.lexpop
|
2221
2263
|
if @version < 24
|
2264
|
+
@cond.lexpop
|
2222
2265
|
@cmdarg.lexpop
|
2223
2266
|
else
|
2267
|
+
@cond.pop
|
2224
2268
|
@cmdarg.pop
|
2225
2269
|
end
|
2226
2270
|
|
2227
|
-
if tok == '}'.freeze
|
2228
|
-
|
2229
|
-
elsif tok == ']'
|
2230
|
-
if @version >= 24
|
2271
|
+
if tok == '}'.freeze || tok == ']'.freeze
|
2272
|
+
if @version >= 25
|
2231
2273
|
fnext expr_end;
|
2232
2274
|
else
|
2233
2275
|
fnext expr_endarg;
|
@@ -12,13 +12,41 @@ module Parser
|
|
12
12
|
def dedent(string)
|
13
13
|
space_begin = space_end = offset = 0
|
14
14
|
last_index = string.length - 1
|
15
|
+
escape = false
|
16
|
+
_at_line_begin = nil
|
17
|
+
|
15
18
|
string.chars.each_with_index do |char, index|
|
16
|
-
if
|
19
|
+
if char == '\\'
|
20
|
+
# entering escape mode
|
21
|
+
escape = true
|
22
|
+
string.slice!(index - offset)
|
23
|
+
offset += 1
|
24
|
+
_at_line_begin = @at_line_begin
|
25
|
+
@at_line_begin = false
|
26
|
+
elsif escape
|
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
|
17
46
|
if char == ?\n || @indent_level >= @dedent_level
|
18
47
|
string.slice!(space_begin...space_end)
|
19
|
-
offset += space_end - space_begin
|
48
|
+
offset += space_end - space_begin
|
20
49
|
@at_line_begin = false
|
21
|
-
redo if char == ?\n
|
22
50
|
end
|
23
51
|
|
24
52
|
case char
|
data/lib/parser/lexer/literal.rb
CHANGED
@@ -103,6 +103,14 @@ module Parser
|
|
103
103
|
!!@heredoc_e
|
104
104
|
end
|
105
105
|
|
106
|
+
def plain_heredoc?
|
107
|
+
heredoc? && !@dedent_body
|
108
|
+
end
|
109
|
+
|
110
|
+
def squiggly_heredoc?
|
111
|
+
heredoc? && @dedent_body
|
112
|
+
end
|
113
|
+
|
106
114
|
def backslash_delimited?
|
107
115
|
@end_delim == '\\'.freeze
|
108
116
|
end
|
data/lib/parser/macruby.y
CHANGED
@@ -1128,7 +1128,7 @@ rule
|
|
1128
1128
|
}
|
1129
1129
|
bodystmt kEND
|
1130
1130
|
{
|
1131
|
-
|
1131
|
+
unless @context.class_definition_allowed?
|
1132
1132
|
diagnostic :error, :class_in_def, nil, val[0]
|
1133
1133
|
end
|
1134
1134
|
|
@@ -1163,7 +1163,7 @@ rule
|
|
1163
1163
|
}
|
1164
1164
|
bodystmt kEND
|
1165
1165
|
{
|
1166
|
-
|
1166
|
+
unless @context.module_definition_allowed?
|
1167
1167
|
diagnostic :error, :module_in_def, nil, val[0]
|
1168
1168
|
end
|
1169
1169
|
|
data/lib/parser/ruby18.y
CHANGED
@@ -1128,7 +1128,7 @@ rule
|
|
1128
1128
|
}
|
1129
1129
|
bodystmt kEND
|
1130
1130
|
{
|
1131
|
-
|
1131
|
+
unless @context.class_definition_allowed?
|
1132
1132
|
diagnostic :error, :class_in_def, nil, val[0]
|
1133
1133
|
end
|
1134
1134
|
|
@@ -1159,7 +1159,7 @@ rule
|
|
1159
1159
|
}
|
1160
1160
|
bodystmt kEND
|
1161
1161
|
{
|
1162
|
-
|
1162
|
+
unless @context.module_definition_allowed?
|
1163
1163
|
diagnostic :error, :module_in_def, nil, val[0]
|
1164
1164
|
end
|
1165
1165
|
|
data/lib/parser/ruby19.y
CHANGED
@@ -1095,7 +1095,7 @@ rule
|
|
1095
1095
|
}
|
1096
1096
|
bodystmt kEND
|
1097
1097
|
{
|
1098
|
-
|
1098
|
+
unless @context.class_definition_allowed?
|
1099
1099
|
diagnostic :error, :class_in_def, nil, val[0]
|
1100
1100
|
end
|
1101
1101
|
|
@@ -1130,7 +1130,7 @@ rule
|
|
1130
1130
|
}
|
1131
1131
|
bodystmt kEND
|
1132
1132
|
{
|
1133
|
-
|
1133
|
+
unless @context.module_definition_allowed?
|
1134
1134
|
diagnostic :error, :module_in_def, nil, val[0]
|
1135
1135
|
end
|
1136
1136
|
|
data/lib/parser/ruby20.y
CHANGED
@@ -1125,7 +1125,7 @@ rule
|
|
1125
1125
|
}
|
1126
1126
|
bodystmt kEND
|
1127
1127
|
{
|
1128
|
-
|
1128
|
+
unless @context.class_definition_allowed?
|
1129
1129
|
diagnostic :error, :class_in_def, nil, val[0]
|
1130
1130
|
end
|
1131
1131
|
|
@@ -1160,7 +1160,7 @@ rule
|
|
1160
1160
|
}
|
1161
1161
|
bodystmt kEND
|
1162
1162
|
{
|
1163
|
-
|
1163
|
+
unless @context.module_definition_allowed?
|
1164
1164
|
diagnostic :error, :module_in_def, nil, val[0]
|
1165
1165
|
end
|
1166
1166
|
|
data/lib/parser/ruby21.y
CHANGED
@@ -1115,7 +1115,7 @@ rule
|
|
1115
1115
|
}
|
1116
1116
|
bodystmt kEND
|
1117
1117
|
{
|
1118
|
-
|
1118
|
+
unless @context.class_definition_allowed?
|
1119
1119
|
diagnostic :error, :class_in_def, nil, val[0]
|
1120
1120
|
end
|
1121
1121
|
|
@@ -1150,7 +1150,7 @@ rule
|
|
1150
1150
|
}
|
1151
1151
|
bodystmt kEND
|
1152
1152
|
{
|
1153
|
-
|
1153
|
+
unless @context.module_definition_allowed?
|
1154
1154
|
diagnostic :error, :module_in_def, nil, val[0]
|
1155
1155
|
end
|
1156
1156
|
|