Repository: spaze/phpstan-disallowed-calls (php)

Issue:
When running phpstan from a subdirectory, allowIn is ignored
When you run phpstan from a subdirectory of the project the allowIn is not checked

`../../vendor/bin/phpstan --configuration=../../phpstan.neon`

```yaml
    disallowedFunctionCalls:
      - function: 'var_export()'
        message: 'use logger instead'
        allowIn:
        - tests/ExtendedFakes/ExtendedQueueFake.php
      - function: 'var_dump()'
        message: 'use logger instead'
      - function: 'print_r()'
        message: 'use logger instead'
      - function: 'dd()'
        message: 'forbidden function'
      - function: 'dump()'
        message: 'forbidden function'
        allowIn:
        - tests/ExtendedFakes/ExtendedQueueFake.php
      - function: 'exit()'
        message: 'forbidden function'
      - function: 'die()'
        message: 'forbidden function'
 ```
 
 Gives me:
 ```
  ------ ------------------------------------------------------- 
  Line   tests/ExtendedFakes/ExtendedQueueFake.php              
 ------ ------------------------------------------------------- 
  51     Calling dump() is forbidden, forbidden function        
  68     Calling var_export() is forbidden, use logger instead  
  77     Calling dump() is forbidden, forbidden function        
 ------ ------------------------------------------------------- 
```

Edit: running from the root, gives no errors

