parser 2.5.0.0 → 2.5.0.1

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
  SHA1:
3
- metadata.gz: 17012e63bed58664c7f879ca77f492e6d551962a
4
- data.tar.gz: 1ba7782eabfc5d33ffbcd5a3f5c7ce1b149e0eb1
3
+ metadata.gz: 9ee63d086cc3d7ade55f51e03ac92d6f88315fb7
4
+ data.tar.gz: 8efdd495d4866bfb27db7b0b15be94515b18a91f
5
5
  SHA512:
6
- metadata.gz: 88787ec044608f586f8d1f9f2ced18005d1af68b5ff6f4cfc7633161bb8e6004aac032803da28c2b37255f98023b47c33d322806096239b1166dc117bf6a1459
7
- data.tar.gz: 564a7e7e4e75bb412677011482eef36cff953fd023f3b889f0bc922ec0f51e36d6110cd1f01cc18d0d670a286a71aa58b8ad2ef3b268c7582e3afbe4cd45e442
6
+ metadata.gz: ae6472a338db72f9d422633eeb83fb6ba37f3f07e99f89d8d2661b840a08177aaffb2ffa8677a7d826f86278c94ba2434b68e00e265d43e7da3ca4998fceeb49
7
+ data.tar.gz: 382b2d934d537bf496e74911a25a7caf286192955a50698f4a0c7b80d5b0f852feebd51d6beb0cd12381052960ab0c4687e26e965a43cab36269ec9919bf730e
@@ -1,8 +1,23 @@
1
1
  Changelog
2
2
  =========
3
3
 
