Skip to content

Commit 7050dd8

Browse files
committed
Implement to define static property
1 parent 74e042c commit 7050dd8

File tree

9 files changed

+194
-59
lines changed

9 files changed

+194
-59
lines changed

src/Compiler/Builder/Collection/AbstractEntryCollection.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,6 @@ public function enableIntern(bool $enable): EntryCollectionInterface
8080

8181
public function length(): int
8282
{
83-
return count($this->entries) - 1;
83+
return count($this->entries);
8484
}
8585
}

src/Compiler/Builder/Field.php

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -107,4 +107,14 @@ public function getValue(): string
107107
{
108108
return $this->value;
109109
}
110+
111+
public function beginPreparation(): self
112+
{
113+
$this->getEnhancedConstantPool()
114+
->addNameAndType(
115+
$this->getName(),
116+
$this->getDescriptor()
117+
);
118+
return $this;
119+
}
110120
}

src/Compiler/Lang/Assembler/ClassAssembler.php

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
use PHPJava\Compiler\Lang\Assembler\Store\Store;
1717
use PHPJava\Compiler\Lang\Assembler\Traits\Bindable;
1818
use PHPJava\Compiler\Lang\Assembler\Traits\Enhancer\ConstantPoolEnhanceable;
19+
use PHPJava\Compiler\Lang\Assembler\Traits\Enhancer\Operation\FieldAssignable;
1920
use PHPJava\Compiler\Lang\Assembler\Traits\OperationManageable;
2021
use PHPJava\Compiler\Lang\Assembler\Traits\ParameterParseable;
2122
use PHPJava\Compiler\Lang\Assembler\Traits\StaticInitializerAssignable;
@@ -34,6 +35,7 @@ class ClassAssembler extends AbstractAssembler implements ClassAssemblerInterfac
3435
use Bindable;
3536
use StaticInitializerAssignable;
3637
use ParameterParseable;
38+
use FieldAssignable;
3739

3840
/**
3941
* @var Methods
@@ -66,6 +68,13 @@ public function assemble(): void
6668
$this->methods = new Methods();
6769
$this->fields = new Fields();
6870

71+
foreach ($this->node->getProperties() as $property) {
72+
$this
73+
->bindParameters(FieldAssembler::factory($property))
74+
->setCollection($this->fields)
75+
->assemble();
76+
}
77+
6978
foreach ($this->node->getMethods() as $method) {
7079
$store = new Store();
7180
if (!$method->isStatic()) {
@@ -87,7 +96,6 @@ public function assemble(): void
8796
->addClass(Object_::class)
8897
->addClass(Runtime::PHP_STANDARD_CLASS_NAME);
8998

90-
// TODO: Implement fields.
9199
$this->assignStaticInitializer($this->className);
92100

93101
$compiler = new Compiler(
Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
<?php
2+
declare(strict_types=1);
3+
namespace PHPJava\Compiler\Lang\Assembler;
4+
5+
use PHPJava\Compiler\Builder\Collection\Fields;
6+
use PHPJava\Compiler\Builder\Field;
7+
use PHPJava\Compiler\Builder\Method;
8+
use PHPJava\Compiler\Builder\Signatures\Descriptor;
9+
use PHPJava\Compiler\Lang\Assembler\Traits\Bindable;
10+
use PHPJava\Compiler\Lang\Assembler\Traits\Enhancer\ConstantPoolEnhanceable;
11+
use PHPJava\Compiler\Lang\Assembler\Traits\Enhancer\Operation\LocalVariableAssignable;
12+
use PHPJava\Compiler\Lang\Assembler\Traits\Enhancer\Operation\LocalVariableLoadable;
13+
use PHPJava\Compiler\Lang\Assembler\Traits\OperationManageable;
14+
use PHPJava\Compiler\Lang\Assembler\Traits\ParameterParseable;
15+
use PHPJava\Exceptions\AssembleStructureException;
16+
use PhpParser\Node\Stmt\PropertyProperty;
17+
18+
/**
19+
* @method ClassAssembler getParentAssembler()
20+
* @method Fields getCollection()
21+
* @property \PhpParser\Node\Stmt\Property $node
22+
*/
23+
class FieldAssembler extends AbstractAssembler
24+
{
25+
use OperationManageable;
26+
use ConstantPoolEnhanceable;
27+
use LocalVariableAssignable;
28+
use LocalVariableLoadable;
29+
use Bindable;
30+
use ParameterParseable;
31+
32+
public function assemble(): void
33+
{
34+
$typedDocument = \phpDocumentor\Reflection\DocBlockFactory::createInstance()
35+
->create((string) $this->node->getDocComment());
36+
37+
if ($typedDocument === false) {
38+
throw new AssembleStructureException(
39+
'A property is needed PHP document #' . $this->node->getStartLine()
40+
);
41+
}
42+
43+
/**
44+
* @var \phpDocumentor\Reflection\DocBlock\Tags\Var_[] $varType
45+
*/
46+
$varType = $typedDocument->getTagsByName('var');
47+
[$variableName, $parameterInfo] = $this->parseFromDocument($varType[0]);
48+
49+
$fieldAccessFlag = (new \PHPJava\Compiler\Builder\Signatures\FieldAccessFlag());
50+
51+
if ($this->node->isPublic()) {
52+
$fieldAccessFlag->enablePublic();
53+
}
54+
55+
if ($this->node->isPrivate()) {
56+
$fieldAccessFlag->enablePrivate();
57+
}
58+
59+
if ($this->node->isStatic()) {
60+
$fieldAccessFlag->enableStatic();
61+
}
62+
63+
if ($this->node->isProtected()) {
64+
$fieldAccessFlag->enableProtected();
65+
}
66+
67+
$fieldAccessFlag = $fieldAccessFlag->make();
68+
69+
$descriptor = Descriptor::factory()
70+
->addArgument($parameterInfo['type'])
71+
->make();
72+
73+
foreach ($this->node->props as $property) {
74+
/**
75+
* @var PropertyProperty $property
76+
*/
77+
$field = (new Field(
78+
$fieldAccessFlag,
79+
$this->getClassAssembler()->getClassName(),
80+
(string) $property->name,
81+
$descriptor
82+
))->setConstantPool($this->getConstantPool())
83+
->setConstantPoolFinder($this->getConstantPoolFinder())
84+
->setValue($property->default->value)
85+
->beginPreparation();
86+
87+
// Register a Fieldref to Constant Pool
88+
$this->getEnhancedConstantPool()
89+
->addFieldref(
90+
$this->getClassAssembler()->getClassName(),
91+
(string) $property->name,
92+
$descriptor
93+
);
94+
95+
$this->getCollection()
96+
->add($field);
97+
}
98+
}
99+
}

