implemented interface method duplication check in the compiler
This commit is contained in:
parent
5be193b3fe
commit
277dc64ac4
@ -10,9 +10,9 @@ interface ClassInterface
|
||||
//
|
||||
class(#pointer,#limited,#uncopyable) Class(Apex) [ClassInterface]
|
||||
{
|
||||
var spec, selfspec, superclass, subclasses, name, modname.
|
||||
var name, instmthdic, classmthdic, nsup, nsdic.
|
||||
var spec, selfspec, superclass, subclasses, modname.
|
||||
var instvars, classinstvars, classvars, pooldics.
|
||||
var instmthdic, classmthdic, nsup, nsdic.
|
||||
var trsize, trgc, initv, initv_ci.
|
||||
|
||||
method(#class) initialize { ^self }
|
||||
@ -46,6 +46,5 @@ class(#pointer,#limited,#uncopyable) Class(Apex) [ClassInterface]
|
||||
|
||||
class(#pointer,#limited,#uncopyable) Interface(Apex)
|
||||
{
|
||||
var name.
|
||||
var instmthdic, classmthdic, nsup, nsdic.
|
||||
var name, instmthdic, classmthdic, nsup, nsdic.
|
||||
}
|
||||
|
@ -9079,17 +9079,29 @@ static int ciim_on_each_method (moo_t* moo, moo_oop_dic_t dic, moo_oop_associati
|
||||
mth = moo_findmethodinclasschain(moo, ciim->_class, ciim->mth_type, &name);
|
||||
if (!mth)
|
||||
{
|
||||
/* TODO: take methods from interface..*/
|
||||
if (MOO_CLASSOF(moo, ass->value) == moo->_method)
|
||||
{
|
||||
moo_oow_t i;
|
||||
moo_oop_method_t im;
|
||||
|
||||
mth = (moo_oop_method_t)ass->value;
|
||||
#if 0
|
||||
if (!moo_putatdic(moo, ciim->_class->mthdic[ciim->mth_type], (moo_oop_t)mth->name, (moo_oop_t)mth))
|
||||
for (i = 0; i < ciim->cc->ifce_mths[ciim->mth_type].count; i++)
|
||||
{
|
||||
/* TODO: error handling. GC safety, etc */
|
||||
}
|
||||
#else
|
||||
/* TODO: check duplication */
|
||||
im = (moo_oop_method_t)ciim->cc->ifce_mths[ciim->mth_type].ptr[i];
|
||||
if (mth->name == im->name)
|
||||
{
|
||||
/* duplicate interface method name found */
|
||||
moo_setsynerrbfmt (moo, MOO_SYNERR_MTHNAMEDUPL, MOO_NULL, MOO_NULL,
|
||||
"%.*js defined in multiple interfaces for %.*js - %.*js, %.*js",
|
||||
name.len, name.ptr,
|
||||
MOO_OBJ_GET_SIZE(ciim->_class->name), MOO_OBJ_GET_CHAR_SLOT(ciim->_class->name),
|
||||
MOO_OBJ_GET_SIZE(im->owner->name), MOO_OBJ_GET_CHAR_SLOT(im->owner->name),
|
||||
MOO_OBJ_GET_SIZE(ciim->ifce->name), MOO_OBJ_GET_CHAR_SLOT(ciim->ifce->name)
|
||||
);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
if (add_oop_to_oopbuf(moo, &ciim->cc->ifce_mths[ciim->mth_type], (moo_oop_t)mth) <= -1)
|
||||
{
|
||||
const moo_ooch_t* oldmsg = moo_backuperrmsg(moo);
|
||||
@ -9101,8 +9113,7 @@ static int ciim_on_each_method (moo_t* moo, moo_oop_dic_t dic, moo_oop_associati
|
||||
);
|
||||
return -1;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -9213,6 +9224,7 @@ static int check_class_interface_conformance (moo_t* moo)
|
||||
if (!class_implements_interface(moo, cc->self_oop, (moo_oop_interface_t)cc->ifces.ptr[i])) return -1;
|
||||
}
|
||||
|
||||
MOO_STATIC_ASSERT (MOO_METHOD_INSTANCE == 0 && MOO_METHOD_CLASS == 1);
|
||||
for (j = MOO_METHOD_INSTANCE; j <= MOO_METHOD_CLASS; j++)
|
||||
{
|
||||
for (i = 0; i < cc->ifce_mths[j].count; i++)
|
||||
|
@ -1847,8 +1847,8 @@ moo_oop_method_t moo_findmethod (moo_t* moo, moo_oop_t receiver, moo_oop_char_t
|
||||
|
||||
if (in_super)
|
||||
{
|
||||
MOO_ASSERT (moo, moo->active_method);
|
||||
MOO_ASSERT (moo, moo->active_method->owner);
|
||||
MOO_ASSERT (moo, moo->active_method != MOO_NULL);
|
||||
MOO_ASSERT (moo, moo->active_method->owner != MOO_NULL);
|
||||
|
||||
/* if 'super' is allowed in the interface method, the owner field
|
||||
* can be an interface. super must not be allowed in the interface
|
||||
|
@ -873,8 +873,8 @@ int moo_genpfmethod (moo_t* moo, moo_mod_t* mod, moo_oop_class_t _class, moo_met
|
||||
mth->literal_frame[0] = (moo_oop_t)pfidsym;
|
||||
|
||||
/* premable should contain the index to the literal frame which is always 0 */
|
||||
mth->owner = _class;
|
||||
mth->name = mnsym;
|
||||
MOO_STORE_OOP (moo, (moo_oop_t*)&mth->owner, (moo_oop_t)_class);
|
||||
MOO_STORE_OOP (moo, (moo_oop_t*)&mth->name, (moo_oop_t)mnsym);
|
||||
if (variadic) preamble_flags |= MOO_METHOD_PREAMBLE_FLAG_VARIADIC;
|
||||
mth->preamble = MOO_SMOOI_TO_OOP(MOO_METHOD_MAKE_PREAMBLE(MOO_METHOD_PREAMBLE_NAMED_PRIMITIVE, 0, preamble_flags));
|
||||
mth->preamble_data[0] = MOO_SMPTR_TO_OOP(0);
|
||||
|
@ -470,6 +470,10 @@ struct moo_dic_t
|
||||
typedef struct moo_nsdic_t moo_nsdic_t;
|
||||
typedef struct moo_nsdic_t* moo_oop_nsdic_t;
|
||||
|
||||
#define MOO_METHOWNER_NAMED_INSTVARS 5
|
||||
typedef struct moo_methowner_t moo_methowner_t;
|
||||
typedef struct moo_methowner_t* moo_oop_methowner_t;
|
||||
|
||||
#define MOO_INTERFACE_NAMED_INSTVARS 5
|
||||
typedef struct moo_interface_t moo_interface_t;
|
||||
typedef struct moo_interface_t* moo_oop_interface_t;
|
||||
@ -489,29 +493,62 @@ struct moo_nsdic_t
|
||||
moo_oop_t nsup; /* a class if it belongs to the class. another nsdic if it doesn't */
|
||||
};
|
||||
|
||||
struct moo_interface_t
|
||||
struct moo_methowner_t
|
||||
{
|
||||
/* a method can be owned by a class or an interface.
|
||||
* this structure defines common fields between a class and an interface and
|
||||
* is for internal VM use only. */
|
||||
MOO_OBJ_HEADER;
|
||||
|
||||
/* === the following five fields must be placed in class and interface === */
|
||||
moo_oop_char_t name;
|
||||
|
||||
/* [0] - instance methods, MethodDictionary
|
||||
* [1] - class methods, MethodDictionary */
|
||||
moo_oop_dic_t mthdic[2];
|
||||
|
||||
moo_oop_nsdic_t nsup; /* pointer to the upper namespace */
|
||||
moo_oop_nsdic_t nsdic; /* dictionary used for namespacing - may be nil when there are no subitems underneath */
|
||||
/* ======================================================================== */
|
||||
};
|
||||
|
||||
struct moo_interface_t
|
||||
{
|
||||
MOO_OBJ_HEADER;
|
||||
|
||||
/* === the following five fields must be in sync with moo_methowner_t === */
|
||||
moo_oop_char_t name;
|
||||
|
||||
/* [0] - instance methods, MethodDictionary
|
||||
* [1] - class methods, MethodDictionary */
|
||||
moo_oop_dic_t mthdic[2];
|
||||
|
||||
moo_oop_nsdic_t nsup; /* pointer to the upper namespace */
|
||||
moo_oop_nsdic_t nsdic; /* dictionary used for namespacing - may be nil when there are no subitems underneath */
|
||||
/* ===================================================================== */
|
||||
};
|
||||
|
||||
struct moo_class_t
|
||||
{
|
||||
MOO_OBJ_HEADER;
|
||||
|
||||
/* === the following five fields must be in sync with moo_methowner_t === */
|
||||
moo_oop_char_t name; /* Symbol */
|
||||
|
||||
/* [0] - instance methods, MethodDictionary
|
||||
* [1] - class methods, MethodDictionary */
|
||||
moo_oop_dic_t mthdic[2];
|
||||
|
||||
moo_oop_nsdic_t nsup; /* pointer to the upper namespace */
|
||||
moo_oop_nsdic_t nsdic; /* dictionary used for namespacing - may be nil when there are no subitems underneath */
|
||||
/* ===================================================================== */
|
||||
|
||||
moo_oop_t spec; /* SmallInteger. instance specification */
|
||||
moo_oop_t selfspec; /* SmallInteger. specification of the class object itself */
|
||||
|
||||
moo_oop_t superclass; /* Another class */
|
||||
moo_oop_t subclasses; /* Array of subclasses */
|
||||
|
||||
moo_oop_char_t name; /* Symbol */
|
||||
moo_oop_t modname; /* Symbol if importing a module. nil if not. */
|
||||
|
||||
/* == NEVER CHANGE THIS ORDER OF 3 ITEMS BELOW == */
|
||||
@ -522,13 +559,6 @@ struct moo_class_t
|
||||
|
||||
moo_oop_char_t pooldics; /* String - pool dictionaries imported */
|
||||
|
||||
/* [0] - instance methods, MethodDictionary
|
||||
* [1] - class methods, MethodDictionary */
|
||||
moo_oop_dic_t mthdic[2];
|
||||
|
||||
moo_oop_nsdic_t nsup; /* pointer to the upper namespace */
|
||||
moo_oop_nsdic_t nsdic; /* dictionary used for namespacing - may be nil when there are no subitems underneath */
|
||||
|
||||
moo_oop_t trsize; /* trailer size for new instances */
|
||||
moo_oop_t trgc; /* trailer gc callback */
|
||||
|
||||
@ -571,7 +601,7 @@ struct moo_method_t
|
||||
{
|
||||
MOO_OBJ_HEADER;
|
||||
|
||||
moo_oop_class_t owner; /* Class */
|
||||
moo_oop_methowner_t owner; /* Class or Interface */
|
||||
|
||||
moo_oop_char_t name; /* Symbol, method name */
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user