4
- Not released (2018-02-16)
5
- -------------------------
4
+ v2.5.0.1 (2018-02-21)
5
+ ---------------------
6
+
7
+ Features implemented:
8
+ * builders/default: __ENCODING__: emit as s(:__ENCODING__) via AST opt-in. (whitequark)
9
+ * ruby25.y: Extract expr_value_do rule. This commit tracks upstream commit ruby/ruby@508533f. (Ilya Bylich)
10
+ * ruby25.y: Extract begin_block rule. This commit tracks upstream commit ruby/ruby@762d23c. (Ilya Bylich)
11
+ * ruby25.y: Allow class and method definition in the while condition. (#432) (Ilya Bylich)
12
+ * ruby25: Allow `-> do rescue; end`. (#431) (Ilya Bylich)
13
+
14
+ Bugs fixed:
15
+ * parser/current: latest released Ruby series is 2.5.x. (whitequark)
16
+ * builders/default: x[], x[]=1: emit as s(:index), s(:indexasgn) via AST opt-in. (whitequark)
17
+ * lexer.rl: "#{-> foo {}}": fix parsing of interpolated lambda with open args. (Ilya Bylich)
18
+
19
+ v2.5.0.0 (2018-02-16)
20
+ ---------------------
6
21
 
7
22
  API modifications:
8
23
  * Parser::Current: bump to 2.2.9 and 2.3.6. (Stan Hu)
data/README.md CHANGED
@@ -24,8 +24,10 @@ below for explanation of `emit_*` calls):
24
24
 
25
25
  require 'parser/current'
26
26
  # opt-in to most recent AST format:
27
- Parser::Builders::Default.emit_lambda = true
27
+ Parser::Builders::Default.emit_lambda = true
28
28
  Parser::Builders::Default.emit_procarg0 = true
29
+ Parser::Builders::Default.emit_encoding = true
30
+ Parser::Builders::Default.emit_index = true
29
31
 
30
32
  Parse a chunk of code:
31
33
 
data/Rakefile CHANGED
@@ -104,7 +104,7 @@ task :changelog do
104
104
 
105
105
  current_version = "#{$1} (#{date})" if version =~ /(v[\d\w.]+)/
106
106
  current_version = "Not released (#{date})" \
107
- if version =~ /(^| |\/)#{Regexp.escape branch}$/
107
+ if version =~ /(^| |\/)#{Regexp.escape branch}$/ && !branch.start_with?('v')
108
108
 
109
109
  next if current_version.nil?
110
110
  changelog[current_version] # add a hash
@@ -1081,18 +1081,6 @@ Format:
1081
1081
  ~ selector
1082
1082
  ^ operator
1083
1083
  ~~~~~~~~~ expression
1084
-
1085
- (send (lvar :foo) :[] (int 1))
1086
- "foo[i]"
1087
- ~~~ selector
1088
- ~~~~~~ expression
1089
-
1090
- (send (lvar :bar) :[]= (int 1) (int 2) (lvar :baz))
1091
- "bar[1, 2] = baz"
1092
- ~~~~~~ selector
1093
- ^ operator
1094
- ~~~~~~~~~~~~~~~ expression
1095
-
1096
1084
  ~~~
1097
1085
 
1098
1086
  ### To superclass
@@ -1135,6 +1123,26 @@ Format:
1135
1123
  ~~~~~~~~~~ expression
1136
1124
  ~~~
1137
1125
 
1126
+ ### Indexing
1127
+
1128
+ Format:
1129
+
1130
+ ~~~
1131
+ (index (lvar :foo) (int 1))
1132
+ "foo[1]"
1133
+ ^ begin
1134
+ ^ end
1135
+ ~~~~~~ expression
1136
+
1137
+ (indexasgn (lvar :bar) (int 1) (int 2) (lvar :baz))
1138
+ "bar[1, 2] = baz"
1139
+ ^ begin
1140
+ ^ end
1141
+ ^ operator
1142
+ ~~~~~~~~~~~~~~~ expression
1143
+
1144
+ ~~~
1145
+
1138
1146
  ### Passing a literal block
1139
1147
 
1140
1148
  ~~~
@@ -1676,3 +1684,35 @@ Format:
1676
1684
  ~~ selector
1677
1685
  ~~~~~~~~~~~~~~~~~~~~~~ expression
1678
1686
  ~~~
1687
+
1688
+ ## Special constants
1689
+
1690
+ ### File
1691
+
1692
+ Format:
1693
+
1694
+ ~~~
1695
+ (__FILE__)
1696
+ "__FILE__"
1697
+ ~~~~~~~~ expression
1698
+ ~~~
1699
+
1700
+ ### Line
1701
+
1702
+ Format:
1703
+
1704
+ ~~~
1705
+ (__LINE__)
1706
+ "__LINE__"
1707
+ ~~~~~~~~ expression
1708
+ ~~~
1709
+
1710
+ ### Encoding
1711
+
1712
+ Format:
1713
+
1714
+ ~~~
1715
+ (__ENCODING__)
1716
+ "__ENCODING__"
1717
+ ~~~~~~~~~~~~ expression
1718
+ ~~~
@@ -47,6 +47,7 @@ module Parser
47
47
  require 'parser/source/map/keyword'
48
48
  require 'parser/source/map/definition'
49
49
  require 'parser/source/map/send'
50
+ require 'parser/source/map/index'
50
51
  require 'parser/source/map/condition'
51
52
  require 'parser/source/map/ternary'
52
53
  require 'parser/source/map/for'
@@ -31,10 +31,10 @@ module Parser
31
31
  # all new code should set this attribute to true.
32
32
  #
33
33
  # If set to false (the default), arguments of `m { |a| }` are emitted as
34
- # `s(:args, s(:arg, :a))`
34
+ # `s(:args, s(:arg, :a))`.
35
35
  #
36
36
  # If set to true, arguments of `m { |a| }` are emitted as
37
- # `s(:args, s(:procarg0, :a))
37
+ # `s(:args, s(:procarg0, :a)).
38
38
  #
39
39
  # @return [Boolean]
40
40
  attr_accessor :emit_procarg0
@@ -42,12 +42,54 @@ module Parser
42
42
 
43
43
  @emit_procarg0 = false
44
44
 
45
+ class << self
46
+ ##
47
+ # AST compatibility attribute; locations of `__ENCODING__` are not the same
48
+ # as locations of `Encoding::UTF_8` causing problems during rewriting,
49
+ # all new code should set this attribute to true.
50
+ #
51
+ # If set to false (the default), `__ENCODING__` is emitted as
52
+ # ` s(:const, s(:const, nil, :Encoding), :UTF_8)`.
53
+ #
54
+ # If set to true, `__ENCODING__` is emitted as
55
+ # `s(:__ENCODING__)`.
56
+ #
57
+ # @return [Boolean]
58
+ attr_accessor :emit_encoding
59
+ end
60
+
61
+ @emit_encoding = false
62
+
63
+ class << self
64
+ ##
65
+ # AST compatibility attribute; indexed assignment, `x[] = 1`, is not
66
+ # semantically equivalent to calling the method directly, `x.[]=(1)`.
67
+ # Specifically, in the former case, the expression's value is always 1,
68
+ # and in the latter case, the expression's value is the return value
69
+ # of the `[]=` method.
70
+ #
71
+ # If set to false (the default), `self[1]` is emitted as
72
+ # `s(:send, s(:self), :[], s(:int, 1))`, and `self[1] = 2` is
73
+ # emitted as `s(:send, s(:self), :[]=, s(:int, 1), s(:int, 2))`.
74
+ #
75
+ # If set to true, `self[1]` is emitted as
76
+ # `s(:index, s(:self), s(:int, 1))`, and `self[1] = 2` is
77
+ # emitted as `s(:indexasgn, s(:self), s(:int, 1), s(:int, 2))`.
78
+ #
79
+ # @return [Boolean]
80
+ attr_accessor :emit_index
81
+ end
82
+
83
+ @emit_index = false
84
+
45
85
  class << self
46
86
  ##
47
87
  # @api private
48
88
  def modernize
49
89
  @emit_lambda = true
50
90
  @emit_procarg0 = true
91
+ @emit_encoding = true
92
+ @emit_index = true
51
93
  end
52
94
  end
53
95
 
@@ -56,7 +98,7 @@ module Parser
56
98
  attr_accessor :parser
57
99
 
58
100
  ##
59
- # If set to true, `__FILE__` and `__LINE__` are transformed to
101
+ # If set to true (the default), `__FILE__` and `__LINE__` are transformed to
60
102
  # literal nodes. For example, `s(:str, "lib/foo.rb")` and `s(:int, 10)`.
61
103
  #
62
104
  # If set to false, `__FILE__` and `__LINE__` are emitted as-is,
@@ -424,8 +466,12 @@ module Parser
424
466
  end
425
467
 
426
468
  when :__ENCODING__
427
- n(:const, [ n(:const, [ nil, :Encoding], nil), :UTF_8 ],
428
- node.loc.dup)
469
+ if !self.class.emit_encoding
470
+ n(:const, [ n(:const, [ nil, :Encoding], nil), :UTF_8 ],
471
+ node.loc.dup)
472
+ else
473
+ node
474
+ end
429
475
 
430
476
  when :ident
431
477
  name, = *node
@@ -515,12 +561,16 @@ module Parser
515
561
 
516
562
  def op_assign(lhs, op_t, rhs)
517
563
  case lhs.type
518
- when :gvasgn, :ivasgn, :lvasgn, :cvasgn, :casgn, :send, :csend
564
+ when :gvasgn, :ivasgn, :lvasgn, :cvasgn, :casgn, :send, :csend, :index
519
565
  operator = value(op_t)[0..-1].to_sym
520
566
  source_map = lhs.loc.
521
567
  with_operator(loc(op_t)).
522
568
  with_expression(join_exprs(lhs, rhs))
523
569
 
570
+ if lhs.type == :index
571
+ lhs = lhs.updated(:indexasgn)
572
+ end
573
+
524
574
  case operator
525
575
  when :'&&'
526
576
  n(:and_asgn, [ lhs, rhs ], source_map)
@@ -785,7 +835,7 @@ module Parser
785
835
  diagnostic :error, :block_and_blockarg, nil, last_arg.loc.expression, [loc(begin_t)]
786
836
  end
787
837
 
788
- if [:send, :csend, :super, :zsuper, :lambda].include?(method_call.type)
838
+ if [:send, :csend, :index, :super, :zsuper, :lambda].include?(method_call.type)
789
839
  n(:block, [ method_call, args, body ],
790
840
  block_map(method_call.loc.expression, begin_t, end_t))
791
841
  else
@@ -825,14 +875,24 @@ module Parser
825
875
  end
826
876
 
827
877
  def index(receiver, lbrack_t, indexes, rbrack_t)
828
- n(:send, [ receiver, :[], *indexes ],
829
- send_index_map(receiver, lbrack_t, rbrack_t))
878
+ if self.class.emit_index
879
+ n(:index, [ receiver, *indexes ],
880
+ index_map(receiver, lbrack_t, rbrack_t))
881
+ else
882
+ n(:send, [ receiver, :[], *indexes ],
883
+ send_index_map(receiver, lbrack_t, rbrack_t))
884
+ end
830
885
  end
831
886
 
832
887
  def index_asgn(receiver, lbrack_t, indexes, rbrack_t)
833
- # Incomplete method call.
834
- n(:send, [ receiver, :[]=, *indexes ],
835
- send_index_map(receiver, lbrack_t, rbrack_t))
888
+ if self.class.emit_index
889
+ n(:indexasgn, [ receiver, *indexes ],
890
+ index_map(receiver, lbrack_t, rbrack_t))
891
+ else
892
+ # Incomplete method call.
893
+ n(:send, [ receiver, :[]=, *indexes ],
894
+ send_index_map(receiver, lbrack_t, rbrack_t))
895
+ end
836
896
  end
837
897
 
838
898
  def binary_op(receiver, operator_t, arg)
@@ -1411,6 +1471,11 @@ module Parser
1411
1471
  expr_l)
