|
2 | 2 |
|
3 | 3 | namespace PHPStan\Rules\Doctrine\ORM;
|
4 | 4 |
|
| 5 | +use Doctrine\ORM\Mapping\ClassMetadata; |
5 | 6 | use PhpParser\Node;
|
6 | 7 | use PHPStan\Analyser\Scope;
|
| 8 | +use PHPStan\Reflection\ClassReflection; |
7 | 9 | use PHPStan\Reflection\MissingPropertyFromReflectionException;
|
| 10 | +use PHPStan\Reflection\Php\PhpPropertyReflection; |
8 | 11 | use PHPStan\Rules\Rule;
|
9 | 12 | use PHPStan\Type\ArrayType;
|
10 | 13 | use PHPStan\Type\Doctrine\DescriptorNotRegisteredException;
|
|
13 | 16 | use PHPStan\Type\ErrorType;
|
14 | 17 | use PHPStan\Type\MixedType;
|
15 | 18 | use PHPStan\Type\NeverType;
|
| 19 | +use PHPStan\Type\ObjectType; |
16 | 20 | use PHPStan\Type\Type;
|
17 | 21 | use PHPStan\Type\TypeCombinator;
|
18 | 22 | use PHPStan\Type\TypeTraverser;
|
@@ -86,6 +90,10 @@ public function processNode(Node $node, Scope $scope): array
|
86 | 90 | return [];
|
87 | 91 | }
|
88 | 92 |
|
| 93 | + if (isset($metadata->embeddedClasses[$propertyName])) { |
| 94 | + return $this->checkEmbeddedObject($class, $property, $metadata, $propertyName); |
| 95 | + } |
| 96 | + |
89 | 97 | if (!isset($metadata->fieldMappings[$propertyName])) {
|
90 | 98 | return [];
|
91 | 99 | }
|
@@ -160,4 +168,23 @@ public function processNode(Node $node, Scope $scope): array
|
160 | 168 | return $errors;
|
161 | 169 | }
|
162 | 170 |
|
| 171 | + private function checkEmbeddedObject(ClassReflection $class, PhpPropertyReflection $property, ClassMetadata $metadata, string $propertyName): array |
| 172 | + { |
| 173 | + $errors = []; |
| 174 | + $embeddedClass = $metadata->embeddedClasses[$propertyName]; |
| 175 | + $propertyWritableType = $property->getWritableType(); |
| 176 | + $accordingToMapping = new ObjectType($embeddedClass['class']); |
| 177 | + if (!TypeCombinator::removeNull($propertyWritableType)->equals($accordingToMapping)) { |
| 178 | + $errors[] = sprintf( |
| 179 | + 'Property %s::$%s type mapping mismatch: mapping specifies %s but property expects %s.', |
| 180 | + $class->getName(), |
| 181 | + $propertyName, |
| 182 | + $accordingToMapping->describe(VerbosityLevel::typeOnly()), |
| 183 | + $propertyWritableType->describe(VerbosityLevel::typeOnly()) |
| 184 | + ); |
| 185 | + } |
| 186 | + |
| 187 | + return $errors; |
| 188 | + } |
| 189 | + |
163 | 190 | }
|
0 commit comments