mirror of
https://github.com/ruby/ruby.git
synced 2022-11-09 12:17:21 -05:00
Revert "Method reference operator"
This reverts commit 67c5747369
.
[Feature #16275]
This commit is contained in:
parent
b41a19f92f
commit
fb6a489af2
18 changed files with 5 additions and 141 deletions
3
NEWS
3
NEWS
|
@ -186,9 +186,6 @@ sufficient information, see the ChangeLog file or Redmine
|
||||||
# Previously parsed as: (a, b = raise) rescue [1, 2]
|
# Previously parsed as: (a, b = raise) rescue [1, 2]
|
||||||
# Now parsed as: a, b = (raise rescue [1, 2])
|
# Now parsed as: a, b = (raise rescue [1, 2])
|
||||||
|
|
||||||
* Method reference operator, <code>.:</code> is introduced as an
|
|
||||||
experimental feature. [Feature #12125] [Feature #13581]
|
|
||||||
|
|
||||||
* +yield+ in singleton class syntax is warned and will be deprecated later [Feature #15575].
|
* +yield+ in singleton class syntax is warned and will be deprecated later [Feature #15575].
|
||||||
|
|
||||||
* Argument forwarding by <code>(...)</code> is introduced. [Feature #16253]
|
* Argument forwarding by <code>(...)</code> is introduced. [Feature #16253]
|
||||||
|
|
3
ast.c
3
ast.c
|
@ -432,9 +432,6 @@ node_children(rb_ast_t *ast, NODE *node)
|
||||||
NEW_CHILD(ast, node->nd_args));
|
NEW_CHILD(ast, node->nd_args));
|
||||||
case NODE_VCALL:
|
case NODE_VCALL:
|
||||||
return rb_ary_new_from_args(1, ID2SYM(node->nd_mid));
|
return rb_ary_new_from_args(1, ID2SYM(node->nd_mid));
|
||||||
case NODE_METHREF:
|
|
||||||
return rb_ary_new_from_args(2, NEW_CHILD(ast, node->nd_recv),
|
|
||||||
ID2SYM(node->nd_mid));
|
|
||||||
case NODE_SUPER:
|
case NODE_SUPER:
|
||||||
return rb_ary_new_from_node_args(ast, 1, node->nd_args);
|
return rb_ary_new_from_node_args(ast, 1, node->nd_args);
|
||||||
case NODE_ZSUPER:
|
case NODE_ZSUPER:
|
||||||
|
|
|
@ -4742,11 +4742,9 @@ defined_expr0(rb_iseq_t *iseq, LINK_ANCHOR *const ret,
|
||||||
case NODE_OPCALL:
|
case NODE_OPCALL:
|
||||||
case NODE_VCALL:
|
case NODE_VCALL:
|
||||||
case NODE_FCALL:
|
case NODE_FCALL:
|
||||||
case NODE_METHREF:
|
|
||||||
case NODE_ATTRASGN:{
|
case NODE_ATTRASGN:{
|
||||||
const int explicit_receiver =
|
const int explicit_receiver =
|
||||||
(type == NODE_CALL || type == NODE_OPCALL ||
|
(type == NODE_CALL || type == NODE_OPCALL ||
|
||||||
type == NODE_METHREF ||
|
|
||||||
(type == NODE_ATTRASGN && !private_recv_p(node)));
|
(type == NODE_ATTRASGN && !private_recv_p(node)));
|
||||||
|
|
||||||
if (!lfinish[1] && (node->nd_args || explicit_receiver)) {
|
if (!lfinish[1] && (node->nd_args || explicit_receiver)) {
|
||||||
|
@ -8484,13 +8482,6 @@ iseq_compile_each0(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *node, in
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case NODE_METHREF:
|
|
||||||
CHECK(COMPILE(ret, "receiver", node->nd_recv));
|
|
||||||
ADD_ELEM(ret, &new_insn_body(iseq, line, BIN(methodref), 1, ID2SYM(node->nd_mid))->link);
|
|
||||||
if (popped) {
|
|
||||||
ADD_INSN(ret, line, pop);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
default:
|
default:
|
||||||
UNKNOWN_NODE("iseq_compile_each", node, COMPILE_NG);
|
UNKNOWN_NODE("iseq_compile_each", node, COMPILE_NG);
|
||||||
ng:
|
ng:
|
||||||
|
|
|
@ -130,7 +130,6 @@ token_ops = %[\
|
||||||
ANDOP &&
|
ANDOP &&
|
||||||
OROP ||
|
OROP ||
|
||||||
ANDDOT &.
|
ANDDOT &.
|
||||||
METHREF .:
|
|
||||||
]
|
]
|
||||||
|
|
||||||
class KeywordError < RuntimeError
|
class KeywordError < RuntimeError
|
||||||
|
|
|
@ -474,7 +474,6 @@ count_nodes(int argc, VALUE *argv, VALUE os)
|
||||||
COUNT_NODE(NODE_DSYM);
|
COUNT_NODE(NODE_DSYM);
|
||||||
COUNT_NODE(NODE_ATTRASGN);
|
COUNT_NODE(NODE_ATTRASGN);
|
||||||
COUNT_NODE(NODE_LAMBDA);
|
COUNT_NODE(NODE_LAMBDA);
|
||||||
COUNT_NODE(NODE_METHREF);
|
|
||||||
COUNT_NODE(NODE_ARYPTN);
|
COUNT_NODE(NODE_ARYPTN);
|
||||||
COUNT_NODE(NODE_HSHPTN);
|
COUNT_NODE(NODE_HSHPTN);
|
||||||
#undef COUNT_NODE
|
#undef COUNT_NODE
|
||||||
|
|
|
@ -261,7 +261,6 @@ ripper_token2eventid(enum yytokentype tok)
|
||||||
[tSTAR] = O(op),
|
[tSTAR] = O(op),
|
||||||
[tDSTAR] = O(op),
|
[tDSTAR] = O(op),
|
||||||
[tANDDOT] = O(op),
|
[tANDDOT] = O(op),
|
||||||
[tMETHREF] = O(op),
|
|
||||||
[tSTRING_BEG] = O(tstring_beg),
|
[tSTRING_BEG] = O(tstring_beg),
|
||||||
[tSTRING_CONTENT] = O(tstring_content),
|
[tSTRING_CONTENT] = O(tstring_content),
|
||||||
[tSTRING_DBEG] = O(embexpr_beg),
|
[tSTRING_DBEG] = O(embexpr_beg),
|
||||||
|
|
11
insns.def
11
insns.def
|
@ -719,17 +719,6 @@ checktype
|
||||||
ret = (TYPE(val) == (int)type) ? Qtrue : Qfalse;
|
ret = (TYPE(val) == (int)type) ? Qtrue : Qfalse;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* get frozen method reference. */
|
|
||||||
DEFINE_INSN
|
|
||||||
methodref
|
|
||||||
(ID id)
|
|
||||||
(VALUE val)
|
|
||||||
(VALUE ret)
|
|
||||||
{
|
|
||||||
ret = rb_obj_method(val, ID2SYM(id));
|
|
||||||
RB_OBJ_FREEZE_RAW(ret);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**********************************************************/
|
/**********************************************************/
|
||||||
/* deal with control flow 1: class/module */
|
/* deal with control flow 1: class/module */
|
||||||
/**********************************************************/
|
/**********************************************************/
|
||||||
|
|
|
@ -1781,7 +1781,7 @@ XXX
|
||||||
visit(:complete, typ, opt, icase, *pat) {|o, *sw| return sw}
|
visit(:complete, typ, opt, icase, *pat) {|o, *sw| return sw}
|
||||||
}
|
}
|
||||||
exc = ambiguous ? AmbiguousOption : InvalidOption
|
exc = ambiguous ? AmbiguousOption : InvalidOption
|
||||||
raise exc.new(opt, additional: self.:additional_message.curry[typ])
|
raise exc.new(opt, additional: self.method(:additional_message).curry[typ])
|
||||||
end
|
end
|
||||||
private :complete
|
private :complete
|
||||||
|
|
||||||
|
|
9
node.c
9
node.c
|
@ -954,15 +954,6 @@ dump_node(VALUE buf, VALUE indent, int comment, const NODE * node)
|
||||||
F_NODE(nd_args, "arguments");
|
F_NODE(nd_args, "arguments");
|
||||||
return;
|
return;
|
||||||
|
|
||||||
case NODE_METHREF:
|
|
||||||
ANN("method reference");
|
|
||||||
ANN("format: [nd_recv].:[nd_mid]");
|
|
||||||
ANN("example: foo.:method");
|
|
||||||
F_NODE(nd_recv, "receiver");
|
|
||||||
LAST_NODE;
|
|
||||||
F_ID(nd_mid, "method name");
|
|
||||||
return;
|
|
||||||
|
|
||||||
case NODE_LAMBDA:
|
case NODE_LAMBDA:
|
||||||
ANN("lambda expression");
|
ANN("lambda expression");
|
||||||
ANN("format: -> [nd_body]");
|
ANN("format: -> [nd_body]");
|
||||||
|
|
2
node.h
2
node.h
|
@ -122,7 +122,6 @@ enum node_type {
|
||||||
NODE_DSYM,
|
NODE_DSYM,
|
||||||
NODE_ATTRASGN,
|
NODE_ATTRASGN,
|
||||||
NODE_LAMBDA,
|
NODE_LAMBDA,
|
||||||
NODE_METHREF,
|
|
||||||
NODE_ARYPTN,
|
NODE_ARYPTN,
|
||||||
NODE_HSHPTN,
|
NODE_HSHPTN,
|
||||||
NODE_LAST
|
NODE_LAST
|
||||||
|
@ -378,7 +377,6 @@ typedef struct RNode {
|
||||||
#define NEW_PREEXE(b,loc) NEW_SCOPE(b,loc)
|
#define NEW_PREEXE(b,loc) NEW_SCOPE(b,loc)
|
||||||
#define NEW_POSTEXE(b,loc) NEW_NODE(NODE_POSTEXE,0,b,0,loc)
|
#define NEW_POSTEXE(b,loc) NEW_NODE(NODE_POSTEXE,0,b,0,loc)
|
||||||
#define NEW_ATTRASGN(r,m,a,loc) NEW_NODE(NODE_ATTRASGN,r,m,a,loc)
|
#define NEW_ATTRASGN(r,m,a,loc) NEW_NODE(NODE_ATTRASGN,r,m,a,loc)
|
||||||
#define NEW_METHREF(r,m,loc) NEW_NODE(NODE_METHREF,r,m,0,loc)
|
|
||||||
|
|
||||||
#define NODE_SPECIAL_REQUIRED_KEYWORD ((NODE *)-1)
|
#define NODE_SPECIAL_REQUIRED_KEYWORD ((NODE *)-1)
|
||||||
#define NODE_REQUIRED_KEYWORD_P(node) ((node)->nd_value == NODE_SPECIAL_REQUIRED_KEYWORD)
|
#define NODE_REQUIRED_KEYWORD_P(node) ((node)->nd_value == NODE_SPECIAL_REQUIRED_KEYWORD)
|
||||||
|
|
28
parse.y
28
parse.y
|
@ -1114,7 +1114,6 @@ static int looking_at_eol_p(struct parser_params *p);
|
||||||
%token tRSHFT RUBY_TOKEN(RSHFT) ">>"
|
%token tRSHFT RUBY_TOKEN(RSHFT) ">>"
|
||||||
%token <id> tANDDOT RUBY_TOKEN(ANDDOT) "&."
|
%token <id> tANDDOT RUBY_TOKEN(ANDDOT) "&."
|
||||||
%token <id> tCOLON2 RUBY_TOKEN(COLON2) "::"
|
%token <id> tCOLON2 RUBY_TOKEN(COLON2) "::"
|
||||||
%token <id> tMETHREF RUBY_TOKEN(METHREF) ".:"
|
|
||||||
%token tCOLON3 ":: at EXPR_BEG"
|
%token tCOLON3 ":: at EXPR_BEG"
|
||||||
%token <id> tOP_ASGN "operator-assignment" /* +=, -= etc. */
|
%token <id> tOP_ASGN "operator-assignment" /* +=, -= etc. */
|
||||||
%token tASSOC "=>"
|
%token tASSOC "=>"
|
||||||
|
@ -3064,13 +3063,6 @@ primary : literal
|
||||||
/*% %*/
|
/*% %*/
|
||||||
/*% ripper: retry! %*/
|
/*% ripper: retry! %*/
|
||||||
}
|
}
|
||||||
| primary_value tMETHREF operation2
|
|
||||||
{
|
|
||||||
/*%%%*/
|
|
||||||
$$ = NEW_METHREF($1, $3, &@$);
|
|
||||||
/*% %*/
|
|
||||||
/*% ripper: methref!($1, $3) %*/
|
|
||||||
}
|
|
||||||
;
|
;
|
||||||
|
|
||||||
primary_value : primary
|
primary_value : primary
|
||||||
|
@ -9232,8 +9224,7 @@ parser_yylex(struct parser_params *p)
|
||||||
case '.': {
|
case '.': {
|
||||||
int is_beg = IS_BEG();
|
int is_beg = IS_BEG();
|
||||||
SET_LEX_STATE(EXPR_BEG);
|
SET_LEX_STATE(EXPR_BEG);
|
||||||
switch (c = nextc(p)) {
|
if ((c = nextc(p)) == '.') {
|
||||||
case '.':
|
|
||||||
if ((c = nextc(p)) == '.') {
|
if ((c = nextc(p)) == '.') {
|
||||||
if (p->lex.paren_nest == 0 && looking_at_eol_p(p)) {
|
if (p->lex.paren_nest == 0 && looking_at_eol_p(p)) {
|
||||||
rb_warn0("... at EOL, should be parenthesized?");
|
rb_warn0("... at EOL, should be parenthesized?");
|
||||||
|
@ -9242,23 +9233,6 @@ parser_yylex(struct parser_params *p)
|
||||||
}
|
}
|
||||||
pushback(p, c);
|
pushback(p, c);
|
||||||
return is_beg ? tBDOT2 : tDOT2;
|
return is_beg ? tBDOT2 : tDOT2;
|
||||||
case ':':
|
|
||||||
switch (c = nextc(p)) {
|
|
||||||
default:
|
|
||||||
if (!parser_is_identchar(p)) break;
|
|
||||||
/* fallthru */
|
|
||||||
case '!': case '%': case '&': case '*': case '+':
|
|
||||||
case '-': case '/': case '<': case '=': case '>':
|
|
||||||
case '[': case '^': case '`': case '|': case '~':
|
|
||||||
pushback(p, c);
|
|
||||||
SET_LEX_STATE(EXPR_DOT);
|
|
||||||
return tMETHREF;
|
|
||||||
case -1:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
pushback(p, c);
|
|
||||||
c = ':';
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
pushback(p, c);
|
pushback(p, c);
|
||||||
if (c != -1 && ISDIGIT(c)) {
|
if (c != -1 && ISDIGIT(c)) {
|
||||||
|
|
|
@ -443,13 +443,6 @@ class TestRipper::ParserEvents < Test::Unit::TestCase
|
||||||
assert_equal "[call(ref(self),&.,foo,[])]", tree
|
assert_equal "[call(ref(self),&.,foo,[])]", tree
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_methref
|
|
||||||
thru_methref = false
|
|
||||||
tree = parse("obj.:foo", :on_methref) {thru_methref = true}
|
|
||||||
assert_equal true, thru_methref
|
|
||||||
assert_equal "[methref(vcall(obj),foo)]", tree
|
|
||||||
end
|
|
||||||
|
|
||||||
def test_excessed_comma
|
def test_excessed_comma
|
||||||
thru_excessed_comma = false
|
thru_excessed_comma = false
|
||||||
parse("proc{|x,|}", :on_excessed_comma) {thru_excessed_comma = true}
|
parse("proc{|x,|}", :on_excessed_comma) {thru_excessed_comma = true}
|
||||||
|
|
|
@ -562,8 +562,6 @@ class TestRipper::ScannerEvents < Test::Unit::TestCase
|
||||||
scan('op', ':[]=')
|
scan('op', ':[]=')
|
||||||
assert_equal ['&.'],
|
assert_equal ['&.'],
|
||||||
scan('op', 'a&.f')
|
scan('op', 'a&.f')
|
||||||
assert_equal %w(.:),
|
|
||||||
scan('op', 'obj.:foo')
|
|
||||||
assert_equal [],
|
assert_equal [],
|
||||||
scan('op', %q[`make all`])
|
scan('op', %q[`make all`])
|
||||||
end
|
end
|
||||||
|
|
|
@ -264,15 +264,6 @@ class TestAst < Test::Unit::TestCase
|
||||||
assert_equal(:SCOPE, defn.type)
|
assert_equal(:SCOPE, defn.type)
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_methref
|
|
||||||
node = RubyVM::AbstractSyntaxTree.parse("obj.:foo")
|
|
||||||
_, _, body = *node.children
|
|
||||||
assert_equal(:METHREF, body.type)
|
|
||||||
recv, mid = body.children
|
|
||||||
assert_equal(:VCALL, recv.type)
|
|
||||||
assert_equal(:foo, mid)
|
|
||||||
end
|
|
||||||
|
|
||||||
def test_dstr
|
def test_dstr
|
||||||
node = parse('"foo#{1}bar"')
|
node = parse('"foo#{1}bar"')
|
||||||
_, _, body = *node.children
|
_, _, body = *node.children
|
||||||
|
|
|
@ -482,13 +482,6 @@ class TestJIT < Test::Unit::TestCase
|
||||||
end;
|
end;
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_compile_insn_methodref
|
|
||||||
assert_compile_once("#{<<~"begin;"}\n#{<<~'end;'}", result_inspect: '"main"', insns: %i[methodref])
|
|
||||||
begin;
|
|
||||||
self.:inspect.call
|
|
||||||
end;
|
|
||||||
end
|
|
||||||
|
|
||||||
def test_compile_insn_inlinecache
|
def test_compile_insn_inlinecache
|
||||||
assert_compile_once('Struct', result_inspect: 'Struct', insns: %i[opt_getinlinecache opt_setinlinecache])
|
assert_compile_once('Struct', result_inspect: 'Struct', insns: %i[opt_getinlinecache opt_setinlinecache])
|
||||||
end
|
end
|
||||||
|
|
|
@ -1125,42 +1125,6 @@ class TestMethod < Test::Unit::TestCase
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_method_reference_operator
|
|
||||||
m = 1.:succ
|
|
||||||
assert_predicate(m, :frozen?)
|
|
||||||
assert_equal(1.method(:succ), m)
|
|
||||||
assert_equal(2, m.())
|
|
||||||
m = 1.:+
|
|
||||||
assert_predicate(m, :frozen?)
|
|
||||||
assert_equal(1.method(:+), m)
|
|
||||||
assert_equal(42, m.(41))
|
|
||||||
m = 1.:-@
|
|
||||||
assert_predicate(m, :frozen?)
|
|
||||||
assert_equal(1.method(:-@), m)
|
|
||||||
assert_equal(-1, m.())
|
|
||||||
o = Object.new
|
|
||||||
def o.foo; 42; end
|
|
||||||
assert_predicate(o.:foo, :frozen?)
|
|
||||||
m = o.method(:foo)
|
|
||||||
assert_equal(m, o.:foo)
|
|
||||||
def o.method(m); nil; end
|
|
||||||
assert_equal(m, o.:foo)
|
|
||||||
assert_nil(o.method(:foo))
|
|
||||||
end
|
|
||||||
|
|
||||||
def test_method_reference_freeze_state
|
|
||||||
m = 1.:succ
|
|
||||||
assert_predicate(m, :frozen?, "dot-symbol method reference should be frozen")
|
|
||||||
m = 1.method(:succ)
|
|
||||||
assert_not_predicate(m, :frozen?, "#method method reference should not be frozen")
|
|
||||||
o = Object.new
|
|
||||||
def o.foo; 42; end
|
|
||||||
m = o.:foo
|
|
||||||
assert_predicate(m, :frozen?, "dot-symbol method reference should be frozen")
|
|
||||||
m = o.method(:foo)
|
|
||||||
assert_not_predicate(m, :frozen?, "#method method reference should not be frozen")
|
|
||||||
end
|
|
||||||
|
|
||||||
def test_umethod_bind_call
|
def test_umethod_bind_call
|
||||||
foo = Base.instance_method(:foo)
|
foo = Base.instance_method(:foo)
|
||||||
assert_equal(:base, foo.bind_call(Base.new))
|
assert_equal(:base, foo.bind_call(Base.new))
|
||||||
|
|
|
@ -235,7 +235,7 @@ class TestRefinement < Test::Unit::TestCase
|
||||||
meth.call(3)
|
meth.call(3)
|
||||||
EOS
|
EOS
|
||||||
assert_equal(:refine_pow, eval_using(MethodIntegerPowEx, "2.pow(3)"))
|
assert_equal(:refine_pow, eval_using(MethodIntegerPowEx, "2.pow(3)"))
|
||||||
assert_equal(:refine_pow, eval_using(MethodIntegerPowEx, "2.:pow.(3)"))
|
assert_equal(:refine_pow, eval_using(MethodIntegerPowEx, "2.method(:pow).(3)"))
|
||||||
end
|
end
|
||||||
|
|
||||||
module InstanceMethodIntegerPowEx
|
module InstanceMethodIntegerPowEx
|
||||||
|
|
|
@ -93,13 +93,6 @@ class TestSyntax < Test::Unit::TestCase
|
||||||
assert_valid_syntax("tap (proc do end)", __FILE__, bug9726)
|
assert_valid_syntax("tap (proc do end)", __FILE__, bug9726)
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_methodref_literal
|
|
||||||
assert_separately [], <<-EOS
|
|
||||||
eval 'nil.:|;1'
|
|
||||||
1000.times{eval 'nil.:|;1'}
|
|
||||||
EOS
|
|
||||||
end
|
|
||||||
|
|
||||||
def test_array_kwsplat_hash
|
def test_array_kwsplat_hash
|
||||||
kw = {}
|
kw = {}
|
||||||
h = {a: 1}
|
h = {a: 1}
|
||||||
|
@ -1014,10 +1007,8 @@ eom
|
||||||
def test_fluent_dot
|
def test_fluent_dot
|
||||||
assert_valid_syntax("a\n.foo")
|
assert_valid_syntax("a\n.foo")
|
||||||
assert_valid_syntax("a\n&.foo")
|
assert_valid_syntax("a\n&.foo")
|
||||||
assert_valid_syntax("a\n.:foo")
|
|
||||||
assert_valid_syntax("a #\n#\n.foo\n")
|
assert_valid_syntax("a #\n#\n.foo\n")
|
||||||
assert_valid_syntax("a #\n#\n&.foo\n")
|
assert_valid_syntax("a #\n#\n&.foo\n")
|
||||||
assert_valid_syntax("a #\n#\n.:foo\n")
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_safe_call_in_massign_lhs
|
def test_safe_call_in_massign_lhs
|
||||||
|
@ -1534,8 +1525,8 @@ eom
|
||||||
assert_warning(/\A\z|:(?!#{__LINE__+1})\d+: #{warning}/o) {
|
assert_warning(/\A\z|:(?!#{__LINE__+1})\d+: #{warning}/o) {
|
||||||
assert_equal([[], {}], obj.foo({}))
|
assert_equal([[], {}], obj.foo({}))
|
||||||
}
|
}
|
||||||
assert_equal(-1, obj.:foo.arity)
|
assert_equal(-1, obj.method(:foo).arity)
|
||||||
parameters = obj.:foo.parameters
|
parameters = obj.method(:foo).parameters
|
||||||
assert_equal(:rest, parameters.dig(0, 0))
|
assert_equal(:rest, parameters.dig(0, 0))
|
||||||
assert_equal(:block, parameters.dig(1, 0))
|
assert_equal(:block, parameters.dig(1, 0))
|
||||||
end
|
end
|
||||||
|
|
Loading…
Add table
Reference in a new issue