src/Compiler/Lang/Assembler/ParameterServiceInterface.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,10 +16,10 @@
1616
* @method ConstantPool getConstantPool()
1717
* @method AbstractAssembler|AbstractProcessor setNamespace(?array $namespace)
1818
* @method null|array getNamespace()
19-
* @method AbstractAssembler|AbstractProcessor setStore(Store $store)
19+
* @method AbstractAssembler|AbstractProcessor setStore(?Store $store)
2020
* @method Store getStore()
2121
* @method Operation getOperation()
22-
* @method AbstractAssembler|AbstractProcessor setOperation(Operation $operation)
22+
* @method AbstractAssembler|AbstractProcessor setOperation(?Operation $operation)
2323
* @method AbstractAssembler|AbstractProcessor setConstantPoolFinder(ConstantPoolFinder $constantPoolFinder)
2424
* @method ConstantPoolFinder getConstantPoolFinder()
2525
* @method AbstractAssembler|AbstractProcessor setMethodAssembler(MethodAssembler $methodAssembler)

src/Compiler/Lang/Assembler/Traits/OperationManageable.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,13 +15,13 @@ trait OperationManageable
1515
*/
1616
protected $operation;
1717

18-
public function setOperation(Operation $operation): self
18+
public function setOperation(?Operation $operation): self
1919
{
2020
$this->operation = $operation;
2121
return $this;
2222
}
2323

24-
public function getOperation(): Operation
24+
public function getOperation(): ?Operation
2525
{
2626
return $this->operation;
2727
}

src/Compiler/Lang/Assembler/Traits/ParameterParseable.php

Lines changed: 61 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22
declare(strict_types=1);
33
namespace PHPJava\Compiler\Lang\Assembler\Traits;
44

5+
use phpDocumentor\Reflection\DocBlock\Tags\Param;
6+
use phpDocumentor\Reflection\DocBlock\Tags\TagWithType;
57
use PHPJava\Compiler\Builder\Attributes\Architects\Operation;
68
use PHPJava\Compiler\Builder\Finder\ConstantPoolFinder;
79
use PHPJava\Compiler\Lang\Assembler\Enhancer\ConstantPoolEnhancer;
@@ -49,37 +51,11 @@ public function parseParameterFromNode(Node $node): array
4951
$documentBlock = \phpDocumentor\Reflection\DocBlockFactory::createInstance()
5052
->create($commentAttribute->getText());
5153

