From d2fc1b230235e1aa9fa5d956e9a7edbbeef72dfb Mon Sep 17 00:00:00 2001 From: Joas Schilling Date: Mon, 15 Jun 2015 15:24:45 +0200 Subject: [PATCH] Correctly handle use statements --- lib/private/app/codechecker.php | 1 + lib/private/app/codecheckvisitor.php | 44 +++++++++++++++++-- .../test-deprecated-use-alias.php | 9 ++++ .../test-deprecated-use-sub-alias.php | 9 ++++ .../code-checker/test-deprecated-use-sub.php | 9 ++++ .../app/code-checker/test-deprecated-use.php | 9 ++++ tests/data/app/code-checker/test-use.php | 12 +++++ tests/lib/app/codechecker.php | 9 ++-- tests/lib/app/deprecationcodechecker.php | 13 ++++-- 9 files changed, 104 insertions(+), 11 deletions(-) create mode 100644 tests/data/app/code-checker/test-deprecated-use-alias.php create mode 100644 tests/data/app/code-checker/test-deprecated-use-sub-alias.php create mode 100644 tests/data/app/code-checker/test-deprecated-use-sub.php create mode 100644 tests/data/app/code-checker/test-deprecated-use.php create mode 100644 tests/data/app/code-checker/test-use.php diff --git a/lib/private/app/codechecker.php b/lib/private/app/codechecker.php index 38d98255cf..0216e61e7a 100644 --- a/lib/private/app/codechecker.php +++ b/lib/private/app/codechecker.php @@ -43,6 +43,7 @@ class CodeChecker extends BasicEmitter { const CLASS_CONST_FETCH_NOT_ALLOWED = 1003; const CLASS_NEW_FETCH_NOT_ALLOWED = 1004; const OP_OPERATOR_USAGE_DISCOURAGED = 1005; + const CLASS_USE_NOT_ALLOWED = 1006; /** @var Parser */ private $parser; diff --git a/lib/private/app/codecheckvisitor.php b/lib/private/app/codecheckvisitor.php index d4b5bedbb1..0dec5b3715 100644 --- a/lib/private/app/codecheckvisitor.php +++ b/lib/private/app/codecheckvisitor.php @@ -43,7 +43,12 @@ class CodeCheckVisitor extends NodeVisitorAbstract { */ public function __construct($blackListDescription, $blackListedClassNames, $checkEqualOperatorUsage) { $this->blackListDescription = $blackListDescription; - $this->blackListedClassNames = array_map('strtolower', $blackListedClassNames); + + $this->blackListedClassNames = []; + foreach ($blackListedClassNames as $class) { + $class = strtolower($class); + $this->blackListedClassNames[$class] = $class; + } $this->checkEqualOperatorUsage = $checkEqualOperatorUsage; $this->errorMessages = [ @@ -52,6 +57,7 @@ class CodeCheckVisitor extends NodeVisitorAbstract { CodeChecker::STATIC_CALL_NOT_ALLOWED => "Static method of {$this->blackListDescription} class must not be called", CodeChecker::CLASS_CONST_FETCH_NOT_ALLOWED => "Constant of {$this->blackListDescription} class must not not be fetched", CodeChecker::CLASS_NEW_FETCH_NOT_ALLOWED => "{$this->blackListDescription} class must not be instanciated", + CodeChecker::CLASS_USE_NOT_ALLOWED => "{$this->blackListDescription} class must not be imported with a use statement", CodeChecker::OP_OPERATOR_USAGE_DISCOURAGED => "is discouraged", ]; @@ -127,15 +133,47 @@ class CodeCheckVisitor extends NodeVisitorAbstract { } } } + if ($node instanceof Node\Stmt\UseUse) { + $this->checkBlackList($node->name->toString(), CodeChecker::CLASS_USE_NOT_ALLOWED, $node); + if ($node->alias) { + $this->addUseNameToBlackList($node->name->toString(), $node->alias); + } else { + $this->addUseNameToBlackList($node->name->toString(), $node->name->getLast()); + } + } + } + + /** + * Check whether an alias was introduced for a namespace of a blacklisted class + * + * Example: + * - Blacklist entry: OCP\AppFramework\IApi + * - Name: OCP\AppFramework + * - Alias: OAF + * => new blacklist entry: OAF\IApi + * + * @param string $name + * @param string $alias + */ + private function addUseNameToBlackList($name, $alias) { + $name = strtolower($name); + $alias = strtolower($alias); + + foreach ($this->blackListedClassNames as $blackListedAlias => $blackListedClassName) { + if (strpos($blackListedClassName, $name . '\\') === 0) { + $aliasedClassName = str_replace($name, $alias, $blackListedClassName); + $this->blackListedClassNames[$aliasedClassName] = $blackListedClassName; + } + } } private function checkBlackList($name, $errorCode, Node $node) { - if (in_array(strtolower($name), $this->blackListedClassNames)) { + if (isset($this->blackListedClassNames[strtolower($name)])) { $this->errors[]= [ 'disallowedToken' => $name, 'errorCode' => $errorCode, 'line' => $node->getLine(), - 'reason' => $this->buildReason($name, $errorCode) + 'reason' => $this->buildReason($this->blackListedClassNames[strtolower($name)], $errorCode) ]; } } diff --git a/tests/data/app/code-checker/test-deprecated-use-alias.php b/tests/data/app/code-checker/test-deprecated-use-alias.php new file mode 100644 index 0000000000..a92187fa88 --- /dev/null +++ b/tests/data/app/code-checker/test-deprecated-use-alias.php @@ -0,0 +1,9 @@ +