Only decorate the type when it was matched
This commit is contained in:
parent
0de5c35dba
commit
8a64abf4e4
9 changed files with 194 additions and 79 deletions
139
lib/private/app/codechecker/abstractcheck.php
Normal file
139
lib/private/app/codechecker/abstractcheck.php
Normal file
|
@ -0,0 +1,139 @@
|
|||
<?php
|
||||
/**
|
||||
* @author Joas Schilling <nickvergessen@owncloud.com>
|
||||
*
|
||||
* @copyright Copyright (c) 2015, ownCloud, Inc.
|
||||
* @license AGPL-3.0
|
||||
*
|
||||
* This code is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License, version 3,
|
||||
* as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License, version 3,
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||
*
|
||||
*/
|
||||
|
||||
namespace OC\App\CodeChecker;
|
||||
|
||||
abstract class AbstractCheck implements ICheck {
|
||||
/** @var ICheck */
|
||||
protected $check;
|
||||
|
||||
/**
|
||||
* @param ICheck $check
|
||||
*/
|
||||
public function __construct(ICheck $check) {
|
||||
$this->check = $check;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $errorCode
|
||||
* @param string $errorObject
|
||||
* @return string
|
||||
*/
|
||||
public function getDescription($errorCode, $errorObject) {
|
||||
switch ($errorCode) {
|
||||
case CodeChecker::STATIC_CALL_NOT_ALLOWED:
|
||||
$functions = $this->getLocalFunctions();
|
||||
$functions = array_change_key_case($functions, CASE_LOWER);
|
||||
if (isset($functions[$errorObject])) {
|
||||
return $this->getLocalDescription();
|
||||
}
|
||||
// no break;
|
||||
case CodeChecker::CLASS_EXTENDS_NOT_ALLOWED:
|
||||
case CodeChecker::CLASS_IMPLEMENTS_NOT_ALLOWED:
|
||||
case CodeChecker::CLASS_NEW_NOT_ALLOWED:
|
||||
case CodeChecker::CLASS_USE_NOT_ALLOWED:
|
||||
$classes = $this->getLocalClasses();
|
||||
$classes = array_change_key_case($classes, CASE_LOWER);
|
||||
if (isset($classes[$errorObject])) {
|
||||
return $this->getLocalDescription();
|
||||
}
|
||||
break;
|
||||
|
||||
case CodeChecker::CLASS_CONST_FETCH_NOT_ALLOWED:
|
||||
$constants = $this->getLocalConstants();
|
||||
$constants = array_change_key_case($constants, CASE_LOWER);
|
||||
if (isset($constants[$errorObject])) {
|
||||
return $this->getLocalDescription();
|
||||
}
|
||||
break;
|
||||
|
||||
case CodeChecker::CLASS_METHOD_CALL_NOT_ALLOWED:
|
||||
$methods = $this->getLocalMethods();
|
||||
$methods = array_change_key_case($methods, CASE_LOWER);
|
||||
if (isset($methods[$errorObject])) {
|
||||
return $this->getLocalDescription();
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
return $this->check->getDescription($errorCode, $errorObject);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
abstract protected function getLocalDescription();
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
abstract protected function getLocalClasses();
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
abstract protected function getLocalConstants();
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
abstract protected function getLocalFunctions();
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
abstract protected function getLocalMethods();
|
||||
|
||||
/**
|
||||
* @return array E.g.: `'ClassName' => 'oc version',`
|
||||
*/
|
||||
public function getClasses() {
|
||||
return array_merge($this->getLocalClasses(), $this->check->getClasses());
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array E.g.: `'ClassName::CONSTANT_NAME' => 'oc version',`
|
||||
*/
|
||||
public function getConstants() {
|
||||
return array_merge($this->getLocalConstants(), $this->check->getConstants());
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array E.g.: `'functionName' => 'oc version',`
|
||||
*/
|
||||
public function getFunctions() {
|
||||
return array_merge($this->getLocalFunctions(), $this->check->getFunctions());
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array E.g.: `'ClassName::methodName' => 'oc version',`
|
||||
*/
|
||||
public function getMethods() {
|
||||
return array_merge($this->getLocalMethods(), $this->check->getMethods());
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function checkStrongComparisons() {
|
||||
return $this->check->checkStrongComparisons();
|
||||
}
|
||||
}
|
|
@ -41,7 +41,7 @@ class CodeChecker extends BasicEmitter {
|
|||
const CLASS_IMPLEMENTS_NOT_ALLOWED = 1001;
|
||||
const STATIC_CALL_NOT_ALLOWED = 1002;
|
||||
const CLASS_CONST_FETCH_NOT_ALLOWED = 1003;
|
||||
const CLASS_NEW_FETCH_NOT_ALLOWED = 1004;
|
||||
const CLASS_NEW_NOT_ALLOWED = 1004;
|
||||
const OP_OPERATOR_USAGE_DISCOURAGED = 1005;
|
||||
const CLASS_USE_NOT_ALLOWED = 1006;
|
||||
const CLASS_METHOD_CALL_NOT_ALLOWED = 1007;
|
||||
|
|
|
@ -21,30 +21,19 @@
|
|||
|
||||
namespace OC\App\CodeChecker;
|
||||
|
||||
class DeprecationCheck implements ICheck {
|
||||
/** @var ICheck */
|
||||
protected $check;
|
||||
|
||||
/**
|
||||
* @param ICheck $check
|
||||
*/
|
||||
public function __construct(ICheck $check) {
|
||||
$this->check = $check;
|
||||
}
|
||||
|
||||
class DeprecationCheck extends AbstractCheck implements ICheck {
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getDescription() {
|
||||
$innerDescription = $this->check->getDescription();
|
||||
return 'deprecated' . (($innerDescription === '') ? '' : ' ' . $innerDescription);
|
||||
protected function getLocalDescription() {
|
||||
return 'deprecated';
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array E.g.: `'ClassName' => 'oc version',`
|
||||
*/
|
||||
public function getClasses() {
|
||||
return array_merge([
|
||||
protected function getLocalClasses() {
|
||||
return [
|
||||
'OCP\Config' => '8.0.0',
|
||||
'OCP\Contacts' => '8.1.0',
|
||||
'OCP\DB' => '8.1.0',
|
||||
|
@ -52,14 +41,14 @@ class DeprecationCheck implements ICheck {
|
|||
'OCP\JSON' => '8.1.0',
|
||||
'OCP\Response' => '8.1.0',
|
||||
'OCP\AppFramework\IApi' => '8.0.0',
|
||||
], $this->check->getClasses());
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array E.g.: `'ClassName::CONSTANT_NAME' => 'oc version',`
|
||||
*/
|
||||
public function getConstants() {
|
||||
return array_merge([
|
||||
protected function getLocalConstants() {
|
||||
return [
|
||||
'OCP::PERMISSION_CREATE' => '8.0.0',
|
||||
'OCP::PERMISSION_READ' => '8.0.0',
|
||||
'OCP::PERMISSION_UPDATE' => '8.0.0',
|
||||
|
@ -67,14 +56,14 @@ class DeprecationCheck implements ICheck {
|
|||
'OCP::PERMISSION_SHARE' => '8.0.0',
|
||||
'OCP::PERMISSION_ALL' => '8.0.0',
|
||||
'OCP::FILENAME_INVALID_CHARS' => '8.0.0',
|
||||
], $this->check->getConstants());
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array E.g.: `'functionName' => 'oc version',`
|
||||
*/
|
||||
public function getFunctions() {
|
||||
return array_merge([
|
||||
protected function getLocalFunctions() {
|
||||
return [
|
||||
'OCP::image_path' => '8.0.0',
|
||||
'OCP::mimetype_icon' => '8.0.0',
|
||||
'OCP::preview_icon' => '8.0.0',
|
||||
|
@ -83,14 +72,14 @@ class DeprecationCheck implements ICheck {
|
|||
'OCP::relative_modified_date' => '8.0.0',
|
||||
'OCP::simple_file_size' => '8.0.0',
|
||||
'OCP::html_select_options' => '8.0.0',
|
||||
], $this->check->getFunctions());
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array E.g.: `'ClassName::methodName' => 'oc version',`
|
||||
*/
|
||||
public function getMethods() {
|
||||
return array_merge([
|
||||
protected function getLocalMethods() {
|
||||
return [
|
||||
'OCP\App::register' => '8.1.0',
|
||||
'OCP\App::addNavigationEntry' => '8.1.0',
|
||||
'OCP\App::setActiveNavigationEntry' => '8.1.0',
|
||||
|
@ -151,13 +140,6 @@ class DeprecationCheck implements ICheck {
|
|||
'OCP\Util::imagePath' => '8.1.0',
|
||||
'OCP\Util::isValidFileName' => '8.1.0',
|
||||
'OCP\Util::generateRandomBytes' => '8.1.0',
|
||||
], $this->check->getMethods());
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function checkStrongComparisons() {
|
||||
return $this->check->checkStrongComparisons();
|
||||
];
|
||||
}
|
||||
}
|
||||
|
|
|
@ -22,9 +22,11 @@ namespace OC\App\CodeChecker;
|
|||
|
||||
class EmptyCheck implements ICheck {
|
||||
/**
|
||||
* @param int $errorCode
|
||||
* @param string $errorObject
|
||||
* @return string
|
||||
*/
|
||||
public function getDescription() {
|
||||
public function getDescription($errorCode, $errorObject) {
|
||||
return '';
|
||||
}
|
||||
|
||||
|
|
|
@ -22,9 +22,11 @@ namespace OC\App\CodeChecker;
|
|||
|
||||
interface ICheck {
|
||||
/**
|
||||
* @param int $errorCode
|
||||
* @param string $errorObject
|
||||
* @return string
|
||||
*/
|
||||
public function getDescription();
|
||||
public function getDescription($errorCode, $errorObject);
|
||||
|
||||
/**
|
||||
* @return array E.g.: `'ClassName' => 'oc version',`
|
||||
|
|
|
@ -27,6 +27,9 @@ use PhpParser\Node\Name;
|
|||
use PhpParser\NodeVisitorAbstract;
|
||||
|
||||
class NodeVisitor extends NodeVisitorAbstract {
|
||||
/** @var ICheck */
|
||||
protected $list;
|
||||
|
||||
/** @var string */
|
||||
protected $blackListDescription;
|
||||
/** @var string[] */
|
||||
|
@ -46,7 +49,7 @@ class NodeVisitor extends NodeVisitorAbstract {
|
|||
* @param ICheck $list
|
||||
*/
|
||||
public function __construct(ICheck $list) {
|
||||
$this->blackListDescription = $list->getDescription();
|
||||
$this->list = $list;
|
||||
|
||||
$this->blackListedClassNames = [];
|
||||
foreach ($list->getClasses() as $class => $blackListInfo) {
|
||||
|
@ -80,13 +83,13 @@ class NodeVisitor extends NodeVisitorAbstract {
|
|||
$this->checkEqualOperatorUsage = $list->checkStrongComparisons();
|
||||
|
||||
$this->errorMessages = [
|
||||
CodeChecker::CLASS_EXTENDS_NOT_ALLOWED => "{$this->blackListDescription} class must not be extended",
|
||||
CodeChecker::CLASS_IMPLEMENTS_NOT_ALLOWED => "{$this->blackListDescription} interface must not be implemented",
|
||||
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::CLASS_METHOD_CALL_NOT_ALLOWED => "Method of {$this->blackListDescription} class must not be called",
|
||||
CodeChecker::CLASS_EXTENDS_NOT_ALLOWED => "%s class must not be extended",
|
||||
CodeChecker::CLASS_IMPLEMENTS_NOT_ALLOWED => "%s interface must not be implemented",
|
||||
CodeChecker::STATIC_CALL_NOT_ALLOWED => "Static method of %s class must not be called",
|
||||
CodeChecker::CLASS_CONST_FETCH_NOT_ALLOWED => "Constant of %s class must not not be fetched",
|
||||
CodeChecker::CLASS_NEW_NOT_ALLOWED => "%s class must not be instantiated",
|
||||
CodeChecker::CLASS_USE_NOT_ALLOWED => "%s class must not be imported with a use statement",
|
||||
CodeChecker::CLASS_METHOD_CALL_NOT_ALLOWED => "Method of %s class must not be called",
|
||||
|
||||
CodeChecker::OP_OPERATOR_USAGE_DISCOURAGED => "is discouraged",
|
||||
];
|
||||
|
@ -171,7 +174,7 @@ class NodeVisitor extends NodeVisitorAbstract {
|
|||
if ($node instanceof Node\Expr\New_) {
|
||||
if (!is_null($node->class)) {
|
||||
if ($node->class instanceof Name) {
|
||||
$this->checkBlackList($node->class->toString(), CodeChecker::CLASS_NEW_FETCH_NOT_ALLOWED, $node);
|
||||
$this->checkBlackList($node->class->toString(), CodeChecker::CLASS_NEW_NOT_ALLOWED, $node);
|
||||
}
|
||||
if ($node->class instanceof Node\Expr\Variable) {
|
||||
/**
|
||||
|
@ -294,7 +297,8 @@ class NodeVisitor extends NodeVisitorAbstract {
|
|||
|
||||
private function buildReason($name, $errorCode) {
|
||||
if (isset($this->errorMessages[$errorCode])) {
|
||||
return $this->errorMessages[$errorCode];
|
||||
$desc = $this->list->getDescription($errorCode, $name);
|
||||
return sprintf($this->errorMessages[$errorCode], $desc);
|
||||
}
|
||||
|
||||
return "$name usage not allowed - error: $errorCode";
|
||||
|
|
|
@ -23,30 +23,19 @@
|
|||
|
||||
namespace OC\App\CodeChecker;
|
||||
|
||||
class PrivateCheck implements ICheck {
|
||||
/** @var ICheck */
|
||||
protected $check;
|
||||
|
||||
/**
|
||||
* @param ICheck $check
|
||||
*/
|
||||
public function __construct(ICheck $check) {
|
||||
$this->check = $check;
|
||||
}
|
||||
|
||||
class PrivateCheck extends AbstractCheck implements ICheck {
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getDescription() {
|
||||
$innerDescription = $this->check->getDescription();
|
||||
return 'private' . (($innerDescription === '') ? '' : ' ' . $innerDescription);
|
||||
protected function getLocalDescription() {
|
||||
return 'private';
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function getClasses() {
|
||||
return array_merge([
|
||||
public function getLocalClasses() {
|
||||
return [
|
||||
// classes replaced by the public api
|
||||
'OC_API' => '6.0.0',
|
||||
'OC_App' => '6.0.0',
|
||||
|
@ -71,34 +60,27 @@ class PrivateCheck implements ICheck {
|
|||
'OC_Template' => '6.0.0',
|
||||
'OC_User' => '6.0.0',
|
||||
'OC_Util' => '6.0.0',
|
||||
], $this->check->getClasses());
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function getConstants() {
|
||||
return $this->check->getConstants();
|
||||
public function getLocalConstants() {
|
||||
return [];
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function getFunctions() {
|
||||
return $this->check->getFunctions();
|
||||
public function getLocalFunctions() {
|
||||
return [];
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function getMethods() {
|
||||
return $this->check->getMethods();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function checkStrongComparisons() {
|
||||
return $this->check->checkStrongComparisons();
|
||||
public function getLocalMethods() {
|
||||
return [];
|
||||
}
|
||||
}
|
||||
|
|
|
@ -35,10 +35,12 @@ class StrongComparisonCheck implements ICheck {
|
|||
}
|
||||
|
||||
/**
|
||||
* @param int $errorCode
|
||||
* @param string $errorObject
|
||||
* @return string
|
||||
*/
|
||||
public function getDescription() {
|
||||
return $this->check->getDescription();
|
||||
public function getDescription($errorCode, $errorObject) {
|
||||
return $this->check->getDescription($errorCode, $errorObject);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -35,9 +35,11 @@ class TestList implements ICheck {
|
|||
}
|
||||
|
||||
/**
|
||||
* @param int $errorCode
|
||||
* @param string $errorObject
|
||||
* @return string
|
||||
*/
|
||||
public function getDescription() {
|
||||
public function getDescription($errorCode, $errorObject) {
|
||||
return 'testing';
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue