Skip to content

Commit 75e6115

Browse files
committed
Tip for Discovering Symbols on all "not found" messages
1 parent 4a9c159 commit 75e6115

File tree

44 files changed

+98
-23
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

44 files changed

+98
-23
lines changed

src/Analyser/FileAnalyser.php

+2-2
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,7 @@ public function analyseFile(
9191
$fileErrors[] = new Error($e->getMessage(), $file, $node->getLine(), false, null, null, $e->getTip());
9292
continue;
9393
} catch (IdentifierNotFound $e) {
94-
$fileErrors[] = new Error(sprintf('Reflection error: %s not found.', $e->getIdentifier()->getName()), $file, $node->getLine(), false);
94+
$fileErrors[] = new Error(sprintf('Reflection error: %s not found.', $e->getIdentifier()->getName()), $file, $node->getLine(), false, null, null, 'Learn more at https://phpstan.org/user-guide/discovering-symbols');
9595
continue;
9696
}
9797

@@ -232,7 +232,7 @@ public function analyseFile(
232232
} catch (\PHPStan\AnalysedCodeException $e) {
233233
$fileErrors[] = new Error($e->getMessage(), $file, null, false, null, null, $e->getTip());
234234
} catch (IdentifierNotFound $e) {
235-
$fileErrors[] = new Error(sprintf('Reflection error: %s not found.', $e->getIdentifier()->getName()), $file, null, false);
235+
$fileErrors[] = new Error(sprintf('Reflection error: %s not found.', $e->getIdentifier()->getName()), $file, null, false, null, null, 'Learn more at https://phpstan.org/user-guide/discovering-symbols');
236236
}
237237
} elseif (is_dir($file)) {
238238
$fileErrors[] = new Error(sprintf('File %s is a directory.', $file), $file, null, false);

src/Rules/Classes/ClassConstantRule.php

+2-2
Original file line numberDiff line numberDiff line change
@@ -91,14 +91,14 @@ public function processNode(Node $node, Scope $scope): array
9191

9292
if (strtolower($constantName) === 'class') {
9393
return [
94-
RuleErrorBuilder::message(sprintf('Class %s not found.', $className))->build(),
94+
RuleErrorBuilder::message(sprintf('Class %s not found.', $className))->discoveringSymbolsTip()->build(),
9595
];
9696
}
9797

9898
return [
9999
RuleErrorBuilder::message(
100100
sprintf('Access to constant %s on an unknown class %s.', $constantName, $className)
101-
)->build(),
101+
)->discoveringSymbolsTip()->build(),
102102
];
103103
} else {
104104
$messages = $this->classCaseSensitivityCheck->checkClassNames([new ClassNameNodePair($className, $class)]);

src/Rules/Classes/ExistingClassInClassExtendsRule.php

+1-1
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ public function processNode(Node $node, Scope $scope): array
5050
'%s extends unknown class %s.',
5151
$currentClassName !== null ? sprintf('Class %s', $currentClassName) : 'Anonymous class',
5252
$extendedClassName
53-
))->nonIgnorable()->build();
53+
))->nonIgnorable()->discoveringSymbolsTip()->build();
5454
}
5555
} else {
5656
$reflection = $this->reflectionProvider->getClass($extendedClassName);

src/Rules/Classes/ExistingClassInInstanceOfRule.php

+1-1
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ public function processNode(Node $node, Scope $scope): array
6868
}
6969

