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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: eae6cafd7a3fce8e37c8659d938ebaf9c07809373b09e67aadfce5812e270798
4
- data.tar.gz: f5c5cbe528398b002fd7663fcd87083a4a6674a9c506b2d57c0c94015a3a006a
3
+ metadata.gz: 3d4445244332537a2a91b8b6f6a2d35b750ffb1dbc3869c91f1a4de840a89600
4
+ data.tar.gz: 800b3adeae6c64459f2b604c3c4b935eb728018bfe4136debae16c96df0384bf
5
5
  SHA512:
6
- metadata.gz: 8721c4dd25927f9913423c7a5a1076b40d9652b2e327b6d74d02f9994e45a4bb53a69c1889d0fa271f1fb4756600a809cf11876add173fd4c65e64c4316c4225
7
- data.tar.gz: 6b356ff3f6889594738f9b5c2ded84bc0abf20cf506caaaa627ff2ce5759edc68f0b73f6e4a9c0cab4dbf377df821979cd2fb179bf24ee3939868ec871fe3396
6
+ metadata.gz: 99138e99f88e016a3da7cac3fe45c492068fe5fa5ecb6df640ade2f6890c05fdc2aff096d255e0fd57f75f4e5c3300c15f16fa9be177e9fdc56711c6e6ea29ac
7
+ data.tar.gz: 71504873b9c22a3adfd0d0ee304e69e3317b93d52a7e2506c6225e2c768cea2ddd9bf1a874a04c8b0706047f78dc97f49b7841307f64198678f03a3336ad2675
data/.gitignore CHANGED
@@ -27,5 +27,6 @@ lib/parser/ruby22.rb
27
27
  lib/parser/ruby23.rb
28
28
  lib/parser/ruby24.rb
29
29
  lib/parser/ruby25.rb
30
+ lib/parser/ruby26.rb
30
31
  lib/parser/macruby.rb
31
32
  lib/parser/rubymotion.rb
@@ -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
@@ -30,6 +30,7 @@ GENERATED_FILES = %w(lib/parser/lexer.rb
30
30
  lib/parser/ruby23.rb
31
31
  lib/parser/ruby24.rb
32
32
  lib/parser/ruby25.rb
33
+ lib/parser/ruby26.rb
33
34
  lib/parser/macruby.rb
34
35
  lib/parser/rubymotion.rb)
35
36
 
@@ -8,3 +8,4 @@ require 'parser/ruby22'
8
8
  require 'parser/ruby23'
9
9
  require 'parser/ruby24'
10
10
  require 'parser/ruby25'
11
+ require 'parser/ruby26'
@@ -527,7 +527,7 @@ module Parser
527
527
  node.updated(:gvasgn)
528
528
 
529
529
  when :const
530
- if @parser.context.indirectly_in_def?
530
+ unless @parser.context.dynamic_const_definition_allowed?
531
531
  diagnostic :error, :dynamic_const, nil, node.loc.expression
532
532
  end
533
533
 
@@ -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
@@ -30,7 +30,7 @@ module Parser
30
30
  CurrentRuby = Ruby21
31
31
 
32
32
  when /^2\.2\./
33
- current_version = '2.2.9'
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.6'
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.3'
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.0'
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'
@@ -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
- if new_literal.words? && new_literal.backslash_delimited?
384
- if new_literal.interpolate?
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 new_literal.words? && !new_literal.backslash_delimited?
390
- if new_literal.interpolate?
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 !new_literal.words? && new_literal.backslash_delimited?
396
- if new_literal.interpolate?
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 new_literal.interpolate?
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 *stack_pop;
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
- fcall expr_value;
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.dup.force_encoding(Encoding::BINARY)[0].ord)
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
- ( e_lparen
2210
- | operator_arithmetic
2211
- | operator_rest
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
- fnext expr_endarg;
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 @at_line_begin
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 - 1
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
@@ -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
@@ -1128,7 +1128,7 @@ rule
1128
1128
  }
1129
1129
  bodystmt kEND
1130
1130
  {
1131
- if @context.indirectly_in_def?
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
- if @context.indirectly_in_def?
1166
+ unless @context.module_definition_allowed?
1167
1167
  diagnostic :error, :module_in_def, nil, val[0]
1168
1168
  end
1169
1169
 
@@ -1128,7 +1128,7 @@ rule
1128
1128
  }
1129
1129
  bodystmt kEND
1130
1130
  {
1131
- if @context.indirectly_in_def?
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
- if @context.indirectly_in_def?
1162
+ unless @context.module_definition_allowed?
1163
1163
  diagnostic :error, :module_in_def, nil, val[0]
1164
1164
  end
1165
1165
 
@@ -1095,7 +1095,7 @@ rule
1095
1095
  }
1096
1096
  bodystmt kEND
1097
1097
  {
1098
- if @context.indirectly_in_def?
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
- if @context.indirectly_in_def?
1133
+ unless @context.module_definition_allowed?
1134
1134
  diagnostic :error, :module_in_def, nil, val[0]
1135
1135
  end
1136
1136
 
@@ -1125,7 +1125,7 @@ rule
1125
1125
  }
1126
1126
  bodystmt kEND
1127
1127
  {
1128
- if @context.indirectly_in_def?
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
- if @context.indirectly_in_def?
1163
+ unless @context.module_definition_allowed?
1164
1164
  diagnostic :error, :module_in_def, nil, val[0]
1165
1165
  end
1166
1166
 
@@ -1115,7 +1115,7 @@ rule
1115
1115
  }
1116
1116
  bodystmt kEND
1117
1117
  {
1118
- if @context.indirectly_in_def?
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
- if @context.indirectly_in_def?
1153
+ unless @context.module_definition_allowed?
1154
1154
  diagnostic :error, :module_in_def, nil, val[0]
1155
1155
  end
1156
1156