Skip to content

Commit

Permalink
Simplify code
Browse files Browse the repository at this point in the history
  • Loading branch information
janedbal committed Dec 3, 2024
1 parent 40442f8 commit 7f66396
Show file tree
Hide file tree
Showing 2 changed files with 56 additions and 75 deletions.
130 changes: 55 additions & 75 deletions src/Rule/ForbidCustomFunctionsRule.php
Original file line number Diff line number Diff line change
Expand Up @@ -97,96 +97,82 @@ public function getNodeType(): string
*/
public function processNode(Node $node, Scope $scope): array
{
if ($node instanceof MethodCall) {
$caller = $scope->getType($node->var);
$methodNames = $this->getMethodNames($node->name, $scope);

$errors = [];

foreach ($methodNames as $methodName) {
$errors = [
...$errors,
...$this->validateCallOverExpr([$methodName], $caller),
...$this->validateCallLikeArguments($caller, $methodName, $node, $scope),
];
}

return $errors;
if ($node instanceof FuncCall) {
return $this->validateFunctionCall($node, $scope);
}

if ($node instanceof StaticCall) {
if ($node instanceof MethodCall) {
$caller = $scope->getType($node->var);
$methodNames = $this->getMethodNames($node->name, $scope);

} elseif ($node instanceof StaticCall) {
$classNode = $node->class;
$caller = $classNode instanceof Name
? $scope->resolveTypeByName($classNode)
: $scope->getType($classNode);

$errors = [];
$caller = $classNode instanceof Name ? $scope->resolveTypeByName($classNode) : $scope->getType($classNode);
$methodNames = $this->getMethodNames($node->name, $scope);

foreach ($methodNames as $methodName) {
$errors = [
...$errors,
...$this->validateCallOverExpr([$methodName], $caller),
...$this->validateCallLikeArguments($caller, $methodName, $node, $scope),
];
}
} elseif ($node instanceof New_) {
$caller = $this->getNewCaller($node, $scope);
$methodNames = ['__construct'];

return $errors;
} else {
return [];
}

if ($node instanceof FuncCall) {
$functionNames = $this->getFunctionNames($node->name, $scope);
$errors = [];

$errors = [];
foreach ($methodNames as $methodName) {
$errors = [
...$errors,
...$this->validateCallOverExpr($methodName, $caller),
...$this->validateCallLikeArguments($caller, $methodName, $node, $scope),
];
}

foreach ($functionNames as $functionName) {
$errors = [
...$errors,
...$this->validateFunction([$functionName]),
...$this->validateFunctionArguments($functionName, $node, $scope),
];
}
return $errors;
}

return $errors;
}
/**
* @return list<IdentifierRuleError>
*/
private function validateFunctionCall(FuncCall $node, Scope $scope): array
{
$functionNames = $this->getFunctionNames($node->name, $scope);

if ($node instanceof New_) {
$caller = $this->getNewCaller($node, $scope);
$errors = [];

return [
...$this->validateCallOverExpr(['__construct'], $caller),
...$this->validateCallLikeArguments($caller, '__construct', $node, $scope),
foreach ($functionNames as $functionName) {
$errors = [
...$errors,
...$this->validateFunction($functionName),
...$this->validateFunctionArguments($functionName, $node, $scope),
];
}

return [];
return $errors;
}

/**
* @param list<string> $methodNames
* @return list<IdentifierRuleError>
*/
private function validateCallOverExpr(array $methodNames, Type $caller): array
private function validateCallOverExpr(string $methodName, Type $caller): array
{
$classNames = $caller->getObjectTypeOrClassStringObjectType()->getObjectClassNames();
$errors = [];

foreach ($classNames as $className) {
$errors = [
...$errors,
...$this->validateMethod($methodNames, $className),
...$this->validateMethod($methodName, $className),
];
}

return $errors;
}

/**
* @param list<string> $methodNames
* @return list<IdentifierRuleError>
*/
private function validateMethod(array $methodNames, string $className): array
private function validateMethod(string $methodName, string $className): array
{
if (!$this->reflectionProvider->hasClass($className)) {
return [];
Expand All @@ -204,34 +190,29 @@ private function validateMethod(array $methodNames, string $className): array
->build();
}

foreach ($methodNames as $methodName) {
if (isset($this->forbiddenFunctions[$ancestorClassName][$methodName])) {
$errorMessage = sprintf('Method %s::%s() is forbidden. %s', $ancestorClassName, $methodName, $this->forbiddenFunctions[$ancestorClassName][$methodName]);
$errors[] = RuleErrorBuilder::message($errorMessage)
->identifier('shipmonk.methodCallDenied')
->build();
}
if (isset($this->forbiddenFunctions[$ancestorClassName][$methodName])) {
$errorMessage = sprintf('Method %s::%s() is forbidden. %s', $ancestorClassName, $methodName, $this->forbiddenFunctions[$ancestorClassName][$methodName]);
$errors[] = RuleErrorBuilder::message($errorMessage)
->identifier('shipmonk.methodCallDenied')
->build();
}
}

return $errors;
}

/**
* @param list<string> $functionNames
* @return list<IdentifierRuleError>
*/
private function validateFunction(array $functionNames): array
private function validateFunction(string $functionName): array
{
$errors = [];

foreach ($functionNames as $functionName) {
if (isset($this->forbiddenFunctions[self::FUNCTION][$functionName])) {
$errorMessage = sprintf('Function %s() is forbidden. %s', $functionName, $this->forbiddenFunctions[self::FUNCTION][$functionName]);
$errors[] = RuleErrorBuilder::message($errorMessage)
->identifier('shipmonk.functionCallDenied')
->build();
}
if (isset($this->forbiddenFunctions[self::FUNCTION][$functionName])) {
$errorMessage = sprintf('Function %s() is forbidden. %s', $functionName, $this->forbiddenFunctions[self::FUNCTION][$functionName]);
$errors[] = RuleErrorBuilder::message($errorMessage)
->identifier('shipmonk.functionCallDenied')
->build();
}

return $errors;
Expand Down Expand Up @@ -297,7 +278,7 @@ private function validateCallable(
foreach ($callableType->getConstantStrings() as $constantString) {
$errors = [
...$errors,
...$this->validateFunction([$constantString->getValue()]),
...$this->validateFunction($constantString->getValue()),
];
}

Expand All @@ -315,7 +296,7 @@ private function validateCallable(
foreach ($classNames as $className) {
$errors = [
...$errors,
...$this->validateMethod([$methodName], $className),
...$this->validateMethod($methodName, $className),
];
}
}
Expand All @@ -325,15 +306,14 @@ private function validateCallable(
}

/**
* @param MethodCall|StaticCall|New_ $node
* @return list<IdentifierRuleError>
*/
private function validateCallLikeArguments(Type $caller, string $methodName, CallLike $node, Scope $scope): array
{
$errors = [];

foreach ($caller->getObjectTypeOrClassStringObjectType()->getObjectClassNames() as $className) {
$methodReflection = $this->getMethodReflection($className, $methodName);
$methodReflection = $this->getMethodReflection($className, $methodName, $scope);

if ($methodReflection === null) {
continue;
Expand Down Expand Up @@ -398,19 +378,19 @@ private function validateFunctionArguments(string $functionName, FuncCall $node,
return $this->validateCallableArguments($orderedArgs, $parametersAcceptor, $scope);
}

private function getMethodReflection(string $className, string $methodName): ?ExtendedMethodReflection
private function getMethodReflection(string $className, string $methodName, Scope $scope): ?ExtendedMethodReflection
{
if (!$this->reflectionProvider->hasClass($className)) {
return null;
}

$classReflection = $this->reflectionProvider->getClass($className);

if (!$classReflection->hasNativeMethod($methodName)) {
if (!$classReflection->hasMethod($methodName)) {
return null;
}

return $classReflection->getNativeMethod($methodName);
return $classReflection->getMethod($methodName, $scope);
}

private function getFunctionReflection(Name $functionName, Scope $scope): ?FunctionReflection
Expand Down
1 change: 1 addition & 0 deletions tests/Rule/data/ForbidCustomFunctionsRule/code.php
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,7 @@ public function test(

$class->allowedMethod();
$class->forbiddenMethod(); // error: Method ForbidCustomFunctionsRule\SomeClass::forbiddenMethod() is forbidden. Description 4
$class?->forbiddenMethod(); // error: Method ForbidCustomFunctionsRule\SomeClass::forbiddenMethod() is forbidden. Description 4
$class->allowedInterfaceMethod();
$class->forbiddenInterfaceMethod(); // error: Method ForbidCustomFunctionsRule\SomeInterface::forbiddenInterfaceMethod() is forbidden. Description 6
$class->forbiddenMethodOfParent(); // error: Method ForbidCustomFunctionsRule\SomeParent::forbiddenMethodOfParent() is forbidden. Description 8
Expand Down

0 comments on commit 7f66396

Please sign in to comment.