Skip to content

Commit

Permalink
Merge pull request #28 from jmcclell/master
Browse files Browse the repository at this point in the history
PHP 7.0 Scalar Type Hinting Support (Should be BC)
  • Loading branch information
schmittjoh committed Apr 7, 2016
2 parents 0af1113 + 70e0bd1 commit 2152ea2
Show file tree
Hide file tree
Showing 19 changed files with 514 additions and 21 deletions.
2 changes: 1 addition & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ php:

before_script:
- curl -s http://getcomposer.org/installer | php
- php composer.phar install --dev
- php composer.phar install

script: phpunit --coverage-clover clover

Expand Down
3 changes: 3 additions & 0 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,9 @@
"require": {
"php": ">=5.3.0"
},
"require-dev": {
"phpunit/phpunit": ">=4.5"
},
"autoload": {
"psr-0": { "CG\\": "src/" }
},
Expand Down
20 changes: 20 additions & 0 deletions src/CG/Generator/BuiltinType.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
<?php

namespace CG\Generator;

class BuiltinType
{
private static $builtinTypes = array('self', 'array', 'callable', 'bool', 'float', 'int', 'string');

private function __construct(){
// Static class
}

public static function isBuiltin($type)
{
return in_array($type, static::$builtinTypes);
}
}



46 changes: 34 additions & 12 deletions src/CG/Generator/DefaultVisitor.php
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ public function startVisitingClass(PhpClass $class)
}

if ($docblock = $class->getDocblock()) {
$this->writer->write($docblock);
$this->writer->writeln($docblock);
}

if ($class->isAbstract()) {
Expand Down Expand Up @@ -137,7 +137,7 @@ public function startVisitingProperties()
public function visitProperty(PhpProperty $property)
{
if ($docblock = $property->getDocblock()) {
$this->writer->write($docblock)->rtrim();
$this->writer->writeln($docblock)->rtrim();
}

$this->writer->write($property->getVisibility().' '.($property->isStatic()? 'static ' : '').'$'.$property->getName());
Expand Down Expand Up @@ -184,15 +184,25 @@ public function visitMethod(PhpMethod $method)

$this->writeParameters($method->getParameters());

$this->writer->write(")");

if ($method->hasReturnType()) {
$type = $method->getReturnType();
$this->writer->write(': ');
if (!$method->hasBuiltInReturnType() && '\\' !== $type[0]) {
$this->writer->write('\\');
}
$this->writer->write($type);
}

if ($method->isAbstract() || $this->isInterface) {
$this->writer->write(");\n\n");
$this->writer->write(";\n\n");

return;
}

$this->writer
->writeln(")")
->writeln('{')
->writeln("\n{")
->indent()
->writeln($method->getBody())
->outdent()
Expand Down Expand Up @@ -221,13 +231,25 @@ public function visitFunction(PhpFunction $function)
}

if ($docblock = $function->getDocblock()) {
$this->writer->write($docblock)->rtrim();
$this->writer->writeln($docblock)->rtrim();
}

$this->writer->write("function {$function->getName()}(");
$this->writeParameters($function->getParameters());
$this->writer->write(')');

if ($function->hasReturnType()) {
$type = $function->getReturnType();
$this->writer->write(': ');
if (!$function->hasBuiltinReturnType() && '\\' !== $type[0]) {
$this->writer->write('\\');
}

$this->writer->write($type);
}

$this->writer
->write(")\n{\n")
->write("\n{\n")
->indent()
->writeln($function->getBody())
->outdent()
Expand All @@ -250,12 +272,12 @@ private function writeParameters(array $parameters)
}
$first = false;

