init without trunk

This commit is contained in:
Kevin Adametz 2020-07-09 12:49:32 +02:00
parent ed24ac4994
commit bb809e7233
14652 changed files with 177862 additions and 94817 deletions

View file

@ -0,0 +1,8 @@
{
"title": "zend-code Generator Component",
"content": [
{"Intro": "intro.md"},
{"Examples": "examples.md"},
{"Reference": "reference.md"}
]
}

View file

@ -0,0 +1,372 @@
# Zend\\Code\\Generator Examples
## Generating PHP classes
The following example generates an empty class with a class-level DocBlock.
```php
use Zend\Code\Generator\ClassGenerator;
use Zend\Code\Generator\DocBlockGenerator;
$foo = new ClassGenerator();
$docblock = DocBlockGenerator::fromArray([
'shortDescription' => 'Sample generated class',
'longDescription' => 'This is a class generated with Zend\Code\Generator.',
'tags' => [
[
'name' => 'version',
'description' => '$Rev:$',
],
[
'name' => 'license',
'description' => 'New BSD',
],
],
]);
$foo->setName('Foo')
->setDocblock($docblock);
echo $foo->generate();
```
The above code will result in the following:
```php
/**
* Sample generated class
*
* This is a class generated with Zend\Code\Generator.
*
* @version $Rev:$
* @license New BSD
*
*/
class Foo
{
}
```
### Generating PHP classes with class properties
Building on the previous example, we now add properties to our generated class.
```php
use Zend\Code\Generator\ClassGenerator;
use Zend\Code\Generator\DocBlockGenerator;
use Zend\Code\Generator\PropertyGenerator;
$foo = new ClassGenerator();
$docblock = DocBlockGenerator::fromArray([
'shortDescription' => 'Sample generated class',
'longDescription' => 'This is a class generated with Zend\Code\Generator.',
'tags' => [
[
'name' => 'version',
'description' => '$Rev:$',
],
[
'name' => 'license',
'description' => 'New BSD',
],
],
]);
$foo->setName('Foo')
->setDocblock($docblock)
->addProperties([
['_bar', 'baz', PropertyGenerator::FLAG_PROTECTED],
['baz', 'bat', PropertyGenerator::FLAG_PUBLIC]
])
->addConstants([
['bat', 'foobarbazbat']
]);
echo $foo->generate();
```
The above results in the following class definition:
```php
/**
* Sample generated class
*
* This is a class generated with Zend\Code\Generator.
*
* @version $Rev:$
* @license New BSD
*
*/
class Foo
{
protected $_bar = 'baz';
public $baz = 'bat';
const bat = 'foobarbazbat';
}
```
### Generating PHP classes with class methods
`Zend\Code\Generator\ClassGenerator` allows you to attach methods with optional content to your
classes. Methods may be attached as either arrays or concrete `Zend\Code\Generator\MethodGenerator`
instances.
```php
use Zend\Code\Generator\ClassGenerator;
use Zend\Code\Generator\DocBlockGenerator;
use Zend\Code\Generator\DocBlock\Tag;
use Zend\Code\Generator\MethodGenerator;
use Zend\Code\Generator\PropertyGenerator;
$foo = new ClassGenerator();
$docblock = DocBlockGenerator::fromArray([
'shortDescription' => 'Sample generated class',
'longDescription' => 'This is a class generated with Zend\Code\Generator.',
'tags' => [
[
'name' => 'version',
'description' => '$Rev:$',
],
[
'name' => 'license',
'description' => 'New BSD',
],
],
]);
$foo->setName('Foo')
->setDocblock($docblock)
->addProperties([
['_bar', 'baz', PropertyGenerator::FLAG_PROTECTED],
['baz', 'bat', PropertyGenerator::FLAG_PUBLIC]
])
->addConstants([
['bat', 'foobarbazbat', PropertyGenerator::FLAG_CONSTANT]
])
->addMethods([
// Method passed as array
MethodGenerator::fromArray([
'name' => 'setBar',
'parameters' => ['bar'],
'body' => '$this->_bar = $bar;' . "\n" . 'return $this;',
'docblock' => DocBlockGenerator::fromArray([
'shortDescription' => 'Set the bar property',
'longDescription' => null,
'tags' => [
new Tag\ParamTag([
'paramName' => 'bar',
'datatype' => 'string'
]),
new Tag\ReturnTag([
'datatype' => 'string',
]),
],
]),
]),
// Method passed as concrete instance
new MethodGenerator(
'getBar',
[],
MethodGenerator::FLAG_PUBLIC,
'return $this->_bar;',
DocBlockGenerator::fromArray([
'shortDescription' => 'Retrieve the bar property',
'longDescription' => null,
'tags' => [
new Tag\ReturnTag([
'datatype' => 'string|null',
]),
],
])
),
]);
echo $foo->generate();
```
The above generates the following output:
```php
/**
* Sample generated class
*
* This is a class generated with Zend\Code\Generator.
*
* @version $Rev:$
* @license New BSD
*/
class Foo
{
protected $_bar = 'baz';
public $baz = 'bat';
const bat = 'foobarbazbat';
/**
* Set the bar property
*
* @param string bar
* @return string
*/
public function setBar($bar)
{
$this->_bar = $bar;
return $this;
}
/**
* Retrieve the bar property
*
* @return string|null
*/
public function getBar()
{
return $this->_bar;
}
}
```
## Generating PHP files
`Zend\Code\Generator\FileGenerator` can be used to generate the contents of a *PHP* file. You can
include classes as well as arbitrary content body. When attaching classes, you should attach either
concrete `Zend\Code\Generator\ClassGenerator` instances or an array defining the class.
In the example below, we will assume you've defined `$foo` per one of the class definitions in a
previous example.
```php
use Zend\Code\Generator\DocBlockGenerator;
use Zend\Code\Generator\FileGenerator;
$file = FileGenerator::fromArray([
'classes' => [$foo],
'docblock' => DocBlockGenerator::fromArray([
'shortDescription' => 'Foo class file',
'longDescription' => null,
'tags' => [
[
'name' => 'license',
'description' => 'New BSD',
],
],
]),
'body' => 'define(\'APPLICATION_ENV\', \'testing\');',
]);
```
Calling `generate()` will generate the code -- but not write it to a file. You will need to capture
the contents and write them to a file yourself. As an example:
```php
$code = $file->generate();
file_put_contents('Foo.php', $code);
```
The above will generate the following file:
```php
<?php
/**
* Foo class file
*
* @license New BSD
*/
/**
* Sample generated class
*
* This is a class generated with Zend\Code\Generator.
*
* @version $Rev:$
* @license New BSD
*/
class Foo
{
protected $_bar = 'baz';
public $baz = 'bat';
const bat = 'foobarbazbat';
/**
* Set the bar property
*
* @param string bar
* @return string
*/
public function setBar($bar)
{
$this->_bar = $bar;
return $this;
}
/**
* Retrieve the bar property
*
* @return string|null
*/
public function getBar()
{
return $this->_bar;
}
}
define('APPLICATION_ENV', 'testing');
```
## Add code to existing PHP files and classes
### Seeding PHP file code generation via reflection
You can add *PHP* code to an existing *PHP* file using the code generator. To do so, you need to
first do reflection on it. The static method `fromReflectedFileName()` allows you to do this.
```php
$generator = Zend\Code\Generator\FileGenerator::fromReflectedFileName($path);
$generator->setBody("\$foo->bar();");
file_put_contents($path, $generator->generate());
```
### Seeding PHP class generation via reflection
You may add code to an existing class. To do so, first use the static `fromReflection()` method to
map the class into a generator object. From there, you may add additional properties or methods, and
then regenerate the class.
```php
use Zend\Code\Generator\ClassGenerator;
use Zend\Code\Generator\DocBlockGenerator;
use Zend\Code\Generator\DocBlock\Tag;
use Zend\Code\Generator\MethodGenerator;
use Zend\Code\Reflection\ClassReflection;
$generator = ClassGenerator::fromReflection(
new ClassReflection($class)
);
$generator->addMethod(
'setBaz',
['baz'],
MethodGenerator::FLAG_PUBLIC,
'$this->_baz = $baz;' . "\n" . 'return $this;',
DocBlockGenerator::fromArray([
'shortDescription' => 'Set the baz property',
'longDescription' => null,
'tags' => [
new Tag\ParamTag([
'paramName' => 'baz',
'datatype' => 'string'
]),
new Tag\ReturnTag([
'datatype' => 'string',
]),
],
])
);
$code = $generator->generate();
```

