Skip to content

Commit

Permalink
inferring params from calls to request object
Browse files Browse the repository at this point in the history
  • Loading branch information
romalytvynenko committed Apr 7, 2024
1 parent 80fa442 commit 8cdff9c
Show file tree
Hide file tree
Showing 15 changed files with 337 additions and 6 deletions.
7 changes: 5 additions & 2 deletions src/Infer/Analyzer/MethodAnalyzer.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
use Dedoc\Scramble\Infer\Context;
use Dedoc\Scramble\Infer\Definition\ClassDefinition;
use Dedoc\Scramble\Infer\Definition\FunctionLikeDefinition;
use Dedoc\Scramble\Infer\Handler\IndexBuildingHandler;
use Dedoc\Scramble\Infer\Reflector\ClassReflector;
use Dedoc\Scramble\Infer\Scope\Index;
use Dedoc\Scramble\Infer\Scope\NodeTypesResolver;
Expand All @@ -25,11 +26,12 @@ public function __construct(
) {
}

public function analyze(FunctionLikeDefinition $methodDefinition)
public function analyze(FunctionLikeDefinition $methodDefinition, array $indexBuilders = [])
{
$this->traverseClassMethod(
[$this->getClassReflector()->getMethod($methodDefinition->type->name)->getAstNode()],
$methodDefinition,
$indexBuilders,
);

$methodDefinition = $this->index
Expand All @@ -46,7 +48,7 @@ private function getClassReflector(): ClassReflector
return ClassReflector::make($this->classDefinition->name);
}

private function traverseClassMethod(array $nodes, FunctionLikeDefinition $methodDefinition)
private function traverseClassMethod(array $nodes, FunctionLikeDefinition $methodDefinition, array $indexBuilders = [])
{
$traverser = new NodeTraverser;

Expand All @@ -57,6 +59,7 @@ private function traverseClassMethod(array $nodes, FunctionLikeDefinition $metho
$nameResolver,
new Scope($this->index, new NodeTypesResolver(), new ScopeContext($this->classDefinition), $nameResolver),
Context::getInstance()->extensionsBroker->extensions,
[new IndexBuildingHandler($indexBuilders)],
));

$node = (new NodeFinder())
Expand Down
4 changes: 2 additions & 2 deletions src/Infer/Definition/ClassDefinition.php
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ public function isChildOf(string $className)
return $this->isInstanceOf($className) && $this->name !== $className;
}

public function getMethodDefinition(string $name, Scope $scope = new GlobalScope)
public function getMethodDefinition(string $name, Scope $scope = new GlobalScope, array $indexBuilders = [])
{
if (! array_key_exists($name, $this->methods)) {
return null;
Expand All @@ -55,7 +55,7 @@ public function getMethodDefinition(string $name, Scope $scope = new GlobalScope
$this->methods[$name] = (new MethodAnalyzer(
$scope->index,
$this
))->analyze($methodDefinition);
))->analyze($methodDefinition, $indexBuilders);
}

$methodScope = new Scope(
Expand Down
25 changes: 25 additions & 0 deletions src/Infer/Handler/IndexBuildingHandler.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
<?php

namespace Dedoc\Scramble\Infer\Handler;

use Dedoc\Scramble\Infer\Scope\Scope;
use PhpParser\Node;

class IndexBuildingHandler
{
public function __construct(
private array $indexBuilders,
){}

public function shouldHandle($node)
{
return true;
}

public function leave(Node $node, Scope $scope)
{
foreach ($this->indexBuilders as $indexBuilder) {
$indexBuilder->afterAnalyzedNode($scope, $node);
}
}
}
5 changes: 5 additions & 0 deletions src/Infer/SimpleTypeGetters/ScalarTypeGetter.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

namespace Dedoc\Scramble\Infer\SimpleTypeGetters;

use Dedoc\Scramble\Support\Type\Literal\LiteralFloatType;
use Dedoc\Scramble\Support\Type\Literal\LiteralIntegerType;
use Dedoc\Scramble\Support\Type\Literal\LiteralStringType;
use Dedoc\Scramble\Support\Type\Type;
Expand All @@ -20,6 +21,10 @@ public function __invoke(Node\Scalar $node): Type
return new LiteralIntegerType($node->value);
}

