Repository: JsonMapper/JsonMapper (php)

Issue:
NamespaceResolver does not correctly lookup namespace for properties in parent class
**Describe the bug**
I want to map a class which extends another class and has property with phpdoc (class).

```php
<?php
declare(strict_types = 1);

namespace Foo

use Foo\Model\BarModel

class test extends BarModel
{
}
```

```php
<?php
declare(strict_types = 1);

namespace Foo\Model

use Foo\MetaModel\Meta;

class BarModel
{
    /** @var null|Meta */
    public $meta;
}
```

```php
<?php

declare(strict_types = 1);

namespace Foo\MetaModel;

class Meta
{
    /** @var null|string */
    public $type;
}

```
The Namespaceresolver does not correct lookup the namespace of the used Foo\MetaModel\Meta.
Instead it will look only for Meta. Only a complete phpdoc helps here with Foo\MetaModel\Meta


PHP Version: 7.2
Json-Mapper: 2.9.0
Mode: (new JsonMapperFactory())->bestFit()

Pull request:
Add support for imports in parent class(es)
Would fix #116 

Patch:
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 19a3dff..9ba2cc5 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -5,6 +5,8 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
 and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
 
 ## [Unreleased]
+### Fixed
+- Namespace resolving improved to include imports from parent classes [PR#117](https://github.com/JsonMapper/JsonMapper/pull/117) Thanks to [template-provider](https://github.com/template-provider) for reporting the issue
 
 ## [2.9.0] - 2021-11-09
 ### Added
diff --git a/src/Helpers/UseStatementHelper.php b/src/Helpers/UseStatementHelper.php
index d1f5c90..095eb62 100644
--- a/src/Helpers/UseStatementHelper.php
+++ b/src/Helpers/UseStatementHelper.php
@@ -15,7 +15,7 @@ class UseStatementHelper
     /** @var string */
     private static $evaldCodeFileNameEnding = "eval()'d code";
 
-    /** @return Import */
+    /** @return Import[] */
     public static function getImports(\ReflectionClass $class): array
     {
         if (!$class->isUserDefined()) {
@@ -27,6 +27,19 @@ class UseStatementHelper
             throw new \RuntimeException("Class {$class->getName()} has no filename available");
         }
 
+        if ($class->getParentClass() === false) {
+            return self::getImportsForFileName($filename);
+        }
+
+        return array_unique(
+            array_merge(self::getImportsForFileName($filename), self::getImports($class->getParentClass())),
+            SORT_REGULAR
+        );
+    }
+
+    /** @return Import[] */
+    private static function getImportsForFileName(string $filename): array
+    {
         if (! \is_readable($filename)) {
             throw new \RuntimeException("Unable to read {$filename}");
         }


Test patch:
diff --git a/tests/Implementation/Foo/MetaModel/Meta.php b/tests/Implementation/Foo/MetaModel/Meta.php
new file mode 100644
index 0000000..762d4e6
--- /dev/null
+++ b/tests/Implementation/Foo/MetaModel/Meta.php
@@ -0,0 +1,11 @@
+<?php
+
+declare(strict_types=1);
+
+namespace JsonMapper\Tests\Implementation\Foo\MetaModel;
+
+class Meta
+{
+    /** @var null|string */
+    public $type;
+}
diff --git a/tests/Implementation/Foo/Model/BarModel.php b/tests/Implementation/Foo/Model/BarModel.php
new file mode 100644
index 0000000..98205d9
--- /dev/null
+++ b/tests/Implementation/Foo/Model/BarModel.php
@@ -0,0 +1,13 @@
+<?php
+
+declare(strict_types=1);
+
+namespace JsonMapper\Tests\Implementation\Foo\Model;
+
+use JsonMapper\Tests\Implementation\Foo\MetaModel\Meta;
+
+class BarModel
+{
+    /** @var null|Meta */
+    public $meta;
+}
diff --git a/tests/Implementation/Foo/Test.php b/tests/Implementation/Foo/Test.php
new file mode 100644
index 0000000..c1ee63a
--- /dev/null
+++ b/tests/Implementation/Foo/Test.php
@@ -0,0 +1,11 @@
+<?php
+
+declare(strict_types=1);
+
+namespace JsonMapper\Tests\Implementation\Foo;
+
+use JsonMapper\Tests\Implementation\Foo\Model\BarModel;
+
+class Test extends BarModel
+{
+}
diff --git a/tests/Integration/Regression/Bug116RegressionTest.php b/tests/Integration/Regression/Bug116RegressionTest.php
new file mode 100644
index 0000000..0bd65b7
--- /dev/null
+++ b/tests/Integration/Regression/Bug116RegressionTest.php
@@ -0,0 +1,29 @@
+<?php
+
+declare(strict_types=1);
+
+namespace JsonMapper\Tests\Integration\Regression;
+
+use JsonMapper\JsonMapperFactory;
+use JsonMapper\Tests\Implementation\Foo\Test;
+use PHPUnit\Framework\TestCase;
+
+class Bug116RegressionTest extends TestCase
+{
+    /**
+     * @test
+     * @requires PHP >= 7.4
+     * @coversNothing
+     */
+    public function jsonMapperDoesImportLookupForParentClasses(): void
+    {
+        $mapper = (new JsonMapperFactory())->bestFit();
+        $expected = 'some-type-string';
+        $data = (object) ['meta' => (object) ['type' => $expected]];
+        $object = new Test();
+
+        $mapper->mapObject($data, $object);
+
+        self::assertSame($expected, $object->meta->type);
+    }
+}
diff --git a/tests/Unit/Helpers/UseStatementHelperTest.php b/tests/Unit/Helpers/UseStatementHelperTest.php
index 15bea71..ec6ba23 100644
--- a/tests/Unit/Helpers/UseStatementHelperTest.php
+++ b/tests/Unit/Helpers/UseStatementHelperTest.php
@@ -7,7 +7,9 @@ namespace JsonMapper\Tests\Unit\Helpers;
 use JsonMapper\Exception\PhpFileParseException;
 use JsonMapper\Helpers\UseStatementHelper;
 use JsonMapper\Parser\Import;
-use JsonMapper\Tests\Implementation\SimpleObject;
+use JsonMapper\Tests\Implementation\Foo\MetaModel\Meta;
+use JsonMapper\Tests\Implementation\Foo\Model\BarModel;
+use JsonMapper\Tests\Implementation\Foo\Test;
 use PHPUnit\Framework\TestCase;
 
 class UseStatementHelperTest extends TestCase
@@ -17,15 +19,12 @@ class UseStatementHelperTest extends TestCase
      */
     public function testCanGetImports(): void
     {
-        $imports = UseStatementHelper::getImports(new \ReflectionClass($this));
+        $imports = UseStatementHelper::getImports(new \ReflectionClass(Test::class));
 
         self::assertEquals(
             [
-                new Import(PhpFileParseException::class, null),
-                new Import(UseStatementHelper::class, null),
-                new Import(Import::class, null),
-                new Import(SimpleObject::class, null),
-                new Import(TestCase::class, null)
+                new Import(BarModel::class, null),
+                new Import(Meta::class, null),
             ],
             $imports
         );