2 namespace Robo\Task\Development;
4 use Robo\Task\BaseTask;
8 * Generate a Robo Task that is a wrapper around an existing class.
12 * $this->taskGenerateTask('Symfony\Component\Filesystem\Filesystem', 'FilesystemStack')
16 class GenerateTask extends BaseTask
26 protected $wrapperClassName;
29 * @param string $className
30 * @param string $wrapperClassName
32 public function __construct($className, $wrapperClassName = '')
34 $this->className = $className;
35 $this->wrapperClassName = $wrapperClassName;
43 $delegate = new \ReflectionClass($this->className);
46 $leadingCommentChars = " * ";
47 $methodDescriptions = [];
48 $methodImplementations = [];
49 $immediateMethods = [];
50 foreach ($delegate->getMethods(\ReflectionMethod::IS_PUBLIC) as $method) {
51 $methodName = $method->name;
52 $getter = preg_match('/^(get|has|is)/', $methodName);
53 $setter = preg_match('/^(set|unset)/', $methodName);
54 $argPrototypeList = [];
56 $needsImplementation = false;
57 foreach ($method->getParameters() as $arg) {
58 $argDescription = '$' . $arg->name;
59 $argNameList[] = $argDescription;
60 if ($arg->isOptional()) {
61 $argDescription = $argDescription . ' = ' . str_replace("\n", "", var_export($arg->getDefaultValue(), true));
62 // We will create wrapper methods for any method that
63 // has default parameters.
64 $needsImplementation = true;
66 $argPrototypeList[] = $argDescription;
68 $argPrototypeString = implode(', ', $argPrototypeList);
69 $argNameListString = implode(', ', $argNameList);
71 if ($methodName[0] != '_') {
72 $methodDescriptions[] = "@method $methodName($argPrototypeString)";
75 $immediateMethods[] = " public function $methodName($argPrototypeString)\n {\n return \$this->delegate->$methodName($argNameListString);\n }";
77 $immediateMethods[] = " public function $methodName($argPrototypeString)\n {\n \$this->delegate->$methodName($argNameListString);\n return \$this;\n }";
78 } elseif ($needsImplementation) {
79 // Include an implementation for the wrapper method if necessary
80 $methodImplementations[] = " protected function _$methodName($argPrototypeString)\n {\n \$this->delegate->$methodName($argNameListString);\n }";
85 $classNameParts = explode('\\', $this->className);
86 $delegate = array_pop($classNameParts);
87 $delegateNamespace = implode('\\', $classNameParts);
89 if (empty($this->wrapperClassName)) {
90 $this->wrapperClassName = $delegate;
93 $replacements['{delegateNamespace}'] = $delegateNamespace;
94 $replacements['{delegate}'] = $delegate;
95 $replacements['{wrapperClassName}'] = $this->wrapperClassName;
96 $replacements['{taskname}'] = "task$delegate";
97 $replacements['{methodList}'] = $leadingCommentChars . implode("\n$leadingCommentChars", $methodDescriptions);
98 $replacements['{immediateMethods}'] = "\n\n" . implode("\n\n", $immediateMethods);
99 $replacements['{methodImplementations}'] = "\n\n" . implode("\n\n", $methodImplementations);
101 $template = file_get_contents(__DIR__ . '/../../../data/Task/Development/GeneratedWrapper.tmpl');
102 $template = str_replace(array_keys($replacements), array_values($replacements), $template);
104 // Returning data in the $message will cause it to be printed.
105 return Result::success($this, $template);