Feature #10287 » colon3-colon2head.diff
bootstraptest/test_class.rb | ||
---|---|---|
assert_equal '1', %q( C = 1 # [yarv-dev:800]
|
||
begin module C; end; rescue TypeError; 1 end )
|
||
# colon2, colon3
|
||
# colon2, colon2_head
|
||
assert_equal '1', %q( class A; end; A::C = 1; A::C )
|
||
assert_equal '1', %q( A = 7; begin A::C = 7; rescue TypeError; 1 end )
|
||
assert_equal '1', %q( begin 7::C = 7; rescue TypeError; 1 end )
|
compile.c | ||
---|---|---|
debugi("compile_colon2 - colon", node->nd_vid);
|
||
ADD_INSN1(body, nd_line(node), getconstant, ID2SYM(node->nd_vid));
|
||
break;
|
||
case NODE_COLON3:
|
||
debugi("compile_colon2 - colon3", node->nd_mid);
|
||
case NODE_COLON2_HEAD:
|
||
debugi("compile_colon2 - colon2_head", node->nd_mid);
|
||
ADD_INSN(body, nd_line(node), pop);
|
||
ADD_INSN1(body, nd_line(node), putobject, rb_cObject);
|
||
ADD_INSN1(body, nd_line(node), getconstant, ID2SYM(node->nd_mid));
|
||
... | ... | |
static VALUE
|
||
compile_cpath(LINK_ANCHOR *ret, rb_iseq_t *iseq, NODE *cpath)
|
||
{
|
||
if (nd_type(cpath) == NODE_COLON3) {
|
||
if (nd_type(cpath) == NODE_COLON2_HEAD) {
|
||
/* toplevel class ::Foo */
|
||
ADD_INSN1(ret, nd_line(cpath), putobject, rb_cObject);
|
||
return Qfalse;
|
||
... | ... | |
ID2SYM(node->nd_mid), needstr);
|
||
}
|
||
return 1;
|
||
case NODE_COLON3:
|
||
case NODE_COLON2_HEAD:
|
||
ADD_INSN1(ret, nd_line(node), putobject, rb_cObject);
|
||
ADD_INSN3(ret, nd_line(node), defined,
|
||
INT2FIX(DEFINED_CONST), ID2SYM(node->nd_mid), needstr);
|
||
... | ... | |
ID mid;
|
||
switch (nd_type(node->nd_head)) {
|
||
case NODE_COLON3:
|
||
case NODE_COLON2_HEAD:
|
||
ADD_INSN1(ret, line, putobject, rb_cObject);
|
||
break;
|
||
case NODE_COLON2:
|
||
... | ... | |
}
|
||
break;
|
||
}
|
||
case NODE_COLON3:{
|
||
case NODE_COLON2_HEAD:{
|
||
LABEL *lend = NEW_LABEL(line);
|
||
int ic_index = iseq->is_size++;
|
||
debugi("colon3#nd_mid", node->nd_mid);
|
||
debugi("colon2_head#nd_mid", node->nd_mid);
|
||
/* add cache insn */
|
||
if (iseq->compile_data->option->inline_const_cache) {
|
ext/objspace/objspace.c | ||
---|---|---|
COUNT_NODE(NODE_MODULE);
|
||
COUNT_NODE(NODE_SCLASS);
|
||
COUNT_NODE(NODE_COLON2);
|
||
COUNT_NODE(NODE_COLON3);
|
||
COUNT_NODE(NODE_COLON2_HEAD);
|
||
COUNT_NODE(NODE_CREF);
|
||
COUNT_NODE(NODE_DOT2);
|
||
COUNT_NODE(NODE_DOT3);
|
ext/ripper/eventids2.c | ||
---|---|---|
{tCHAR, &ripper_id_CHAR},
|
||
{tCMP, &ripper_id_op},
|
||
{tCOLON2, &ripper_id_op},
|
||
{tCOLON3, &ripper_id_op},
|
||
{tCOLON2_HEAD, &ripper_id_op},
|
||
{tCONSTANT, &ripper_id_const},
|
||
{tCVAR, &ripper_id_cvar},
|
||
{tDOT2, &ripper_id_op},
|
lib/irb/ruby-lex.rb | ||
---|---|---|
|op, io|
|
||
if @lex_state == EXPR_BEG or @lex_state == EXPR_ARG && @space_seen
|
||
@lex_state = EXPR_BEG
|
||
Token(TkCOLON3)
|
||
Token(TkCOLON2_HEAD)
|
||
else
|
||
@lex_state = EXPR_DOT
|
||
Token(TkCOLON2)
|
lib/irb/ruby-token.rb | ||
---|---|---|
[:TkLSHFT, TkOp, "<<"],
|
||
[:TkRSHFT, TkOp, ">>"],
|
||
[:TkCOLON2, TkOp],
|
||
[:TkCOLON3, TkOp],
|
||
[:TkCOLON2_HEAD,TkOp],
|
||
[:TkASSOC, TkOp, "=>"],
|
||
[:TkQUESTION, TkOp, "?"], #?
|
||
[:TkCOLON, TkOp, ":"], #:
|
lib/rdoc/parser/ruby.rb | ||
---|---|---|
# class ::A -> A is in the top level
|
||
case name_t
|
||
when TkCOLON2, TkCOLON3 then # bug
|
||
when TkCOLON2, TkCOLON2_HEAD then # bug
|
||
name_t = get_tk
|
||
container = @top_level
|
||
given_name << '::'
|
||
... | ... | |
skip_tkspace false
|
||
tk = get_tk
|
||
while TkCOLON2 === tk or TkCOLON3 === tk or TkCONSTANT === tk do
|
||
while TkCOLON2 === tk or TkCOLON2_HEAD === tk or TkCONSTANT === tk do
|
||
res += tk.name
|
||
tk = get_tk
|
||
end
|
||
... | ... | |
unget_tk tk
|
||
break
|
||
end
|
||
when TkCOLON2, TkCOLON3 then
|
||
when TkCOLON2, TkCOLON2_HEAD then
|
||
rhs_name << '::'
|
||
when nil then
|
||
break
|
lib/rdoc/ruby_lex.rb | ||
---|---|---|
# p @lex_state.id2name, @space_seen
|
||
if @lex_state == :EXPR_BEG or @lex_state == :EXPR_ARG && @space_seen
|
||
@lex_state = :EXPR_BEG
|
||
Token(TkCOLON3)
|
||
Token(TkCOLON2_HEAD)
|
||
else
|
||
@lex_state = :EXPR_DOT
|
||
Token(TkCOLON2)
|
lib/rdoc/ruby_token.rb | ||
---|---|---|
[:TkLSHFT, TkOp, "<<"],
|
||
[:TkRSHFT, TkOp, ">>"],
|
||
[:TkCOLON2, TkOp, '::'],
|
||
[:TkCOLON3, TkOp, '::'],
|
||
[:TkCOLON2_HEAD,TkOp, '::'],
|
||
#[:OPASGN, TkOp], # +=, -= etc. #
|
||
[:TkASSOC, TkOp, "=>"],
|
||
[:TkQUESTION, TkOp, "?"], #?
|
node.c | ||
---|---|---|
F_NODE(nd_head, "receiver");
|
||
break;
|
||
case NODE_COLON3:
|
||
case NODE_COLON2_HEAD:
|
||
ANN("top-level constant reference");
|
||
ANN("format: ::[nd_mid]");
|
||
ANN("example: ::Object");
|
||
... | ... | |
case NODE_IASGN:
|
||
case NODE_IASGN2:
|
||
case NODE_CVASGN:
|
||
case NODE_COLON3:
|
||
case NODE_COLON2_HEAD:
|
||
case NODE_OPT_N:
|
||
case NODE_EVSTR:
|
||
case NODE_UNDEF:
|
node.h | ||
---|---|---|
#define NODE_SCLASS NODE_SCLASS
|
||
NODE_COLON2,
|
||
#define NODE_COLON2 NODE_COLON2
|
||
NODE_COLON3,
|
||
#define NODE_COLON3 NODE_COLON3
|
||
NODE_COLON2_HEAD,
|
||
#define NODE_COLON2_HEAD NODE_COLON2_HEAD
|
||
NODE_CREF,
|
||
#define NODE_CREF NODE_CREF
|
||
NODE_DOT2,
|
||
... | ... | |
#define NEW_SCLASS(r,b) NEW_NODE(NODE_SCLASS,r,NEW_SCOPE(0,b),0)
|
||
#define NEW_MODULE(n,b) NEW_NODE(NODE_MODULE,n,NEW_SCOPE(0,b),0)
|
||
#define NEW_COLON2(c,i) NEW_NODE(NODE_COLON2,c,i,0)
|
||
#define NEW_COLON3(i) NEW_NODE(NODE_COLON3,0,i,0)
|
||
#define NEW_COLON2_HEAD(i) NEW_NODE(NODE_COLON2_HEAD,0,i,0)
|
||
#define NEW_CREF(a) NEW_NODE(NODE_CREF,a,0,0)
|
||
#define NEW_DOT2(b,e) NEW_NODE(NODE_DOT2,b,e,0)
|
||
#define NEW_DOT3(b,e) NEW_NODE(NODE_DOT3,b,e,0)
|
parse.y | ||
---|---|---|
%token tLSHFT RUBY_TOKEN(LSHFT) "<<"
|
||
%token tRSHFT RUBY_TOKEN(RSHFT) ">>"
|
||
%token tCOLON2 "::"
|
||
%token tCOLON3 ":: at EXPR_BEG"
|
||
%token tCOLON2_HEAD ":: at EXPR_BEG"
|
||
%token <id> tOP_ASGN /* +=, -= etc. */
|
||
%token tASSOC "=>"
|
||
%token tLPAREN "("
|
||
... | ... | |
}
|
||
%*/
|
||
}
|
||
| tCOLON3 tCONSTANT
|
||
| tCOLON2_HEAD tCONSTANT
|
||
{
|
||
/*%%%*/
|
||
if (in_def || in_single)
|
||
yyerror("dynamic constant assignment");
|
||
$$ = NEW_CDECL(0, 0, NEW_COLON3($2));
|
||
$$ = NEW_CDECL(0, 0, NEW_COLON2_HEAD($2));
|
||
/*%
|
||
$$ = dispatch1(top_const_field, $2);
|
||
if (in_def || in_single) {
|
||
... | ... | |
}
|
||
%*/
|
||
}
|
||
| tCOLON3 tCONSTANT
|
||
| tCOLON2_HEAD tCONSTANT
|
||
{
|
||
/*%%%*/
|
||
if (in_def || in_single)
|
||
yyerror("dynamic constant assignment");
|
||
$$ = NEW_CDECL(0, 0, NEW_COLON3($2));
|
||
$$ = NEW_CDECL(0, 0, NEW_COLON2_HEAD($2));
|
||
/*%
|
||
$$ = dispatch1(top_const_field, $2);
|
||
if (in_def || in_single) {
|
||
... | ... | |
| tCONSTANT
|
||
;
|
||
cpath : tCOLON3 cname
|
||
cpath : tCOLON2_HEAD cname
|
||
{
|
||
/*%%%*/
|
||
$$ = NEW_COLON3($2);
|
||
$$ = NEW_COLON2_HEAD($2);
|
||
/*%
|
||
$$ = dispatch1(top_const_ref, $2);
|
||
%*/
|
||
... | ... | |
$$ = dispatch3(opassign, $$, $4, $5);
|
||
%*/
|
||
}
|
||
| tCOLON3 tCONSTANT tOP_ASGN arg
|
||
| tCOLON2_HEAD tCONSTANT tOP_ASGN arg
|
||
{
|
||
/*%%%*/
|
||
$$ = NEW_COLON3($2);
|
||
$$ = NEW_COLON2_HEAD($2);
|
||
$$ = new_const_op_assign($$, $3, $4);
|
||
/*%
|
||
$$ = dispatch1(top_const_field, $2);
|
||
... | ... | |
$$ = dispatch2(const_path_ref, $1, $3);
|
||
%*/
|
||
}
|
||
| tCOLON3 tCONSTANT
|
||
| tCOLON2_HEAD tCONSTANT
|
||
{
|
||
/*%%%*/
|
||
$$ = NEW_COLON3($2);
|
||
$$ = NEW_COLON2_HEAD($2);
|
||
/*%
|
||
$$ = dispatch1(top_const_ref, $2);
|
||
%*/
|
||
... | ... | |
if (c == ':') {
|
||
if (IS_BEG() || IS_lex_state(EXPR_CLASS) || IS_SPCARG(-1)) {
|
||
lex_state = EXPR_BEG;
|
||
return tCOLON3;
|
||
return tCOLON2_HEAD;
|
||
}
|
||
lex_state = EXPR_DOT;
|
||
return tCOLON2;
|
||
... | ... | |
useless = "a literal";
|
||
break;
|
||
case NODE_COLON2:
|
||
case NODE_COLON3:
|
||
case NODE_COLON2_HEAD:
|
||
useless = "::";
|
||
break;
|
||
case NODE_DOT2:
|
template/id.h.tmpl | ||
---|---|---|
token_op_ids = %w[
|
||
tDOT2 tDOT3 tUPLUS tUMINUS tPOW tDSTAR tCMP tLSHFT tRSHFT
|
||
tLEQ tGEQ tEQ tEQQ tNEQ tMATCH tNMATCH tAREF tASET
|
||
tCOLON2 tCOLON3
|
||
tCOLON2 tCOLON2_HEAD
|
||
]
|
||
defs = File.join(File.dirname(File.dirname(erb.filename)), "defs/id.def")
|
test/rdoc/test_rdoc_parser_ruby.rb | ||
---|---|---|
assert_empty foo.comment
|
||
end
|
||
def test_parse_class_colon3
|
||
def test_parse_class_colon2_head
|
||
code = <<-CODE
|
||
class A
|
||
class ::B
|
||
... | ... | |
assert_equal %w[A B], @store.all_classes.map { |c| c.full_name }.sort
|
||
end
|
||
def test_parse_class_colon3_self_reference
|
||
def test_parse_class_colon2_head_self_reference
|
||
code = <<-CODE
|
||
class A::B
|
||
class ::A
|