52-
foreach ($documentBlock->getTagsByName('param') as $documentParameter) {
54+
foreach ($documentBlock->getTagsByName('param') as $documentedParameter) {
5355
/**
54-
* @var \phpDocumentor\Reflection\DocBlock\Tags\Param $documentParameter
55-
* @var null|\phpDocumentor\Reflection\Types\Object_ $typeObject
56+
* @var Param $documentedParameter
5657
*/
57-
$typeObject = $documentParameter
58-
->getType();
59-
$stringifiedType = (string) $typeObject;
60-
61-
$type = $stringifiedType;
62-
63-
if ($typeObject instanceof \phpDocumentor\Reflection\Types\Array_) {
64-
$typeObject = $typeObject
65-
->getValueType();
66-
}
67-
68-
if ($typeObject instanceof \phpDocumentor\Reflection\Types\Object_) {
69-
$fullPath = (string) $typeObject->getFqsen();
70-
71-
$type = $typeObject
72-
->getFqsen()
73-
->getName();
74-
75-
// FIXED: phpDocumentor has an omitted path completion problem
76-
// This statement fix it.
77-
if ($fullPath !== '\\' . ((string) $type)) {
78-
$type = $fullPath;
79-
}
80-
}
81-
82-
$variableName = $documentParameter->getVariableName();
58+
[$variableName, $parameterInfo] = $this->parseFromDocument($documentedParameter);
8359

8460
if (!isset($paramOrdersTable[$variableName])) {
8561
throw new AssembleStructureException(
@@ -88,25 +64,9 @@ public function parseParameterFromNode(Node $node): array
8864
}
8965

9066
// Update variable detail.
91-
$parameters[$variableName] = [
92-
'type' => $this->convertWithImport(
93-
Formatter::convertPHPPrimitiveTypeToJavaType(
94-
str_replace(
95-
'[]',
96-
'',
97-
$type
98-
)
99-
)
100-
),
101-
'dimensions_of_array' => substr_count(
102-
$stringifiedType,
103-
'[]'
104-
),
67+
$parameters[$variableName] = $parameterInfo + [
10568
'order' => $paramOrdersTable[$variableName],
10669
];
107-
108-
$definedType = $parameters[$variableName]['type'];
109-
$definedTypeDimensionsOfArray = $parameters[$variableName]['dimensions_of_array'];
11070
}
11171
}
11272

@@ -137,4 +97,59 @@ static function ($a, $b) {
13797

13898
return $parameters;
13999
}
100+
101+
public function parseFromDocument(TagWithType $documentedParameter): array
102+
{
103+
/**
104+
* @var null|\phpDocumentor\Reflection\Types\Object_ $typeObject
105+
*/
106+
$typeObject = $documentedParameter
107+
->getType();
108+
$stringifiedType = (string) $typeObject;
109+
110+
$type = $stringifiedType;
111+
112+
if ($typeObject instanceof \phpDocumentor\Reflection\Types\Array_) {
113+
$typeObject = $typeObject
114+
->getValueType();
115+
}
116+
117+
if ($typeObject instanceof \phpDocumentor\Reflection\Types\Object_) {
118+
$fullPath = (string) $typeObject->getFqsen();
119+
120+
$type = $typeObject
121+
->getFqsen()
122+
->getName();
123+
124+
// FIXED: phpDocumentor has an omitted path completion problem
125+
// This statement fix it.
126+
if ($fullPath !== '\\' . ((string) $type)) {
127+
$type = $fullPath;
128+
}
129+
}
130+
131+
$variableName = $documentedParameter->getVariableName();
132+
133+
// Update variable detail.
134+
return [
135+
$variableName === ''
136+
? null
137+
: $variableName,
138+
[
139+
'type' => $this->convertWithImport(
140+
Formatter::convertPHPPrimitiveTypeToJavaType(
141+
str_replace(
142+
'[]',
143+
'',
144+
$type
145+
)
146+
)
147+
),
148+
'dimensions_of_array' => substr_count(
149+
$stringifiedType,
150+
'[]'
151+
),
152+
],
153+
];
154+
}
140155
}

src/Compiler/Lang/Assembler/Traits/StaticInitializerAssignable.php

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -27,13 +27,15 @@ public function assignStaticInitializer(string $className): self
2727
if ($this->fields->length() === 0) {
2828
return $this;
2929
}
30+
$descriptor = (new Descriptor())
31+
->setReturn(Void_::class)
32+
->make();
3033

3134
$this->getEnhancedConstantPool()
32-
->addUtf8('<clinit>')
33-
->addUtf8(
34-
$descriptor = (new Descriptor())
35-
->setReturn(Void_::class)
36-
->make()
35+
->addMethodref(
36+
$className,
37+
'<clinit>',
38+
$descriptor
3739
);
3840

3941
$staticInitializerOperations = [];
@@ -61,6 +63,7 @@ public function assignStaticInitializer(string $className): self
6163
->add(
6264
(new Method(
6365
(new MethodAccessFlag())
66+
->enablePrivate()
6467
->enableStatic()
6568
->make(),
6669
$className,

src/Compiler/Lang/Assembler/Traits/StoreManageable.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,13 +18,13 @@ trait StoreManageable
1818
{
1919
protected $store;
2020

21-
public function setStore(Store $store): self
21+
public function setStore(?Store $store): self
2222
{
2323
$this->store = $store;
2424
return $this;
2525
}
2626

27-
public function getStore(): Store
27+
public function getStore(): ?Store
2828
{
2929
return $this->store;
3030
}

0 commit comments

Comments
 (0)