Skip to content

Commit c91451a

Browse files
authored
Merge pull request #146 from php-java/fix-mistake-superclass-resolver
Fix mistaken superclass resolver
2 parents b190342 + 257f0f5 commit c91451a

9 files changed

Lines changed: 125 additions & 19 deletions

File tree

src/Core/JVM/Invoker/Invokable.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ public function __construct(JavaClassInvoker $javaClassInvoker, array $methods,
4040
$this->methods = $methods;
4141
$this->options = $options;
4242
$this->debugTool = new DebugTool(
43-
str_replace('/', '.', $javaClassInvoker->getJavaClass()->getClassName(true)),
43+
str_replace('/', '.', $javaClassInvoker->getJavaClass()->getClassName()),
4444
$this->options
4545
);
4646
}

src/Core/JavaClassInterface.php

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,25 @@
11
<?php
22
namespace PHPJava\Core;
33

4+
use PHPJava\Core\JVM\ConstantPool;
5+
use PHPJava\Core\Stream\Reader\ReaderInterface;
6+
7+
/**
8+
* @method __construct(ReaderInterface $reader, array $options = [])
9+
* @method ConstantPool getConstantPool()
10+
* @method JavaClass getSuperClass()
11+
* @method void debug()
12+
* @method array getAttributes()
13+
* @method JavaClass getParentClass()
14+
* @method bool hasParentClass()
15+
* @method JavaClassInvoker getInvoker()
16+
* @method array getDefinedMethods()
17+
* @method array getDefinedFields()
18+
* @method array getInnerClasses()
19+
* @method string getPackageName()
20+
* @method string getClassName(bool $shortName = false)
21+
* @method mixed getOptions($key = null)
22+
*/
423
interface JavaClassInterface
524
{
625
}

src/Core/JavaClassInvoker.php

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,10 @@ public function construct(...$arguments): self
106106
);
107107

108108
if (isset($this->dynamicMethods['<init>'])) {
109-
$this->getDynamic()->getMethods()->call('<init>', ...$arguments);
109+
$this->getDynamic()->getMethods()->call(
110+
'<init>',
111+
...$arguments
112+
);
110113
}
111114

112115
return $this;

src/Utilities/ClassResolver.php

