refactor(di): enhance InitializerDependencyAnalyzer with fallback namespace resolution and improved return type handling
- Add fallback logic to resolve classes in the same namespace from file contents. - Simplify `getInitializerInvokeReturnType` by reducing redundancy in return type validation. - Extend support for detecting and resolving full class names from method return statements. - Introduce named parameter pattern matching for return type extraction.
This commit is contained in:
@@ -224,6 +224,16 @@ final readonly class InitializerDependencyAnalyzer
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Fallback: Prüfe ob Klasse im gleichen Namespace ist
|
||||||
|
// Extrahiere Namespace aus der Datei
|
||||||
|
if (preg_match('/^namespace\s+([^;]+);/m', $fileContent, $namespaceMatch)) {
|
||||||
|
$namespace = trim($namespaceMatch[1]);
|
||||||
|
$fullClassName = $namespace . '\\' . $shortName;
|
||||||
|
if (class_exists($fullClassName)) {
|
||||||
|
return $fullClassName;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
} catch (\Throwable) {
|
} catch (\Throwable) {
|
||||||
return null;
|
return null;
|
||||||
@@ -560,12 +570,8 @@ final readonly class InitializerDependencyAnalyzer
|
|||||||
$initializerClass = $this->findInitializerForInterface($interface);
|
$initializerClass = $this->findInitializerForInterface($interface);
|
||||||
if ($initializerClass !== null && class_exists($initializerClass)) {
|
if ($initializerClass !== null && class_exists($initializerClass)) {
|
||||||
$invokeReturnType = $this->getInitializerInvokeReturnType($initializerClass);
|
$invokeReturnType = $this->getInitializerInvokeReturnType($initializerClass);
|
||||||
if ($invokeReturnType !== null) {
|
if ($invokeReturnType !== null && class_exists($invokeReturnType)) {
|
||||||
// getInitializerInvokeReturnType() extrahiert bereits die tatsächliche Klasse
|
return $invokeReturnType;
|
||||||
// aus dem Code (z.B. "return new Engine(...)"), also können wir sie direkt verwenden
|
|
||||||
if (class_exists($invokeReturnType)) {
|
|
||||||
return $invokeReturnType;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -788,6 +794,7 @@ final readonly class InitializerDependencyAnalyzer
|
|||||||
$methodCode = implode("\n", $methodLines);
|
$methodCode = implode("\n", $methodLines);
|
||||||
|
|
||||||
// Suche nach "return new ClassName(" oder "return new ClassName;"
|
// Suche nach "return new ClassName(" oder "return new ClassName;"
|
||||||
|
// Pattern muss auch Named Parameters unterstützen: "return new Engine(...)"
|
||||||
$pattern = '/return\s+new\s+([A-Z][A-Za-z0-9\\\\]+)\s*[\(;]/';
|
$pattern = '/return\s+new\s+([A-Z][A-Za-z0-9\\\\]+)\s*[\(;]/';
|
||||||
if (preg_match($pattern, $methodCode, $matches)) {
|
if (preg_match($pattern, $methodCode, $matches)) {
|
||||||
$className = $matches[1];
|
$className = $matches[1];
|
||||||
@@ -800,6 +807,21 @@ final readonly class InitializerDependencyAnalyzer
|
|||||||
return $className;
|
return $className;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Fallback: Suche auch nach Named Parameters Syntax: "return new Engine(...)"
|
||||||
|
// mit Named Parameters: loader: ..., processor: ...
|
||||||
|
$pattern2 = '/return\s+new\s+([A-Z][A-Za-z0-9\\\\]+)\s*\(/';
|
||||||
|
if (preg_match($pattern2, $methodCode, $matches)) {
|
||||||
|
$className = $matches[1];
|
||||||
|
|
||||||
|
// Resolve vollständigen Namespace
|
||||||
|
$fullClassName = $this->resolveClassNameFromMethod($className, $fileContent, $invokeMethod);
|
||||||
|
if ($fullClassName !== null && class_exists($fullClassName)) {
|
||||||
|
return $fullClassName;
|
||||||
|
} elseif (class_exists($className)) {
|
||||||
|
return $className;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
} catch (\Throwable) {
|
} catch (\Throwable) {
|
||||||
|
|||||||
@@ -150,83 +150,3 @@ final readonly class CompiledComponentMetadata
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Component Property Metadata
|
|
||||||
*/
|
|
||||||
final readonly class ComponentPropertyMetadata
|
|
||||||
{
|
|
||||||
public function __construct(
|
|
||||||
public string $name,
|
|
||||||
public string $type,
|
|
||||||
public bool $isPublic,
|
|
||||||
public bool $isReadonly,
|
|
||||||
public mixed $defaultValue = null,
|
|
||||||
public bool $hasDefaultValue = false
|
|
||||||
) {
|
|
||||||
}
|
|
||||||
|
|
||||||
public function toArray(): array
|
|
||||||
{
|
|
||||||
return [
|
|
||||||
'name' => $this->name,
|
|
||||||
'type' => $this->type,
|
|
||||||
'is_public' => $this->isPublic,
|
|
||||||
'is_readonly' => $this->isReadonly,
|
|
||||||
'default_value' => $this->defaultValue,
|
|
||||||
'has_default_value' => $this->hasDefaultValue,
|
|
||||||
];
|
|
||||||
}
|
|
||||||
|
|
||||||
public static function fromArray(array $data): self
|
|
||||||
{
|
|
||||||
return new self(
|
|
||||||
name: $data['name'],
|
|
||||||
type: $data['type'],
|
|
||||||
isPublic: $data['is_public'],
|
|
||||||
isReadonly: $data['is_readonly'],
|
|
||||||
defaultValue: $data['default_value'] ?? null,
|
|
||||||
hasDefaultValue: $data['has_default_value'] ?? false
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Component Action Metadata
|
|
||||||
*/
|
|
||||||
final readonly class ComponentActionMetadata
|
|
||||||
{
|
|
||||||
/**
|
|
||||||
* @param string $name Action name
|
|
||||||
* @param array<string, string> $parameters Parameter name => type
|
|
||||||
* @param string|null $returnType Return type
|
|
||||||
* @param bool $isPublic Is public method
|
|
||||||
*/
|
|
||||||
public function __construct(
|
|
||||||
public string $name,
|
|
||||||
public array $parameters,
|
|
||||||
public ?string $returnType = null,
|
|
||||||
public bool $isPublic = true
|
|
||||||
) {
|
|
||||||
}
|
|
||||||
|
|
||||||
public function toArray(): array
|
|
||||||
{
|
|
||||||
return [
|
|
||||||
'name' => $this->name,
|
|
||||||
'parameters' => $this->parameters,
|
|
||||||
'return_type' => $this->returnType,
|
|
||||||
'is_public' => $this->isPublic,
|
|
||||||
];
|
|
||||||
}
|
|
||||||
|
|
||||||
public static function fromArray(array $data): self
|
|
||||||
{
|
|
||||||
return new self(
|
|
||||||
name: $data['name'],
|
|
||||||
parameters: $data['parameters'],
|
|
||||||
returnType: $data['return_type'] ?? null,
|
|
||||||
isPublic: $data['is_public'] ?? true
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -0,0 +1,42 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Framework\LiveComponents\Performance;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Component Action Metadata
|
||||||
|
*/
|
||||||
|
final readonly class ComponentActionMetadata
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @param string $name Action name
|
||||||
|
* @param array<string, string> $parameters Parameter name => type
|
||||||
|
* @param string|null $returnType Return type
|
||||||
|
* @param bool $isPublic Is public method
|
||||||
|
*/
|
||||||
|
public function __construct(
|
||||||
|
public string $name,
|
||||||
|
public array $parameters,
|
||||||
|
public ?string $returnType = null,
|
||||||
|
public bool $isPublic = true
|
||||||
|
) {}
|
||||||
|
|
||||||
|
public function toArray(): array
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
'name' => $this->name,
|
||||||
|
'parameters' => $this->parameters,
|
||||||
|
'return_type' => $this->returnType,
|
||||||
|
'is_public' => $this->isPublic,
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function fromArray(array $data): self
|
||||||
|
{
|
||||||
|
return new self(
|
||||||
|
name : $data['name'],
|
||||||
|
parameters: $data['parameters'],
|
||||||
|
returnType: $data['return_type'] ?? null,
|
||||||
|
isPublic : $data['is_public'] ?? true
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,42 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Framework\LiveComponents\Performance;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Component Property Metadata
|
||||||
|
*/
|
||||||
|
final readonly class ComponentPropertyMetadata
|
||||||
|
{
|
||||||
|
public function __construct(
|
||||||
|
public string $name,
|
||||||
|
public string $type,
|
||||||
|
public bool $isPublic,
|
||||||
|
public bool $isReadonly,
|
||||||
|
public mixed $defaultValue = null,
|
||||||
|
public bool $hasDefaultValue = false
|
||||||
|
) {}
|
||||||
|
|
||||||
|
public function toArray(): array
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
'name' => $this->name,
|
||||||
|
'type' => $this->type,
|
||||||
|
'is_public' => $this->isPublic,
|
||||||
|
'is_readonly' => $this->isReadonly,
|
||||||
|
'default_value' => $this->defaultValue,
|
||||||
|
'has_default_value' => $this->hasDefaultValue,
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function fromArray(array $data): self
|
||||||
|
{
|
||||||
|
return new self(
|
||||||
|
name : $data['name'],
|
||||||
|
type : $data['type'],
|
||||||
|
isPublic : $data['is_public'],
|
||||||
|
isReadonly : $data['is_readonly'],
|
||||||
|
defaultValue : $data['default_value'] ?? null,
|
||||||
|
hasDefaultValue: $data['has_default_value'] ?? false
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user