Change TC hierarchy in XS
[gitmo/Mouse.git] / xs-src / Mouse.xs
CommitLineData
df6dd016 1#include "mouse.h"
2
cccb83de 3SV* mouse_package;
4SV* mouse_namespace;
3e44140b 5SV* mouse_methods;
a5df48e5 6SV* mouse_name;
cccb83de 7
646c0371 8MODULE = Mouse PACKAGE = Mouse
df6dd016 9
10PROTOTYPES: DISABLE
11
cccb83de 12BOOT:
13 mouse_package = newSVpvs_share("package");
14 mouse_namespace = newSVpvs_share("namespace");
3e44140b 15 mouse_methods = newSVpvs_share("methods");
a5df48e5 16 mouse_name = newSVpvs_share("name");
3e44140b 17
646c0371 18 MOUSE_CALL_BOOT(Mouse__Util);
1d5ecd5f 19 MOUSE_CALL_BOOT(Mouse__Util__TypeConstraints);
646c0371 20 MOUSE_CALL_BOOT(Mouse__Meta__Method__Accessor__XS);
f48920c1 21
cccb83de 22
7d96ae4d 23MODULE = Mouse PACKAGE = Mouse::Meta::Module
24
25BOOT:
26 INSTALL_SIMPLE_READER_WITH_KEY(Module, name, package);
27 INSTALL_SIMPLE_READER_WITH_KEY(Module, _method_map, methods);
28 INSTALL_SIMPLE_READER_WITH_KEY(Module, _attribute_map, attributes);
29
30HV*
31namespace(SV* self)
32CODE:
33{
3ea28db6 34 SV* const package = mouse_instance_get_slot(aTHX_ self, mouse_package);
7d96ae4d 35 if(!(package && SvOK(package))){
3e44140b 36 croak("No package name defined");
7d96ae4d 37 }
38 RETVAL = gv_stashsv(package, GV_ADDMULTI);
39}
40OUTPUT:
41 RETVAL
42
3e44140b 43# ignore extra arguments for extensibility
44void
45add_method(SV* self, SV* name, SV* code, ...)
46CODE:
47{
b330ee2d 48 SV* const package = mouse_instance_get_slot(aTHX_ self, mouse_package); /* $self->{package} */
49 SV* const methods = mouse_instance_get_slot(aTHX_ self, mouse_methods); /* $self->{methods} */
3e44140b 50 GV* gv;
51 SV* code_ref;
52
53 if(!(package && SvOK(package))){
54 croak("No package name defined");
55 }
56
57 SvGETMAGIC(name);
58 SvGETMAGIC(code);
59
60 if(!SvOK(name)){
61 mouse_throw_error(self, NULL, "You must define a method name");
62 }
63 if(!SvROK(code)){
64 mouse_throw_error(self, NULL, "You must define a CODE reference");
65 }
66
67 code_ref = code;
68 if(SvTYPE(SvRV(code_ref)) != SVt_PVCV){
69 SV* sv = code_ref; /* used in tryAMAGICunDEREF */
70 SV** sp = &sv; /* used in tryAMAGICunDEREF */
71 tryAMAGICunDEREF(to_cv); /* try \&{$code} */
72 if(SvROK(sv) && SvTYPE(SvRV(sv)) == SVt_PVCV){
73 mouse_throw_error(self, NULL, "Not a CODE reference");
74 }
75 code_ref = sv;
76 }
77
78 /* *{$package . '::' . $name} -> *gv */
79 gv = gv_fetchpv(form("%"SVf"::%"SVf, package, name), GV_ADDMULTI, SVt_PVCV);
80 if(GvCVu(gv)){ /* delete *slot{gv} to work around "redefine" warning */
81 SvREFCNT_dec(GvCV(gv));
82 GvCV(gv) = NULL;
83 }
84 sv_setsv_mg((SV*)gv, code_ref); /* *gv = $code_ref */
85
b330ee2d 86 mouse_instance_set_slot(aTHX_ methods, name, code); /* $self->{methods}{$name} = $code */
3e44140b 87
88 /* TODO: name the CODE ref if it's anonymous */
89 //code_entity = (CV*)SvRV(code_ref);
90 //if(CvANON(code_entity)
91 // && CvGV(code_entity) /* a cv under construction has no gv */ ){
92
93 // CvGV(code_entity) = gv;
94 // CvANON_off(code_entity);
95 //}
96}
97
43165725 98MODULE = Mouse PACKAGE = Mouse::Meta::Class
99
100BOOT:
101 INSTALL_SIMPLE_READER(Class, roles);
102 INSTALL_SIMPLE_PREDICATE_WITH_KEY(Class, is_anon_class, anon_serial_id);
103
cccb83de 104void
105linearized_isa(SV* self)
106PPCODE:
107{
108 SV* const stash_ref = mcall0(self, mouse_namespace); /* $self->namespace */
109 AV* linearized_isa;
110 I32 len;
111 I32 i;
112 if(!(SvROK(stash_ref) && SvTYPE(SvRV(stash_ref)) == SVt_PVHV)){
113 croak("namespace() didn't return a HASH reference");
114 }
115 linearized_isa = mro_get_linear_isa((HV*)SvRV(stash_ref));
116 len = AvFILLp(linearized_isa) + 1;
117 EXTEND(SP, len);
118 for(i = 0; i < len; i++){
119 PUSHs(AvARRAY(linearized_isa)[i]);
120 }
121}
122
441964ce 123
43165725 124MODULE = Mouse PACKAGE = Mouse::Meta::Role
125
126BOOT:
127 INSTALL_SIMPLE_READER_WITH_KEY(Role, get_roles, roles);
128 INSTALL_SIMPLE_PREDICATE_WITH_KEY(Role, is_anon_role, anon_serial_id);
129
43165725 130MODULE = Mouse PACKAGE = Mouse::Meta::Attribute
131
132BOOT:
133 /* readers */
134 INSTALL_SIMPLE_READER(Attribute, name);
135 INSTALL_SIMPLE_READER(Attribute, associated_class);
136 INSTALL_SIMPLE_READER(Attribute, accessor);
137 INSTALL_SIMPLE_READER(Attribute, reader);
138 INSTALL_SIMPLE_READER(Attribute, writer);
139 INSTALL_SIMPLE_READER(Attribute, predicate);
140 INSTALL_SIMPLE_READER(Attribute, clearer);
141 INSTALL_SIMPLE_READER(Attribute, handles);
142
143 INSTALL_SIMPLE_READER_WITH_KEY(Attribute, _is_metadata, is);
144 INSTALL_SIMPLE_READER_WITH_KEY(Attribute, is_required, required);
145 INSTALL_SIMPLE_READER(Attribute, default);
146 INSTALL_SIMPLE_READER_WITH_KEY(Attribute, is_lazy, lazy);
147 INSTALL_SIMPLE_READER_WITH_KEY(Attribute, is_lazy_build, lazy_build);
148 INSTALL_SIMPLE_READER_WITH_KEY(Attribute, is_weak_ref, weak_ref);
149 INSTALL_SIMPLE_READER(Attribute, init_arg);
150 INSTALL_SIMPLE_READER(Attribute, type_constraint);
151 INSTALL_SIMPLE_READER(Attribute, trigger);
152 INSTALL_SIMPLE_READER(Attribute, builder);
153 INSTALL_SIMPLE_READER_WITH_KEY(Attribute, should_auto_deref, auto_deref);
154 INSTALL_SIMPLE_READER_WITH_KEY(Attribute, should_coerce, coerce);
155 INSTALL_SIMPLE_READER(Attribute, documentation);
156
157 /* predicates */
158 INSTALL_SIMPLE_PREDICATE_WITH_KEY(Attribute, has_accessor, accessor);
159 INSTALL_SIMPLE_PREDICATE_WITH_KEY(Attribute, has_reader, reader);
160 INSTALL_SIMPLE_PREDICATE_WITH_KEY(Attribute, has_writer, writer);
161 INSTALL_SIMPLE_PREDICATE_WITH_KEY(Attribute, has_predicate, predicate);
162 INSTALL_SIMPLE_PREDICATE_WITH_KEY(Attribute, has_clearer, clearer);
163 INSTALL_SIMPLE_PREDICATE_WITH_KEY(Attribute, has_handles, handles);
164
165 INSTALL_SIMPLE_PREDICATE_WITH_KEY(Attribute, has_default, default);
166 INSTALL_SIMPLE_PREDICATE_WITH_KEY(Attribute, has_type_constraint, type_constraint);
167 INSTALL_SIMPLE_PREDICATE_WITH_KEY(Attribute, has_trigger, trigger);
168 INSTALL_SIMPLE_PREDICATE_WITH_KEY(Attribute, has_builder, builder);
169 INSTALL_SIMPLE_PREDICATE_WITH_KEY(Attribute, has_documentation, documentation);
170
93540011 171 newCONSTSUB(gv_stashpvs("Mouse::Meta::Attribute", TRUE), "accessor_metaclass",
172 newSVpvs("Mouse::Meta::Method::Accessor::XS"));
173
43165725 174MODULE = Mouse PACKAGE = Mouse::Meta::TypeConstraint
175
176BOOT:
177 INSTALL_SIMPLE_READER(TypeConstraint, name);
178 INSTALL_SIMPLE_READER(TypeConstraint, parent);
179 INSTALL_SIMPLE_READER(TypeConstraint, message);
180
181 INSTALL_SIMPLE_READER_WITH_KEY(TypeConstraint, _compiled_type_constraint, compiled_type_constraint);
182 INSTALL_SIMPLE_READER(TypeConstraint, _compiled_type_coercion); /* Mouse specific */
183
184 INSTALL_SIMPLE_PREDICATE_WITH_KEY(TypeConstraint, has_coercion, _compiled_type_coercion);
93540011 185
186