7070
return [
71-
RuleErrorBuilder::message(sprintf('Class %s not found.', $name))->line($class->getLine())->build(),
71+
RuleErrorBuilder::message(sprintf('Class %s not found.', $name))->line($class->getLine())->discoveringSymbolsTip()->build(),
7272
];
7373
} elseif ($this->checkClassCaseSensitivity) {
7474
return $this->classCaseSensitivityCheck->checkClassNames([new ClassNameNodePair($name, $class)]);

src/Rules/Classes/ExistingClassInTraitUseRule.php

+1-1
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ public function processNode(Node $node, Scope $scope): array
6565
foreach ($node->traits as $trait) {
6666
$traitName = (string) $trait;
6767
if (!$this->reflectionProvider->hasClass($traitName)) {
68-
$messages[] = RuleErrorBuilder::message(sprintf('%s uses unknown trait %s.', $currentName, $traitName))->nonIgnorable()->build();
68+
$messages[] = RuleErrorBuilder::message(sprintf('%s uses unknown trait %s.', $currentName, $traitName))->nonIgnorable()->discoveringSymbolsTip()->build();
6969
} else {
7070
$reflection = $this->reflectionProvider->getClass($traitName);
7171
if ($reflection->isClass()) {

src/Rules/Classes/ExistingClassesInClassImplementsRule.php

+1-1
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ public function processNode(Node $node, Scope $scope): array
5454
'%s implements unknown interface %s.',
5555
$currentClassName !== null ? sprintf('Class %s', $currentClassName) : 'Anonymous class',
5656
$implementedClassName
57-
))->nonIgnorable()->build();
57+
))->nonIgnorable()->discoveringSymbolsTip()->build();
5858
}
5959
} else {
6060
$reflection = $this->reflectionProvider->getClass($implementedClassName);

src/Rules/Classes/ExistingClassesInInterfaceExtendsRule.php

+1-1
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ public function processNode(Node $node, Scope $scope): array
5050
'Interface %s extends unknown interface %s.',
5151
$currentInterfaceName,
5252
$extendedInterfaceName
53-
))->nonIgnorable()->build();
53+
))->nonIgnorable()->discoveringSymbolsTip()->build();
5454
}
5555
} else {
5656
$reflection = $this->reflectionProvider->getClass($extendedInterfaceName);

src/Rules/Classes/InstantiationRule.php

+1-1
Original file line numberDiff line numberDiff line change
@@ -120,7 +120,7 @@ private function checkClassName(string $class, Node $node, Scope $scope): array
120120
}
121121

122122
return [
123-
RuleErrorBuilder::message(sprintf('Instantiated class %s not found.', $class))->build(),
123+
RuleErrorBuilder::message(sprintf('Instantiated class %s not found.', $class))->discoveringSymbolsTip()->build(),
124124
];
125125
} else {
126126
$messages = $this->classCaseSensitivityCheck->checkClassNames([

src/Rules/Classes/MixinRule.php

+1-1
Original file line numberDiff line numberDiff line change
@@ -110,7 +110,7 @@ public function processNode(Node $node, Scope $scope): array
110110

111111
foreach ($type->getReferencedClasses() as $class) {
112112
if (!$this->reflectionProvider->hasClass($class)) {
113-
$errors[] = RuleErrorBuilder::message(sprintf('PHPDoc tag @mixin contains unknown class %s.', $class))->build();
113+
$errors[] = RuleErrorBuilder::message(sprintf('PHPDoc tag @mixin contains unknown class %s.', $class))->discoveringSymbolsTip()->build();
114114
} elseif ($this->reflectionProvider->getClass($class)->isTrait()) {
115115
$errors[] = RuleErrorBuilder::message(sprintf('PHPDoc tag @mixin contains invalid type %s.', $class))->build();
116116
} elseif ($this->checkClassCaseSensitivity) {

src/Rules/Constants/ConstantRule.php

+1-1
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ public function processNode(Node $node, Scope $scope): array
2424
RuleErrorBuilder::message(sprintf(
2525
'Constant %s not found.',
2626
(string) $node->name
27-
))->build(),
27+
))->discoveringSymbolsTip()->build(),
2828
];
2929
}
3030

src/Rules/Exceptions/CaughtExceptionExistenceRule.php

+1-1
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ public function processNode(Node $node, Scope $scope): array
4747
if ($scope->isInClassExists($className)) {
4848
continue;
4949
}
50-
$errors[] = RuleErrorBuilder::message(sprintf('Caught class %s not found.', $className))->line($class->getLine())->build();
50+
$errors[] = RuleErrorBuilder::message(sprintf('Caught class %s not found.', $className))->line($class->getLine())->discoveringSymbolsTip()->build();
5151
continue;
5252
}
5353

src/Rules/Functions/CallToNonExistentFunctionRule.php

+1-1
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ public function processNode(Node $node, Scope $scope): array
4040

4141
if (!$this->reflectionProvider->hasFunction($node->name, $scope)) {
4242
return [
43-
RuleErrorBuilder::message(sprintf('Function %s not found.', (string) $node->name))->build(),
43+
RuleErrorBuilder::message(sprintf('Function %s not found.', (string) $node->name))->discoveringSymbolsTip()->build(),
4444
];
4545
}
4646

src/Rules/Methods/CallStaticMethodsRule.php

