Skip to content

Commit 753fbcb

Browse files
committed
several improvements
1 parent 84dab25 commit 753fbcb

18 files changed

+471
-35
lines changed

src/CG/Core/ClassUtils.php

+19
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
<?php
2+
3+
namespace CG\Core;
4+
5+
use CG\Proxy\Enhancer;
6+
7+
abstract class ClassUtils
8+
{
9+
public static function getUserClass($className)
10+
{
11+
if (false === $pos = strpos($className, NamingStrategyInterface::SEPARATOR)) {
12+
return $className;
13+
}
14+
15+
return substr($className, 0, $pos);
16+
}
17+
18+
private final function __construct() {}
19+
}

src/CG/Core/DefaultNamingStrategy.php

+3-3
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,10 @@
44

55
class DefaultNamingStrategy implements NamingStrategyInterface
66
{
7-
const SEPARATOR = '__CG__';
8-
97
public function getClassName(\ReflectionClass $class)
108
{
11-
return $class->name.self::SEPARATOR.sha1($class->name.spl_object_hash($class));
9+
$userClass = ClassUtils::getUserClass($class->name);
10+
11+
return $userClass.self::SEPARATOR.sha1($class->name);
1212
}
1313
}

src/CG/Core/NamingStrategyInterface.php

+2
Original file line numberDiff line numberDiff line change
@@ -4,5 +4,7 @@
44

55
interface NamingStrategyInterface
66
{
7+
const SEPARATOR = '__CG__';
8+
79
function getClassName(\ReflectionClass $class);
810
}

src/CG/Generator/DefaultVisitor.php

+57-26
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,14 @@ public function startVisitingClass(PhpClass $class)
2727
$this->writer->write('namespace '.$namespace.';'."\n\n");
2828
}
2929

30+
if ($files = $class->getRequiredFiles()) {
31+
foreach ($files as $file) {
32+
$this->writer->writeln('require_once '.var_export($file, true).';');
33+
}
34+
35+
$this->writer->write("\n");
36+
}
37+
3038
if ($useStatements = $class->getUseStatements()) {
3139
foreach ($useStatements as $alias => $namespace) {
3240
$this->writer->write('use '.$namespace);
@@ -35,7 +43,7 @@ public function startVisitingClass(PhpClass $class)
3543
$this->writer->write(' as '.$alias);
3644
}
3745

38-
$this->writer->write("\n");
46+
$this->writer->write(";\n");
3947
}
4048

4149
$this->writer->write("\n");
@@ -113,7 +121,7 @@ public function startVisitingMethods()
113121
public function visitMethod(PhpMethod $method)
114122
{
115123
if ($docblock = $method->getDocblock()) {
116-
$this->writer->write($docblock);
124+
$this->writer->writeln($docblock)->rtrim();
117125
}
118126

119127
if ($method->isAbstract()) {
@@ -128,30 +136,7 @@ public function visitMethod(PhpMethod $method)
128136

129137
$this->writer->write('function '.$method->getName().'(');
130138

131-
$first = true;
132-
foreach ($method->getParameters() as $parameter) {
133-
if (!$first) {
134-
$this->writer->write(', ');
135-
}
136-
$first = false;
137-
138-
if ($type = $parameter->getType()) {
139-
$this->writer->write(
140-
('array' === $type ? 'array' : ('\\' === $type[0] ? $type : '\\'. $type))
141-
.' '
142-
);
143-
}
144-
145-
if ($parameter->isPassedByReference()) {
146-
$this->writer->write('&');
147-
}
148-
149-
$this->writer->write('$'.$parameter->getName());
150-
151-
if ($parameter->hasDefaultValue()) {
152-
$this->writer->write(' = '.var_export($parameter->getDefaultValue(), true));
153-
}
154-
}
139+
$this->writeParameters($method->getParameters());
155140

156141
if ($method->isAbstract()) {
157142
$this->writer->write(");\n\n");
@@ -183,8 +168,54 @@ public function endVisitingClass(PhpClass $class)
183168
;
184169
}
185170

171+
public function visitFunction(PhpFunction $function)
172+
{
173+
if ($namespace = $function->getNamespace()) {
174+
$this->writer->write("namespace $namespace;\n\n");
175+
}
176+
177+
$this->writer->write("function {$function->getName()}(");
178+
$this->writeParameters($function->getParameters());
179+
$this->writer
180+
->write(")\n{\n")
181+
->indent()
182+
->writeln($function->getBody())
183+
->outdent()
184+
->rtrim()
185+
->write('}')
186+
;
187+
}
188+
186189
public function getContent()
187190
{
188191
return $this->writer->getContent();
189192
}
193+
194+
private function writeParameters(array $parameters)
195+
{
196+
$first = true;
197+
foreach ($parameters as $parameter) {
198+
if (!$first) {
199+
$this->writer->write(', ');
200+
}
201+
$first = false;
202+
203+
if ($type = $parameter->getType()) {
204+
$this->writer->write(
205+
('array' === $type ? 'array' : ('\\' === $type[0] ? $type : '\\'. $type))
206+
.' '
207+
);
208+
}
209+
210+
if ($parameter->isPassedByReference()) {
211+
$this->writer->write('&');
212+
}
213+
214+
$this->writer->write('$'.$parameter->getName());
215+
216+
if ($parameter->hasDefaultValue()) {
217+
$this->writer->write(' = '.var_export($parameter->getDefaultValue(), true));
218+
}
219+
}
220+
}
190221
}

src/CG/Generator/DefaultVisitorInterface.php

+1
Original file line numberDiff line numberDiff line change
@@ -27,4 +27,5 @@ function startVisitingMethods();
2727
function visitMethod(PhpMethod $method);
2828
function endVisitingMethods();
2929
function endVisitingClass(PhpClass $class);
30+
function visitFunction(PhpFunction $function);
3031
}