View file

@ -0,0 +1,126 @@
# Introduction
`Zend\Code\Generator` provides facilities to generate arbitrary code using an object-oriented
interface, both to create new code as well as to update existing code. While the current
implementation is limited to generating *PHP* code, you can easily extend the base class in order to
provide code generation for other tasks: JavaScript, configuration files, apache vhosts, etc.
## Theory of Operation
In the most typical use case, you will simply instantiate a code generator class and either pass it
the appropriate configuration or configure it after instantiation. To generate the code, you will
simply echo the object or call its `generate()` method.
```php
// Passing configuration to the constructor:
$file = new Zend\Code\Generator\FileGenerator(array(
'classes' => array(
new Zend\Code\Generator\ClassGenerator(
'World', // name
null, // namespace
null, // flags
null, // extends
array(), // interfaces
array(), // properties
array(
new Zend\Code\Generator\MethodGenerator(
'hello', // name
array(), // parameters
'public', // visibility
'echo \'Hello world!\';' // body
),
)
),
),
));
// Render the generated file
echo $file->generate();
// or write it to a file:
file_put_contents('World.php', $file->generate());
// OR
// Configuring after instantiation
$method = new Zend\Code\Generator\MethodGenerator();
$method->setName('hello')
->setBody('echo \'Hello world!\';');
$class = new Zend\Code\Generator\ClassGenerator();
$class->setName('World')
->addMethodFromGenerator($method);
$file = new Zend\Code\Generator\FileGenerator();
$file->setClass($class);
// Render the generated file
echo $file->generate();
// or write it to a file:
file_put_contents('World.php', $file->generate());
```
Both of the above samples will render the same result:
```php
<?php
class World
{
public function hello()
{
echo 'Hello world!';
}
}
```
Another common use case is to update existing code -- for instance, to add a method to a class. In
such a case, you must first inspect the existing code using reflection, and then add your new
method. `Zend\Code\Generator` makes this trivially simple, by leveraging `Zend\Code\Reflection`.
As an example, let's say we've saved the above to the file `World.php`, and have already included
it. We could then do the following:
```php
$class = Zend\Code\Generator\ClassGenerator::fromReflection(
new Zend\Code\Reflection\ClassReflection('World')
);
$method = new Zend\Code\Generator\MethodGenerator();
$method->setName('mrMcFeeley')
->setBody('echo \'Hello, Mr. McFeeley!\';');
$class->addMethodFromGenerator($method);
$file = new Zend\Code\Generator\FileGenerator();
$file->setClass($class);
// Render the generated file
echo $file->generate();
// Or, better yet, write it back to the original file:
file_put_contents('World.php', $file->generate());
```
The resulting class file will now look like this:
```php
<?php
class World
{
public function hello()
{
echo 'Hello world!';
}
public function mrMcFeeley()
{
echo 'Hellow Mr. McFeeley!';
}
}
```