if ($node instanceof Node\Scalar\DNumber) {
return new LiteralFloatType($node->value);
}

return new UnknownType('Cannot get type from scalar');
}
}
2 changes: 2 additions & 0 deletions src/Infer/TypeInferer.php
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ public function __construct(
private FileNameResolver $nameResolver,
private ?Scope $scope = null,
array $extensions = [],
array $handlers = [],
) {
$this->handlers = [
new FunctionLikeHandler(),
Expand All @@ -56,6 +57,7 @@ public function __construct(
fn ($ext) => $ext instanceof ExpressionExceptionExtension,
))),
new PhpDocHandler(),
...$handlers,
];
}

Expand Down
19 changes: 18 additions & 1 deletion src/Support/Generator/Parameter.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ class Parameter

/**
* Possible values are "query", "header", "path" or "cookie".
* @var "query"|"header"|"path"|"cookie".
*/
public string $in;

Expand All @@ -18,6 +19,9 @@ class Parameter
/** @var array|scalar|null|MissingExample */
public $example;

/** @var array|scalar|null|MissingExample */
public $default;

public bool $deprecated = false;

public bool $allowEmptyValue = false;
Expand All @@ -28,7 +32,9 @@ public function __construct(string $name, string $in)
{
$this->name = $name;
$this->in = $in;

$this->example = new MissingExample;
$this->default = new MissingExample;

if ($this->in === 'path') {
$this->required = true;
Expand All @@ -55,7 +61,11 @@ public function toArray(): array
$result['schema'] = $this->schema->toArray();
}

return array_merge($result, $this->example instanceof MissingExample ? [] : ['example' => $this->example]);
return array_merge(
$result,
$this->example instanceof MissingExample ? [] : ['example' => $this->example],
$this->default instanceof MissingExample ? [] : ['default' => $this->default],
);
}

public function required(bool $required)
Expand All @@ -79,6 +89,13 @@ public function setSchema(?Schema $schema): self
return $this;
}

public function default($default)
{
$this->default = $default;

return $this;
}

public function description(string $description)
{
$this->description = $description;
Expand Down
1 change: 1 addition & 0 deletions src/Support/Generator/Schema.php
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ public static function createFromParameters(array $parameters)

$paramType->setDescription($parameter->description);
$paramType->example($parameter->example);
$paramType->default($parameter->default);

$type->addProperty($parameter->name, $paramType);
})
Expand Down
16 changes: 16 additions & 0 deletions src/Support/Generator/Types/Type.php
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,9 @@ abstract class Type
/** @var array|scalar|null|MissingExample */
public $example;

/** @var array|scalar|null|MissingExample */
public $default;

/** @var array<array|scalar|null|MissingExample> */
public $examples = [];

Expand All @@ -29,6 +32,7 @@ public function __construct(string $type)
{
$this->type = $type;
$this->example = new MissingExample;
$this->default = new MissingExample;
}

public function nullable(bool $nullable)
Expand All @@ -53,6 +57,7 @@ public function addProperties(Type $fromType)
$this->enum = $fromType->enum;
$this->description = $fromType->description;
$this->example = $fromType->example;
$this->default = $fromType->default;

return $this;
}
Expand All @@ -67,6 +72,7 @@ public function toArray()
'enum' => count($this->enum) ? $this->enum : null,
]),
$this->example instanceof MissingExample ? [] : ['example' => $this->example],
$this->default instanceof MissingExample ? [] : ['default' => $this->default],
count(
$examples = collect($this->examples)
->reject(fn ($example) => $example instanceof MissingExample)
Expand Down Expand Up @@ -100,6 +106,16 @@ public function example($example)
return $this;
}

/**
* @param array|scalar|null|MissingExample $default
*/
public function default($default)
{
$this->default = $default;

return $this;
}

/**
* @param array<array|scalar|null|MissingExample> $examples
*/
Expand Down
17 changes: 17 additions & 0 deletions src/Support/IndexBuilders/Bag.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
<?php

namespace Dedoc\Scramble\Support\IndexBuilders;

class Bag
{
public function __construct(
public array $data = []
) {}

public function set(string $key, $value)
{
$this->data[$key] = $value;

return $this;
}
}
Loading

0 comments on commit 8cdff9c

Please sign in to comment.