src/CG/Generator/PhpClass.php

+36
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22

33
namespace CG\Generator;
44

5+
use Doctrine\Common\Annotations\PhpParser;
6+
57
use CG\Core\ReflectionUtils;
68

79
/**
@@ -11,12 +13,15 @@
1113
*/
1214
class PhpClass
1315
{
16+
private static $phpParser;
17+
1418
private $name;
1519
private $parentClassName;
1620
private $interfaceNames = array();
1721
private $useStatements = array();
1822
private $constants = array();
1923
private $properties = array();
24+
private $requiredFiles = array();
2025
private $methods = array();
2126
private $abstract = false;
2227
private $final = false;
@@ -37,6 +42,18 @@ public static function fromReflection(\ReflectionClass $ref)
3742
->setConstants($ref->getConstants())
3843
;
3944

45+
if (null === self::$phpParser) {
46+
if (!class_exists('Doctrine\Common\Annotations\PhpParser')) {
47+
self::$phpParser = false;
48+
} else {
49+
self::$phpParser = new PhpParser();
50+
}
51+
}
52+
53+
if (false !== self::$phpParser) {
54+
$class->setUseStatements(self::$phpParser->parseClass($ref));
55+
}
56+
4057
if ($docComment = $ref->getDocComment()) {
4158
$class->setDocblock(ReflectionUtils::getUnindentedDocComment($docComment));
4259
}
@@ -95,6 +112,20 @@ public function addInterfaceName($name)
95112
return $this;
96113
}
97114

115+
public function setRequiredFiles(array $files)
116+
{
117+
$this->files = $files;
118+
119+
return $this;
120+
}
121+
122+
public function addRequiredFile($file)
123+
{
124+
$this->files[] = $file;
125+
126+
return $this;
127+
}
128+
98129
public function setUseStatements(array $useStatements)
99130
{
100131
$this->useStatements = $useStatements;
@@ -253,6 +284,11 @@ public function getInterfaceNames()
253284
return $this->interfaceNames;
254285
}
255286

287+
public function getRequiredFiles()
288+
{
289+
return $this->requiredFiles;
290+
}
291+
256292
public function getUseStatements()
257293
{
258294
return $this->useStatements;

src/CG/Generator/PhpFunction.php

+130
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,130 @@
1+
<?php
2+
3+
namespace CG\Generator;
4+
5+
/**
6+
* Represents a PHP function.
7+
*
8+
* @author Johannes M. Schmitt <[email protected]>
9+
*/
10+
class PhpFunction
11+
{
12+
private $name;
13+
private $namespace;
14+
private $parameters = array();
15+
private $body = '';
16+
private $referenceReturned = false;
17+
private $docblock;
18+
19+
public static function create($name = null)
20+
{
21+
return new static($name);
22+
}
23+
24+
public function __construct($name = null)
25+
{
26+
$this->name = $name;
27+
}
28+
29+
public function setName($name)
30+
{
31+
$this->name = $name;
32+
33+
return $this;
34+
}
35+
36+
public function setNamespace($namespace)
37+
{
38+
$this->namespace = $namespace;
39+
40+
return $this;
41+
}
42+
43+
public function setParameters(array $parameters)
44+
{
45+
$this->parameters = $parameters;
46+
47+
return $this;
48+
}
49+
50+
public function setReferenceReturned($bool)
51+
{
52+
$this->referenceReturned = (Boolean) $bool;
53+
54+
return $this;
55+
}
56+
57+
public function replaceParameter($position, PhpParameter $parameter)
58+
{
59+
if ($position < 0 || $position > count($this->parameters)) {
60+
throw new \InvalidArgumentException(sprintf('$position must be in the range [0, %d].', count($this->parameters)));
61+
}
62+
63+
$this->parameters[$position] = $parameter;
64+
65+
return $this;
66+
}
67+
68+
public function addParameter(PhpParameter $parameter)
69+
{
70+
$this->parameters[] = $parameter;
71+
72+
return $this;
73+
}
74+
75+
public function removeParameter($position)
76+
{
77+
if (!isset($this->parameters[$position])) {
78+
throw new \InvalidArgumentException(sprintf('There is not parameter at position %d.', $position));
79+
}
80+
81+
unset($this->parameters[$position]);
82+
$this->parameters = array_values($this->parameters);
83+
84+
return $this;
85+
}
86+
87+
public function setBody($body)
88+
{
89+
$this->body = $body;
90+
91+
return $this;
92+
}
93+
94+
public function setDocblock($docBlock)
95+
{
96+
$this->docblock = $docBlock;
97+
98+
return $this;
99+
}
100+
101+
public function getName()
102+
{
103+
return $this->name;
104+
}
105+
106+
public function getNamespace()
107+
{
108+
return $this->namespace;
109+
}
110+
111+
public function getParameters()
112+
{
113+
return $this->parameters;
114+
}
115+
116+
public function getBody()
117+
{
118+
return $this->body;
119+
}
120+
121+
public function getDocblock()
122+
{
123+
return $this->docblock;
124+
}
125+
126+
public function isReferenceReturned()
127+
{
128+
return $this->referenceReturned;
129+
}
130+
}

0 commit comments

Comments
 (0)