1412
1472
  end
1413
1473
 
1474
+ def index_map(receiver_e, lbrack_t, rbrack_t)
1475
+ Source::Map::Index.new(loc(lbrack_t), loc(rbrack_t),
1476
+ receiver_e.loc.expression.join(loc(rbrack_t)))
1477
+ end
1478
+
1414
1479
  def send_index_map(receiver_e, lbrack_t, rbrack_t)
1415
1480
  Source::Map::Send.new(nil, loc(lbrack_t).join(loc(rbrack_t)),
1416
1481
  nil, nil,
@@ -67,8 +67,8 @@ module Parser
67
67
 
68
68
  else # :nocov:
69
69
  # Keep this in sync with released Ruby.
70
- warn_syntax_deviation 'parser/ruby24', '2.4.x'
71
- require 'parser/ruby24'
72
- CurrentRuby = Ruby24
70
+ warn_syntax_deviation 'parser/ruby25', '2.5.x'
71
+ require 'parser/ruby25'
72
+ CurrentRuby = Ruby25
73
73
  end
74
74
  end
@@ -89,7 +89,7 @@ class Parser::Lexer
89
89
 
90
90
  REGEXP_META_CHARACTERS = Regexp.union(*"\\$()*+.<>?[]^{|}".chars).freeze
91
91
 
92
- attr_reader :source_buffer
92
+ attr_reader :source_buffer, :last_token
93
93
 
94
94
  attr_accessor :diagnostics
95
95
  attr_accessor :static_env
@@ -175,6 +175,9 @@ class Parser::Lexer
175
175
 
176
176
  # State before =begin / =end block comment
177
177
  @cs_before_block_comment = self.class.lex_en_line_begin
178
+
179
+ # Last emitted token
180
+ @last_token = nil
178
181
  end
179
182
 
180
183
  def source_buffer=(source_buffer)
@@ -325,6 +328,7 @@ class Parser::Lexer
325
328
  token = [ type, [ value, range(s, e) ] ]
326
329
 
327
330
  @token_queue.push(token)
331
+ @last_token = token
328
332
 
329
333
  @tokens.push(token) if @tokens
330
334
 
@@ -1433,12 +1437,12 @@ class Parser::Lexer
1433
1437
  w_space* e_lbrace
1434
1438
  => {
1435
1439
  if @lambda_stack.last == @paren_nest
1436
- p = @ts - 1
1437
- fgoto expr_end;
1440
+ @lambda_stack.pop
1441
+ emit(:tLAMBEG, '{'.freeze, @te - 1, @te)
1438
1442
  else
1439
1443
  emit(:tLCURLY, '{'.freeze, @te - 1, @te)
1440
- fnext expr_value; fbreak;
1441
1444
  end
1445
+ fnext expr_value; fbreak;
1442
1446
  };
1443
1447
 
1444
1448
  #
@@ -22,7 +22,7 @@ module Parser
22
22
  and not or if when case while until while_post
23
23
  until_post for break next redo return resbody
24
24
  kwbegin begin retry preexe postexe iflipflop eflipflop
25
- shadowarg complex rational __FILE__ __LINE__
25
+ shadowarg complex rational __FILE__ __LINE__ __ENCODING__
26
26
  ).map(&:to_sym).to_set.freeze
27
27
 
28
28
  end # Meta
@@ -850,7 +850,28 @@ rule
850
850
  }
851
851
 
