From 050c56ef263d90d862ef565bc1762909110e02eb Mon Sep 17 00:00:00 2001 From: nsfisis Date: Tue, 18 Aug 2026 01:57:02 +0900 Subject: fix(class-map-generator): anchor the type keyword search PhpFileCleaner::clean scans for the single class/interface/trait keyword of a one-declaration file with a pattern PHP runs anchored (`A`) one char before the keyword. The port dropped the anchor and relied on the leftmost match of an offset search instead, on the grounds that the keyword sits exactly one char past the offset. That holds for the keyword but not for the guards around it: where the preceding char makes PCRE fail (`Foo::class`, `$class`, `->class`), the unanchored search does not fail, it matches the next declaration further down the file and returns the cleaned prefix cut short there. Given --- crates/shirabe-class-map-generator/src/php_file_cleaner.rs | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) (limited to 'crates/shirabe-class-map-generator/src/php_file_cleaner.rs') diff --git a/crates/shirabe-class-map-generator/src/php_file_cleaner.rs b/crates/shirabe-class-map-generator/src/php_file_cleaner.rs index cfd8f77f..80aa9ce6 100644 --- a/crates/shirabe-class-map-generator/src/php_file_cleaner.rs +++ b/crates/shirabe-class-map-generator/src/php_file_cleaner.rs @@ -1,7 +1,7 @@ //! ref: composer/vendor/composer/class-map-generator/src/PhpFileCleaner.php use indexmap::IndexMap; -use shirabe_php_shim::{PregMatches, preg_match, preg_match2}; +use shirabe_php_shim::{PregMatches, preg_match}; use std::sync::Mutex; #[derive(Debug, Clone)] @@ -40,11 +40,10 @@ impl PhpFileCleaner { // consumed char plus both guards collapse into one negated class // `[^a-zA-Z0-9_$:>]` (the `\w` set reproducing `\b`, plus the three operators). // The possessive quantifiers (`++`, `*+`) are performance-only and become plain - // `+`/`*`. The leftmost-match semantics of `captures_at(.., offset)` stand in for - // the dropped `A` (anchored) modifier, since the keyword is known to sit exactly - // one char past the search offset. + // `+`/`*`. The `A` (anchored) modifier becomes a leading `^` over the sub-slice + // that begins at the search offset. pattern: format!( - "{{[^a-zA-Z0-9_$:>]{}\\s+[a-zA-Z_\\x7f-\\xff:][a-zA-Z0-9_\\x7f-\\xff:\\-]*}}is", + "{{^[^a-zA-Z0-9_$:>]{}\\s+[a-zA-Z_\\x7f-\\xff:][a-zA-Z0-9_\\x7f-\\xff:\\-]*}}is", r#type ), }, @@ -147,7 +146,7 @@ impl PhpFileCleaner { if end <= self.len && self.contents[self.index..end] == entry.name { let offset = if self.index > 0 { self.index - 1 } else { 0 }; if let Some(r#match) = - preg_match2(&entry.pattern, &self.contents, offset) + preg_match(&entry.pattern, &self.contents[offset..]) { return clean + r#match.get(0).unwrap_or(""); } -- cgit v1.3.1-4-g156e