src/pmc/class.pmc - defines a class
This class implements the Class PMC,
as outlined in docs/pdds/pdd15_objects.pod.
Class is not derived from any other PMC.
The Role PMC structure (Parrot_Role
) consists of five items:
name
- The name of the class -- a STRING.
An empty STRING is allocated during initialization.
namespace
- The namespace the class is associated with,
if any.
A Null PMC is allocated during initialization.
instantiated
- A flag denoting whether this class has been instantiated since last modification.
A native integer with value zero is allocated during initialization.
parents
- An array of immediate parent classes.
An empty ResizablePMCArray PMC is allocated during initialization.
all_parents
- A cached array of ourself and all parent classes,
in MRO order.
A ResizablePMCArray PMC is allocated during initialization,
and is populated with the current class.
roles
- An array of the roles this class has been composed from.
An empty ResizablePMCArray PMC is allocated during initialization.
methods
- A directory of method names and method bodies this class provides.
An empty Hash PMC is allocated during initialization.
vtable_overrides
- A directory of vtable method names and method bodies this class overrides.
An empty Hash PMC is allocated during initialization.
attrib_metadata
- A directory of attribute names and attribute metadata this class contains.
An empty Hash PMC is allocated during initialization.
attrib_index
- A lookup table for attributes in this class and parents.
A Null PMC is allocated during initialization.
attrib_cache
- A cache of visible attribute names to attribute indexes.
A Null PMC is allocated during initialization.
resolve_method
- A list of method names the class provides used for name conflict resolution.
An empty ResizablePMCArray PMC is allocated during initialization.
void init()
- Initializes a Class PMC.
void init_pmc(PMC *init_data)
- The actual class creation code,
called from
newclass
opcode.
The init
argument may either be the name of the class,
or a hash of initialization arguments.
The class is attatched to the current namespace.
PMC *subclass(PMC *name)
- Creates a subclass,
optionally with a given
name
.
void destroy()
- Free the memory associated with the object's underlying struct.
STRING *get_string()
- Return the name of the class (without the HLL namespace).
void mark()
- Mark any referenced strings and PMCs in the structure as live.
void add_attribute(STRING *name, PMC *type)
- Adds the given attribute (
name
) with an optional type
.
Creates a new class if the current class has been instantiated.
Enters the attribute in the attributes
array.
Returns an error if an attribute of name
already exists.
void add_method(STRING *name, PMC *sub)
- Adds the given sub PMC as a method with the given name.
void add_vtable_override(STRING *name, PMC *sub)
- Adds the given sub PMC as a vtable override with the given name.
void add_parent(PMC *parent)
- Adds the supplied PMC to the list of parents for the class.
void add_role(PMC *role)
- Adds the supplied PMC to the list of roles for the class,
provided there are no conflicts.
PMC *inspect_str(STRING *what)
- Provides introspection of a specific piece of information about the class.
The available information is:
- name
- String PMC containing the name of the class
- namespace
- NameSpace PMC of the the namespace attached to the class
- attributes
- Hash keyed on attribute name,
value is hash describing it
- methods
- Hash keyed on method name,
value is an invokable PMC.
Includes methods composed in from roles.
- roles
- Array of Role PMCs.
Includes roles done by the roles that were composed into this class.
- parents
- Array of Class PMCs representing the direct parents of this class.
PMC *inspect()
- Returns a Hash describing the class,
with key/value pairs as described in inspect_str.
PMC *clone()
- Returns an anonymous copy of the class (with no name and no link to a namespace).
Unsets the instantiated flag,
allowing modifications.
PMC *clone_pmc(PMC *args)
- Makes a copy of the class,
then modifies or adds to it based upon the contents of the supplied initialization data.
If a new name or namespace is not supplied in
args
then the cloned class will be anonymous.
The instantiated flag is unset to allow further modifications.
PMC *instantiate(PMC *init)
- Creates a new PMC object of the type of the class and calls init().
INTVAL isa(STRING *classname)
- Returns whether the class is or inherits from
*classname
.
void name(STRING *name :optional, int has_name :opt_flag)
- Sets the name of the class,
and updates the namespace accoringly.
void pmc_namespace()
- Gets the namespace that this class is attached to.
void resolve_method()
- Sets the list of method names that the class provides to resolve conflicts in methods from roles.
When called with no parameter,
returns the list.
void new(PMC *args :slurpy :named)
- Creates an instance of the object.
Initializes any attributes specified in the parameter list.
void attributes()
- Return a hash where the keys are attribute names and the values are hashes providing a set of key/value pairs describing the attribute.
void add_attribute()
- Add an attribute to the class.
Requires a name and,
optionally,
a type.
void methods()
- Return a hash where the keys are method names and the values are methods.
void add_method(STRING *name, PMC *sub)
- Adds the given sub PMC as a method with the given name.
Delegates to the
add_method
vtable method.
PMC *find_method(STRING *name)
- Walks the MRO of the class and finds the method with the given name.
- */
PCCMETHOD find_method(STRING *name) {
Parrot_Class * const _class = PARROT_CLASS(SELF);
PMC *_namespace = _class->_namespace;
int num_classes, i;
if ( ! PMC_IS_NULL(_namespace)
&& VTABLE_exists_keyed_str(interp, _namespace, name)) {
PMC *ret = VTABLE_get_pmc_keyed_str(interp, _namespace, name);
PCCRETURN(PMC *ret);
}
/* Walk and search. One day, we'll use the cache first. */
num_classes = VTABLE_elements(interp, _class->all_parents);
for (i = 0; i < num_classes; i++) {
/* Get the class and see if it has the method. */
PMC * const cur_class =
VTABLE_get_pmc_keyed_int(interp, _class->all_parents, i);
const Parrot_Class * const class_info = PARROT_CLASS(cur_class);
/* Found it! */
if (VTABLE_exists_keyed_str(interp, class_info->methods, name)) {
PMC *ret = VTABLE_get_pmc_keyed_str(interp, class_info->methods,
name);
PCCRETURN(PMC *ret);
}
}
PCCRETURN(PMC *PMCNULL);
}
- /*
void parents()
- Return the parents array PMC.
void add_parent(PMC *parent)
- Adds the supplied PMC to the list of parents for the class.
void roles()
- Return the roles array PMC.
void add_role(PMC *role, PMC *exclude :optional :named["exclude"], PMC *alias :optional :named["alias"])
- Compose a role into a class with the given exclusions and aliases.
void inspect(STRING *what :optional)
- Gets all introspection data for the class or, if the optional string parameter is supplied, a particular item of introspection data.
void isa(STRING *class_name)
- Returns true if this object is or derives from the class named in
class_name
, false otherwise.
void does(STRING *role_name)
- Returns true if this object or one of its parents performs the named role, false otherwise.
docs/pdds/pdd15_objects.pod.