Skip to content

Commit ca68fad

Browse files
authored
Readme: improve AST-based usage provider example (#156)
1 parent a4fef66 commit ca68fad

File tree

1 file changed

+15
-14
lines changed

1 file changed

+15
-14
lines changed

README.md

Lines changed: 15 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -129,32 +129,42 @@ services:
129129
use ReflectionMethod;
130130
use ShipMonk\PHPStan\DeadCode\Provider\ReflectionBasedMemberUsageProvider;
131131

132-
class ApiOutputUsageProvider extends ReflectionBasedMemberUsageProvider
132+
class FuzzyTwigUsageProvider extends ReflectionBasedMemberUsageProvider
133133
{
134134

135135
public function shouldMarkMethodAsUsed(ReflectionMethod $method): bool
136136
{
137-
// all methods from our ApiOutput interface are called automatically (e.g. during serialization)
138-
return $method->getDeclaringClass()->implementsInterface(ApiOutput::class);
137+
return $method->getDeclaringClass()->implementsInterface(UsedInTwigMarkerInterface::class);
139138
}
140139

141140
}
142141
```
143142

144143
### AST-based customization:
145-
- For more complex usecases that are deducible only from AST (e.g. serialization calls), you just stick with raw `MemberUsageProvider` interface:
144+
- For more complex usecases that are deducible only from AST, you just stick with raw `MemberUsageProvider` interface.
145+
- Here is simplified example how to emit `User::__construct` usage in following PHP snippet:
146146

147147
```php
148+
function test(SerializerInterface $serializer): User {
149+
return $serializer->deserialize('{"name": "John"}', User::class, 'json');
150+
}
151+
```
148152

153+
```php
149154
use ReflectionMethod;
150155
use ShipMonk\PHPStan\DeadCode\Graph\ClassMethodRef;
151156
use ShipMonk\PHPStan\DeadCode\Graph\ClassMethodUsage;
157+
use ShipMonk\PHPStan\DeadCode\Graph\UsageOriginDetector;
152158
use ShipMonk\PHPStan\DeadCode\Provider\MemberUsageProvider;
153159
use Symfony\Component\Serializer\SerializerInterface;
154160

155161
class DeserializationUsageProvider implements MemberUsageProvider
156162
{
157163

164+
public function __construct(
165+
private UsageOriginDetector $originDetector,
166+
) {}
167+
158168
/**
159169
* @return list<ClassMemberUsage>
160170
*/
@@ -173,7 +183,7 @@ class DeserializationUsageProvider implements MemberUsageProvider
173183
$serializedClass = $scope->getType($secondArgument)->getConstantStrings()[0];
174184

175185
// record the method it was called from (needed for proper transitive dead code elimination)
176-
$originRef = $this->getOriginMethodRef($scope);
186+
$originRef = $this->originDetector->detectOrigin($node, $scope);
177187

178188
// record the hidden constructor call
179189
$constructorRef = new ClassMethodRef($serializedClass->getValue(), '__construct', false);
@@ -184,15 +194,6 @@ class DeserializationUsageProvider implements MemberUsageProvider
184194
return [];
185195
}
186196

187-
private function getOriginMethodRef(Scope $scope): ?ClassMethodRef
188-
{
189-
return new ClassMethodRef(
190-
$scope->getClassReflection()->getName(),
191-
$scope->getFunction()->getName(),
192-
false,
193-
);
194-
}
195-
196197
}
197198
```
198199

0 commit comments

Comments
 (0)