+1-1
Original file line numberDiff line numberDiff line change
@@ -129,7 +129,7 @@ public function processNode(Node $node, Scope $scope): array
129129
'Call to static method %s() on an unknown class %s.',
130130
$methodName,
131131
$className
132-
))->build(),
132+
))->discoveringSymbolsTip()->build(),
133133
];
134134
} else {
135135
$errors = $this->classCaseSensitivityCheck->checkClassNames([new ClassNameNodePair($className, $class)]);

src/Rules/Namespaces/ExistingNamesInGroupUseRule.php

+2-2
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@ public function processNode(Node $node, Scope $scope): array
7676
private function checkConstant(Node\Name $name): ?RuleError
7777
{
7878
if (!$this->reflectionProvider->hasConstant($name, null)) {
79-
return RuleErrorBuilder::message(sprintf('Used constant %s not found.', (string) $name))->line($name->getLine())->build();
79+
return RuleErrorBuilder::message(sprintf('Used constant %s not found.', (string) $name))->discoveringSymbolsTip()->line($name->getLine())->build();
8080
}
8181

8282
return null;
@@ -85,7 +85,7 @@ private function checkConstant(Node\Name $name): ?RuleError
8585
private function checkFunction(Node\Name $name): ?RuleError
8686
{
8787
if (!$this->reflectionProvider->hasFunction($name, null)) {
88-
return RuleErrorBuilder::message(sprintf('Used function %s not found.', (string) $name))->line($name->getLine())->build();
88+
return RuleErrorBuilder::message(sprintf('Used function %s not found.', (string) $name))->discoveringSymbolsTip()->line($name->getLine())->build();
8989
}
9090

9191
if ($this->checkFunctionNameCase) {

src/Rules/Namespaces/ExistingNamesInUseRule.php

+2-2
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ private function checkConstants(array $uses): array
7373
continue;
7474
}
7575

76-
$errors[] = RuleErrorBuilder::message(sprintf('Used constant %s not found.', (string) $use->name))->line($use->name->getLine())->build();
76+
$errors[] = RuleErrorBuilder::message(sprintf('Used constant %s not found.', (string) $use->name))->line($use->name->getLine())->discoveringSymbolsTip()->build();
7777
}
7878

7979
return $errors;
@@ -88,7 +88,7 @@ private function checkFunctions(array $uses): array
8888
$errors = [];
8989
foreach ($uses as $use) {
9090
if (!$this->reflectionProvider->hasFunction($use->name, null)) {
91-
$errors[] = RuleErrorBuilder::message(sprintf('Used function %s not found.', (string) $use->name))->line($use->name->getLine())->build();
91+
$errors[] = RuleErrorBuilder::message(sprintf('Used function %s not found.', (string) $use->name))->line($use->name->getLine())->discoveringSymbolsTip()->build();
9292
} elseif ($this->checkFunctionNameCase) {
9393
$functionReflection = $this->reflectionProvider->getFunction($use->name, null);
9494
$realName = $functionReflection->getName();

src/Rules/PhpDoc/InvalidPhpDocVarTagTypeRule.php

+1-1
Original file line numberDiff line numberDiff line change
@@ -144,7 +144,7 @@ public function processNode(Node $node, Scope $scope): array
144144
$errors[] = RuleErrorBuilder::message(sprintf(
145145
sprintf('%s contains unknown class %%s.', $identifier),
146146
$referencedClass
147-
))->build();
147+
))->discoveringSymbolsTip()->build();
148148
}
149149

150150
if (!$this->checkClassCaseSensitivity) {

src/Rules/Properties/AccessStaticPropertiesRule.php

+1-1
Original file line numberDiff line numberDiff line change
@@ -113,7 +113,7 @@ public function processNode(Node $node, Scope $scope): array
113113
'Access to static property $%s on an unknown class %s.',
114114
$name,
115115
$class
116-
))->build(),
116+
))->discoveringSymbolsTip()->build(),
117117
];
118118
} else {
119119
$messages = $this->classCaseSensitivityCheck->checkClassNames([new ClassNameNodePair($class, $node->class)]);

src/Rules/Properties/ExistingClassesInPropertiesRule.php

+1-1
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ public function processNode(Node $node, Scope $scope): array
7777
$propertyReflection->getDeclaringClass()->getDisplayName(),
7878
$node->name->name,
7979
$referencedClass
80-
))->build();
80+
))->discoveringSymbolsTip()->build();
8181
}
8282

8383
if ($this->checkClassCaseSensitivity) {

src/Rules/RuleErrorBuilder.php

+5
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,11 @@ public function tip(string $tip): self
104104
return $this;
105105
}
106106