Lines changed: 18 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -46,8 +46,26 @@ public function resolve(string $javaPath, JavaClass $class = null): array
4646
case static::RESOURCE_TYPE_INNER_CLASS:
4747
// TODO: Implement here
4848
break;
49+
case static::RESOURCE_TYPE_JAR:
50+
if (($key = array_search($relativePath, $this->resolvedPaths, true)) !== false) {
51+
return $this->resolvedPaths[$relativePath];
52+
}
53+
/**
54+
* @var JavaArchive $value
55+
*/
56+
try {
57+
return $this->resolvedPaths[] = [
58+
static::RESOLVED_TYPE_CLASS,
59+
$value->getClassByName($relativePath),
60+
];
61+
} catch (ClassNotFoundException $e) {
62+
}
63+
break;
4964
case static::RESOURCE_TYPE_FILE:
5065
$path = realpath($value . '/' . $relativePath . '.class');
66+
if ($path === false) {
67+
break;
68+
}
5169
if (($key = array_search($path, $this->resolvedPaths, true)) !== false) {
5270
return $this->resolvedPaths[$key];
5371
}
@@ -68,18 +86,6 @@ public function resolve(string $javaPath, JavaClass $class = null): array
6886
];
6987
}
7088
break;
71-
case static::RESOURCE_TYPE_JAR:
72-
/**
73-
* @var JavaArchive $value
74-
*/
75-
try {
76-
return $this->resolvedPaths[] = [
77-
static::RESOLVED_TYPE_CLASS,
78-
$value->getClassByName($relativePath),
79-
];
80-
} catch (ClassNotFoundException $e) {
81-
}
82-
break;
8389
case static::RESOURCE_TYPE_CLASS:
8490
/**
8591
* @var ReaderInterface $value

src/Utilities/SuperClassResolver.php

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,17 +2,18 @@
22
namespace PHPJava\Utilities;
33

44
use PHPJava\Core\JavaClass;
5+
use PHPJava\Core\JavaClassInterface;
56
use PHPJava\Core\JVM\FlexibleMethod;
67

78
class SuperClassResolver
89
{
910
private $classes = [];
1011
private $constantPool;
1112

12-
public function resolveMethod($methodName, JavaClass $class)
13+
public function resolveMethod($methodName, JavaClassInterface $class)
1314
{
1415
$cpInfo = $class->getConstantPool();
15-
if ($class->getSuperClass() instanceof JavaClass) {
16+
if ($class->getSuperClass() instanceof JavaClassInterface) {
1617
foreach ($class->getSuperClass()->getInvoker()->getDynamic()->getMethods()->getList() as $calleeMethodName => $callee) {
1718
if ($methodName !== $calleeMethodName) {
1819
continue;
@@ -36,6 +37,9 @@ public function resolveMethod($methodName, JavaClass $class)
3637
[new FlexibleMethod($class->getSuperClass(), $callee)]
3738
);
3839
}
39-
return array_merge($prependItems, $this->classes);
40+
return array_merge(
41+
$prependItems,
42+
$this->classes
43+
);
4044
}
4145
}

tests/Base.php

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,21 @@ public function setUp(): void
2525
}
2626
}
2727

28+
public function createJAR($name, $entrypoint, array $fixtures = [])
29+
{
30+
$classes = implode(
31+
' ',
32+
array_map(
33+
function ($fixture) {
34+
return $fixture . '.class';
35+
},
36+
$fixtures
37+
)
38+
);
39+
exec('cd ' . __DIR__ . '/caches && jar -cvfe ' . $name . ' ' . $entrypoint . ' ' . $classes);
40+
return $this;
41+
}
42+
2843
protected function getClassName($fixtureName)
2944
{
3045
return __DIR__ . '/caches/' . $fixtureName . '.class';

tests/JarTest.php

Lines changed: 42 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,13 +9,37 @@ class JarTest extends Base
99
'OuterClassTest',
1010
'JarCalleeTest',
1111
'JarCallerTest',
12+
'CalleeEnclosingMethodInJarTest',
13+
'CallerEnclosingMethodInJarTest',
1214
];
1315

1416
public function setUp(): void
1517
{
1618
parent::setUp();
17-
exec('cd ' . __DIR__ . '/caches && jar -cvfe JarTest.jar OuterClassTest OuterClassTest.class');
18-
exec('cd ' . __DIR__ . '/caches && jar -cvfe JarCallTest.jar JarCallerTest JarCalleeTest.class JarCallerTest.class');
19+
$this
20+
->createJAR(
21+
'JarTest.jar',
22+
'OuterClassTest',
23+
[
24+
'OuterClassTest',
25+
]
26+
)
27+
->createJAR(
28+
'JarCallTest.jar',
29+
'JarCallerTest',
30+
[
31+
'JarCalleeTest',
32+
'JarCallerTest',
33+
]
34+
)
35+
->createJAR(
36+
'CallEnclosingMethodInJarTest.jar',
37+
'CallerEnclosingMethodInJarTest',
38+
[
39+
'CalleeEnclosingMethodInJarTest',
40+
'CallerEnclosingMethodInJarTest',
41+
]
42+
);
1943
}
2044

2145
public function testCallWithEntryPoint()
@@ -65,4 +89,20 @@ public function testSamePlaceClass()
6589
$result = ob_get_clean();
6690
$this->assertEquals("TEST\n", $result);
6791
}
92+
93+
public function testEnclosingMethodInJar()
94+
{
95+
ob_start();
96+
(new JavaArchive(__DIR__ . '/caches/CallEnclosingMethodInJarTest.jar'))
97+
->getClassByName('CallerEnclosingMethodInJarTest')
98+
->getInvoker()
99+
->getStatic()
100+
->getMethods()
101+
->call(
102+
'main',
103+
[]
104+
);
105+
$result = ob_get_clean();
106+
$this->assertEquals("Hello World!\n", $result);
107+
}
68108
}
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
class CalleeEnclosingMethodInJarTest
2+
{
3+
public String text;
4+
5+
public void callHelloWorld()
6+
{
7+
System.out.println(this.text);
8+
}
9+
}
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
class CallerEnclosingMethodInJarTest
2+
{
3+
public static void main(String[] args)
4+
{
5+
new CalleeEnclosingMethodInJarTest() {{
6+
this.text = "Hello World!";
7+
callHelloWorld();
8+
}};
9+
}
10+
}

0 commit comments

Comments
 (0)