summaryrefslogtreecommitdiff
path: root/parse.y
diff options
context:
space:
mode:
authornobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2011-07-22 12:06:42 +0000
committernobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2011-07-22 12:06:42 +0000
commit34918aa83260246e545911efe6e1672507c3e699 (patch)
tree8815d9f98358df4f59fc18a49a43e2a81f03e7d3 /parse.y
parentc276b7380499eb5b181eca838ec86fc480d4ac94 (diff)
* object.c (rb_mod_{const,cvar}_defined, rb_obj_ivar_defined):
avoid inadvertent symbol creation in reflection methods. based on a patch by Jeremy Evans at [ruby-core:38367]. [Feature #5072] * vm_method.c (rb_mod_method_defined) (rb_mod_{public,private,protected}_method_defined) (obj_respond_to): ditto. * parse.y (rb_check_id): new function returns already interned ID or 0. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@32621 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'parse.y')
-rw-r--r--parse.y137
1 files changed, 119 insertions, 18 deletions
diff --git a/parse.y b/parse.y
index 2dfd33d92a..d38e0d04c6 100644
--- a/parse.y
+++ b/parse.y
@@ -9678,24 +9678,29 @@ rb_enc_symname_p(const char *name, rb_encoding *enc)
return rb_enc_symname2_p(name, strlen(name), enc);
}
-int
-rb_enc_symname2_p(const char *name, long len, rb_encoding *enc)
+static int
+rb_enc_symname_type(const char *name, long len, rb_encoding *enc)
{
const char *m = name;
const char *e = m + len;
- int localid = FALSE;
+ int type = ID_JUNK;
- if (!m || len <= 0) return FALSE;
+ if (!m || len <= 0) return -1;
switch (*m) {
case '\0':
- return FALSE;
+ return -1;
case '$':
- if (is_special_global_name(++m, e, enc)) return TRUE;
+ type = ID_GLOBAL;
+ if (is_special_global_name(++m, e, enc)) return type;
goto id;
case '@':
- if (*++m == '@') ++m;
+ type = ID_INSTANCE;
+ if (*++m == '@') {
+ ++m;
+ type = ID_CLASS;
+ }
goto id;
case '<':
@@ -9716,7 +9721,7 @@ rb_enc_symname2_p(const char *name, long len, rb_encoding *enc)
switch (*++m) {
case '~': ++m; break;
case '=': if (*++m == '=') ++m; break;
- default: return FALSE;
+ default: return -1;
}
break;
@@ -9733,32 +9738,53 @@ rb_enc_symname2_p(const char *name, long len, rb_encoding *enc)
break;
case '[':
- if (*++m != ']') return FALSE;
+ if (*++m != ']') return -1;
if (*++m == '=') ++m;
break;
case '!':
- if (len == 1) return FALSE;
+ if (len == 1) return ID_JUNK;
switch (*++m) {
case '=': case '~': ++m; break;
- default: return FALSE;
+ default: return -1;
}
break;
default:
- localid = !rb_enc_isupper(*m, enc);
+ type = rb_enc_isupper(*m, enc) ? ID_CONST : ID_LOCAL;
id:
if (m >= e || (*m != '_' && !rb_enc_isalpha(*m, enc) && ISASCII(*m)))
- return FALSE;
+ return -1;
while (m < e && is_identchar(m, e, enc)) m += rb_enc_mbclen(m, e, enc);
- if (localid) {
- switch (*m) {
- case '!': case '?': case '=': ++m;
- }
+ switch (*m) {
+ case '!': case '?':
+ type = ID_JUNK;
+ ++m;
+ break;
+ case '=':
+ type = ID_ATTRSET;
+ ++m;
+ break;
}
break;
}
- return m == e;
+ return m == e ? type : -1;
+}
+
+int
+rb_enc_symname2_p(const char *name, long len, rb_encoding *enc)
+{
+ return rb_enc_symname_type(name, len, enc) != -1;
+}
+
+static int
+rb_str_symname_type(VALUE name)
+{
+ const char *ptr = StringValuePtr(name);
+ long len = RSTRING_LEN(name);
+ int type = rb_enc_symname_type(ptr, len, rb_enc_get(name));
+ RB_GC_GUARD(name);
+ return type;
}
static ID
@@ -10076,6 +10102,81 @@ rb_is_junk_id(ID id)
return is_junk_id(id);
}
+ID
+rb_check_id(VALUE name)
+{
+ st_data_t id;
+ VALUE tmp;
+
+ if (SYMBOL_P(name)) {
+ return SYM2ID(name);
+ }
+ else if (RB_TYPE_P(name, T_STRING)) {
+ tmp = rb_check_string_type(name);
+ if (NIL_P(tmp)) {
+ tmp = rb_inspect(name);
+ rb_raise(rb_eTypeError, "%s is not a symbol",
+ RSTRING_PTR(tmp));
+ }
+ name = tmp;
+ }
+ if (!st_lookup(global_symbols.sym_id, (st_data_t)name, &id))
+ return (ID)0;
+ return (ID)id;
+}
+
+int
+rb_is_const_name(VALUE name)
+{
+ return rb_str_symname_type(name) == ID_CONST;
+}
+
+int
+rb_is_class_name(VALUE name)
+{
+ return rb_str_symname_type(name) == ID_CLASS;
+}
+
+int
+rb_is_global_name(VALUE name)
+{
+ return rb_str_symname_type(name) == ID_GLOBAL;
+}
+
+int
+rb_is_instance_name(VALUE name)
+{
+ return rb_str_symname_type(name) == ID_INSTANCE;
+}
+
+int
+rb_is_attrset_name(VALUE name)
+{
+ return rb_str_symname_type(name) == ID_ATTRSET;
+}
+
+int
+rb_is_local_name(VALUE name)
+{
+ return rb_str_symname_type(name) == ID_LOCAL;
+}
+
+int
+rb_is_method_name(VALUE name)
+{
+ switch (rb_str_symname_type(name)) {
+ case ID_LOCAL: case ID_ATTRSET: case ID_JUNK:
+ return TRUE;
+ }
+ return FALSE;
+}
+
+int
+rb_is_junk_name(VALUE name)
+{
+ return rb_str_symname_type(name) == -1;
+}
+
#endif /* !RIPPER */
static void