1: <?php
2:
3: namespace Mockery\Generator\StringManipulation\Pass;
4:
5: use Mockery\Generator\Method;
6: use Mockery\Generator\MockConfiguration;
7:
8: class MethodDefinitionPass implements Pass
9: {
10: public function apply($code, MockConfiguration $config)
11: {
12: foreach ($config->getMethodsToMock() as $method) {
13:
14: if ($method->isPublic()) {
15: $methodDef = 'public';
16: } elseif($method->isProtected()) {
17: $methodDef = 'protected';
18: } else {
19: $methodDef = 'private';
20: }
21:
22: if ($method->isStatic()) {
23: $methodDef .= ' static';
24: }
25:
26: $methodDef .= ' function ';
27: $methodDef .= $method->returnsReference() ? ' & ' : '';
28: $methodDef .= $method->getName();
29: $methodDef .= $this->renderParams($method, $config);
30: $methodDef .= $this->renderMethodBody($method, $config);
31:
32: $code = $this->appendToClass($code, $methodDef);
33: }
34:
35: return $code;
36: }
37:
38: protected function renderParams(Method $method, $config)
39: {
40: $class = $method->getDeclaringClass();
41: if ($class->isInternal()) {
42: $overrides = $config->getParameterOverrides();
43:
44: if (isset($overrides[strtolower($class->getName())][$method->getName()])) {
45: return '(' . implode(',', $overrides[strtolower($class->getName())][$method->getName()]) . ')';
46: }
47: }
48:
49: $methodParams = array();
50: $params = $method->getParameters();
51: foreach ($params as $param) {
52: $paramDef = $param->getTypeHintAsString();
53: $paramDef .= $param->isPassedByReference() ? '&' : '';
54: $paramDef .= '$' . $param->getName();
55:
56: if (false !== $param->isDefaultValueAvailable()) {
57: $paramDef .= ' = ' . var_export($param->getDefaultValue(), true);
58: } elseif ($param->isOptional()) {
59: $paramDef .= ' = null';
60: }
61:
62: $methodParams[] = $paramDef;
63: }
64: return '(' . implode(', ', $methodParams) . ')';
65: }
66:
67: protected function appendToClass($class, $code)
68: {
69: $lastBrace = strrpos($class, "}");
70: $class = substr($class, 0, $lastBrace) . $code . "\n }\n";
71: return $class;
72: }
73:
74: private function renderMethodBody($method, $config)
75: {
76: $invoke = $method->isStatic() ? 'static::_mockery_handleStaticMethodCall' : '$this->_mockery_handleMethodCall';
77: $body = <<<BODY
78: {
79: \$argc = func_num_args();
80: \$argv = func_get_args();
81:
82: BODY;
83:
84:
85:
86:
87: $class = $method->getDeclaringClass();
88: $class_name = strtolower($class->getName());
89: $overrides = $config->getParameterOverrides();
90: if (isset($overrides[$class_name][$method->getName()])) {
91: $params = array_values($overrides[$class_name][$method->getName()]);
92: $paramCount = count($params);
93: for ($i = 0; $i < $paramCount; ++$i) {
94: $param = $params[$i];
95: if (strpos($param, '&') !== false) {
96: $body .= <<<BODY
97: if (\$argc > $i) {
98: \$argv[$i] = {$param};
99: }
100:
101: BODY;
102: }
103: }
104: } else {
105: $params = array_values($method->getParameters());
106: $paramCount = count($params);
107: for ($i = 0; $i < $paramCount; ++$i) {
108: $param = $params[$i];
109: if (!$param->isPassedByReference()) {
110: continue;
111: }
112: $body .= <<<BODY
113: if (\$argc > $i) {
114: \$argv[$i] =& \${$param->getName()};
115: }
116:
117: BODY;
118: }
119: }
120: $body .= <<<BODY
121: \$ret = {$invoke}(__FUNCTION__, \$argv);
122: return \$ret;
123: }
124: BODY;
125: return $body;
126: }
127: }
128: