]> git.vpit.fr Git - perl/modules/indirect.git/blobdiff - indirect.xs
Handle __PACKAGE__ as object name correctly
[perl/modules/indirect.git] / indirect.xs
index d3d1e00726adca2872ed02771dc2f29c94ae6f83..3bd5e6cef5addca2a46f23de0f07979c1152d5dc 100644 (file)
@@ -75,6 +75,9 @@
 # ifndef PL_oldbufptr
 #  define PL_oldbufptr PL_parser->oldbufptr
 # endif
 # ifndef PL_oldbufptr
 #  define PL_oldbufptr PL_parser->oldbufptr
 # endif
+# ifndef PL_lex_inwhat
+#  define PL_lex_inwhat PL_parser->lex_inwhat
+# endif
 #else
 # ifndef PL_linestr
 #  define PL_linestr PL_Ilinestr
 #else
 # ifndef PL_linestr
 #  define PL_linestr PL_Ilinestr
@@ -85,6 +88,9 @@
 # ifndef PL_oldbufptr
 #  define PL_oldbufptr PL_Ioldbufptr
 # endif
 # ifndef PL_oldbufptr
 #  define PL_oldbufptr PL_Ioldbufptr
 # endif
+# ifndef PL_lex_inwhat
+#  define PL_lex_inwhat PL_Ilex_inwhat
+# endif
 #endif
 
 #ifndef I_WORKAROUND_REQUIRE_PROPAGATION
 #endif
 
 #ifndef I_WORKAROUND_REQUIRE_PROPAGATION
@@ -517,27 +523,12 @@ STATIC void indirect_map_delete(pTHX_ const OP *o) {
 
 /* --- Check functions ----------------------------------------------------- */
 
 
 /* --- Check functions ----------------------------------------------------- */
 
-STATIC STRLEN indirect_nextline(const char *s, STRLEN len) {
- STRLEN i;
-
- for (i = 0; i < len; ++i) {
-  if (s[i] == '\n') {
-   ++i;
-   while (i < len && s[i] == '\r')
-    ++i;
-   break;
-  }
- }
-
- return i;
-}
-
 STATIC int indirect_find(pTHX_ SV *name_sv, const char *line_bufptr, STRLEN *name_pos) {
 #define indirect_find(NSV, LBP, NP) indirect_find(aTHX_ (NSV), (LBP), (NP))
  STRLEN      name_len, line_len;
  const char *name, *name_end;
  const char *line, *line_end;
 STATIC int indirect_find(pTHX_ SV *name_sv, const char *line_bufptr, STRLEN *name_pos) {
 #define indirect_find(NSV, LBP, NP) indirect_find(aTHX_ (NSV), (LBP), (NP))
  STRLEN      name_len, line_len;
  const char *name, *name_end;
  const char *line, *line_end;
- const char *p, *t, *u;
+ const char *p;
 
  line     = SvPV_const(PL_linestr, line_len);
  line_end = line + line_len;
 
  line     = SvPV_const(PL_linestr, line_len);
  line_end = line + line_len;
@@ -566,17 +557,7 @@ STATIC int indirect_find(pTHX_ SV *name_sv, const char *line_bufptr, STRLEN *nam
    ++p;
  }
 
    ++p;
  }
 
- t = line;
- u = t;
- while (t <= p) {
-  STRLEN i = indirect_nextline(t, line_len);
-  if (i >= line_len)
-   break;
-  u         = t;
-  t        += i;
-  line_len -= i;
- }
- *name_pos = p - u;
+ *name_pos = p - line;
 
  return 1;
 }
 
  return 1;
 }
@@ -595,6 +576,25 @@ STATIC OP *indirect_ck_const(pTHX_ OP *o) {
    STRLEN pos;
 
    if (indirect_find(sv, PL_oldbufptr, &pos)) {
    STRLEN pos;
 
    if (indirect_find(sv, PL_oldbufptr, &pos)) {
+    STRLEN len;
+
+    /* If the constant is equal to the current package name, try to look for
+     * a "__PACKAGE__" coming before what we got. We only need to check this
+     * when we already had a match because __PACKAGE__ can only appear in
+     * direct method calls ("new __PACKAGE__" is a syntax error). */
+    len = SvCUR(sv);
+    if (len == HvNAMELEN_get(PL_curstash)
+        && memcmp(SvPVX(sv), HvNAME_get(PL_curstash), len) == 0) {
+     STRLEN pos_pkg;
+     SV    *pkg = sv_newmortal();
+     sv_setpvn(pkg, "__PACKAGE__", sizeof("__PACKAGE__")-1);
+
+     if (indirect_find(pkg, PL_oldbufptr, &pos_pkg) && pos_pkg < pos) {
+      sv  = pkg;
+      pos = pos_pkg;
+     }
+    }
+
     indirect_map_store(o, pos, sv, CopLINE(&PL_compiling));
     return o;
    }
     indirect_map_store(o, pos, sv, CopLINE(&PL_compiling));
     return o;
    }