852
852
  command_args: {
853
- @lexer.cmdarg.push(true)
853
+ # When branch gets invoked by RACC's lookahead
854
+ # and command args start with '[' or '('
855
+ # we need to put `true` to the cmdarg stack
856
+ # **before** `false` pushed by lexer
857
+ # m [], n
858
+ # ^
859
+ # Right here we have cmdarg [...0] because
860
+ # lexer pushed it on '['
861
+ # We need to modify cmdarg stack to [...10]
862
+ #
863
+ # For all other cases (like `m n` or `m n, []`) we simply put 1 to the stack
864
+ # and later lexer pushes corresponding bits on top of it.
865
+ last_token = @lexer.last_token[0]
866
+ lookahead = last_token == :tLBRACK || last_token == :tLPAREN_ARG
867
+
868
+ if lookahead
869
+ top = @lexer.cmdarg.pop
870
+ @lexer.cmdarg.push(true)
871
+ @lexer.cmdarg.push(top)
872
+ else
873
+ @lexer.cmdarg.push(true)
874
+ end
854
875
  }
855
876
  call_args
856
877
  {
@@ -1836,7 +1857,7 @@ regexp_contents: # nothing
1836
1857
  }
1837
1858
  compstmt tSTRING_DEND
1838
1859
  {
1839
- @lexer.cond.lexpop
1860
+ @lexer.cond.pop
1840
1861
  @lexer.cmdarg.pop
1841
1862
 
1842
1863
  result = @builder.begin(val[0], val[2], val[3])
@@ -71,9 +71,14 @@ rule
71
71
  }
72
72
 
73
73
  top_stmt: stmt
74
- | klBEGIN tLCURLY top_compstmt tRCURLY
74
+ | klBEGIN begin_block
75
75
  {
76
- result = @builder.preexe(val[0], val[1], val[2], val[3])
76
+ result = @builder.preexe(val[0], *val[1])
77
+ }
78
+
79
+ begin_block: tLCURLY top_compstmt tRCURLY
80
+ {
81
+ result = val
77
82
  }
78
83
 
79
84
  bodystmt: compstmt opt_rescue opt_else opt_ensure
@@ -115,7 +120,7 @@ rule
115
120
  }
116
121
 
117
122
  stmt_or_begin: stmt
118
- | klBEGIN tLCURLY top_compstmt tRCURLY
123
+ | klBEGIN begin_block
119
124
  {
120
125
  diagnostic :error, :begin_in_method, nil, val[0]
121
126
  }
@@ -273,6 +278,15 @@ rule
273
278
 
274
279
  expr_value: expr
275
280
 
281
+ expr_value_do: {
282
+ @lexer.cond.push(true)
283
+ }
284
+ expr_value do
285
+ {
286
+ @lexer.cond.pop
287
+ result = [ val[1], val[2] ]
288
+ }
289
+
276
290
  command_call: command
277
291
  | block_command
278
292
 
@@ -846,7 +860,28 @@ rule
846
860
  }
847
861
 
848
862
  command_args: {
849
- @lexer.cmdarg.push(true)
863
+ # When branch gets invoked by RACC's lookahead
864
+ # and command args start with '[' or '('
865
+ # we need to put `true` to the cmdarg stack
866
+ # **before** `false` pushed by lexer
867
+ # m [], n
868
+ # ^
869
+ # Right here we have cmdarg [...0] because
870
+ # lexer pushed it on '['
871
+ # We need to modify cmdarg stack to [...10]
872
+ #
873
+ # For all other cases (like `m n` or `m n, []`) we simply put 1 to the stack
874
+ # and later lexer pushes corresponding bits on top of it.
875
+ last_token = @lexer.last_token[0]
876
+ lookahead = last_token == :tLBRACK || last_token == :tLPAREN_ARG
877
+
878
+ if lookahead
879
+ top = @lexer.cmdarg.pop
880
+ @lexer.cmdarg.push(true)
881
+ @lexer.cmdarg.push(top)
882
+ else
883
+ @lexer.cmdarg.push(true)
884
+ end
850
885
  }
851
886
  call_args
852
887
  {
@@ -1039,31 +1074,13 @@ rule
1039
1074
  else_, else_t,
1040
1075
  val[3], val[5])
1041
1076
  }
1042
- | kWHILE
1077
+ | kWHILE expr_value_do compstmt kEND
1043
1078
  {
1044
- @lexer.cond.push(true)
1045
- }
1046
- expr_value do
1047
- {
1048
- @lexer.cond.pop
1079
+ result = @builder.loop(:while, val[0], *val[1], val[2], val[3])
1049
1080
  }
1050
- compstmt kEND
1081
+ | kUNTIL expr_value_do compstmt kEND
1051
1082
  {
1052
- result = @builder.loop(:while, val[0], val[2], val[3],
1053
- val[5], val[6])
1054
- }
1055
- | kUNTIL
1056
- {
1057
- @lexer.cond.push(true)
1058
- }
1059
- expr_value do
1060
- {
1061
- @lexer.cond.pop
1062
- }
1063
- compstmt kEND
1064
- {
1065
- result = @builder.loop(:until, val[0], val[2], val[3],
1066
- val[5], val[6])
1083
+ result = @builder.loop(:until, val[0], *val[1], val[2], val[3])
1067
1084
  }
1068
1085
  | kCASE expr_value opt_terms case_body kEND
1069
1086
  {
@@ -1081,24 +1098,15 @@ rule
1081
1098
  when_bodies, else_t, else_body,
1082
1099
  val[3])
1083
1100
  }
1084
- | kFOR for_var kIN
1085
- {
1086
- @lexer.cond.push(true)
1087
- }
1088
- expr_value do
1101
+ | kFOR for_var kIN expr_value_do compstmt kEND
1089
1102
  {
1090
- @lexer.cond.pop
1091
- }
1092
- compstmt kEND
1093
- {
1094
- result = @builder.for(val[0], val[1],
1095
- val[2], val[4],
1096
- val[5], val[7], val[8])
1103
+ result = @builder.for(val[0], val[1], val[2], *val[3], val[4], val[5])
1097
1104
  }
