Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Handle types as Map of objects, auto add use statements, and some utility methods #67

Closed
wants to merge 10 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -45,4 +45,4 @@
"test" : "phpunit",
"api" : "sami.php update sami.php"
}
}
}
2 changes: 1 addition & 1 deletion docs/model.rst
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,7 @@ We've just learned how to pass a blank method, the constructor to the class. We
)
->setBody('$this->driver = $driver');
)
->setProperty(PhpProperty::create('driver')
->addProperty(PhpProperty::create('driver')
->setVisibility('private')
->setType('string')
)
Expand Down
32 changes: 19 additions & 13 deletions src/generator/builder/parts/TypeBuilderPart.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,16 @@
namespace gossi\codegen\generator\builder\parts;

use gossi\codegen\model\AbstractModel;
use gossi\codegen\model\parts\TypePart;
use phootwork\collection\Map;

trait TypeBuilderPart {

protected static $noTypeHints = [
'string', 'int', 'integer', 'bool', 'boolean', 'float', 'double', 'object', 'mixed', 'resource'
];

protected static $php7typeHints = [
protected static $php7typeHints = [
'string', 'int', 'integer', 'bool', 'boolean', 'float', 'double'
];

Expand All @@ -27,22 +29,26 @@ trait TypeBuilderPart {

/**
*
* @param AbstractModel $model
* @param AbstractModel|TypePart $model
* @param bool $allowed
*
* @return string|null
*/
private function getType(AbstractModel $model, bool $allowed, bool $nullable): ?string {
$type = $model->getType();
if (!empty($type) && strpos($type, '|') === false
&& (!in_array($type, self::$noTypeHints)
|| ($allowed && in_array($type, self::$php7typeHints)))
) {

$type = isset(self::$typeHintMap[$type])
? self::$typeHintMap[$type]
: $type;

if ($nullable && $model->getNullable()) {
$types = $model->getTypes();
if ($types->get('iterable')) {
$types = new Map(['iterable' => 'iterable']);
}
if (!$types || $types->size() !== 1) {
return null;
}
$type = (string)$types->values()->toArray()[0];
if (!in_array($type, self::$noTypeHints, true)
|| ($allowed && in_array($type, self::$php7typeHints, true))) {

$type = self::$typeHintMap[$type] ?? $type;

if ($nullable && $model->getNullable()) {
$type = '?' . $type;
}

Expand Down
4 changes: 3 additions & 1 deletion src/model/AbstractModel.php
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,9 @@ public function setDescription($description) {
if (is_array($description)) {
$description = implode("\n", $description);
}
$this->description = $description;
if ($description) {
$this->description = $description;
}
return $this;
}

Expand Down
1 change: 1 addition & 0 deletions src/model/AbstractPhpMember.php
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@ abstract class AbstractPhpMember extends AbstractModel implements DocblockInterf
public function __construct(string $name) {
$this->setName($name);
$this->docblock = new Docblock();
$this->initTypes();
}

/**
Expand Down
58 changes: 48 additions & 10 deletions src/model/AbstractPhpStruct.php
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
use gossi\codegen\model\parts\DocblockPart;
use gossi\codegen\model\parts\LongDescriptionPart;
use gossi\codegen\model\parts\QualifiedNamePart;
use gossi\codegen\utils\TypeUtils;
use gossi\docblock\Docblock;
use phootwork\collection\Map;
use phootwork\collection\Set;
Expand All @@ -37,13 +38,13 @@ abstract class AbstractPhpStruct extends AbstractModel implements NamespaceInter
use LongDescriptionPart;
use QualifiedNamePart;

/** @var Map */
/** @var Map|string[] */
private $useStatements;

/** @var Set */
/** @var Set|string[] */
private $requiredFiles;

/** @var Map */
/** @var Map|PhpMethod[] */
private $methods;

/**
Expand All @@ -56,6 +57,13 @@ public static function create(?string $name = null) {
return new static($name);
}

public static function fromName(string $name): self
{
$ref = new \ReflectionClass($name);

return static::fromFile($ref->getFileName());
}

/**
* Creates a new struct
*
Expand Down Expand Up @@ -122,11 +130,23 @@ public function setUseStatements(array $useStatements) {
/**
* Adds a use statement with an optional alias
*
* @param string $qualifiedName
* @param string|PhpTypeInterface $qualifiedName
* @param null|string $alias
* @return $this
*/
public function addUseStatement(string $qualifiedName, string $alias = null) {
public function addUseStatement($qualifiedName, string $alias = null) {
if ($qualifiedName instanceof PhpTypeInterface) {
$qualifiedName = $qualifiedName->getQualifiedName();
}

if (TypeUtils::isGlobalQualifiedName($qualifiedName) || TypeUtils::isNativeType($qualifiedName)) {
return $this;
}

if (preg_replace('#\\\\[^\\\\]+$#', '', $qualifiedName) === $this->getNamespace()) {
return $this;
}

if (!is_string($alias)) {
if (false === strpos($qualifiedName, '\\')) {
$alias = $qualifiedName;
Expand All @@ -135,6 +155,7 @@ public function addUseStatement(string $qualifiedName, string $alias = null) {
}
}

$qualifiedName = str_replace('[]', '', $qualifiedName);
$this->useStatements->set($alias, $qualifiedName);

return $this;
Expand Down Expand Up @@ -236,7 +257,7 @@ public function setMethods(array $methods) {

$this->methods->clear();
foreach ($methods as $method) {
$this->setMethod($method);
$this->addMethod($method);
}

return $this;
Expand All @@ -248,11 +269,28 @@ public function setMethods(array $methods) {
* @param PhpMethod $method
* @return $this
*/
public function setMethod(PhpMethod $method) {
public function addMethod(PhpMethod $method) {
$method->setParent($this);
$this->methods->set($method->getName(), $method);

return $this;
$types = $method->getTypes();
if ($types) {
foreach ($types as $type) {
$this->addUseStatement($type);
$method->addType($type);
}
}

foreach ($method->getParameters() as $parameter) {
$types = $parameter->getTypes();
if ($types) {
foreach ($types as $type) {
$this->addUseStatement($type);
$parameter->addType($type);
}
}
}

return $this;
}

/**
Expand Down Expand Up @@ -313,7 +351,7 @@ public function getMethod($nameOrMethod): PhpMethod {
/**
* Returns all methods
*
* @return Map collection of methods
* @return Map|PhpMethod[] collection of methods
*/
public function getMethods(): Map {
return $this->methods;
Expand Down
19 changes: 14 additions & 5 deletions src/model/PhpClass.php
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
*
* @author Thomas Gossmann
*/
class PhpClass extends AbstractPhpStruct implements GenerateableInterface, TraitsInterface, ConstantsInterface, PropertiesInterface {
class PhpClass extends AbstractPhpStruct implements GenerateableInterface, TraitsInterface, ConstantsInterface, PropertiesInterface, PhpTypeInterface {

use AbstractPart;
use ConstantsPart;
Expand Down Expand Up @@ -71,16 +71,25 @@ public function getParentClassName(): ?string {
return $this->parentClassName;
}

public function getParentClass(): PhpClass {
return class_exists($this->parentClassName) ?
self::fromName($this->parentClassName) : PhpClass::create($this->parentClassName);
}

/**
* Sets the parent class name
*
* @param string|null $name the new parent
* @param PhpClass|string|null $name the new parent
* @return $this
*/
public function setParentClassName(?string $name) {
$this->parentClassName = $name;
public function setParentClassName($parent) {
if ($parent instanceof PhpClass) {
$this->addUseStatement($parent->getQualifiedName());
$parent = $parent->getName();
}
$this->parentClassName = $parent;

return $this;
return $this;
}

public function generateDocblock(): void {
Expand Down
1 change: 1 addition & 0 deletions src/model/PhpConstant.php
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ public function __construct($name = null, $value = null, $isExpression = false)
$this->setValue($value);
}
$this->docblock = new Docblock();
$this->initTypes();
}

/**
Expand Down
3 changes: 2 additions & 1 deletion src/model/PhpFunction.php
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,8 @@ public function __construct($name = null) {
$this->setQualifiedName($name);
$this->docblock = new Docblock();
$this->initParameters();
}
$this->initTypes();
}

/**
* @inheritDoc
Expand Down
2 changes: 1 addition & 1 deletion src/model/PhpInterface.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
*
* @author Thomas Gossmann
*/
class PhpInterface extends AbstractPhpStruct implements GenerateableInterface, ConstantsInterface {
class PhpInterface extends AbstractPhpStruct implements GenerateableInterface, ConstantsInterface, PhpTypeInterface {

use ConstantsPart;
use InterfacesPart;
Expand Down
16 changes: 14 additions & 2 deletions src/model/PhpParameter.php
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
use gossi\codegen\model\parts\NamePart;
use gossi\codegen\model\parts\TypePart;
use gossi\codegen\model\parts\ValuePart;
use gossi\codegen\utils\TypeUtils;
use gossi\docblock\tags\ParamTag;

/**
Expand Down Expand Up @@ -54,7 +55,8 @@ public static function create($name = null) {
*/
public function __construct($name = null) {
$this->setName($name);
}
$this->initTypes();
}

/**
* Sets whether this parameter is passed by reference
Expand Down Expand Up @@ -83,8 +85,18 @@ public function isPassedByReference(): bool {
* @return ParamTag
*/
public function getDocblockTag(): ParamTag {
$type = '';
if ($this->getNullable()) {
$type = 'null';
}
if ($this->getTypes()) {
if ($type) {
$type .= '|';
}
$type .= TypeUtils::typesToExpression($this->getTypes());
}
return ParamTag::create()
->setType($this->getType())
->setType($type)
->setVariable($this->getName())
->setDescription($this->getTypeDescription());
}
Expand Down
15 changes: 15 additions & 0 deletions src/model/PhpType.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
<?php

namespace gossi\codegen\model;

use gossi\codegen\model\parts\QualifiedNamePart;

class PhpType implements PhpTypeInterface
{
use QualifiedNamePart;

public function __construct($qualifiedName)
{
$this->setQualifiedName($qualifiedName);
}
}
16 changes: 16 additions & 0 deletions src/model/PhpTypeInterface.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
<?php

namespace gossi\codegen\model;

interface PhpTypeInterface extends NamespaceInterface
{
public function getName(): ?string;

public function getQualifiedName(): ?string;

public function setName(?string $name);

public function setQualifiedName(?string $qualifiedName);

public function __toString(): string;
}
2 changes: 1 addition & 1 deletion src/model/PropertiesInterface.php
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ public function setProperties(array $properties);
* @param PhpProperty $property
* @return $this
*/
public function setProperty(PhpProperty $property);
public function addProperty(PhpProperty $property);

/**
* Removes a property
Expand Down
8 changes: 4 additions & 4 deletions src/model/RoutineInterface.php
Original file line number Diff line number Diff line change
Expand Up @@ -35,24 +35,24 @@ public function hasParameter(string $name): bool;
* A quick way to add a parameter which is created from the given parameters
*
* @param string $name
* @param null|string $type
* @param string[]|PhpTypeInterface[] $types
* @param mixed $defaultValue omit the argument to define no default value
*
* @return $this
*/
public function addSimpleParameter(string $name, string $type = null, $defaultValue = null);
public function addSimpleParameter(string $name, $type = null, $defaultValue = null);

/**
* A quick way to add a parameter with description which is created from the given parameters
*
* @param string $name
* @param null|string $type
* @param string[]|PhpTypeInterface[] $types
* @param null|string $typeDescription
* @param mixed $defaultValue omit the argument to define no default value
*
* @return $this
*/
public function addSimpleDescParameter(string $name, string $type = null, string $typeDescription = null, $defaultValue = null);
public function addSimpleDescParameter(string $name, $type = null, string $typeDescription = null, $defaultValue = null);

/**
* Returns a parameter by index or name
Expand Down
Loading