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 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