1098
1105
  | kCLASS cpath superclass
1099
1106
  {
1100
1107
  @static_env.extend_static
1101
1108
  @lexer.push_cmdarg
1109
+ @lexer.push_cond
1102
1110
  @context.push(:class)
1103
1111
  }
1104
1112
  bodystmt kEND
@@ -1113,6 +1121,7 @@ rule
1113
1121
  val[4], val[5])
1114
1122
 
1115
1123
  @lexer.pop_cmdarg
1124
+ @lexer.pop_cond
1116
1125
  @static_env.unextend
1117
1126
  @context.pop
1118
1127
  }
@@ -1120,6 +1129,7 @@ rule
1120
1129
  {
1121
1130
  @static_env.extend_static
1122
1131
  @lexer.push_cmdarg
1132
+ @lexer.push_cond
1123
1133
  @context.push(:sclass)
1124
1134
  }
1125
1135
  bodystmt kEND
@@ -1128,6 +1138,7 @@ rule
1128
1138
  val[5], val[6])
1129
1139
 
1130
1140
  @lexer.pop_cmdarg
1141
+ @lexer.pop_cond
1131
1142
  @static_env.unextend
1132
1143
  @context.pop
1133
1144
  }
@@ -1152,6 +1163,7 @@ rule
1152
1163
  {
1153
1164
  @static_env.extend_static
1154
1165
  @lexer.push_cmdarg
1166
+ @lexer.push_cond
1155
1167
  @context.push(:def)
1156
1168
  }
1157
1169
  f_arglist bodystmt kEND
@@ -1160,6 +1172,7 @@ rule
1160
1172
  val[3], val[4], val[5])
1161
1173
 
1162
1174
  @lexer.pop_cmdarg
1175
+ @lexer.pop_cond
1163
1176
  @static_env.unextend
1164
1177
  @context.pop
1165
1178
  }
@@ -1171,6 +1184,7 @@ rule
1171
1184
  {
1172
1185
  @static_env.extend_static
1173
1186
  @lexer.push_cmdarg
1187
+ @lexer.push_cond
1174
1188
  @context.push(:defs)
1175
1189
  }
1176
1190
  f_arglist bodystmt kEND
@@ -1179,6 +1193,7 @@ rule
1179
1193
  val[4], val[6], val[7], val[8])
1180
1194
 
1181
1195
  @lexer.pop_cmdarg
1196
+ @lexer.pop_cond
1182
1197
  @static_env.unextend
1183
1198
  @context.pop
1184
1199
  }
@@ -1497,7 +1512,7 @@ opt_block_args_tail:
1497
1512
  {
1498
1513
  @context.push(:lambda)
1499
1514
  }
1500
- compstmt kEND
1515
+ bodystmt kEND
1501
1516
  {
1502
1517
  result = [ val[0], val[2], val[3] ]
1503
1518
  @context.pop
@@ -1839,7 +1854,7 @@ regexp_contents: # nothing
1839
1854
  }
1840
1855
  compstmt tSTRING_DEND
1841
1856
  {
1842
- @lexer.cond.lexpop
1857
+ @lexer.cond.pop
1843
1858
  @lexer.cmdarg.pop
1844
1859
 
1845
1860
  result = @builder.begin(val[0], val[2], val[3])
@@ -29,7 +29,7 @@ module Parser
29
29
  # @api private
30
30
  #
31
31
  ENCODING_RE =
32
- /\A\#\s*(en)?coding\s*[:=]\s*
32
+ /[\s#](en)?coding\s*[:=]\s*
33
33
  (
34
34
  # Special-case: there's a UTF8-MAC encoding.
35
35
  (utf8-mac)
@@ -63,6 +63,8 @@ module Parser
63
63
  encoding_line = first_line
64
64
  end
65
65
 
66
+ return nil if encoding_line[0] != '#'
67
+
66
68
  if (result = ENCODING_RE.match(encoding_line))
67
69
  Encoding.find(result[3] || result[4] || result[6])
68
70
  else
@@ -0,0 +1,33 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Parser
4
+ module Source
5
+
6
+ class Map::Index < Map
7
+ attr_reader :begin
8
+ attr_reader :end
9
+ attr_reader :operator
10
+
11
+ def initialize(begin_l, end_l, expression_l)
12
+ @begin, @end = begin_l, end_l
13
+ @operator = nil
14
+
15
+ super(expression_l)
16
+ end
17
+
18
+ ##
19
+ # @api private
20
+ #
21
+ def with_operator(operator_l)
22
+ with { |map| map.update_operator(operator_l) }
23
+ end
24
+
25
+ protected
26
+
27
+ def update_operator(operator_l)
28
+ @operator = operator_l
29
+ end
30
+ end
31
+
32
+ end
33
+ end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Parser
4
- VERSION = '2.5.0.0'
4
+ VERSION = '2.5.0.1'
5
5
  end
@@ -87,4 +87,12 @@ class TestEncoding < Minitest::Test
87
87
  assert_equal Encoding::KOI8_R, recognize('#encoding:koi8-r')
88
88
  assert_equal Encoding::KOI8_R, recognize('#coding:koi8-r')
89
89
  end
90
+
91
+ def test_underscore_and_star_characters
92
+ assert_equal Encoding::KOI8_R, recognize('# -*- encoding: koi8-r -*-')
93
+ end
94
+
95
+ def test_garbage_around_encoding_comment
96
+ assert_equal Encoding::KOI8_R, recognize('# 1$# -*- &)* encoding: koi8-r 1$# -*- &)*')
97
+ end
90
98
  end
@@ -924,11 +924,22 @@ class TestParser < Minitest::Test
924
924
  end
925
925
 
926
926
  def test___ENCODING__
927
+ assert_parses(
928
+ s(:__ENCODING__),
929
+ %q{__ENCODING__},
930
+ %q{~~~~~~~~~~~~ expression},
931
+ SINCE_1_9)
932
+ end
933
+
934
+ def test___ENCODING___legacy_
935
+ Parser::Builders::Default.emit_encoding = false
927
936
  assert_parses(
928
937
  s(:const, s(:const, nil, :Encoding), :UTF_8),
929
938
  %q{__ENCODING__},
930
939
  %q{~~~~~~~~~~~~ expression},
931
940
  SINCE_1_9)
941
+ ensure
942
+ Parser::Builders::Default.emit_encoding = true
932
943
  end
933
944
 
934
945
  # defined?
@@ -1270,13 +1281,14 @@ class TestParser < Minitest::Test
1270
1281
  s(:masgn,
1271
1282
  s(:mlhs,
1272
1283
  s(:send, s(:self), :a=),
1273
- s(:send, s(:self), :[]=, s(:int, 1), s(:int, 2))),
1284
+ s(:indexasgn, s(:self), s(:int, 1), s(:int, 2))),
1274
1285
  s(:lvar, :foo)),
1275
1286
  %q{self.a, self[1, 2] = foo},
1276
- %q{~~~~~~ expression (mlhs.send/1)
1277
- | ~ selector (mlhs.send/1)
1278
- | ~~~~~~ selector (mlhs.send/2)
1279
- | ~~~~~~~~~~ expression (mlhs.send/2)})
1287
+ %q{~~~~~~ expression (mlhs.send)
1288
+ | ~ selector (mlhs.send)
1289
+ | ^ begin (mlhs.indexasgn)
1290
+ | ^ end (mlhs.indexasgn)
1291
+ | ~~~~~~~~~~ expression (mlhs.indexasgn)})
1280
1292
 
