From a814daa4dbb58c4bf6f2916ca0b61e8721a8d027 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matthias=20G=C3=BCnter?= Date: Wed, 8 Apr 2020 13:36:26 +0200 Subject: [PATCH] fix: resolve namespace section and traits correctly (fixes TypistTech/imposter#111) --- composer.json | 3 +- composer.lock | 75 ++++++++++++++++++++++++++-- src/Transformer.php | 26 ++++++++-- tests/_data/fake-vendor/Dummy.php | 13 +++++ tests/_data/fake-vendor/Expected.php | 13 +++++ 5 files changed, 122 insertions(+), 8 deletions(-) diff --git a/composer.json b/composer.json index 3d6fac0..6f1299d 100644 --- a/composer.json +++ b/composer.json @@ -25,7 +25,8 @@ ], "require": { "php": "^7.2", - "ext-json": "*" + "ext-json": "*", + "rawr/t-regx": "^0.9.6" }, "require-dev": { "codeception/codeception": "^4.1", diff --git a/composer.lock b/composer.lock index 2953f51..fb64db6 100644 --- a/composer.lock +++ b/composer.lock @@ -4,8 +4,76 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "867f7aa7959c7dce71784c2aa9d201cd", - "packages": [], + "content-hash": "97a1ea6dea5810082639711c79badb35", + "packages": [ + { + "name": "rawr/t-regx", + "version": "v0.9.6", + "source": { + "type": "git", + "url": "https://github.com/T-Regx/T-Regx.git", + "reference": "2e5b65622a194a66401db720c931fe3012c4fcee" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/T-Regx/T-Regx/zipball/2e5b65622a194a66401db720c931fe3012c4fcee", + "reference": "2e5b65622a194a66401db720c931fe3012c4fcee", + "shasum": "" + }, + "require": { + "ext-mbstring": "*", + "php": ">=7.1.0" + }, + "require-dev": { + "kelunik/fqn-check": "^0.1.3", + "php-coveralls/php-coveralls": "^2.0", + "phpunit/phpunit": "^9.0 || ^8.0 || ^7.5", + "rawr/cross-data-providers": "^2.1" + }, + "type": "library", + "autoload": { + "files": [ + "helper/helper.php" + ], + "psr-4": { + "TRegx\\": "src/TRegx" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "The most advanced PHP regexp library. Clean, descriptive wrapper functions enhancing PCRE extension methods.", + "keywords": [ + "OOP", + "PCRE", + "TDD", + "automatic delimiters", + "clean", + "delimiters", + "expression", + "php", + "preg", + "preg_match", + "preg_match_all", + "preg_quote", + "preg_replace", + "preg_replace_callback", + "prepared patterns", + "regex", + "regexp", + "regular", + "t-regx" + ], + "funding": [ + { + "url": "https://github.com/Danon", + "type": "github" + } + ], + "time": "2020-04-02T17:02:33+00:00" + } + ], "packages-dev": [ { "name": "behat/gherkin", @@ -2854,5 +2922,6 @@ "php": "^7.2", "ext-json": "*" }, - "platform-dev": [] + "platform-dev": [], + "plugin-api-version": "1.1.0" } diff --git a/src/Transformer.php b/src/Transformer.php index 4332acd..d540643 100644 --- a/src/Transformer.php +++ b/src/Transformer.php @@ -5,6 +5,7 @@ namespace TypistTech\Imposter; use SplFileInfo; +use TRegx\CleanRegex\Match\Details\Match; class Transformer implements TransformerInterface { @@ -155,12 +156,29 @@ private function prefixUseFunction(string $targetFile) private function prefixUse(string $targetFile) { $pattern = sprintf( - '/%1$s\\s+(?!(const)|(function)|(%2$s)|(\\\\(?!.*\\\\.*))|(Composer(\\\\|;)|(?!.*\\\\.*)))/', + '%1$s\\s+(?!(const)|(function)|(%2$s)|(\\\\(?!.*\\\\.*))|(Composer(\\\\|;)|(?!.*\\\\.*)))', 'use', $this->namespacePrefix ); - $replacement = sprintf('%1$s %2$s', 'use', $this->namespacePrefix); - - $this->replace($pattern, $replacement, $targetFile); + $replacement = sprintf('%1$s %2$s', 'use', str_replace('\\\\', '\\', $this->namespacePrefix)); + + $content = $this->filesystem->get($targetFile); + $output = pattern($pattern)->replace($content)->all() + ->callback(function (Match $m) use ($replacement, $content) { + // Find previous offset content and check if the last match of namespace or class is "class" + $offsetContent = substr($content, 0, $m->offset()); + preg_match_all( + '/(namespace|class)[A-Za-z0-9\\\\ ]+.?{/sm', + $offsetContent, + $nsClass, + PREG_SET_ORDER + ); + if (count($nsClass) > 0 && $nsClass[count($nsClass) - 1][1] === 'class') { + return $m->text(); + } + return $replacement; + }); + + $this->filesystem->put($targetFile, $output); } } diff --git a/tests/_data/fake-vendor/Dummy.php b/tests/_data/fake-vendor/Dummy.php index f3969ee..f390c03 100644 --- a/tests/_data/fake-vendor/Dummy.php +++ b/tests/_data/fake-vendor/Dummy.php @@ -13,6 +13,16 @@ use \UnexpectedValueException; use function OtherVendor\myFunc; use const OtherVendor\MY_MAGIC_NUMBER; +use OtherVendor\MyTrait; +use OtherVendor\Package; + +namespace OtherVendor\Package2 { + use OtherVendor\MyTrait; + + class DummyClass2 { + use OtherVendor\MyTrait; + } +} $closure = function () use ($aaa) { // Just testing. @@ -20,6 +30,9 @@ class DummyClass { + use MyTrait; + use Package\OtherTrait; + public function useClosure() { array_map(function () use ($xxx) { diff --git a/tests/_data/fake-vendor/Expected.php b/tests/_data/fake-vendor/Expected.php index 555d538..20ceb86 100644 --- a/tests/_data/fake-vendor/Expected.php +++ b/tests/_data/fake-vendor/Expected.php @@ -13,6 +13,16 @@ use \UnexpectedValueException; use function MyPlugin\Vendor\OtherVendor\myFunc; use const MyPlugin\Vendor\OtherVendor\MY_MAGIC_NUMBER; +use MyPlugin\Vendor\OtherVendor\MyTrait; +use MyPlugin\Vendor\OtherVendor\Package; + +namespace MyPlugin\Vendor\OtherVendor\Package2 { + use MyPlugin\Vendor\OtherVendor\MyTrait; + + class DummyClass2 { + use OtherVendor\MyTrait; + } +} $closure = function () use ($aaa) { // Just testing. @@ -20,6 +30,9 @@ class DummyClass { + use MyTrait; + use Package\OtherTrait; + public function useClosure() { array_map(function () use ($xxx) {