Skip to content

Commit ef4ebf5

Browse files
committed
Support to extend other class and support a part of annotations
1 parent da84d38 commit ef4ebf5

4 files changed

Lines changed: 98 additions & 16 deletions

File tree

src/Core/JVM/Invoker/Invokable.php

Lines changed: 25 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
use PHPJava\Kernel\Mnemonics\OperationInterface;
1919
use PHPJava\Kernel\Structures\_MethodInfo;
2020
use PHPJava\Utilities\Formatter;
21+
use PHPJava\Utilities\SuperClassResolver;
2122
use PHPJava\Utilities\TypeResolver;
2223

2324
trait Invokable
@@ -59,15 +60,22 @@ public function call(string $name, ...$arguments)
5960
/**
6061
* @var _MethodInfo|null $method
6162
*/
62-
$methodReferences = $this->methods[$name] ?? null;
63-
if ($methodReferences === null) {
64-
throw new UndefinedMethodException('Call to undefined method ' . $name . '.');
63+
$methodReferences = array_merge(
64+
$this->methods[$name] ?? [],
65+
(new SuperClassResolver())->resolveMethod($name, $this->javaClassInvoker->getJavaClass())[$name] ?? []
66+
);
67+
68+
if (empty($methodReferences)) {
69+
if (!isset($methodReferences)) {
70+
throw new UndefinedMethodException('Call to undefined method ' . $name . '.');
71+
}
6572
}
6673

67-
$constantPool = $this->javaClassInvoker
74+
$currentConstantPool = $this->javaClassInvoker
6875
->getJavaClass()
69-
->getConstantPool()
70-
->getEntries();
76+
->getConstantPool();
77+
78+
$constantPool = $currentConstantPool->getEntries();
7179

7280
if ($name === '<init>' && $this->javaClassInvoker->getJavaClass()->hasParentClass()) {
7381
array_unshift(
@@ -88,8 +96,11 @@ function ($argument) {
8896

8997
$method = null;
9098

91-
// the special method
9299
foreach ($methodReferences as $methodReference) {
100+
$constantPool = ($currentConstantPool = $methodReference->getConstantPool())->getEntries();
101+
/**
102+
* @var _MethodInfo $methodReference
103+
*/
93104
$methodSignature = Formatter::buildArgumentsSignature(
94105
Formatter::parseSignature($constantPool[$methodReference->getDescriptorIndex()]->getString())['arguments']
95106
);
@@ -140,7 +151,7 @@ function ($argument) {
140151
$mnemonic = $mnemonicMap->getName($opcode);
141152

142153
if ($mnemonic === null) {
143-
throw new UndefinedOpCodeException('Call to undefined OpCode ' . sprintf('0x%X', $cursor) . '.');
154+
throw new UndefinedOpCodeException('Call to undefined OpCode ' . sprintf('0x%X', $opcode) . '.');
144155
}
145156
$pointer = $reader->getOffset() - 1;
146157

@@ -152,7 +163,7 @@ function ($argument) {
152163
* @var OperationInterface|Accumulator|ConstantPool $executor
153164
*/
154165
$executor = new $fullName();
155-
$executor->setConstantPool($this->javaClassInvoker->getJavaClass()->getConstantPool());
166+
$executor->setConstantPool($currentConstantPool);
156167
$executor->setParameters(
157168
$this->javaClassInvoker,
158169
$reader,
@@ -171,4 +182,9 @@ function ($argument) {
171182
$this->javaClassInvoker->getJavaClass()->appendDebug($debugTraces);
172183
return null;
173184
}
185+
186+
public function getList(): array
187+
{
188+
return $this->methods;
189+
}
174190
}

src/Core/JavaClass.php

Lines changed: 26 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
use PHPJava\Kernel\Attributes\InnerClassesAttribute;
1313
use PHPJava\Kernel\Maps\AccessFlag;
1414
use PHPJava\Kernel\Structures\_Utf8;
15+
use PHPJava\Utilities\ClassResolver;
1516
use PHPJava\Utilities\Formatter;
1617

1718
class JavaClass
@@ -50,7 +51,7 @@ class JavaClass
5051

5152
private $accessFlag = 0;
5253
private $thisClass = 0;
53-
private $superClass = 0;
54+
private $superClassIndex = 0;
5455

5556
/**
5657
* @var _Utf8|null
@@ -68,11 +69,14 @@ class JavaClass
6869

6970
private $parentClass;
7071

72+
private $superClass;
73+
7174
/**
7275
* JavaClass constructor.
7376
* @param JavaClassReader $reader
7477
* @throws ValidatorException
7578
* @throws \PHPJava\Exceptions\ReadEntryException
79+
* @throws \PHPJava\Imitation\java\lang\ClassNotFoundException
7680
*/
7781
public function __construct(JavaClassReader $reader)
7882
{
@@ -104,7 +108,22 @@ public function __construct(JavaClassReader $reader)
104108
$this->className = $constantPoolEntries[$constantPoolEntries[$this->thisClass]->getClassIndex()];
105109

106110
// read super class
107-
$this->superClass = $reader->getBinaryReader()->readUnsignedShort();
111+
$this->superClassIndex = $reader->getBinaryReader()->readUnsignedShort();
112+
113+
$cpInfo = $this->getConstantPool()->getEntries();
114+
[$resolvedType, $superClass] = ClassResolver::resolve(
115+
$cpInfo[$cpInfo[$this->superClassIndex]->getClassIndex()]->getString(),
116+
$this
117+
);
118+
119+
switch ($resolvedType) {
120+
case ClassResolver::RESOLVED_TYPE_IMITATION:
121+
$this->superClass = new $superClass();
122+
break;
123+
default:
124+
$this->superClass = $superClass;
125+
break;
126+
}
108127

109128
// read interfaces
110129
$this->activeInterfaces = new ActiveInterface(
@@ -197,6 +216,11 @@ public function getParentClass(): JavaClass
197216
return $this->parentClass;
198217
}
199218

219+
public function getSuperClass()
220+
{
221+
return $this->superClass;
222+
}
223+
200224
public function debug(): void
201225
{
202226
$cpInfo = $this->getConstantPool()->getEntries();

src/Kernel/Annotations/ElementValuePairs.php

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -14,10 +14,6 @@ final class ElementValuePairs implements AnnotationInterface
1414

1515
public function execute(): void
1616
{
17-
$this->elementNameIndex = $this->readUnsignedShort();
18-
$this->tag = $this->readByte();
19-
20-
var_dump($this->elementNameIndex, $this->tag);
21-
exit();
17+
throw new NotImplementedException(__CLASS__);
2218
}
2319
}
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
<?php
2+
namespace PHPJava\Utilities;
3+
4+
use PHPJava\Core\JavaClass;
5+
use PHPJava\Core\JVM\ConstantPool;
6+
use PHPJava\Imitation\java\lang\_Object;
7+
8+
class SuperClassResolver
9+
{
10+
private $classes = [];
11+
private $constantPool;
12+
13+
public function resolveMethod($methodName, JavaClass $class)
14+
{
15+
$cpInfo = $class->getConstantPool()->getEntries();
16+
if ($class->getSuperClass() instanceof JavaClass) {
17+
foreach ($class->getSuperClass()->getInvoker()->getDynamic()->getMethods()->getList() as $calleeMethodName => $callee) {
18+
if ($methodName !== $calleeMethodName) {
19+
continue;
20+
}
21+
if (!isset($this->classes[$methodName])) {
22+
$this->classes[$methodName] = [];
23+
}
24+
$this->classes[$methodName] = array_merge($this->classes[$methodName], $callee);
25+
}
26+
return $this->resolveMethod($methodName, $class->getSuperClass());
27+
}
28+
// TODO: Will implement extends imitation classes
29+
// elseif (!($class->getSuperClass() instanceof _Object)) {
30+
// $this->classes = array_merge($this->classes, array_map(
31+
// function ($method) use ($class) {
32+
// return static::convertToCallable($method, $class->getSuperClass());
33+
// },
34+
// (new \ReflectionClass($class->getSuperClass()))->getMethods()
35+
// ));
36+
// return $this->resolveAll($class->getSuperClass());
37+
// }
38+
// $this->classes = array_merge($this->classes, array_map(
39+
// function ($method) use ($class) {
40+
// return static::convertToCallable($method, $class->getSuperClass());
41+
// },
42+
// (new \ReflectionClass($class->getSuperClass()))->getMethods()
43+
// ));
44+
return $this->classes;
45+
}
46+
}

0 commit comments

Comments
 (0)