1281
1293
  assert_parses(
1282
1294
  s(:masgn,
@@ -1541,20 +1553,21 @@ class TestParser < Minitest::Test
1541
1553
  def test_op_asgn_index
1542
1554
  assert_parses(
1543
1555
  s(:op_asgn,
1544
- s(:send, s(:lvar, :foo), :[],
1556
+ s(:indexasgn, s(:lvar, :foo),
1545
1557
  s(:int, 0), s(:int, 1)), :+,
1546
1558
  s(:int, 2)),
1547
1559
  %q{foo[0, 1] += 2},
1548
1560
  %q{ ^^ operator
1549
- | ~~~~~~ selector (send)
1550
- |~~~~~~~~~ expression (send)
1561
+ | ^ begin (indexasgn)
1562
+ | ^ end (indexasgn)
1563
+ |~~~~~~~~~ expression (indexasgn)
1551
1564
  |~~~~~~~~~~~~~~ expression})
1552
1565
  end
1553
1566
 
1554
1567
  def test_op_asgn_index_cmd
1555
1568
  assert_parses(
1556
1569
  s(:op_asgn,
1557
- s(:send, s(:lvar, :foo), :[],
1570
+ s(:indexasgn, s(:lvar, :foo),
1558
1571
  s(:int, 0), s(:int, 1)), :+,
1559
1572
  s(:send, nil, :m, s(:lvar, :foo))),
1560
1573
  %q{foo[0, 1] += m foo})
@@ -1610,13 +1623,14 @@ class TestParser < Minitest::Test
1610
1623
 
1611
1624
  assert_parses(
1612
1625
  s(:or_asgn,
1613
- s(:send, s(:lvar, :foo), :[],
1626
+ s(:indexasgn, s(:lvar, :foo),
1614
1627
  s(:int, 0), s(:int, 1)),
1615
1628
  s(:int, 2)),
1616
1629
  %q{foo[0, 1] ||= 2},
1617
1630
  %q{ ^^^ operator
1618
- | ~~~~~~ selector (send)
1619
- |~~~~~~~~~ expression (send)
1631
+ | ^ begin (indexasgn)
1632
+ | ^ end (indexasgn)
1633
+ |~~~~~~~~~ expression (indexasgn)
1620
1634
  |~~~~~~~~~~~~~~~ expression})
1621
1635
  end
1622
1636
 
@@ -1633,13 +1647,14 @@ class TestParser < Minitest::Test
1633
1647
 
1634
1648
  assert_parses(
1635
1649
  s(:and_asgn,
1636
- s(:send, s(:lvar, :foo), :[],
1650
+ s(:indexasgn, s(:lvar, :foo),
1637
1651
  s(:int, 0), s(:int, 1)),
1638
1652
  s(:int, 2)),
1639
1653
  %q{foo[0, 1] &&= 2},
1640
1654
  %q{ ^^^ operator
1641
- | ~~~~~~ selector (send)
1642
- |~~~~~~~~~ expression (send)
1655
+ | ^ begin (indexasgn)
1656
+ | ^ end (indexasgn)
1657
+ |~~~~~~~~~ expression (indexasgn)
1643
1658
  |~~~~~~~~~~~~~~~ expression})
1644
1659
  end
1645
1660
 
@@ -2617,6 +2632,7 @@ class TestParser < Minitest::Test
2617
2632
  s(:arg, :a)),
2618
2633
  %q{|a|}
2619
2634
  )
2635
+ ensure
2620
2636
  Parser::Builders::Default.emit_procarg0 = true
2621
2637
  end
2622
2638
 
@@ -3346,22 +3362,47 @@ class TestParser < Minitest::Test
3346
3362
  end
3347
3363
 
3348
3364
  def test_send_index
3365
+ assert_parses(
3366
+ s(:index, s(:lvar, :foo),
3367
+ s(:int, 1), s(:int, 2)),
3368
+ %q{foo[1, 2]},
3369
+ %q{ ^ begin
3370
+ | ^ end
3371
+ |~~~~~~~~~ expression})
3372
+ end
3373
+
3374
+ def test_send_index_legacy
3375
+ Parser::Builders::Default.emit_index = false
3349
3376
  assert_parses(
3350
3377
  s(:send, s(:lvar, :foo), :[],
3351
3378
  s(:int, 1), s(:int, 2)),
3352
3379
  %q{foo[1, 2]},
3353
3380
  %q{ ~~~~~~ selector
3354
3381
  |~~~~~~~~~ expression})
3382
+ ensure
3383
+ Parser::Builders::Default.emit_index = true
3355
3384
  end
3356
3385
 
3357
3386
  def test_send_index_cmd
3358
3387
  assert_parses(
3359
- s(:send, s(:lvar, :foo), :[],
3388
+ s(:index, s(:lvar, :foo),
3360
3389
  s(:send, nil, :m, s(:lvar, :bar))),
3361
3390
  %q{foo[m bar]})
3362
3391
  end
3363
3392
 
3364
3393
  def test_send_index_asgn
3394
+ assert_parses(
3395
+ s(:indexasgn, s(:lvar, :foo),
3396
+ s(:int, 1), s(:int, 2), s(:int, 3)),
3397
+ %q{foo[1, 2] = 3},
3398
+ %q{ ^ begin
3399
+ | ^ end
3400
+ | ^ operator
3401
+ |~~~~~~~~~~~~~ expression})
3402
+ end
3403
+
3404
+ def test_send_index_asgn_legacy
3405
+ Parser::Builders::Default.emit_index = false
3365
3406
  assert_parses(
3366
3407
  s(:send, s(:lvar, :foo), :[]=,
3367
3408
  s(:int, 1), s(:int, 2), s(:int, 3)),
@@ -3369,6 +3410,8 @@ class TestParser < Minitest::Test
3369
3410
  %q{ ~~~~~~ selector
3370
3411
  | ^ operator
3371
3412
  |~~~~~~~~~~~~~ expression})
3413
+ ensure
3414
+ Parser::Builders::Default.emit_index = true
3372
3415
  end
3373
3416
 
3374
3417
  def test_send_lambda
@@ -3473,6 +3516,7 @@ class TestParser < Minitest::Test
3473
3516
  | ^ end
3474
3517
  |~~~~~ expression},
3475
3518
  SINCE_1_9)
3519
+ ensure
3476
3520
  Parser::Builders::Default.emit_lambda = true
3477
3521
  end
3478
3522
 
@@ -3698,7 +3742,7 @@ class TestParser < Minitest::Test
3698
3742
 
3699
3743
  def test_args_args_comma
3700
3744
  assert_parses(
3701
- s(:send, s(:lvar, :foo), :[],
3745
+ s(:index, s(:lvar, :foo),
3702
3746
  s(:lvar, :bar)),
3703
3747
  %q{foo[bar,]},
3704
3748
  %q{},
@@ -3739,7 +3783,7 @@ class TestParser < Minitest::Test
3739
3783
 
3740
3784
  def test_args_assocs_comma
3741
3785
  assert_parses(
3742
- s(:send, s(:lvar, :foo), :[],
3786
+ s(:index, s(:lvar, :foo),
3743
3787
  s(:hash, s(:pair, s(:sym, :baz), s(:int, 1)))),
3744
3788
  %q{foo[:baz => 1,]},
3745
3789
  %q{},
@@ -3763,7 +3807,7 @@ class TestParser < Minitest::Test
3763
3807
 
3764
3808
  def test_args_args_assocs_comma
3765
3809
  assert_parses(
3766
- s(:send, s(:lvar, :foo), :[],
3810
+ s(:index, s(:lvar, :foo),
3767
3811
  s(:lvar, :bar),
3768
3812
  s(:hash, s(:pair, s(:sym, :baz), s(:int, 1)))),
3769
3813
  %q{foo[bar, :baz => 1,]},
@@ -5776,8 +5820,8 @@ class TestParser < Minitest::Test
5776
5820
 
5777
5821
  assert_parses(
5778
5822
  s(:op_asgn,
5779
- s(:send,
5780
- s(:lvar, :foo), :[],
5823
+ s(:indexasgn,
5824
+ s(:lvar, :foo),
5781
5825
  s(:int, 0)), :+,
5782
5826
  s(:rescue,
5783
5827
  s(:send, nil, :raise,
@@ -5865,8 +5909,8 @@ class TestParser < Minitest::Test
5865
5909
 
5866
5910
  assert_parses(
5867
5911
  s(:op_asgn,
5868
- s(:send,
5869
- s(:lvar, :foo), :[],
5912
+ s(:indexasgn,
5913
+ s(:lvar, :foo),
5870
5914
  s(:int, 0)), :+,
5871
5915
  s(:rescue,
5872
5916
  s(:send, nil, :raise,
@@ -6484,6 +6528,136 @@ class TestParser < Minitest::Test
6484
6528
  end
6485
6529
  end
6486
6530
 
6531
+ def test_method_definition_in_while_cond
6532
+ assert_parses(
6533
+ s(:while,
6534
+ s(:def, :foo,
6535
+ s(:args),
6536
+ s(:block,
6537
+ s(:send, nil, :tap),
6538
+ s(:args), nil)),
6539
+ s(:break)),
6540
+ %q{while def foo; tap do end; end; break; end},
6541
+ %q{},
6542
+ SINCE_2_5)
6543
+
6544
+ assert_parses(
6545
+ s(:while,
6546
+ s(:defs,
6547
+ s(:self), :foo,
6548
+ s(:args),
6549
+ s(:block,
6550
+ s(:send, nil, :tap),
6551
+ s(:args), nil)),
6552
+ s(:break)),
6553
+ %q{while def self.foo; tap do end; end; break; end},
6554
+ %q{},
6555
+ SINCE_2_5)
6556
+
6557
+ assert_parses(
6558
+ s(:while,
6559
+ s(:def, :foo,
6560
+ s(:args,
6561
+ s(:optarg, :a,
6562
+ s(:block,
6563
+ s(:send, nil, :tap),
6564
+ s(:args), nil))), nil),
6565
+ s(:break)),
6566
+ %q{while def foo a = tap do end; end; break; end},
6567
+ %q{},
6568
+ SINCE_2_5)
6569
+
6570
+ assert_parses(
6571
+ s(:while,
6572
+ s(:defs,
6573
+ s(:self), :foo,
6574
+ s(:args,
6575
+ s(:optarg, :a,
6576
+ s(:block,
6577
+ s(:send, nil, :tap),
6578
+ s(:args), nil))), nil),
6579
+ s(:break)),
6580
+ %q{while def self.foo a = tap do end; end; break; end},
6581
+ %q{},
6582
+ SINCE_2_5)
6583
+ end
6584
+
6585
+ def test_class_definition_in_while_cond
6586
+ assert_parses(
6587
+ s(:while,
6588
+ s(:class,
6589
+ s(:const, nil, :Foo), nil,
6590
+ s(:block,
6591
+ s(:send, nil, :tap),
6592
+ s(:args), nil)),
6593
+ s(:break)),
6594
+ %q{while class Foo; tap do end; end; break; end},
6595
+ %q{},
6596
+ SINCE_2_5)
6597
+
6598
+ assert_parses(
6599
+ s(:while,
6600
+ s(:class,
6601
+ s(:const, nil, :Foo), nil,
6602
+ s(:lvasgn, :a,
6603
+ s(:block,
6604
+ s(:send, nil, :tap),
6605
+ s(:args), nil))),
6606
+ s(:break)),
6607
+ %q{while class Foo a = tap do end; end; break; end},
6608
+ %q{},
6609
+ SINCE_2_5)
6610
+
6611
+ assert_parses(
6612
+ s(:while,
6613
+ s(:sclass,
6614
+ s(:self),
6615
+ s(:block,
6616
+ s(:send, nil, :tap),
6617
+ s(:args), nil)),
6618
+ s(:break)),
6619
+ %q{while class << self; tap do end; end; break; end},
6620
+ %q{},
6621
+ SINCE_2_5)
6622
+
6623
+ assert_parses(
6624
+ s(:while,
6625
+ s(:sclass,
6626
+ s(:self),
6627
+ s(:lvasgn, :a,
6628
+ s(:block,
6629
+ s(:send, nil, :tap),
6630
+ s(:args), nil))),
6631
+ s(:break)),
6632
+ %q{while class << self; a = tap do end; end; break; end},
6633
+ %q{},
6634
+ SINCE_2_5)
6635
+ end
6636
+
6637
+ def test_rescue_in_lambda_block
6638
+ assert_diagnoses(
6639
+ [:error, :unexpected_token, { :token => 'kRESCUE'}],
6640
+ %q{-> do rescue; end},
6641
+ %q{ ~~~~~~ location},
6642
+ SINCE_1_9 - SINCE_2_5)
6643
+
6644
+ assert_parses(
6645
+ s(:block,
6646
+ s(:lambda),
6647
+ s(:args),
6648
+ s(:rescue, nil,
6649
+ s(:resbody, nil, nil, nil), nil)),
6650
+ %q{-> do rescue; end},
6651
+ %q{ ~~~~~~ keyword (rescue.resbody)},
6652
+ SINCE_2_5)
6653
+
6654
+ assert_diagnoses(
6655
+ [:error, :unexpected_token, { :token => 'kRESCUE'}],
6656
+ %q{-> { rescue; }},
6657
+ %q{ ~~~~~~ location},
6658
+ SINCE_1_9)
6659
+ end
6660
+
6487
6661
  def test_ruby_bug_13547
6488
6662
  assert_diagnoses(
6489
6663
  [:error, :unexpected_token, { :token => 'tLCURLY' }],
@@ -6559,8 +6733,8 @@ class TestParser < Minitest::Test
6559
6733
 
6560
6734
  assert_parses(
6561
6735
  s(:block,
6562
- s(:send,
6563
- s(:send, nil, :meth), :[]),
6736
+ s(:index,
6737
+ s(:send, nil, :meth)),
6564
6738
  s(:args), nil),
6565
6739
  %q{meth[] {}},
6566
6740
  %q{},
@@ -6583,4 +6757,28 @@ class TestParser < Minitest::Test
6583
6757
  %q{m /foo/x {}},
6584
6758
  SINCE_2_4)
6585
6759
  end
6760
+
6761
+ def test_bug_447
6762
+ assert_parses(
6763
+ s(:block,
6764
+ s(:send, nil, :m,
6765
+ s(:array)),
6766
+ s(:args), nil),
6767
+ %q{m [] do end},
6768
+ %q{},
6769
+ ALL_VERSIONS)
6770
+ end
6771
+
6772
+ def test_bug_435
6773
+ assert_parses(
6774
+ s(:dstr,
6775
+ s(:begin,
6776
+ s(:block,
6777
+ s(:lambda),
6778
+ s(:args,
6779
+ s(:arg, :foo)), nil))),
6780
+ %q{"#{-> foo {}}"},
6781
+ %q{},
6782
+ SINCE_1_9)
6783
+ end
6586
6784
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: parser
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.5.0.0
4
+ version: 2.5.0.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - whitequark
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2018-02-16 00:00:00.000000000 Z
11
+ date: 2018-02-21 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: ast
@@ -230,6 +230,7 @@ files:
230
230
  - lib/parser/source/map/definition.rb
231
231
  - lib/parser/source/map/for.rb
232
232
  - lib/parser/source/map/heredoc.rb
233
+ - lib/parser/source/map/index.rb
233
234
  - lib/parser/source/map/keyword.rb
234
235
  - lib/parser/source/map/objc_kwarg.rb
235
236
  - lib/parser/source/map/operator.rb