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