if ($type = $parameter->getType()) {
if ('array' === $type || 'callable' === $type) {
$this->writer->write($type . ' ');
} else {
$this->writer->write(('\\' === $type[0] ? $type : '\\'. $type) . ' ');
if ($parameter->hasType()) {
$type = $parameter->getType();
if (!$parameter->hasBuiltinType() && '\\' !== $type[0]) {
$this->writer->write('\\');
}
$this->writer->write($type . ' ');
}

if ($parameter->isPassedByReference()) {
Expand Down
31 changes: 30 additions & 1 deletion src/CG/Generator/PhpClass.php
Original file line number Diff line number Diff line change
Expand Up @@ -161,7 +161,12 @@ public function addRequiredFile($file)

public function setUseStatements(array $useStatements)
{
$this->useStatements = $useStatements;
foreach ($useStatements as $alias => $namespace) {
if (!is_string($alias)) {
$alias = null;
}
$this->addUseStatement($namespace, $alias);
}

return $this;
}
Expand Down Expand Up @@ -466,4 +471,28 @@ public function getDocblock()
{
return $this->docblock;
}

public function hasUseStatements()
{
return count($this->getUseStatements()) > 0;
}

public function uses($typeDef)
{
if (empty($typeDef)) {
throw new \InvalidArgumentException("Empty type definition name given in " . __METHOD__);
}

if (!$this->hasUseStatements()) {
return false;
}

if ('\\' === $typeDef[0]) {
return false; // typedef references the root
}

$parts = explode('\\', $typeDef);
$typeDef = array_shift($parts);
return isset($this->useStatements[$typeDef]);
}
}
30 changes: 30 additions & 0 deletions src/CG/Generator/PhpFunction.php
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,8 @@ class PhpFunction extends AbstractBuilder
private $body = '';
private $referenceReturned = false;
private $docblock;
private $returnType;
private $returnTypeBuiltin = false;

public static function fromReflection(\ReflectionFunction $ref)
{
Expand All @@ -45,6 +47,11 @@ public static function fromReflection(\ReflectionFunction $ref)
$function->setName($ref->name);
}

if (method_exists($ref, 'getReturnType')) {
if ($type = $ref->getReturnType()) {
$function->setReturnType((string)$type);
}
}
$function->referenceReturned = $ref->returnsReference();
$function->docblock = ReflectionUtils::getUnindentedDocComment($ref->getDocComment());

Expand Down Expand Up @@ -126,6 +133,13 @@ public function setReferenceReturned($bool)
return $this;
}

public function setReturnType($type)
{
$this->returnType = $type;
$this->returnTypeBuiltin = BuiltinType::isBuiltIn($type);
return $this;
}

/**
* @param integer $position
*/
Expand Down Expand Up @@ -246,4 +260,20 @@ public function isReferenceReturned()
{
return $this->referenceReturned;
}

public function getReturnType()
{
return $this->returnType;
}

public function hasReturnType()
{
return null !== $this->getReturnType();
}

public function hasBuiltinReturnType()
{
return $this->returnTypeBuiltin;
}

}
30 changes: 30 additions & 0 deletions src/CG/Generator/PhpMethod.php
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@ class PhpMethod extends AbstractPhpMember
private $abstract = false;
private $parameters = array();
private $referenceReturned = false;
private $returnType = null;
private $returnTypeBuiltin = false;
private $body = '';

/**
Expand All @@ -53,6 +55,12 @@ public static function fromReflection(\ReflectionMethod $ref)
->setName($ref->name)
;

if (method_exists($ref, 'getReturnType')) {
if ($type = $ref->getReturnType()) {
$method->setReturnType((string)$type);
}
}

if ($docComment = $ref->getDocComment()) {
$method->setDocblock(ReflectionUtils::getUnindentedDocComment($docComment));
}
Expand Down Expand Up @@ -127,6 +135,13 @@ public function addParameter(PhpParameter $parameter)
return $this;
}

public function setReturnType($type)
{
$this->returnType = $type;
$this->returnTypeBuiltin = BuiltinType::isBuiltin($type);
return $this;
}

/**
* @param string|integer $nameOrIndex
*
Expand Down Expand Up @@ -201,4 +216,19 @@ public function getParameters()
{
return $this->parameters;
}

public function getReturnType()
{
return $this->returnType;
}

public function hasReturnType()
{
return null !== $this->getReturnType();
}

public function hasBuiltInReturnType()
{
return $this->returnTypeBuiltin;
}
}
30 changes: 24 additions & 6 deletions src/CG/Generator/PhpParameter.php
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ class PhpParameter extends AbstractBuilder
private $hasDefaultValue = false;
private $passedByReference = false;
private $type;
private $typeBuiltin;

/**
* @param string|null $name
Expand All @@ -51,12 +52,18 @@ public static function fromReflection(\ReflectionParameter $ref)
$parameter->setDefaultValue($ref->getDefaultValue());
}

if ($ref->isArray()) {
$parameter->setType('array');
} elseif ($class = $ref->getClass()) {
$parameter->setType($class->name);
} elseif (method_exists($ref, 'isCallable') && $ref->isCallable()) {
$parameter->setType('callable');
if (method_exists($ref, 'getType')) {
if ($type = $ref->getType()) {
$parameter->setType((string)$type);
}
} else {
if ($ref->isArray()) {
$parameter->setType('array');
} elseif ($class = $ref->getClass()) {
$parameter->setType($class->name);
} elseif (method_exists($ref, 'isCallable') && $ref->isCallable()) {
$parameter->setType('callable');
}
}

return $parameter;
Expand Down Expand Up @@ -109,6 +116,7 @@ public function setPassedByReference($bool)
public function setType($type)
{
$this->type = $type;
$this->typeBuiltin = BuiltinType::isBuiltIn($type);

return $this;
}
Expand Down Expand Up @@ -137,4 +145,14 @@ public function getType()
{
return $this->type;
}

public function hasType()
{
return null !== $this->type;
}

public function hasBuiltinType()
{
return $this->typeBuiltin;
}
}
2 changes: 1 addition & 1 deletion src/CG/Proxy/Enhancer.php
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ final public function generateClass()
->writeln(' *')
->writeln(' * This code was generated automatically by the CG library, manual changes to it')
->writeln(' * will be lost upon next generation.')
->writeln(' */')
->write(' */')
;
$docBlock = $writer->getContent();
}
Expand Down

0 comments on commit 2152ea2

Please sign in to comment.