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