parser 2.5.0.0 → 2.5.0.1

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