107+
public function discoveringSymbolsTip(): self
108+
{
109+
return $this->tip('Learn more at https://phpstan.org/user-guide/discovering-symbols');
110+
}
111+
107112
public function identifier(string $identifier): self
108113
{
109114
$this->properties['identifier'] = $identifier;

src/Rules/RuleLevelHelper.php

+1-1
Original file line numberDiff line numberDiff line change
@@ -157,7 +157,7 @@ public function findTypeToCheck(
157157
continue;
158158
}
159159

160-
$errors[] = RuleErrorBuilder::message(sprintf($unknownClassErrorPattern, $referencedClass))->line($var->getLine())->build();
160+
$errors[] = RuleErrorBuilder::message(sprintf($unknownClassErrorPattern, $referencedClass))->line($var->getLine())->discoveringSymbolsTip()->build();
161161
}
162162

163163
if (count($errors) > 0 || $hasClassExistsClass) {

tests/PHPStan/Rules/Arrays/IterableInForeachRuleTest.php

+1
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ public function testCheckWithMaybes(): void
2929
[
3030
'Iterating over an object of an unknown class IterablesInForeach\Bar.',
3131
47,
32+
'Learn more at https://phpstan.org/user-guide/discovering-symbols',
3233
],
3334
]);
3435
}

tests/PHPStan/Rules/Arrays/NonexistentOffsetInArrayDimFetchRuleTest.php

