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]
|
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 instvars, classinstvars, classvars, pooldics.
|
||||||
var instmthdic, classmthdic, nsup, nsdic.
|
|
||||||
var trsize, trgc, initv, initv_ci.
|
var trsize, trgc, initv, initv_ci.
|
||||||
|
|
||||||
method(#class) initialize { ^self }
|
method(#class) initialize { ^self }
|
||||||
@ -46,6 +46,5 @@ class(#pointer,#limited,#uncopyable) Class(Apex) [ClassInterface]
|
|||||||
|
|
||||||
class(#pointer,#limited,#uncopyable) Interface(Apex)
|
class(#pointer,#limited,#uncopyable) Interface(Apex)
|
||||||
{
|
{
|
||||||
var name.
|
var name, instmthdic, classmthdic, nsup, nsdic.
|
||||||
var 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);
|
mth = moo_findmethodinclasschain(moo, ciim->_class, ciim->mth_type, &name);
|
||||||
if (!mth)
|
if (!mth)
|
||||||
{
|
{
|
||||||
/* TODO: take methods from interface..*/
|
|
||||||
if (MOO_CLASSOF(moo, ass->value) == moo->_method)
|
if (MOO_CLASSOF(moo, ass->value) == moo->_method)
|
||||||
{
|
{
|
||||||
|
moo_oow_t i;
|
||||||
|
moo_oop_method_t im;
|
||||||
|
|
||||||
mth = (moo_oop_method_t)ass->value;
|
mth = (moo_oop_method_t)ass->value;
|
||||||
#if 0
|
for (i = 0; i < ciim->cc->ifce_mths[ciim->mth_type].count; i++)
|
||||||
if (!moo_putatdic(moo, ciim->_class->mthdic[ciim->mth_type], (moo_oop_t)mth->name, (moo_oop_t)mth))
|
|
||||||
{
|
{
|
||||||
/* TODO: error handling. GC safety, etc */
|
im = (moo_oop_method_t)ciim->cc->ifce_mths[ciim->mth_type].ptr[i];
|
||||||
}
|
if (mth->name == im->name)
|
||||||
#else
|
{
|
||||||
/* TODO: check duplication */
|
/* 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)
|
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);
|
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;
|
return -1;
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
return 0;
|
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;
|
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 (j = MOO_METHOD_INSTANCE; j <= MOO_METHOD_CLASS; j++)
|
||||||
{
|
{
|
||||||
for (i = 0; i < cc->ifce_mths[j].count; i++)
|
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)
|
if (in_super)
|
||||||
{
|
{
|
||||||
MOO_ASSERT (moo, moo->active_method);
|
MOO_ASSERT (moo, moo->active_method != MOO_NULL);
|
||||||
MOO_ASSERT (moo, moo->active_method->owner);
|
MOO_ASSERT (moo, moo->active_method->owner != MOO_NULL);
|
||||||
|
|
||||||
/* if 'super' is allowed in the interface method, the owner field
|
/* if 'super' is allowed in the interface method, the owner field
|
||||||
* can be an interface. super must not be allowed in the interface
|
* 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;
|
mth->literal_frame[0] = (moo_oop_t)pfidsym;
|
||||||
|
|
||||||
/* premable should contain the index to the literal frame which is always 0 */
|
/* premable should contain the index to the literal frame which is always 0 */
|
||||||
mth->owner = _class;
|
MOO_STORE_OOP (moo, (moo_oop_t*)&mth->owner, (moo_oop_t)_class);
|
||||||
mth->name = mnsym;
|
MOO_STORE_OOP (moo, (moo_oop_t*)&mth->name, (moo_oop_t)mnsym);
|
||||||
if (variadic) preamble_flags |= MOO_METHOD_PREAMBLE_FLAG_VARIADIC;
|
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 = 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);
|
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_nsdic_t;
|
||||||
typedef struct moo_nsdic_t* moo_oop_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
|
#define MOO_INTERFACE_NAMED_INSTVARS 5
|
||||||
typedef struct moo_interface_t moo_interface_t;
|
typedef struct moo_interface_t moo_interface_t;
|
||||||
typedef struct moo_interface_t* moo_oop_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 */
|
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;
|
MOO_OBJ_HEADER;
|
||||||
|
|
||||||
|
/* === the following five fields must be placed in class and interface === */
|
||||||
moo_oop_char_t name;
|
moo_oop_char_t name;
|
||||||
|
|
||||||
/* [0] - instance methods, MethodDictionary
|
/* [0] - instance methods, MethodDictionary
|
||||||
* [1] - class methods, MethodDictionary */
|
* [1] - class methods, MethodDictionary */
|
||||||
moo_oop_dic_t mthdic[2];
|
moo_oop_dic_t mthdic[2];
|
||||||
|
|
||||||
moo_oop_nsdic_t nsup; /* pointer to the upper namespace */
|
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_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
|
struct moo_class_t
|
||||||
{
|
{
|
||||||
MOO_OBJ_HEADER;
|
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 spec; /* SmallInteger. instance specification */
|
||||||
moo_oop_t selfspec; /* SmallInteger. specification of the class object itself */
|
moo_oop_t selfspec; /* SmallInteger. specification of the class object itself */
|
||||||
|
|
||||||
moo_oop_t superclass; /* Another class */
|
moo_oop_t superclass; /* Another class */
|
||||||
moo_oop_t subclasses; /* Array of subclasses */
|
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. */
|
moo_oop_t modname; /* Symbol if importing a module. nil if not. */
|
||||||
|
|
||||||
/* == NEVER CHANGE THIS ORDER OF 3 ITEMS BELOW == */
|
/* == 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 */
|
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 trsize; /* trailer size for new instances */
|
||||||
moo_oop_t trgc; /* trailer gc callback */
|
moo_oop_t trgc; /* trailer gc callback */
|
||||||
|
|
||||||
@ -571,7 +601,7 @@ struct moo_method_t
|
|||||||
{
|
{
|
||||||
MOO_OBJ_HEADER;
|
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 */
|
moo_oop_char_t name; /* Symbol, method name */
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user