Pull request:
Can now specify root dir for all `allowIn` paths
Seems I can't get the "root" directory in an automated way. Directives like `ignoreError`'s `path`/`paths` [resolve relative paths](https://phpstan.org/user-guide/ignoring-errors#ignoring-in-configuration-file) based on the directory of the config file is in but those are [special cases](https://github.com/phpstan/phpstan-src/blob/13047ff2264f7672ad819470b6a801283f353aa8/src/DependencyInjection/NeonAdapter.php#L103-L124) which I can't add into.

Fix #100

Patch:
diff --git a/README.md b/README.md
index 3a7c1cd..a64854a 100644
--- a/README.md
+++ b/README.md
@@ -216,7 +216,23 @@ parameters:
                 - tests/*.test.php
 ```
 
-The paths in `allowIn` are relative to the config file location and support [fnmatch()](https://www.php.net/function.fnmatch) patterns.
+Paths in `allowIn` support [fnmatch()](https://www.php.net/function.fnmatch) patterns.
+
+Relative paths in `allowIn` are resolved based on the current working directory. When running PHPStan from a directory or subdirectory which is not your "root" directory, the paths will probably not work.
+Use `allowInRootDir` in that case to specify an absolute root directory for all `allowIn` paths. Absolute paths might change between machines (for example your local development machine and a continous integration machine) but you
+can use [`%rootDir%`](https://phpstan.org/config-reference#expanding-paths) to start with PHPStan's root directory (usually `/something/something/vendor/phpstan/phpstan`) and then `..` from there to your "root" directory.
+
+For example when PHPStan is installed in `/home/foo/vendor/phpstan/phpstan` and you're using a configuration like this:
+```neon
+parameters:
+    allowInRootDir: %rootDir%/../../..
+    disallowedMethodCalls:
+        -
+            method: 'PotentiallyDangerous\Logger::log()'
+            allowIn:
+                - path/to/some/file-*.php
+```
+then `Logger::log()` will be allowed in `/home/foo/path/to/some/file-bar.php`.
 
 To allow a previously disallowed method or function only when called from a different method or function in any file, use `allowInFunctions` (or `allowInMethods` alias):
 
diff --git a/extension.neon b/extension.neon
index eed5908..0097cdf 100644
--- a/extension.neon
+++ b/extension.neon
@@ -1,4 +1,5 @@
 parameters:
+	allowInRootDir: null
 	disallowedNamespaces: []
 	disallowedMethodCalls: []
 	disallowedStaticCalls: []
@@ -6,6 +7,7 @@ parameters:
 	disallowedConstants: []
 
 parametersSchema:
+	allowInRootDir: schema(string(), nullable())
 	# These should be defined using `structure` with listed keys but it seems to me that PHPStan requires
 	# all keys to be present in a structure but `message` & `allow*` are optional.
 	disallowedNamespaces: listOf(
@@ -55,7 +57,7 @@ parametersSchema:
 	)
 
 services:
-	- Spaze\PHPStan\Rules\Disallowed\FileHelper
+	- Spaze\PHPStan\Rules\Disallowed\IsAllowedFileHelper(allowInRootDir: %allowInRootDir%)
 	- Spaze\PHPStan\Rules\Disallowed\DisallowedCallFactory
 	- Spaze\PHPStan\Rules\Disallowed\DisallowedConstantFactory
 	- Spaze\PHPStan\Rules\Disallowed\DisallowedHelper
diff --git a/src/DisallowedHelper.php b/src/DisallowedHelper.php
index 1c9728c..e7ea127 100644
--- a/src/DisallowedHelper.php
+++ b/src/DisallowedHelper.php
@@ -22,13 +22,13 @@ use Spaze\PHPStan\Rules\Disallowed\Params\DisallowedCallParam;
 class DisallowedHelper
 {
 
-	/** @var FileHelper */
-	private $fileHelper;
+	/** @var IsAllowedFileHelper */
+	private $isAllowedFileHelper;
 
 
-	public function __construct(FileHelper $fileHelper)
+	public function __construct(IsAllowedFileHelper $isAllowedFileHelper)
 	{
-		$this->fileHelper = $fileHelper;
+		$this->isAllowedFileHelper = $isAllowedFileHelper;
 	}
 
 
@@ -47,7 +47,7 @@ class DisallowedHelper
 			}
 		}
 		foreach ($disallowedCall->getAllowIn() as $allowedPath) {
-			if (fnmatch($this->fileHelper->absolutizePath($allowedPath), $scope->getFile())) {
+			if (fnmatch($this->isAllowedFileHelper->absolutizePath($allowedPath), $scope->getFile())) {
 				return $this->hasAllowedParamsInAllowed($scope, $node, $disallowedCall);
 			}
 		}
@@ -206,7 +206,7 @@ class DisallowedHelper
 	private function isAllowedPath(Scope $scope, DisallowedConstant $disallowedConstant): bool
 	{
 		foreach ($disallowedConstant->getAllowIn() as $allowedPath) {
-			if (fnmatch($this->fileHelper->absolutizePath($allowedPath), $scope->getFile())) {
+			if (fnmatch($this->isAllowedFileHelper->absolutizePath($allowedPath), $scope->getFile())) {
 				return true;
 			}
 		}
diff --git a/src/DisallowedNamespaceHelper.php b/src/DisallowedNamespaceHelper.php
index a887154..8b464e5 100644
--- a/src/DisallowedNamespaceHelper.php
+++ b/src/DisallowedNamespaceHelper.php
@@ -10,13 +10,13 @@ use PHPStan\Rules\RuleErrorBuilder;
 class DisallowedNamespaceHelper
 {
 
-	/** @var FileHelper */
-	private $fileHelper;
+	/** @var IsAllowedFileHelper */
+	private $isAllowedFileHelper;
 
 
-	public function __construct(FileHelper $fileHelper)
+	public function __construct(IsAllowedFileHelper $isAllowedFileHelper)
 	{
-		$this->fileHelper = $fileHelper;
+		$this->isAllowedFileHelper = $isAllowedFileHelper;
 	}
 
 
@@ -28,7 +28,7 @@ class DisallowedNamespaceHelper
 	private function isAllowed(Scope $scope, DisallowedNamespace $disallowedNamespace): bool
 	{
 		foreach ($disallowedNamespace->getAllowIn() as $allowedPath) {
-			$match = fnmatch($this->fileHelper->absolutizePath($allowedPath), $scope->getFile());
+			$match = fnmatch($this->isAllowedFileHelper->absolutizePath($allowedPath), $scope->getFile());
 			if ($match) {
 				return true;
 			}
diff --git a/src/FileHelper.php b/src/IsAllowedFileHelper.php
similarity index 50%
rename from src/FileHelper.php
rename to src/IsAllowedFileHelper.php
index 9dcf68e..cc8ebc0 100644
--- a/src/FileHelper.php
+++ b/src/IsAllowedFileHelper.php
@@ -3,18 +3,22 @@ declare(strict_types = 1);
 
 namespace Spaze\PHPStan\Rules\Disallowed;
 
-use PHPStan\File\FileHelper as PHPStanFileHelper;
+use PHPStan\File\FileHelper;
 
-class FileHelper
+class IsAllowedFileHelper
 {
 
-	/** @var PHPStanFileHelper */
+	/** @var FileHelper */
 	private $fileHelper;
 
+	/** @var string|null */
+	private $allowInRootDir;
 
-	public function __construct(PHPStanFileHelper $fileHelper)
+
+	public function __construct(FileHelper $fileHelper, ?string $allowInRootDir = null)
 	{
 		$this->fileHelper = $fileHelper;
+		$this->allowInRootDir = $allowInRootDir !== null ? $this->fileHelper->normalizePath($fileHelper->absolutizePath($allowInRootDir)) : null;
 	}
 
 
@@ -30,6 +34,9 @@ class FileHelper
 			return $path;
 		}
 
+		if ($this->allowInRootDir !== null) {
+			$path = rtrim($this->allowInRootDir, '/') . '/' . ltrim($path, '/');
+		}
 		return $this->fileHelper->normalizePath($this->fileHelper->absolutizePath($path));
 	}
 


Test patch:
diff --git a/tests/Calls/EchoCallsTest.php b/tests/Calls/EchoCallsTest.php
index b1226e2..a86228f 100644
--- a/tests/Calls/EchoCallsTest.php
+++ b/tests/Calls/EchoCallsTest.php
@@ -3,12 +3,12 @@ declare(strict_types = 1);
 
 namespace Spaze\PHPStan\Rules\Disallowed\Calls;
 
-use PHPStan\File\FileHelper as PHPStanFileHelper;
+use PHPStan\File\FileHelper;
 use PHPStan\Rules\Rule;
 use PHPStan\Testing\RuleTestCase;
 use Spaze\PHPStan\Rules\Disallowed\DisallowedCallFactory;
 use Spaze\PHPStan\Rules\Disallowed\DisallowedHelper;
-use Spaze\PHPStan\Rules\Disallowed\FileHelper;
+use Spaze\PHPStan\Rules\Disallowed\IsAllowedFileHelper;
 
 class EchoCallsTest extends RuleTestCase
 {
@@ -16,7 +16,7 @@ class EchoCallsTest extends RuleTestCase
 	protected function getRule(): Rule
 	{
 		return new EchoCalls(
-			new DisallowedHelper(new FileHelper(new PHPStanFileHelper(__DIR__))),
+			new DisallowedHelper(new IsAllowedFileHelper(new FileHelper(__DIR__))),
 			new DisallowedCallFactory(),
 			[
 				[
diff --git a/tests/Calls/EmptyCallsTest.php b/tests/Calls/EmptyCallsTest.php
index 146d9c7..14e8bd0 100644
--- a/tests/Calls/EmptyCallsTest.php
+++ b/tests/Calls/EmptyCallsTest.php
@@ -3,12 +3,12 @@ declare(strict_types = 1);
 
 namespace Spaze\PHPStan\Rules\Disallowed\Calls;
 
-use PHPStan\File\FileHelper as PHPStanFileHelper;
+use PHPStan\File\FileHelper;
 use PHPStan\Rules\Rule;
 use PHPStan\Testing\RuleTestCase;
 use Spaze\PHPStan\Rules\Disallowed\DisallowedCallFactory;
 use Spaze\PHPStan\Rules\Disallowed\DisallowedHelper;
-use Spaze\PHPStan\Rules\Disallowed\FileHelper;
+use Spaze\PHPStan\Rules\Disallowed\IsAllowedFileHelper;
 
 class EmptyCallsTest extends RuleTestCase
 {
@@ -16,7 +16,7 @@ class EmptyCallsTest extends RuleTestCase
 	protected function getRule(): Rule
 	{
 		return new EmptyCalls(
-			new DisallowedHelper(new FileHelper(new PHPStanFileHelper(__DIR__))),
+			new DisallowedHelper(new IsAllowedFileHelper(new FileHelper(__DIR__))),
 			new DisallowedCallFactory(),
 			[
 				[
diff --git a/tests/Calls/EvalCallsTest.php b/tests/Calls/EvalCallsTest.php
index e80674c..198bdf1 100644
--- a/tests/Calls/EvalCallsTest.php
+++ b/tests/Calls/EvalCallsTest.php
@@ -3,12 +3,12 @@ declare(strict_types = 1);
 
 namespace Spaze\PHPStan\Rules\Disallowed\Calls;
 
-use PHPStan\File\FileHelper as PHPStanFileHelper;
+use PHPStan\File\FileHelper;
 use PHPStan\Rules\Rule;
 use PHPStan\Testing\RuleTestCase;
 use Spaze\PHPStan\Rules\Disallowed\DisallowedCallFactory;
 use Spaze\PHPStan\Rules\Disallowed\DisallowedHelper;
-use Spaze\PHPStan\Rules\Disallowed\FileHelper;
+use Spaze\PHPStan\Rules\Disallowed\IsAllowedFileHelper;
 
 class EvalCallsTest extends RuleTestCase
 {
@@ -16,7 +16,7 @@ class EvalCallsTest extends RuleTestCase
 	protected function getRule(): Rule
 	{
 		return new EvalCalls(
-			new DisallowedHelper(new FileHelper(new PHPStanFileHelper(__DIR__))),
+			new DisallowedHelper(new IsAllowedFileHelper(new FileHelper(__DIR__))),
 			new DisallowedCallFactory(),
 			[
 				[
diff --git a/tests/Calls/ExitDieCallsTest.php b/tests/Calls/ExitDieCallsTest.php
index 0a49399..4f2e0f1 100644
--- a/tests/Calls/ExitDieCallsTest.php
+++ b/tests/Calls/ExitDieCallsTest.php
@@ -3,12 +3,12 @@ declare(strict_types = 1);
 
 namespace Spaze\PHPStan\Rules\Disallowed\Calls;
 
-use PHPStan\File\FileHelper as PHPStanFileHelper;
+use PHPStan\File\FileHelper;
 use PHPStan\Rules\Rule;
 use PHPStan\Testing\RuleTestCase;
 use Spaze\PHPStan\Rules\Disallowed\DisallowedCallFactory;
 use Spaze\PHPStan\Rules\Disallowed\DisallowedHelper;
-use Spaze\PHPStan\Rules\Disallowed\FileHelper;
+use Spaze\PHPStan\Rules\Disallowed\IsAllowedFileHelper;
 
 class ExitDieCallsTest extends RuleTestCase
 {
@@ -16,7 +16,7 @@ class ExitDieCallsTest extends RuleTestCase
 	protected function getRule(): Rule
 	{
 		return new ExitDieCalls(
-			new DisallowedHelper(new FileHelper(new PHPStanFileHelper(__DIR__))),
+			new DisallowedHelper(new IsAllowedFileHelper(new FileHelper(__DIR__))),
 			new DisallowedCallFactory(),
 			[
 				[
diff --git a/tests/Calls/FunctionCallsAllowInFunctionsTest.php b/tests/Calls/FunctionCallsAllowInFunctionsTest.php
index 3fb5776..6539916 100644
--- a/tests/Calls/FunctionCallsAllowInFunctionsTest.php
+++ b/tests/Calls/FunctionCallsAllowInFunctionsTest.php
@@ -3,12 +3,12 @@ declare(strict_types = 1);
 
 namespace Spaze\PHPStan\Rules\Disallowed\Calls;
 
-use PHPStan\File\FileHelper as PHPStanFileHelper;
+use PHPStan\File\FileHelper;
 use PHPStan\Rules\Rule;
 use PHPStan\Testing\RuleTestCase;
 use Spaze\PHPStan\Rules\Disallowed\DisallowedCallFactory;
 use Spaze\PHPStan\Rules\Disallowed\DisallowedHelper;
-use Spaze\PHPStan\Rules\Disallowed\FileHelper;
+use Spaze\PHPStan\Rules\Disallowed\IsAllowedFileHelper;
 
 class FunctionCallsAllowInFunctionsTest extends RuleTestCase
 {
@@ -16,7 +16,7 @@ class FunctionCallsAllowInFunctionsTest extends RuleTestCase
 	protected function getRule(): Rule
 	{
 		return new FunctionCalls(
-			new DisallowedHelper(new FileHelper(new PHPStanFileHelper(__DIR__))),
+			new DisallowedHelper(new IsAllowedFileHelper(new FileHelper(__DIR__))),
 			new DisallowedCallFactory(),
 			[
 				[
diff --git a/tests/Calls/FunctionCallsAllowInMethodsTest.php b/tests/Calls/FunctionCallsAllowInMethodsTest.php
index 1e31d7c..d12dc83 100644
--- a/tests/Calls/FunctionCallsAllowInMethodsTest.php
+++ b/tests/Calls/FunctionCallsAllowInMethodsTest.php
@@ -3,12 +3,12 @@ declare(strict_types = 1);
 
 namespace Spaze\PHPStan\Rules\Disallowed\Calls;
 
-use PHPStan\File\FileHelper as PHPStanFileHelper;
+use PHPStan\File\FileHelper;
 use PHPStan\Rules\Rule;
 use PHPStan\Testing\RuleTestCase;
 use Spaze\PHPStan\Rules\Disallowed\DisallowedCallFactory;
 use Spaze\PHPStan\Rules\Disallowed\DisallowedHelper;
-use Spaze\PHPStan\Rules\Disallowed\FileHelper;
+use Spaze\PHPStan\Rules\Disallowed\IsAllowedFileHelper;
 
 class FunctionCallsAllowInMethodsTest extends RuleTestCase
 {
@@ -16,7 +16,7 @@ class FunctionCallsAllowInMethodsTest extends RuleTestCase
 	protected function getRule(): Rule
 	{
 		return new FunctionCalls(
-			new DisallowedHelper(new FileHelper(new PHPStanFileHelper(__DIR__))),
+			new DisallowedHelper(new IsAllowedFileHelper(new FileHelper(__DIR__))),
 			new DisallowedCallFactory(),
 			[
 				[
diff --git a/tests/Calls/FunctionCallsTest.php b/tests/Calls/FunctionCallsTest.php
index 933b52f..35d10e8 100644
--- a/tests/Calls/FunctionCallsTest.php
+++ b/tests/Calls/FunctionCallsTest.php
@@ -3,12 +3,12 @@ declare(strict_types = 1);
 
 namespace Spaze\PHPStan\Rules\Disallowed\Calls;
 
-use PHPStan\File\FileHelper as PHPStanFileHelper;
+use PHPStan\File\FileHelper;
 use PHPStan\Rules\Rule;
 use PHPStan\Testing\RuleTestCase;
 use Spaze\PHPStan\Rules\Disallowed\DisallowedCallFactory;
 use Spaze\PHPStan\Rules\Disallowed\DisallowedHelper;
-use Spaze\PHPStan\Rules\Disallowed\FileHelper;
+use Spaze\PHPStan\Rules\Disallowed\IsAllowedFileHelper;
 
 class FunctionCallsTest extends RuleTestCase
 {
@@ -16,7 +16,7 @@ class FunctionCallsTest extends RuleTestCase
 	protected function getRule(): Rule
 	{
 		return new FunctionCalls(
-			new DisallowedHelper(new FileHelper(new PHPStanFileHelper(__DIR__))),
+			new DisallowedHelper(new IsAllowedFileHelper(new FileHelper(__DIR__))),
 			new DisallowedCallFactory(),
 			[
 				[
diff --git a/tests/Calls/MethodCallsTest.php b/tests/Calls/MethodCallsTest.php
index ae443eb..1bcbbb4 100644
--- a/tests/Calls/MethodCallsTest.php
+++ b/tests/Calls/MethodCallsTest.php
@@ -3,12 +3,12 @@ declare(strict_types = 1);
 
 namespace Spaze\PHPStan\Rules\Disallowed\Calls;
 
-use PHPStan\File\FileHelper as PHPStanFileHelper;
+use PHPStan\File\FileHelper;
 use PHPStan\Rules\Rule;
 use PHPStan\Testing\RuleTestCase;
 use Spaze\PHPStan\Rules\Disallowed\DisallowedCallFactory;
 use Spaze\PHPStan\Rules\Disallowed\DisallowedHelper;
-use Spaze\PHPStan\Rules\Disallowed\FileHelper;
+use Spaze\PHPStan\Rules\Disallowed\IsAllowedFileHelper;
 
 class MethodCallsTest extends RuleTestCase
 {
@@ -16,7 +16,7 @@ class MethodCallsTest extends RuleTestCase
 	protected function getRule(): Rule
 	{
 		return new MethodCalls(
-			new DisallowedHelper(new FileHelper(new PHPStanFileHelper(__DIR__))),
+			new DisallowedHelper(new IsAllowedFileHelper(new FileHelper(__DIR__))),
 			new DisallowedCallFactory(),
 			[
 				[
diff --git a/tests/Calls/NewCallsTest.php b/tests/Calls/NewCallsTest.php
index 90412a8..55cfa17 100644
--- a/tests/Calls/NewCallsTest.php
+++ b/tests/Calls/NewCallsTest.php
@@ -3,12 +3,12 @@ declare(strict_types = 1);
 
 namespace Spaze\PHPStan\Rules\Disallowed\Calls;
 
-use PHPStan\File\FileHelper as PHPStanFileHelper;
+use PHPStan\File\FileHelper;
 use PHPStan\Rules\Rule;
 use PHPStan\Testing\RuleTestCase;
 use Spaze\PHPStan\Rules\Disallowed\DisallowedCallFactory;
 use Spaze\PHPStan\Rules\Disallowed\DisallowedHelper;
-use Spaze\PHPStan\Rules\Disallowed\FileHelper;
+use Spaze\PHPStan\Rules\Disallowed\IsAllowedFileHelper;
 
 class NewCallsTest extends RuleTestCase
 {
@@ -16,7 +16,7 @@ class NewCallsTest extends RuleTestCase
 	protected function getRule(): Rule
 	{
 		return new NewCalls(
-			new DisallowedHelper(new FileHelper(new PHPStanFileHelper(__DIR__))),
+			new DisallowedHelper(new IsAllowedFileHelper(new FileHelper(__DIR__))),
 			new DisallowedCallFactory(),
 			[
 				[
diff --git a/tests/Calls/PrintCallsTest.php b/tests/Calls/PrintCallsTest.php
index 166ce7d..657a5c8 100644
--- a/tests/Calls/PrintCallsTest.php
+++ b/tests/Calls/PrintCallsTest.php
@@ -3,12 +3,12 @@ declare(strict_types = 1);
 
 namespace Spaze\PHPStan\Rules\Disallowed\Calls;
 
-use PHPStan\File\FileHelper as PHPStanFileHelper;
+use PHPStan\File\FileHelper;
 use PHPStan\Rules\Rule;
 use PHPStan\Testing\RuleTestCase;
 use Spaze\PHPStan\Rules\Disallowed\DisallowedCallFactory;
 use Spaze\PHPStan\Rules\Disallowed\DisallowedHelper;
-use Spaze\PHPStan\Rules\Disallowed\FileHelper;
+use Spaze\PHPStan\Rules\Disallowed\IsAllowedFileHelper;
 
 class PrintCallsTest extends RuleTestCase
 {
@@ -16,7 +16,7 @@ class PrintCallsTest extends RuleTestCase
 	protected function getRule(): Rule
 	{
 		return new PrintCalls(
-			new DisallowedHelper(new FileHelper(new PHPStanFileHelper(__DIR__))),
+			new DisallowedHelper(new IsAllowedFileHelper(new FileHelper(__DIR__))),
 			new DisallowedCallFactory(),
 			[
 				[
diff --git a/tests/Calls/ShellExecCallsTest.php b/tests/Calls/ShellExecCallsTest.php
index a8454a4..ea73248 100644
--- a/tests/Calls/ShellExecCallsTest.php
+++ b/tests/Calls/ShellExecCallsTest.php
@@ -3,12 +3,12 @@ declare(strict_types = 1);
 
 namespace Spaze\PHPStan\Rules\Disallowed\Calls;
 
-use PHPStan\File\FileHelper as PHPStanFileHelper;
+use PHPStan\File\FileHelper;
 use PHPStan\Rules\Rule;
 use PHPStan\Testing\RuleTestCase;
 use Spaze\PHPStan\Rules\Disallowed\DisallowedCallFactory;
 use Spaze\PHPStan\Rules\Disallowed\DisallowedHelper;
-use Spaze\PHPStan\Rules\Disallowed\FileHelper;
+use Spaze\PHPStan\Rules\Disallowed\IsAllowedFileHelper;
 
 class ShellExecCallsTest extends RuleTestCase
 {
@@ -16,7 +16,7 @@ class ShellExecCallsTest extends RuleTestCase
 	protected function getRule(): Rule
 	{
 		return new ShellExecCalls(
-			new DisallowedHelper(new FileHelper(new PHPStanFileHelper(__DIR__))),
+			new DisallowedHelper(new IsAllowedFileHelper(new FileHelper(__DIR__))),
 			new DisallowedCallFactory(),
 			[
 				[
diff --git a/tests/Calls/StaticCallsTest.php b/tests/Calls/StaticCallsTest.php
index 8030ee6..b8d68e6 100644
--- a/tests/Calls/StaticCallsTest.php
+++ b/tests/Calls/StaticCallsTest.php
@@ -3,12 +3,12 @@ declare(strict_types = 1);
 
 namespace Spaze\PHPStan\Rules\Disallowed\Calls;
 
-use PHPStan\File\FileHelper as PHPStanFileHelper;
+use PHPStan\File\FileHelper;
 use PHPStan\Rules\Rule;
 use PHPStan\Testing\RuleTestCase;
 use Spaze\PHPStan\Rules\Disallowed\DisallowedCallFactory;
 use Spaze\PHPStan\Rules\Disallowed\DisallowedHelper;
-use Spaze\PHPStan\Rules\Disallowed\FileHelper;
+use Spaze\PHPStan\Rules\Disallowed\IsAllowedFileHelper;
 
 class StaticCallsTest extends RuleTestCase
 {
@@ -16,7 +16,7 @@ class StaticCallsTest extends RuleTestCase
 	protected function getRule(): Rule
 	{
 		return new StaticCalls(
-			new DisallowedHelper(new FileHelper(new PHPStanFileHelper(__DIR__))),
+			new DisallowedHelper(new IsAllowedFileHelper(new FileHelper(__DIR__))),
 			new DisallowedCallFactory(),
 			[
 				[
diff --git a/tests/Configs/DangerousConfigEvalCallsTest.php b/tests/Configs/DangerousConfigEvalCallsTest.php
index b1cf8c5..c5fae94 100644
--- a/tests/Configs/DangerousConfigEvalCallsTest.php
+++ b/tests/Configs/DangerousConfigEvalCallsTest.php
@@ -4,13 +4,13 @@ declare(strict_types = 1);
 namespace Spaze\PHPStan\Rules\Disallowed\Configs;
 
 use Nette\Neon\Neon;
-use PHPStan\File\FileHelper as PHPStanFileHelper;
+use PHPStan\File\FileHelper;
 use PHPStan\Rules\Rule;
 use PHPStan\Testing\RuleTestCase;
 use Spaze\PHPStan\Rules\Disallowed\Calls\EvalCalls;
 use Spaze\PHPStan\Rules\Disallowed\DisallowedCallFactory;
 use Spaze\PHPStan\Rules\Disallowed\DisallowedHelper;
-use Spaze\PHPStan\Rules\Disallowed\FileHelper;
+use Spaze\PHPStan\Rules\Disallowed\IsAllowedFileHelper;
 
 class DangerousConfigEvalCallsTest extends RuleTestCase
 {
@@ -20,7 +20,7 @@ class DangerousConfigEvalCallsTest extends RuleTestCase
 		// Load the configuration from this file
 		$config = Neon::decode(file_get_contents(__DIR__ . '/../../disallowed-dangerous-calls.neon'));
 		return new EvalCalls(
-			new DisallowedHelper(new FileHelper(new PHPStanFileHelper(__DIR__))),
+			new DisallowedHelper(new IsAllowedFileHelper(new FileHelper(__DIR__))),
 			new DisallowedCallFactory(),
 			$config['parameters']['disallowedFunctionCalls']
 		);
diff --git a/tests/Configs/DangerousConfigFunctionCallsTest.php b/tests/Configs/DangerousConfigFunctionCallsTest.php
index 6298e99..c51595c 100644
--- a/tests/Configs/DangerousConfigFunctionCallsTest.php
+++ b/tests/Configs/DangerousConfigFunctionCallsTest.php
@@ -4,13 +4,13 @@ declare(strict_types = 1);
 namespace Spaze\PHPStan\Rules\Disallowed\Configs;
 
 use Nette\Neon\Neon;
-use PHPStan\File\FileHelper as PHPStanFileHelper;
+use PHPStan\File\FileHelper;
 use PHPStan\Rules\Rule;
 use PHPStan\Testing\RuleTestCase;
 use Spaze\PHPStan\Rules\Disallowed\Calls\FunctionCalls;
 use Spaze\PHPStan\Rules\Disallowed\DisallowedCallFactory;
 use Spaze\PHPStan\Rules\Disallowed\DisallowedHelper;
-use Spaze\PHPStan\Rules\Disallowed\FileHelper;
+use Spaze\PHPStan\Rules\Disallowed\IsAllowedFileHelper;
 
 class DangerousConfigFunctionCallsTest extends RuleTestCase
 {
@@ -20,7 +20,7 @@ class DangerousConfigFunctionCallsTest extends RuleTestCase
 		// Load the configuration from this file
 		$config = Neon::decode(file_get_contents(__DIR__ . '/../../disallowed-dangerous-calls.neon'));
 		return new FunctionCalls(
-			new DisallowedHelper(new FileHelper(new PHPStanFileHelper(__DIR__))),
+			new DisallowedHelper(new IsAllowedFileHelper(new FileHelper(__DIR__))),
 			new DisallowedCallFactory(),
 			$config['parameters']['disallowedFunctionCalls']
 		);
diff --git a/tests/Configs/ExecutionConfigFunctionCallsTest.php b/tests/Configs/ExecutionConfigFunctionCallsTest.php
index 7b75db8..89619cf 100644
--- a/tests/Configs/ExecutionConfigFunctionCallsTest.php
+++ b/tests/Configs/ExecutionConfigFunctionCallsTest.php
@@ -4,13 +4,13 @@ declare(strict_types = 1);
 namespace Spaze\PHPStan\Rules\Disallowed\Configs;
 
 use Nette\Neon\Neon;
-use PHPStan\File\FileHelper as PHPStanFileHelper;
+use PHPStan\File\FileHelper;
 use PHPStan\Rules\Rule;
 use PHPStan\Testing\RuleTestCase;
 use Spaze\PHPStan\Rules\Disallowed\Calls\FunctionCalls;
 use Spaze\PHPStan\Rules\Disallowed\DisallowedCallFactory;
 use Spaze\PHPStan\Rules\Disallowed\DisallowedHelper;
-use Spaze\PHPStan\Rules\Disallowed\FileHelper;
+use Spaze\PHPStan\Rules\Disallowed\IsAllowedFileHelper;
 
 class ExecutionConfigFunctionCallsTest extends RuleTestCase
 {
@@ -20,7 +20,7 @@ class ExecutionConfigFunctionCallsTest extends RuleTestCase
 		// Load the configuration from this file
 		$config = Neon::decode(file_get_contents(__DIR__ . '/../../disallowed-execution-calls.neon'));
 		return new FunctionCalls(
-			new DisallowedHelper(new FileHelper(new PHPStanFileHelper(__DIR__))),
+			new DisallowedHelper(new IsAllowedFileHelper(new FileHelper(__DIR__))),
 			new DisallowedCallFactory(),
 			$config['parameters']['disallowedFunctionCalls']
 		);
diff --git a/tests/Configs/ExecutionConfigShellExecCallsTest.php b/tests/Configs/ExecutionConfigShellExecCallsTest.php
index 4f8fa59..cb5fc99 100644
--- a/tests/Configs/ExecutionConfigShellExecCallsTest.php
+++ b/tests/Configs/ExecutionConfigShellExecCallsTest.php
@@ -4,13 +4,13 @@ declare(strict_types = 1);
 namespace Spaze\PHPStan\Rules\Disallowed\Configs;
 
 use Nette\Neon\Neon;
-use PHPStan\File\FileHelper as PHPStanFileHelper;
+use PHPStan\File\FileHelper;
 use PHPStan\Rules\Rule;
 use PHPStan\Testing\RuleTestCase;
 use Spaze\PHPStan\Rules\Disallowed\Calls\ShellExecCalls;
 use Spaze\PHPStan\Rules\Disallowed\DisallowedCallFactory;
 use Spaze\PHPStan\Rules\Disallowed\DisallowedHelper;
-use Spaze\PHPStan\Rules\Disallowed\FileHelper;
+use Spaze\PHPStan\Rules\Disallowed\IsAllowedFileHelper;
 
 class ExecutionConfigShellExecCallsTest extends RuleTestCase
 {
@@ -20,7 +20,7 @@ class ExecutionConfigShellExecCallsTest extends RuleTestCase
 		// Load the configuration from this file
 		$config = Neon::decode(file_get_contents(__DIR__ . '/../../disallowed-execution-calls.neon'));
 		return new ShellExecCalls(
-			new DisallowedHelper(new FileHelper(new PHPStanFileHelper(__DIR__))),
+			new DisallowedHelper(new IsAllowedFileHelper(new FileHelper(__DIR__))),
 			new DisallowedCallFactory(),
 			$config['parameters']['disallowedFunctionCalls']
 		);
diff --git a/tests/Configs/InsecureConfigFunctionCallsTest.php b/tests/Configs/InsecureConfigFunctionCallsTest.php
index 4fc6120..4adfb06 100644
--- a/tests/Configs/InsecureConfigFunctionCallsTest.php
+++ b/tests/Configs/InsecureConfigFunctionCallsTest.php
@@ -4,13 +4,13 @@ declare(strict_types = 1);
 namespace Spaze\PHPStan\Rules\Disallowed\Configs;
 
 use Nette\Neon\Neon;
-use PHPStan\File\FileHelper as PHPStanFileHelper;
+use PHPStan\File\FileHelper;
 use PHPStan\Rules\Rule;
 use PHPStan\Testing\RuleTestCase;
 use Spaze\PHPStan\Rules\Disallowed\Calls\FunctionCalls;
 use Spaze\PHPStan\Rules\Disallowed\DisallowedCallFactory;
 use Spaze\PHPStan\Rules\Disallowed\DisallowedHelper;
-use Spaze\PHPStan\Rules\Disallowed\FileHelper;
+use Spaze\PHPStan\Rules\Disallowed\IsAllowedFileHelper;
 
 class InsecureConfigFunctionCallsTest extends RuleTestCase
 {
@@ -20,7 +20,7 @@ class InsecureConfigFunctionCallsTest extends RuleTestCase
 		// Load the configuration from this file
 		$config = Neon::decode(file_get_contents(__DIR__ . '/../../disallowed-insecure-calls.neon'));
 		return new FunctionCalls(
-			new DisallowedHelper(new FileHelper(new PHPStanFileHelper(__DIR__))),
+			new DisallowedHelper(new IsAllowedFileHelper(new FileHelper(__DIR__))),
 			new DisallowedCallFactory(),
 			$config['parameters']['disallowedFunctionCalls']
 		);
diff --git a/tests/Configs/InsecureConfigMethodCallsTest.php b/tests/Configs/InsecureConfigMethodCallsTest.php
index 2551ec0..04b50ba 100644
--- a/tests/Configs/InsecureConfigMethodCallsTest.php
+++ b/tests/Configs/InsecureConfigMethodCallsTest.php
@@ -4,13 +4,13 @@ declare(strict_types = 1);
 namespace Spaze\PHPStan\Rules\Disallowed\Configs;
 
 use Nette\Neon\Neon;
-use PHPStan\File\FileHelper as PHPStanFileHelper;
+use PHPStan\File\FileHelper;
 use PHPStan\Rules\Rule;
 use PHPStan\Testing\RuleTestCase;
 use Spaze\PHPStan\Rules\Disallowed\Calls\MethodCalls;
 use Spaze\PHPStan\Rules\Disallowed\DisallowedCallFactory;
 use Spaze\PHPStan\Rules\Disallowed\DisallowedHelper;
-use Spaze\PHPStan\Rules\Disallowed\FileHelper;
+use Spaze\PHPStan\Rules\Disallowed\IsAllowedFileHelper;
 
 class InsecureConfigMethodCallsTest extends RuleTestCase
 {
@@ -20,7 +20,7 @@ class InsecureConfigMethodCallsTest extends RuleTestCase
 		// Load the configuration from this file
 		$config = Neon::decode(file_get_contents(__DIR__ . '/../../disallowed-insecure-calls.neon'));
 		return new MethodCalls(
-			new DisallowedHelper(new FileHelper(new PHPStanFileHelper(__DIR__))),
+			new DisallowedHelper(new IsAllowedFileHelper(new FileHelper(__DIR__))),
 			new DisallowedCallFactory(),
 			$config['parameters']['disallowedMethodCalls']
 		);
diff --git a/tests/Configs/LooseConfigFunctionCallsTest.php b/tests/Configs/LooseConfigFunctionCallsTest.php
index 261a6db..2b74c29 100644
--- a/tests/Configs/LooseConfigFunctionCallsTest.php
+++ b/tests/Configs/LooseConfigFunctionCallsTest.php
@@ -4,13 +4,13 @@ declare(strict_types = 1);
 namespace Spaze\PHPStan\Rules\Disallowed\Configs;
 
 use Nette\Neon\Neon;
-use PHPStan\File\FileHelper as PHPStanFileHelper;
+use PHPStan\File\FileHelper;
 use PHPStan\Rules\Rule;
 use PHPStan\Testing\RuleTestCase;
 use Spaze\PHPStan\Rules\Disallowed\Calls\FunctionCalls;
 use Spaze\PHPStan\Rules\Disallowed\DisallowedCallFactory;
 use Spaze\PHPStan\Rules\Disallowed\DisallowedHelper;
-use Spaze\PHPStan\Rules\Disallowed\FileHelper;
+use Spaze\PHPStan\Rules\Disallowed\IsAllowedFileHelper;
 
 class LooseConfigFunctionCallsTest extends RuleTestCase
 {
@@ -28,7 +28,7 @@ class LooseConfigFunctionCallsTest extends RuleTestCase
 			}
 		}
 		return new FunctionCalls(
-			new DisallowedHelper(new FileHelper(new PHPStanFileHelper(__DIR__))),
+			new DisallowedHelper(new IsAllowedFileHelper(new FileHelper(__DIR__))),
 			new DisallowedCallFactory(),
 			$config['parameters']['disallowedFunctionCalls']
 		);
diff --git a/tests/FileHelperTest.php b/tests/FileHelperTest.php
deleted file mode 100644
index 1b1c856..0000000
--- a/tests/FileHelperTest.php
+++ /dev/null
@@ -1,44 +0,0 @@
-<?php
-declare(strict_types = 1);
-
-namespace Spaze\PHPStan\Rules\Disallowed;
-
-use Generator;
-use PHPStan\File\FileHelper as PHPStanFileHelper;
-use PHPUnit\Framework\TestCase;
-
-class FileHelperTest extends TestCase
-{
-
-	/** @var FileHelper */
-	private $fileHelper;
-
-
-	protected function setUp(): void
-	{
-		$this->fileHelper = new FileHelper(new PHPStanFileHelper(__DIR__));
-	}
-
-
-	/**
-	 * @param string $input
-	 * @param string $output
-	 * @dataProvider pathProvider
-	 */
-	public function testAbsolutizePath(string $input, string $output): void
-	{
-		$this->assertSame($output, $this->fileHelper->absolutizePath($input));
-	}
-
-
-	public function pathProvider(): Generator
-	{
-		yield ['src', __DIR__ . '/src'];
-		yield ['src/*', __DIR__ . '/src/*'];
-		yield ['../src/*', str_replace(basename(__DIR__) . '/../', '', __DIR__ . '/../src/*')];
-		yield ['src/foo/../*', __DIR__ . '/src/*'];
-		yield ['*/src', '*/src'];
-		yield ['*/../src', '*/../src'];
-	}
-
-}
diff --git a/tests/IsAllowedFileHelperTest.php b/tests/IsAllowedFileHelperTest.php
new file mode 100644
index 0000000..56e2491
--- /dev/null
+++ b/tests/IsAllowedFileHelperTest.php
@@ -0,0 +1,78 @@
+<?php
+declare(strict_types = 1);
+
+namespace Spaze\PHPStan\Rules\Disallowed;
+
+use Generator;
+use PHPStan\File\FileHelper;
+use PHPUnit\Framework\TestCase;
+
+class IsAllowedFileHelperTest extends TestCase
+{
+
+	/** @var IsAllowedFileHelper */
+	private $isAllowedHelper;
+
+	/** @var IsAllowedFileHelper */
+	private $isAllowedHelperWithRootDir;
+
+
+	protected function setUp(): void
+	{
+		$this->isAllowedHelper = new IsAllowedFileHelper(new FileHelper(__DIR__));
+		$this->isAllowedHelperWithRootDir = new IsAllowedFileHelper(new FileHelper(__DIR__), '/foo/bar');
+	}
+
+
+	/**
+	 * @param string $input
+	 * @param string $output
+	 * @dataProvider pathProvider
+	 */
+	public function testAbsolutizePath(string $input, string $output, string $outputWithDir): void
+	{
+		$this->assertSame($output, $this->isAllowedHelper->absolutizePath($input));
+		$this->assertSame($outputWithDir, $this->isAllowedHelperWithRootDir->absolutizePath($input));
+	}
+
+
+	public function pathProvider(): Generator
+	{
+		yield [
+			'src',
+			__DIR__ . '/src',
+			'/foo/bar/src',
+		];
+		yield [
+			'src/*',
+			__DIR__ . '/src/*',
+			'/foo/bar/src/*',
+		];
+		yield [
+			'../src/*',
+			str_replace(basename(__DIR__) . '/../', '', __DIR__ . '/../src/*'),
+			'/foo/src/*',
+		];
+		yield [
+			'src/foo/../*',
+			__DIR__ . '/src/*',
+			'/foo/bar/src/*',
+		];
+		yield [
+			'*/src',
+			'*/src',
+			'*/src',
+		];
+		yield [
+			'*/../src',
+			'*/../src',
+			'*/../src',
+		];
+		yield [
+			'\\src\\foo\\bar\\',
+			__DIR__ . '/src/foo/bar',
+			'/foo/bar/src/foo/bar',
+		];
+	}
+
+}
diff --git a/tests/Usages/ClassConstantInvalidUsagesTest.php b/tests/Usages/ClassConstantInvalidUsagesTest.php
index 035c73c..4fed29c 100644
--- a/tests/Usages/ClassConstantInvalidUsagesTest.php
+++ b/tests/Usages/ClassConstantInvalidUsagesTest.php
@@ -3,12 +3,12 @@ declare(strict_types = 1);
 
 namespace Spaze\PHPStan\Rules\Disallowed\Usages;
 
-use PHPStan\File\FileHelper as PHPStanFileHelper;
+use PHPStan\File\FileHelper;
 use PHPStan\Rules\Rule;
 use PHPStan\Testing\RuleTestCase;
 use Spaze\PHPStan\Rules\Disallowed\DisallowedConstantFactory;
 use Spaze\PHPStan\Rules\Disallowed\DisallowedHelper;
-use Spaze\PHPStan\Rules\Disallowed\FileHelper;
+use Spaze\PHPStan\Rules\Disallowed\IsAllowedFileHelper;
 
 class ClassConstantInvalidUsagesTest extends RuleTestCase
 {
@@ -16,7 +16,7 @@ class ClassConstantInvalidUsagesTest extends RuleTestCase
 	protected function getRule(): Rule
 	{
 		return new ClassConstantUsages(
-			new DisallowedHelper(new FileHelper(new PHPStanFileHelper(__DIR__))),
+			new DisallowedHelper(new IsAllowedFileHelper(new FileHelper(__DIR__))),
 			new DisallowedConstantFactory(),
 			[]
 		);
diff --git a/tests/Usages/ClassConstantUsagesTest.php b/tests/Usages/ClassConstantUsagesTest.php
index 7b8e810..ceabd36 100644
--- a/tests/Usages/ClassConstantUsagesTest.php
+++ b/tests/Usages/ClassConstantUsagesTest.php
@@ -3,12 +3,12 @@ declare(strict_types = 1);
 
 namespace Spaze\PHPStan\Rules\Disallowed\Usages;
 
-use PHPStan\File\FileHelper as PHPStanFileHelper;
+use PHPStan\File\FileHelper;
 use PHPStan\Rules\Rule;
 use PHPStan\Testing\RuleTestCase;
 use Spaze\PHPStan\Rules\Disallowed\DisallowedConstantFactory;
 use Spaze\PHPStan\Rules\Disallowed\DisallowedHelper;
-use Spaze\PHPStan\Rules\Disallowed\FileHelper;
+use Spaze\PHPStan\Rules\Disallowed\IsAllowedFileHelper;
 
 class ClassConstantUsagesTest extends RuleTestCase
 {
@@ -16,7 +16,7 @@ class ClassConstantUsagesTest extends RuleTestCase
 	protected function getRule(): Rule
 	{
 		return new ClassConstantUsages(
-			new DisallowedHelper(new FileHelper(new PHPStanFileHelper(__DIR__))),
+			new DisallowedHelper(new IsAllowedFileHelper(new FileHelper(__DIR__))),
 			new DisallowedConstantFactory(),
 			[
 				[
diff --git a/tests/Usages/ConstantUsagesTest.php b/tests/Usages/ConstantUsagesTest.php
index e80465a..4823c35 100644
--- a/tests/Usages/ConstantUsagesTest.php
+++ b/tests/Usages/ConstantUsagesTest.php
@@ -3,12 +3,12 @@ declare(strict_types = 1);
 
 namespace Spaze\PHPStan\Rules\Disallowed\Usages;
 
-use PHPStan\File\FileHelper as PHPStanFileHelper;
+use PHPStan\File\FileHelper;
 use PHPStan\Rules\Rule;
 use PHPStan\Testing\RuleTestCase;
 use Spaze\PHPStan\Rules\Disallowed\DisallowedConstantFactory;
 use Spaze\PHPStan\Rules\Disallowed\DisallowedHelper;
-use Spaze\PHPStan\Rules\Disallowed\FileHelper;
+use Spaze\PHPStan\Rules\Disallowed\IsAllowedFileHelper;
 
 class ConstantUsagesTest extends RuleTestCase
 {
@@ -16,7 +16,7 @@ class ConstantUsagesTest extends RuleTestCase
 	protected function getRule(): Rule
 	{
 		return new ConstantUsages(
-			new DisallowedHelper(new FileHelper(new PHPStanFileHelper(__DIR__))),
+			new DisallowedHelper(new IsAllowedFileHelper(new FileHelper(__DIR__))),
 			new DisallowedConstantFactory(),
 			[
 				[
diff --git a/tests/Usages/NamespaceUsagesTest.php b/tests/Usages/NamespaceUsagesTest.php
index 7596c0a..ab2c645 100644
--- a/tests/Usages/NamespaceUsagesTest.php
+++ b/tests/Usages/NamespaceUsagesTest.php
@@ -3,12 +3,12 @@ declare(strict_types = 1);
 
 namespace Spaze\PHPStan\Rules\Disallowed\Usages;
 
-use PHPStan\File\FileHelper as PHPStanFileHelper;
+use PHPStan\File\FileHelper;
 use PHPStan\Rules\Rule;
 use PHPStan\Testing\RuleTestCase;
 use Spaze\PHPStan\Rules\Disallowed\DisallowedNamespaceFactory;
 use Spaze\PHPStan\Rules\Disallowed\DisallowedNamespaceHelper;
-use Spaze\PHPStan\Rules\Disallowed\FileHelper;
+use Spaze\PHPStan\Rules\Disallowed\IsAllowedFileHelper;
 
 class NamespaceUsagesTest extends RuleTestCase
 {
@@ -16,7 +16,7 @@ class NamespaceUsagesTest extends RuleTestCase
 	protected function getRule(): Rule
 	{
 		return new NamespaceUsages(
-			new DisallowedNamespaceHelper(new FileHelper(new PHPStanFileHelper(__DIR__))),
+			new DisallowedNamespaceHelper(new IsAllowedFileHelper(new FileHelper(__DIR__))),
 			new DisallowedNamespaceFactory(),
 			[
 				[