+2
Original file line numberDiff line numberDiff line change
@@ -36,10 +36,12 @@ public function testRule(): void
3636
[
3737
'Access to offset \'bar\' on an unknown class NonexistentOffset\Bar.',
3838
101,
39+
'Learn more at https://phpstan.org/user-guide/discovering-symbols',
3940
],
4041
[
4142
'Access to an offset on an unknown class NonexistentOffset\Bar.',
4243
102,
44+
'Learn more at https://phpstan.org/user-guide/discovering-symbols',
4345
],
4446
[
4547
'Offset 0 does not exist on array<string, string>.',

tests/PHPStan/Rules/Classes/ClassConstantRuleTest.php

+7
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ public function testClassConstant(): void
2929
[
3030
'Class ClassConstantNamespace\Bar not found.',
3131
6,
32+
'Learn more at https://phpstan.org/user-guide/discovering-symbols',
3233
],
3334
[
3435
'Using self outside of class scope.',
@@ -53,6 +54,7 @@ public function testClassConstant(): void
5354
[
5455
'Access to constant FOO on an unknown class ClassConstantNamespace\UnknownClass.',
5556
21,
57+
'Learn more at https://phpstan.org/user-guide/discovering-symbols',
5658
],
5759
[
5860
'Class ClassConstantNamespace\Foo referenced with incorrect case: ClassConstantNamespace\FOO.',
@@ -123,10 +125,12 @@ public function testClassConstantVisibility(): void
123125
[
124126
'Access to constant FOO on an unknown class ClassConstantVisibility\UnknownClassFirst.',
125127
112,
128+
'Learn more at https://phpstan.org/user-guide/discovering-symbols',
126129
],
127130
[
128131
'Access to constant FOO on an unknown class ClassConstantVisibility\UnknownClassSecond.',
129132
112,
133+
'Learn more at https://phpstan.org/user-guide/discovering-symbols',
130134
],
131135
[
132136
'Cannot access constant FOO on int|string.',
@@ -149,14 +153,17 @@ public function testClassExists(): void
149153
[
150154
'Class UnknownClass\Bar not found.',
151155
24,
156+
'Learn more at https://phpstan.org/user-guide/discovering-symbols',
152157
],
153158
[
154159
'Class UnknownClass\Foo not found.',
155160
26,
161+
'Learn more at https://phpstan.org/user-guide/discovering-symbols',
156162
],
157163
[
158164
'Class UnknownClass\Foo not found.',
159165
29,
166+
'Learn more at https://phpstan.org/user-guide/discovering-symbols',
160167
],
161168
]);
162169
}

tests/PHPStan/Rules/Classes/ExistingClassInClassExtendsRuleTest.php

+1
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ public function testRuleExtendsError(): void
4040
[
4141
'Class ExtendsError\Foo extends unknown class ExtendsError\Bar.',
4242
5,
43+
'Learn more at https://phpstan.org/user-guide/discovering-symbols',
4344
],
4445
[
4546
'Class ExtendsError\Lorem extends interface ExtendsError\BazInterface.',

tests/PHPStan/Rules/Classes/ExistingClassInInstanceOfRuleTest.php

+1
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ public function testClassDoesNotExist(): void
3232
[
3333
'Class InstanceOfNamespace\Bar not found.',
3434
7,
35+
'Learn more at https://phpstan.org/user-guide/discovering-symbols',
3536
],
3637
[
3738
'Using self outside of class scope.',

tests/PHPStan/Rules/Classes/ExistingClassInTraitUseRuleTest.php

+2
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ public function testTraitUseError(): void
4040
[
4141
'Class TraitUseError\Foo uses unknown trait TraitUseError\FooTrait.',
4242
8,
43+
'Learn more at https://phpstan.org/user-guide/discovering-symbols',
4344
],
4445
/*[
4546
'Trait TraitUseError\BarTrait uses class TraitUseError\Foo.',
@@ -56,6 +57,7 @@ public function testTraitUseError(): void
5657
[
5758
'Anonymous class uses unknown trait TraitUseError\FooTrait.',
5859
27,
60+
'Learn more at https://phpstan.org/user-guide/discovering-symbols',
5961
],
6062
[
6163
'Anonymous class uses interface TraitUseError\Baz.',

tests/PHPStan/Rules/Classes/ExistingClassesInClassImplementsRuleTest.php

+1
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ public function testRuleImplementsError(): void
4040
[
4141
'Class ImplementsError\Foo implements unknown interface ImplementsError\Bar.',
4242
5,
43+
'Learn more at https://phpstan.org/user-guide/discovering-symbols',
4344
],
4445
[
4546
'Class ImplementsError\Lorem implements class ImplementsError\Foo.',

tests/PHPStan/Rules/Classes/ExistingClassesInInterfaceExtendsRuleTest.php

+1
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ public function testRuleExtendsError(): void
4040
[
4141
'Interface InterfaceExtendsError\Foo extends unknown interface InterfaceExtendsError\Bar.',
4242
5,
43+
'Learn more at https://phpstan.org/user-guide/discovering-symbols',
4344
],
4445
[
4546
'Interface InterfaceExtendsError\Lorem extends class InterfaceExtendsError\BazClass.',

tests/PHPStan/Rules/Classes/InstantiationRuleTest.php

+5
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ public function testInstantiation(): void
4545
[
4646
'Instantiated class TestInstantiation\FooBarInstantiation not found.',
4747
27,
48+
'Learn more at https://phpstan.org/user-guide/discovering-symbols',
4849
],
4950
[
5051
'Class TestInstantiation\BarInstantiation constructor invoked with 0 parameters, 1 required.',
@@ -61,6 +62,7 @@ public function testInstantiation(): void
6162
[
6263
'Instantiated class Test not found.',
6364
33,
65+
'Learn more at https://phpstan.org/user-guide/discovering-symbols',
6466
],
6567
[
6668
'Class DatePeriod constructor invoked with 0 parameters, 1-4 required.',
@@ -153,14 +155,17 @@ public function testInstantiation(): void
153155
[
154156
'Instantiated class UndefinedClass1 not found.',
155157
169,
158+
'Learn more at https://phpstan.org/user-guide/discovering-symbols',
156159
],
157160
[
158161
'Instantiated class UndefinedClass2 not found.',
159162
172,
163+
'Learn more at https://phpstan.org/user-guide/discovering-symbols',
160164
],
161165
[
162166
'Instantiated class UndefinedClass3 not found.',
163167
179,
168+
'Learn more at https://phpstan.org/user-guide/discovering-symbols',
164169
],
165170
[
166171
'Class TestInstantiation\FinalClass does not have a constructor and must be instantiated without any parameters.',

tests/PHPStan/Rules/Classes/MixinRuleTest.php

+2
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@ public function testRule(): void
6060
[
6161
'PHPDoc tag @mixin contains unknown class MixinRule\UnknownestClass.',
6262
50,
63+
'Learn more at https://phpstan.org/user-guide/discovering-symbols',
6364
],
6465
[
6566
'PHPDoc tag @mixin contains invalid type MixinRule\FooTrait.',
@@ -68,6 +69,7 @@ public function testRule(): void
6869
[
6970
'PHPDoc tag @mixin contains unknown class MixinRule\U.',
7071
59,
72+
'Learn more at https://phpstan.org/user-guide/discovering-symbols',
7173
],
7274
[
7375
'Generic type MixinRule\Consecteur<MixinRule\Foo> in PHPDoc tag @mixin does not specify all template types of class MixinRule\Consecteur: T, U',

0 commit comments

Comments
 (0)