View file

@ -0,0 +1,403 @@
# Zend\\Code\\Generator Reference
## Abstract Classes and Interfaces
### Zend\\Code\\Generator\\GeneratorInterface
The base interface from which all CodeGenerator classes implement provides the minimal functionality
necessary. It's *API* is as follows:
```php
interface Zend\Code\Generator\GeneratorInterface
{
public function generate();
}
```
### Zend\\Code\\Generator\\AbstractGenerator
`Zend\Code\Generator\AbstractGenerator` implements `Zend\Code\Generator\GeneratorInterface`, and
adds some properties for tracking whether content has changed as well as the amount of indentation
that should appear before generated content. Its *API* is as follows:
```php
abstract class Zend\Code\Generator\AbstractGenerator
implements Zend\Code\Generator\GeneratorInterface
{
public function __construct(Array|Traversable $options = [])
public function setOptions(Array $options)
public function setSourceContent($sourceContent)
public function getSourceContent()
public function setSourceDirty($isSourceDirty = true)
public function isSourceDirty()
public function setIndentation($indentation)
public function getIndentation()
}
```
The constructor passes the `$options` parameter to `setOptions()`.
Like most classes in Zend Framework, `setOptions()` compares an option key to existing setters in
the class, and passes the value on to that method if found.
`setSourceContent()` and `getSourceContent()` are intended to either set the default content for the
code being generated, or to replace said content once all generation tasks are complete.
### Zend\\Code\\Generator\\AbstractMemberGenerator
`Zend\Code\Generator\AbstractMemberGenerator` is a base class for generating class members --
properties and methods -- and provides accessors and mutators for establishing visibility; whether
or not the member is abstract, static, or final; and the name of the member. Its *API* is as
follows:
```php
abstract class Zend\Code\Generator\AbstractMemberGenerator
extends Zend\Code\Generator\AbstractGenerator
{
public function setAbstract($isAbstract)
public function isAbstract()
public function setStatic($isStatic)
public function isStatic()
public function setVisibility($visibility)
public function getVisibility()
public function setName($name)
public function getName()
}
```
## Concrete CodeGenerator Classes
### Zend\\Code\\Generator\\BodyGenerator
`Zend\Code\Generator\BodyGenerator` is intended for generating arbitrary procedural code to include
within a file. As such, you simply set content for the object, and it will return that content when
you invoke `generate()`.
The *API* of the class is as follows:
```php
class Zend\Code\Generator\BodyGenerator extends Zend\Code\Generator\AbstractGenerator
{
public function setContent($content)
public function getContent()
public function generate()
}
```
### Zend\\Code\\Generator\\ClassGenerator
`Zend\Code\Generator\ClassGenerator` is intended for generating *PHP* classes. The basic
functionality just generates the *PHP* class itself, as well as optionally the related *PHP*
DocBlock. Classes may implement or inherit from other classes, and may be marked as abstract.
Utilizing other code generator classes, you can also attach class constants, properties, and
methods.
The *API* is as follows:
```php
class Zend\Code\Generator\ClassGenerator extends Zend\Code\Generator\AbstractGenerator
{
public static function fromReflection(
Zend\Code\Reflection\ClassReflection $reflectionClass
)
public function addConstants(Array $properties)
public function addConstant($property)
public function getConstants()
public function getConstant($propertyName)
public function removeConstant($constantName)
public function setDocblock(Zend\Code\Generator\DocBlockGenerator $docblock)
public function getDocblock()
public function setName($name)
public function getName()
public function setAbstract($isAbstract)
public function isAbstract()
public function setExtendedClass($extendedClass)
public function getExtendedClass()
public function hasExtentedClass()
public function removeExtentedClass()
public function setImplementedInterfaces(Array $implementedInterfaces)
public function getImplementedInterfaces()
public function addProperties(Array $properties)
public function addProperty($property)
public function getProperties()
public function getProperty($propertyName)
public function removeProperty($propertyName)
public function addMethods(Array $methods)
public function addMethod(
$name,
Array $parameters = [],
$flags = Zend\Code\Generator\MethodGenerator::FLAG_PUBLIC,
$body = null,
$docBlock = null
)
public function getMethods()
public function getMethod($methodName)
public function hasMethod($methodName)
public function hasUse($use)
public function removeUse($use)
public function hasUseAlias($use)
public function removeUseAlias($use)
public function hasImplementedInterface($implementedInterface)
public function removeImplementedInterface($implementedInterface)
public function isSourceDirty()
public function generate()
}
```
The `addProperty()` method accepts an array of information that may be used to generate a
`Zend\Code\Generator\PropertyGenerator` instance -- or simply an instance of
`Zend\Code\Generator\PropertyGenerator`. Likewise, `addMethod()` accepts either an array of
information for generating a `Zend\Code\Generator\MethodGenerator` instance or a concrete instance
of that class.
Note that `setDocBlock()` expects an instance of `Zend\Code\Generator\DocBlockGenerator`.
### Zend\\Code\\Generator\\DocBlockGenerator
`Zend\Code\Generator\DocBlockGenerator` can be used to generate arbitrary *PHP* docblocks, including
all the standard docblock features: short and long descriptions and annotation tags.
Annotation tags may be set using the `setTag()` and `setTags()` methods; these each take either an
array describing the tag that may be passed to the `Zend\Code\Generator\DocBlock\Tag` constructor,
or an instance of that class.
The *API* is as follows:
```php
class Zend\Code\Generator\DocBlockGenerator extends Zend\Code\Generator\AbstractGenerator
{
public static function fromReflection(
Zend\Code\Reflection\DocblockReflection $reflectionDocblock
)
public function setShortDescription($shortDescription)
public function getShortDescription()
public function setLongDescription($longDescription)
public function getLongDescription()
public function setTags(Array $tags)
public function setTag($tag)
public function getTags()
public function generate()
}
```
### Zend\\Code\\Generator\\DocBlock\\Tag
`Zend\Code\Generator\DocBlock\Tag` is intended for creating arbitrary annotation tags for inclusion
in *PHP* docblocks. Tags are expected to contain a name (the portion immediately following the '@'
symbol) and a description (everything following the tag name).
The class *API* is as follows:
```php
class Zend\Code\Generator\DocBlock\Tag
extends Zend\Code\Generator\AbstractGenerator
{
public static function fromReflection(
Zend\Code\Reflection\DocBlock\Tag\TagInterface $reflectionTag
)
public function setName($name)
public function getName()
public function setDescription($description)
public function getDescription()
public function generate()
}
```
### Zend\\Code\\Generator\\DocBlock\\Tag\\ParamTag
`Zend\Code\Generator\DocBlock\Tag\ParamTag` is a specialized version of
`Zend\Code\Generator\DocBlock\Tag`, and represents a method parameter. The tag name is therefor
known ("param"), but due to the format of this annotation tag, additional information is required in
order to generate it: the parameter name and data type it represents.
The class *API* is as follows:
```php
class Zend\Code\Generator\DocBlock\Tag\ParamTag
extends Zend\Code\Generator\DocBlock\Tag
{
public static function fromReflection(
Zend\Code\Reflection\DocBlock\Tag\TagInterface $reflectionTagParam
)
public function setDatatype($datatype)
public function getDatatype()
public function setParamName($paramName)
public function getParamName()
public function generate()
}
```
### Zend\\Code\\Generator\\DocBlock\\Tag\\ReturnTag
Like the param docblock tag variant, `Zend\Code\Generator\DocBlock\Tag\ReturnTag` is an annotation
tag variant for representing a method return value. In this case, the annotation tag name is known
("return"), but requires a return type.
The class *API* is as follows:
```php
class Zend\Code\Generator\DocBlock\Tag\ParamTag
extends Zend\Code\Generator\DocBlock\Tag
{
public static function fromReflection(
Zend\Code\Reflection\DocBlock\Tag\TagInterface $reflectionTagReturn
)
public function setDatatype($datatype)
public function getDatatype()
public function generate()
}
```
### Zend\\Code\\Generator\\FileGenerator
`Zend\Code\Generator\FileGenerator` is used to generate the full contents of a file that will
contain *PHP* code. The file may contain classes or arbitrary *PHP* code, as well as a file-level
docblock if desired.
When adding classes to the file, you will need to pass either an array of information to pass to the
`Zend\Code\Generator\ClassGenerator` constructor, or an instance of that class. Similarly, with
docblocks, you will need to pass information for the `Zend\Code\Generator\DocBlockGenerator`
constructor to consume or an instance of the class.
The *API* of the class is as follows:
```php
class Zend\Code\Generator\FileGenerator extends Zend\Code\Generator\AbstractGenerator
{
public static function fromReflectedFilePath(
$filePath,
$usePreviousCodeGeneratorIfItExists = true,
$includeIfNotAlreadyIncluded = true)
public static function fromReflection(Zend\Code\Reflection\FileReflection $reflectionFile)
public function setDocblock(Zend\Code\Generator\DocBlockGenerator $docblock)
public function getDocblock()
public function setRequiredFiles($requiredFiles)
public function getRequiredFiles()
public function setClasses(Array $classes)
public function getClass($name = null)
public function setClass($class)
public function setFilename($filename)
public function getFilename()
public function getClasses()
public function setBody($body)
public function getBody()
public function isSourceDirty()
public function generate()
}
```
### Zend\\Code\\Generator\\Member\\ContainerGenerator
`Zend\Code\Generator\Member\ContainerGenerator` is used internally by
`Zend\Code\Generator\ClassGenerator` to keep track of class members -- properties and methods alike.
These are indexed by name, using the concrete instances of the members as values.
The *API* of the class is as follows:
```php
class Zend\Code\Generator\Member\ContainerGenerator extends ArrayObject
{
public function __construct($type = self::TYPE_PROPERTY)
}
```
### Zend\\Code\\Generator\\MethodGenerator
`Zend\Code\Generator\MethodGenerator` describes a class method, and can generate both the code and
the docblock for the method. The visibility and status as static, abstract, or final may be
indicated, per its parent class, `Zend\Code\Generator\AbstractMemberGenerator`. Finally, the
parameters and return value for the method may be specified.
Parameters may be set using `setParameter()` or `setParameters()`. In each case, a parameter should
either be an array of information to pass to the `Zend\Code\Generator\ParameterGenerator`
constructor or an instance of that class.
The *API* of the class is as follows:
```php
class Zend\Code\Generator\MethodGenerator
extends Zend\Code\Generator\AbstractMemberGenerator
{
public static function fromReflection(
Zend\Code\Reflection\MethodReflection $reflectionMethod
)
public function setDocblock(Zend\Code\Generator\DocBlockGenerator $docblock)
public function getDocblock()
public function setFinal($isFinal)
public function setParameters(Array $parameters)
public function setParameter($parameter)
public function getParameters()
public function setBody($body)
public function getBody()
public function generate()
}
```
### Zend\\Code\\Generator\\ParameterGenerator
`Zend\Code\Generator\ParameterGenerator` may be used to specify method parameters. Each parameter
may have a position (if unspecified, the order in which they are registered with the method will be
used), a default value, and a data type; a parameter name is required.
The *API* of the class is as follows:
```php
class Zend\Code\Generator\ParameterGenerator extends Zend\Code\Generator\AbstractGenerator
{
public static function fromReflection(
Zend\Code\Reflection\ParameterReflection $reflectionParameter
)
public function setType($type)
public function getType()
public function setName($name)
public function getName()
public function setDefaultValue($defaultValue)
public function getDefaultValue()
public function setPosition($position)
public function getPosition()
public function getPassedByReference()
public function setPassedByReference($passedByReference)
public function generate()
}
```
There are several problems that might occur when trying to set `NULL`, booleans or arrays as default
values. For this the value holder object `Zend\Code\Generator\ParameterDefaultValueGenerator` can be
used, for example:
```php
$parameter = new Zend\Code\Generator\ParameterGenerator();
$parameter->setDefaultValue(
new Zend\Code\Generator\ValueGenerator("null")
);
$parameter->setDefaultValue(
new Zend\Code\Generator\ValueGenerator("['foo', 'bar']")
);
```
Internally `setDefaultValue()` also converts the values which can't be expressed in *PHP* into the
value holder.
### Zend\\Code\\Generator\\PropertyGenerator
`Zend\Code\Generator\PropertyGenerator` describes a class property, which may be either a constant
or a variable. In each case, the property may have an optional default value associated with it.
Additionally, the visibility of variable properties may be set, per the parent class,
`Zend\Code\Generator\AbstractMemberGenerator`.
The *API* of the class is as follows:
```php
class Zend\Code\Generator\PropertyGenerator
extends Zend\Code\Generator\AbstractMemberGenerator
{
public static function fromReflection(
Zend\Code\Reflection\PropertyReflection $reflectionProperty
)
public function setConst($const)
public function isConst()
public function setDefaultValue($defaultValue)
public function getDefaultValue()
public function generate()
}
```

