Skip to content

Commit 12f0a78

Browse files
FileVisitor improvements (#512)
* avoid nested precondition checks * rely on checking Node\Name\FullyQualified which saves further checks on built in types and self, parent, static
1 parent 556c3f1 commit 12f0a78

File tree

4 files changed

+164
-155
lines changed

4 files changed

+164
-155
lines changed

Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ csfix: ## it launches cs fix
3838
PHP_CS_FIXER_IGNORE_ENV=1 bin/php-cs-fixer fix -v
3939

4040
psalm: ## it launches psalm
41-
bin/psalm.phar
41+
bin/psalm.phar --no-cache
4242

4343
build: ## it launches all the build
4444
composer install

src/Analyzer/FileVisitor.php

Lines changed: 119 additions & 136 deletions
Original file line numberDiff line numberDiff line change
@@ -29,30 +29,43 @@ public function enterNode(Node $node): void
2929
{
3030
$this->handleClassNode($node);
3131

32+
// handles anonymous class definition like new class() {}
3233
$this->handleAnonClassNode($node);
3334

35+
// handles enum definition
3436
$this->handleEnumNode($node);
3537

38+
// handles interface definition like interface MyInterface {}
39+
$this->handleInterfaceNode($node);
40+
41+
// handles trait definition like trait MyTrait {}
42+
$this->handleTraitNode($node);
43+
44+
// handles code like $constantValue = StaticClass::constant;
3645
$this->handleStaticClassConstantNode($node);
3746

47+
// handles code like $static = StaticClass::foo();
3848
$this->handleStaticClassCallsNode($node);
3949

50+
// handles code lik $a instanceof MyClass
4051
$this->handleInstanceOf($node);
4152

53+
// handles code like $a = new MyClass();
4254
$this->handleNewExpression($node);
4355

56+
// handles code like public MyClass $myClass;
4457
$this->handleTypedProperty($node);
4558

59+
// handles docblock like /** @var MyClass $myClass */
4660
$this->handleDocComment($node);
4761

62+
// handles code like public function myMethod(MyClass $myClass) {}
4863
$this->handleParamDependency($node);
4964

50-
$this->handleInterfaceNode($node);
51-
52-
$this->handleTraitNode($node);
53-
65+
// handles code like public function myMethod(): MyClass {}
5466
$this->handleReturnTypeDependency($node);
5567

68+
// handles attribute definition like #[MyAttribute]
5669
$this->handleAttributeNode($node);
5770
}
5871

@@ -145,117 +158,97 @@ private function handleAnonClassNode(Node $node): void
145158

146159
private function handleEnumNode(Node $node): void
147160
{
148-
if ($node instanceof Node\Stmt\Enum_ && null !== $node->namespacedName) {
149-
$this->classDescriptionBuilder->setClassName($node->namespacedName->toCodeString());
150-
$this->classDescriptionBuilder->setEnum(true);
161+
if (!($node instanceof Node\Stmt\Enum_)) {
162+
return;
163+
}
151164

152-
foreach ($node->implements as $interface) {
153-
$this->classDescriptionBuilder
154-
->addInterface($interface->toString(), $interface->getLine());
155-
}
165+
if (null == $node->namespacedName) {
166+
return;
167+
}
168+
169+
$this->classDescriptionBuilder->setClassName($node->namespacedName->toCodeString());
170+
$this->classDescriptionBuilder->setEnum(true);
171+
172+
foreach ($node->implements as $interface) {
173+
$this->classDescriptionBuilder
174+
->addInterface($interface->toString(), $interface->getLine());
156175
}
157176
}
158177

159178
private function handleStaticClassConstantNode(Node $node): void
160179
{
161-
/**
162-
* adding static classes as dependencies
163-
* $constantValue = StaticClass::constant;.
164-
*
165-
* @see FileVisitorTest::test_it_should_return_errors_for_const_outside_namespace
166-
*/
167-
if (
168-
$node instanceof Node\Expr\ClassConstFetch
169-
&& method_exists($node->class, 'toString')
170-
) {
171-
if ($this->isSelfOrStaticOrParent($node->class->toString())) {
172-
return;
173-
}
180+
if (!($node instanceof Node\Expr\ClassConstFetch)) {
181+
return;
182+
}
174183

175-
$this->classDescriptionBuilder
176-
->addDependency(new ClassDependency($node->class->toString(), $node->getLine()));
184+
if (!($node->class instanceof Node\Name\FullyQualified)) {
185+
return;
177186
}
187+
188+
$this->classDescriptionBuilder
189+
->addDependency(new ClassDependency($node->class->toString(), $node->getLine()));
178190
}
179191

180192
private function handleStaticClassCallsNode(Node $node): void
181193
{
182-
/**
183-
* adding static function classes as dependencies
184-
* $static = StaticClass::foo();.
185-
*
186-
* @see FileVisitorTest::test_should_returns_all_dependencies
187-
*/
188-
if (
189-
$node instanceof Node\Expr\StaticCall
190-
&& method_exists($node->class, 'toString')
191-
) {
192-
if ($this->isSelfOrStaticOrParent($node->class->toString())) {
193-
return;
194-
}
194+
if (!($node instanceof Node\Expr\StaticCall)) {
195+
return;
196+
}
195197

196-
$this->classDescriptionBuilder
197-
->addDependency(new ClassDependency($node->class->toString(), $node->getLine()));
198+
if (!($node->class instanceof Node\Name\FullyQualified)) {
199+
return;
198200
}
201+
202+
$this->classDescriptionBuilder
203+
->addDependency(new ClassDependency($node->class->toString(), $node->getLine()));
199204
}
200205

201206
private function handleInstanceOf(Node $node): void
202207
{
203-
if (
204-
$node instanceof Node\Expr\Instanceof_
205-
&& method_exists($node->class, 'toString')
206-
) {
207-
if ($this->isSelfOrStaticOrParent($node->class->toString())) {
208-
return;
209-
}
210-
$this->classDescriptionBuilder
211-
->addDependency(new ClassDependency($node->class->toString(), $node->getLine()));
208+
if (!($node instanceof Node\Expr\Instanceof_)) {
209+
return;
210+
}
211+
212+
if (!($node->class instanceof Node\Name\FullyQualified)) {
213+
return;
212214
}
215+
216+
$this->classDescriptionBuilder
217+
->addDependency(new ClassDependency($node->class->toString(), $node->getLine()));
213218
}
214219

215220
private function handleNewExpression(Node $node): void
216221
{
217-
if (
218-
$node instanceof Node\Expr\New_
219-
&& !($node->class instanceof Node\Expr\Variable)
220-
) {
221-
if ((method_exists($node->class, 'isAnonymous') && true === $node->class->isAnonymous())
222-
|| !method_exists($node->class, 'toString')
223-
) {
224-
return;
225-
}
226-
227-
if ($this->isSelfOrStaticOrParent($node->class->toString())) {
228-
return;
229-
}
222+
if (!($node instanceof Node\Expr\New_)) {
223+
return;
224+
}
230225

231-
$this->classDescriptionBuilder
232-
->addDependency(new ClassDependency($node->class->toString(), $node->getLine()));
226+
if (!($node->class instanceof Node\Name\FullyQualified)) {
227+
return;
233228
}
229+
230+
$this->classDescriptionBuilder
231+
->addDependency(new ClassDependency($node->class->toString(), $node->getLine()));
234232
}
235233

236234
private function handleTypedProperty(Node $node): void
237235
{
238-
if ($node instanceof Node\Stmt\Property) {
239-
if (null === $node->type) {
240-
return;
241-
}
242-
243-
$type = $node->type;
244-
if ($type instanceof NullableType) {
245-
$type = $type->type;
246-
}
247-
248-
if (!method_exists($type, 'toString') || $this->isBuiltInType($type->toString())) {
249-
return;
250-
}
251-
252-
try {
253-
$this->classDescriptionBuilder
254-
->addDependency(new ClassDependency($type->toString(), $node->getLine()));
255-
} catch (\Exception $e) {
256-
// Silently ignore
257-
}
236+
if (!($node instanceof Node\Stmt\Property)) {
237+
return;
238+
}
239+
240+
if (null === $node->type) {
241+
return;
242+
}
243+
244+
$type = $node->type instanceof NullableType ? $node->type->type : $node->type;
245+
246+
if (!($type instanceof Node\Name\FullyQualified)) {
247+
return;
258248
}
249+
250+
$this->classDescriptionBuilder
251+
->addDependency(new ClassDependency($type->toString(), $node->getLine()));
259252
}
260253

261254
private function handleDocComment(Node $node): void
@@ -278,92 +271,82 @@ private function handleParamDependency(Node $node): void
278271

279272
private function handleInterfaceNode(Node $node): void
280273
{
281-
if ($node instanceof Node\Stmt\Interface_) {
282-
if (null === $node->namespacedName) {
283-
return;
284-
}
274+
if (!($node instanceof Node\Stmt\Interface_)) {
275+
return;
276+
}
285277

286-
$this->classDescriptionBuilder->setClassName($node->namespacedName->toCodeString());
287-
$this->classDescriptionBuilder->setInterface(true);
278+
if (null === $node->namespacedName) {
279+
return;
280+
}
288281

289-
foreach ($node->extends as $interface) {
290-
$this->classDescriptionBuilder
291-
->addExtends($interface->toString(), $interface->getLine());
292-
}
282+
$this->classDescriptionBuilder->setClassName($node->namespacedName->toCodeString());
283+
$this->classDescriptionBuilder->setInterface(true);
284+
285+
foreach ($node->extends as $interface) {
286+
$this->classDescriptionBuilder
287+
->addExtends($interface->toString(), $interface->getLine());
293288
}
294289
}
295290

296291
private function handleTraitNode(Node $node): void
297292
{
298-
if ($node instanceof Node\Stmt\Trait_) {
299-
if (null === $node->namespacedName) {
300-
return;
301-
}
293+
if (!($node instanceof Node\Stmt\Trait_)) {
294+
return;
295+
}
302296

303-
$this->classDescriptionBuilder->setClassName($node->namespacedName->toCodeString());
304-
$this->classDescriptionBuilder->setTrait(true);
297+
if (null === $node->namespacedName) {
298+
return;
305299
}
300+
301+
$this->classDescriptionBuilder->setClassName($node->namespacedName->toCodeString());
302+
$this->classDescriptionBuilder->setTrait(true);
306303
}
307304

308305
private function handleReturnTypeDependency(Node $node): void
309306
{
310-
if ($node instanceof Node\Stmt\ClassMethod) {
311-
$returnType = $node->returnType;
312-
if ($returnType instanceof Node\Name\FullyQualified) {
313-
$this->classDescriptionBuilder
314-
->addDependency(new ClassDependency($returnType->toString(), $returnType->getLine()));
315-
}
307+
if (!($node instanceof Node\Stmt\ClassMethod)) {
308+
return;
316309
}
317-
}
318310

319-
private function handleAttributeNode(Node $node): void
320-
{
321-
if ($node instanceof Node\Attribute) {
322-
$nodeName = $node->name;
311+
$returnType = $node->returnType;
323312

324-
if ($nodeName instanceof Node\Name\FullyQualified) {
325-
$this->classDescriptionBuilder
326-
->addAttribute($node->name->toString(), $node->getLine());
327-
}
313+
if (!($returnType instanceof Node\Name\FullyQualified)) {
314+
return;
328315
}
329-
}
330316

331-
private function isSelfOrStaticOrParent(string $dependencyClass): bool
332-
{
333-
return 'self' === $dependencyClass || 'static' === $dependencyClass || 'parent' === $dependencyClass;
317+
$this->classDescriptionBuilder
318+
->addDependency(new ClassDependency($returnType->toString(), $returnType->getLine()));
334319
}
335320

336-
private function addParamDependency(Node\Param $node): void
321+
private function handleAttributeNode(Node $node): void
337322
{
338-
if (null === $node->type || $node->type instanceof Node\Identifier) {
323+
if (!($node instanceof Node\Attribute)) {
339324
return;
340325
}
341326

342-
$type = $node->type;
343-
if ($type instanceof NullableType) {
344-
/** @var NullableType * */
345-
$nullableType = $type;
346-
$type = $nullableType->type;
347-
}
327+
$nodeName = $node->name;
348328

349-
if (method_exists($type, 'isSpecialClassName') && true === $type->isSpecialClassName()) {
329+
if (!($nodeName instanceof Node\Name\FullyQualified)) {
350330
return;
351331
}
352332

353-
if (!method_exists($type, 'toString')) {
333+
$this->classDescriptionBuilder
334+
->addAttribute($node->name->toString(), $node->getLine());
335+
}
336+
337+
private function addParamDependency(Node\Param $node): void
338+
{
339+
if (null === $node->type || $node->type instanceof Node\Identifier) {
354340
return;
355341
}
356342

357-
if ($this->isBuiltInType($type->toString())) {
343+
$type = $node->type instanceof NullableType ? $node->type->type : $node->type;
344+
345+
if (!($type instanceof Node\Name\FullyQualified)) {
358346
return;
359347
}
360348

361349
$this->classDescriptionBuilder
362350
->addDependency(new ClassDependency($type->toString(), $node->getLine()));
363351
}
364-
365-
private function isBuiltInType(string $typeName): bool
366-
{
367-
return \in_array($typeName, ['bool', 'int', 'float', 'string', 'array', 'resource', 'object', 'null']);
368-
}
369352
}

0 commit comments

Comments
 (0)