From: matthewt Date: Wed, 4 Jun 2008 14:30:26 +0000 (+0000) Subject: make 'method main' work X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=commitdiff_plain;h=8f2a4621f3860068de4a4385d31365a2eca4ef94;p=p5sagit%2FDevel-Declare.git make 'method main' work git-svn-id: http://dev.catalyst.perl.org/repos/bast/trunk/Devel-Declare@4465 bd8105ee-0ff8-0310-8827-fb3f25b6796d --- diff --git a/Changes b/Changes index f1f490d..e80ef14 100644 --- a/Changes +++ b/Changes @@ -1,5 +1,8 @@ Changes for Devel-Declare +0.001011 + - add support for 'method main' and other package names + 0.001010 - fix traits code, again, so it compiles on 5.10. diff --git a/Declare.xs b/Declare.xs index 1cd3434..28950eb 100644 --- a/Declare.xs +++ b/Declare.xs @@ -33,17 +33,14 @@ #define LEX_NORMAL 10 #define LEX_INTERPNORMAL 9 -/* placeholders for PL_check entries we wrap */ - -STATIC OP *(*dd_old_ck_rv2cv)(pTHX_ OP *op); -STATIC OP *(*dd_old_ck_entereval)(pTHX_ OP *op); - /* flag to trigger removal of temporary declaree sub */ static int in_declare = 0; /* replacement PL_check rv2cv entry */ +STATIC OP *(*dd_old_ck_rv2cv)(pTHX_ OP *op); + STATIC OP *dd_ck_rv2cv(pTHX_ OP *o) { OP* kid; char* s; @@ -157,6 +154,12 @@ STATIC OP *dd_ck_rv2cv(pTHX_ OP *o) { DD_DEBUG_S + /* kill the :: added in the ck_const */ + if (*s == ':') + *s++ = ' '; + if (*s == ':') + *s++ = ' '; + /* arg 4 is allow_package */ s = scan_word(s, tmpbuf, sizeof tmpbuf, dd_flags & DD_HANDLE_PACKAGE, &len); @@ -277,6 +280,8 @@ STATIC OP *dd_ck_rv2cv(pTHX_ OP *o) { return o; } +STATIC OP *(*dd_old_ck_entereval)(pTHX_ OP *op); + OP* dd_pp_entereval(pTHX) { dSP; dPOPss; @@ -316,6 +321,102 @@ static I32 dd_filter_realloc(pTHX_ int idx, SV *sv, int maxlen) return count; } +STATIC OP *(*dd_old_ck_const)(pTHX_ OP*op); + +STATIC OP *dd_ck_const(pTHX_ OP *o) { + HV* is_declarator; + SV** is_declarator_pack_ref; + HV* is_declarator_pack_hash; + SV** is_declarator_flag_ref; + int dd_flags; + char* s; + char tmpbuf[sizeof PL_tokenbuf]; + char found_name[sizeof PL_tokenbuf]; + STRLEN len = 0; + + o = dd_old_ck_const(aTHX_ o); /* let the original do its job */ + + is_declarator = get_hv("Devel::Declare::declarators", FALSE); + + is_declarator_pack_ref = hv_fetch(is_declarator, HvNAME(PL_curstash), + strlen(HvNAME(PL_curstash)), FALSE); + + if (!is_declarator_pack_ref || !SvROK(*is_declarator_pack_ref)) + return o; /* not a hashref */ + + is_declarator_pack_hash = (HV*) SvRV(*is_declarator_pack_ref); + + /* don't try and look this up if it's not a string const */ + if (!SvPOK(cSVOPo->op_sv)) + return o; + + is_declarator_flag_ref = hv_fetch( + is_declarator_pack_hash, SvPVX(cSVOPo->op_sv), + strlen(SvPVX(cSVOPo->op_sv)), FALSE + ); + + /* requires SvIOK as well as TRUE since flags not being an int is useless */ + + if (!is_declarator_flag_ref + || !SvIOK(*is_declarator_flag_ref) + || !SvTRUE(*is_declarator_flag_ref)) + return o; + + dd_flags = SvIVX(*is_declarator_flag_ref); + + if (!(dd_flags & DD_HANDLE_NAME)) + return o; /* if we're not handling name, method intuiting not an issue */ + +#ifdef DD_DEBUG + printf("Think I found a declarator %s\n", PL_tokenbuf); + printf("linestr: %s\n", SvPVX(PL_linestr)); +#endif + + s = PL_bufptr; + + while (s < PL_bufend && isSPACE(*s)) s++; + if (memEQ(s, PL_tokenbuf, strlen(PL_tokenbuf))) + s += strlen(PL_tokenbuf); + + DD_DEBUG_S + + /* find next word */ + + s = skipspace(s); + + DD_DEBUG_S + + /* arg 4 is allow_package */ + + s = scan_word(s, tmpbuf, sizeof tmpbuf, dd_flags & DD_HANDLE_PACKAGE, &len); + + DD_DEBUG_S + + if (len) { + const char* old_start = SvPVX(PL_linestr); + int start_diff; + const int old_len = SvCUR(PL_linestr); + + strcpy(found_name, tmpbuf); +#ifdef DD_DEBUG + printf("Found %s\n", found_name); +#endif + + s -= len; + SvGROW(PL_linestr, (STRLEN)(old_len + 2)); + if (start_diff = SvPVX(PL_linestr) - old_start) { + Perl_croak(aTHX_ "forced to realloc PL_linestr for line %s, bailing out before we crash harder", SvPVX(PL_linestr)); + } + memmove(s+2, s, (PL_bufend - s)+1); + *s = ':'; + s++; + *s = ':'; + SvCUR_set(PL_linestr, old_len + 2); + PL_bufend += 2; + } + return o; +} + static int initialized = 0; MODULE = Devel::Declare PACKAGE = Devel::Declare @@ -330,5 +431,7 @@ setup() PL_check[OP_RV2CV] = dd_ck_rv2cv; dd_old_ck_entereval = PL_check[OP_ENTEREVAL]; PL_check[OP_ENTEREVAL] = dd_ck_entereval; + dd_old_ck_const = PL_check[OP_CONST]; + PL_check[OP_CONST] = dd_ck_const; } filter_add(dd_filter_realloc, NULL); diff --git a/lib/Devel/Declare.pm b/lib/Devel/Declare.pm index 3edd596..1840ec0 100644 --- a/lib/Devel/Declare.pm +++ b/lib/Devel/Declare.pm @@ -4,7 +4,7 @@ use strict; use warnings; use 5.008001; -our $VERSION = '0.001010'; +our $VERSION = '0.001011'; # mirrored in Declare.xs as DD_HANDLE_* diff --git a/t/sugar.t b/t/sugar.t index 0f1b685..a582e4b 100644 --- a/t/sugar.t +++ b/t/sugar.t @@ -58,6 +58,8 @@ my ($test_method1, $test_method2, @test_list); return join(', ', ref $self, $what); }; + method main () { return "main"; }; + #@test_list = method { 1 }, sub { 2 }, method () { 3 }, sub { 4 }; } @@ -72,6 +74,8 @@ is($o->{attr}, 'value', '@_ args ok'); is($o->foo('yay'), 'DeclareTest: Foo: yay', 'method with argument ok'); +is($o->main, 'main', 'declaration of package named method ok'); + $o->upgrade; isa_ok($o, 'DeclareTest2');