View file

@ -0,0 +1,10 @@
<div class="container">
<div class="jumbotron">
<h1>zend-code</h1>
<p>Extensions to the PHP Reflection API, static code scanning, and code generation.</p>
<pre><code class="language-bash">$ composer require zendframework/zend-code</code></pre>
</div>
</div>

View file

@ -0,0 +1 @@
../../README.md

View file

@ -0,0 +1,130 @@
# Migrating from zend-code v2 to v3
## `string`, `int`, `float`, `bool` are no longer ignored
In 2.x, a `Zend\Code\Generator\ParameterGenerator` with name `foo` and type
`string`, `int`, `float` or `bool` simply generated code `"$foo"`:
```php
$generator = new \Zend\Code\ParameterGenerator('foo');
$generator->setType('string');
echo $generator->generate(); // "$foo"
```
In 3.x, this code will instead produce `"string $foo"`.
If you generate code that should run in PHP 5.x, it is advisable to strip
`string`, `int`, `float` and `bool` from type definitions passed to
`Zend\Code\ParameterGenerator` instances. The quickest way is to set the
type to `null`, if it matches any of these scalar types:
```php
if (in_array($type, ['string', 'int', 'float', 'bool'])) {
$type = null;
}
$generator->setType($type);
```
## `ParameterReflection::getType()` changes
PHP 7 introduced [`ReflectionParameter#getType()`](http://php.net/manual/en/reflectionparameter.gettype.php).
In order to not override this method, `Zend\Code\Reflection\ParameterReflection#getType()`
was renamed to `Zend\Code\Reflection\ParameterReflection#detectType()`.
If you relied on `Zend\Code\Reflection\ParameterReflection#getType()`, you can
simply replace the method calls in your code.
## DocBlock types ignored by `ParameterGenerator::fromReflection()`
As a direct consequence of the previous change, calls to
`Zend\Code\Generator\ParameterGenerator::fromReflection()` will not mirror the
type hints read from a method's DocBlock.
As an example, take following code:
```php
class Foo
{
/**
* @param string $baz
*/
public function bar($baz)
{
}
}
$methodGenerator = \Zend\Code\Generator\MethodGenerator::fromReflection(
new \Zend\Code\Reflection\MethodReflection('Foo', 'bar')
);
var_dump($methodGenerator->getParameters()[0]->getType());
```
In version 2.x, this code produces `"string"`, in version 3.x it returns `null`. If you
need to rely on the types in the annotations, please use
`Zend\Code\Reflection\ParameterReflection#detectType()` instead, and build a
`MethodGenerator` instance manually.
This change is required: since signatures in PHP 7 include scalar type hints.
That also means that reflecting scalar type hints from DocBlocks into the
signature of a generated method may lead to fatal errors (due to signature
mismatch) at runtime.
## Type strings are validated
If you attempt to generate type-hints for parameters or return types, those types are
now validated before the code is generated.
Be sure to check which values you pass to `Zend\Code\Generator\MethodGenerator#setReturnType()`
or `Zend\Code\Generator\ParameterGenerator#setType()`, as you may incur in a
`Zend\Code\Generator\Exception\InvalidArgumentException` being thrown if any
of those types are invalid strings:
```php
$parameterGenerator->setType('foo'); // valid
$parameterGenerator->setType('array'); // valid
$parameterGenerator->setType('bool'); // valid
$parameterGenerator->setType('123'); // invalid (throws exception)
$parameterGenerator->setType(''); // invalid (throws exception)
$parameterGenerator->setType('*'); // invalid (throws exception)
$parameterGenerator->setType('\\'); // invalid (throws exception)
```
## Generated type-hints are now prefixed by `"\"`
Generated type-hints are now prefixed with the `NAMESPACE_SEPARATOR`,
`"\"`.
Take following example code:
```php
$parameter = new \Zend\Code\Generator\ParameterGenerator('bar', 'baz');
$method = new \Zend\Code\Generator\MethodGenerator('foo', [$parameter]);
$method->setReturnType('tab');
echo $method->generate();
```
This code produces `public function foo(baz $bar) {}` in 2.x.
In version 3.x, it produces `public function foo(\baz $bar) : \tab {}`.
In order to avoid migration problems, be sure to always pass fully qualified class
names to `Zend\Code\Generator\MethodGenerator` and `Zend\Code\Generator\ParameterGenerator`.
## `ParameterGenerator::$simple` was removed
If you extended `Zend\Code\Generator\ParameterGenerator`, be sure to check if you
are accessing the protected static variable `$simple`: it was removed, and you should
adapt your code by either copying it into your class or avoiding its usage.
## `ParameterGenerator::$type` has changed
If you extended `Zend\Code\Generator\ParameterGenerator`, be sure to check if you
are accessing the protected variable `$type`: its type has changed.
While it can still be used as a string via an explicit `(string)` cast, the type of
this protected member is now `null|Zend\Code\Generator\TypeGenerator`.