Skip to content

Commit 471bb06

Browse files
committed
WIP commit
1 parent 5d404e1 commit 471bb06

4 files changed

Lines changed: 146 additions & 39 deletions

File tree

src/core/jvm/invoker/Invokable.php

Lines changed: 25 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
use PHPJava\Exceptions\RuntimeException;
99
use PHPJava\Exceptions\UndefinedMethodException;
1010
use PHPJava\Exceptions\UndefinedOpCodeException;
11+
use PHPJava\Imitation\java\lang\NoSuchMethodException;
1112
use PHPJava\Kernel\Attributes\AttributeInfo;
1213
use PHPJava\Kernel\Attributes\AttributeInterface;
1314
use PHPJava\Kernel\Attributes\CodeAttribute;
@@ -17,6 +18,7 @@
1718
use PHPJava\Kernel\Mnemonics\OperationInterface;
1819
use PHPJava\Kernel\Structures\_MethodInfo;
1920
use PHPJava\Utilities\Formatter;
21+
use PHPJava\Utilities\TypeResolver;
2022

2123
trait Invokable
2224
{
@@ -55,8 +57,8 @@ public function call(string $name, ...$arguments)
5557
/**
5658
* @var _MethodInfo|null $method
5759
*/
58-
$methods = $this->methods[$name] ?? null;
59-
if ($methods === null) {
60+
$methodReferences = $this->methods[$name] ?? null;
61+
if ($methodReferences === null) {
6062
throw new UndefinedMethodException('Call to undefined ' . $name . ' method.');
6163
}
6264

@@ -65,29 +67,29 @@ public function call(string $name, ...$arguments)
6567
->getConstantPool()
6668
->getEntries();
6769

68-
$method = $methods[0];
69-
70-
// TODO: Refactor find to valid method.
71-
// will implement to be compatible to multiple variable arguments size.
72-
// And will be applied NoSuchMethodException when cannot find method.
73-
if ($name === 'main') {
74-
// Find same method
75-
foreach ($methods as $method) {
76-
$signature = Formatter::parseSignature($constantPool[$method->getDescriptorIndex()]->getString());
77-
78-
// compare passed arguments
79-
foreach ($signature['arguments'] as $signatureArgument) {
80-
foreach ($arguments as $argument) {
81-
var_dump(gettype($argument), $signatureArgument);
82-
if ($argument === $signatureArgument) {
83-
84-
}
85-
}
86-
}
87-
var_dump();
70+
// Find same method
71+
$convertedPassedArguments = Formatter::buildArgumentsSignature(
72+
array_map(
73+
function ($argument) {
74+
return TypeResolver::convertPHPtoJava($argument);
75+
},
76+
$arguments
77+
)
78+
);
79+
80+
$method = null;
81+
foreach ($methodReferences as $methodReference) {
82+
$methodSignature = Formatter::buildArgumentsSignature(
83+
Formatter::parseSignature($constantPool[$methodReference->getDescriptorIndex()]->getString())['arguments']
84+
);
85+
if ($methodSignature === $convertedPassedArguments) {
86+
$method = $methodReference;
87+
break;
8888
}
89+
}
8990

90-
exit();
91+
if ($method === null) {
92+
throw new NoSuchMethodException('Call to undefined method ' . $name . '.');
9193
}
9294

9395
$codeAttribute = $getCodeAttribute($method->getAttributes());

src/exceptions/TypeException.php

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
<?php
2+
namespace PHPJava\Exceptions;
3+
4+
class TypeException extends \Exception
5+
{
6+
}

src/utilities/Formatter.php

Lines changed: 23 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -5,22 +5,14 @@
55

66
class Formatter
77
{
8-
public static function parseSignature($signature, $i = 0)
8+
/**
9+
* @param $signature
10+
* @param int $i
11+
* @return array
12+
* @throws \PHPJava\Exceptions\TypeException
13+
*/
14+
public static function parseSignature($signature, $i = 0): array
915
{
10-
$getMappedSignatureType = function ($signature) {
11-
switch ($signature) {
12-
case 'B': return 'byte';
13-
case 'C': return 'char';
14-
case 'D': return 'double';
15-
case 'F': return 'float';
16-
case 'I': return 'int';
17-
case 'J': return 'long';
18-
case 'S': return 'short';
19-
case 'V': return 'void';
20-
case 'Z': return 'boolean';
21-
}
22-
throw new FormatterException('Passed undefined signature ' . $signature);
23-
};
2416
$data = [];
2517
$deepArray = 0;
2618

@@ -36,7 +28,7 @@ public static function parseSignature($signature, $i = 0)
3628
case 'V':
3729
case 'Z':
3830
$data[] = [
39-
'type' => $getMappedSignatureType($signature[$i]),
31+
'type' => TypeResolver::getMappedSignatureType($signature[$i]),
4032
'deep_array' => $deepArray,
4133
];
4234
$deepArray = 0;
@@ -78,4 +70,19 @@ public static function parseSignature($signature, $i = 0)
7870
}
7971
return $data;
8072
}
73+
74+
public static function buildArgumentsSignature($signatures): string
75+
{
76+
$string = '';
77+
foreach ($signatures as $signature) {
78+
$build = str_repeat('[', $signature['deep_array']);
79+
if ($signature['type'] === 'class') {
80+
$build .= 'L' . $signature['class_name'];
81+
} else {
82+
$build .= TypeResolver::resolveType($signature['type']);
83+
}
84+
$string .= $build . ';';
85+
}
86+
return $string;
87+
}
8188
}

src/utilities/TypeResolver.php

Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
<?php
2+
namespace PHPJava\Utilities;
3+
4+
use PHPJava\Exceptions\TypeException;
5+
6+
class TypeResolver
7+
{
8+
const PHP_TYPE_MAP = [
9+
'integer' => 'I',
10+
'string' => 'Ljava.lang.String',
11+
];
12+
13+
const SIGNATURE_MAP = [
14+
'B' => 'byte',
15+
'C' => 'char',
16+
'D' => 'double',
17+
'F' => 'float',
18+
'I' => 'int',
19+
'J' => 'long',
20+
'S' => 'short',
21+
'V' => 'void',
22+
'Z' => 'boolean',
23+
'L' => 'class',
24+
];
25+
26+
/**
27+
* @param $signature
28+
* @return string
29+
* @throws TypeException
30+
*/
31+
public static function getMappedSignatureType($signature): string
32+
{
33+
if (isset(static::SIGNATURE_MAP[$signature])) {
34+
return static::SIGNATURE_MAP[$signature];
35+
}
36+
throw new TypeException('Passed undefined signature ' . $signature);
37+
}
38+
39+
public static function resolveType($type): string
40+
{
41+
$flipped = array_flip(static::SIGNATURE_MAP);
42+
if (isset($flipped[$type])) {
43+
return $flipped[$type];
44+
}
45+
return 'L' . $type;
46+
}
47+
48+
public static function convertPHPtoJava($arguments, $defaultJavaArgumentType = 'java.lang.String'): array
49+
{
50+
$phpType = gettype($arguments);
51+
$deepArray = 0;
52+
if ($phpType === 'array') {
53+
$deepArray++;
54+
$getNestedValues = [];
55+
foreach ($arguments as $argument) {
56+
$getNestedValues[] = static::convertPHPtoJava($argument);
57+
}
58+
if (empty($getNestedValues)) {
59+
$flipped = array_flip(static::PHP_TYPE_MAP);
60+
$resolveType = static::SIGNATURE_MAP[static::resolveType($defaultJavaArgumentType)];
61+
if ($resolveType === 'class') {
62+
return [
63+
'type' => $resolveType,
64+
'class_name' => $defaultJavaArgumentType,
65+
'deep_array' => $deepArray,
66+
];
67+
}
68+
return [
69+
'type' => $resolveType,
70+
'deep_array' => $deepArray,
71+
];
72+
}
73+
$firstParameter = $getNestedValues[0];
74+
75+
// TODO: Validate parameters
76+
$firstParameter['deep_array'] += $deepArray;
77+
return $firstParameter;
78+
}
79+
$resolveType = static::SIGNATURE_MAP[static::PHP_TYPE_MAP[$phpType]] ?? null;
80+
if ($resolveType === 'class') {
81+
return [
82+
'type' => $resolveType,
83+
'class_name' => $defaultJavaArgumentType,
84+
'deep_array' => $deepArray,
85+
];
86+
}
87+
return [
88+
'type' => $resolveType,
89+
'deep_array' => $deepArray,
90+
];
91+
}
92+
}

0 commit comments

Comments
 (0)