public function replace() { $b = new Buffer('Teste'); $b->replace('e', 'a'); $this->assertSource('Tasta', $b); }
/** * Emit method parameters * * @param xp.compiler.emit.Buffer b * @param array<string, *>[] parameters * @param string delim * @return xp.compiler.TypeName[] the signature */ protected function emitParameters($b, array $parameters, $delim) { $signature = []; $b->append('('); $s = sizeof($parameters) - 1; $defer = []; $usesGenerics = false; $genericParams = ''; foreach ($parameters as $i => $param) { if (isset($param['assign'])) { if (null === ($field = $this->resolveType(new TypeName('self'))->getField($param['assign']))) { $this->error('F404', 'Method assignment parameter $this.' . $param['assign'] . ' references non-existant field'); $t = TypeName::$VAR; } else { $t = $field->type; } $ptr = $this->resolveType($t); $param['name'] = $param['assign']; $defer[] = '$this->' . $param['assign'] . '= $' . $param['assign'] . ';'; } else { if (!$param['type']) { $t = TypeName::$VAR; $ptr = new TypeReference($t); } else { if (!$usesGenerics && $this->scope[0]->declarations[0]->name->isPlaceHolder($param['type'])) { $usesGenerics = true; } $t = $param['type']; $ptr = $this->resolveType($t); if (!isset($param['check']) || !$param['check'] || isset($param['vararg'])) { // No runtime type checks } else { if ($t->isArray() || $t->isMap()) { $b->append('array '); } else { if ($t->isFunction()) { $b->append('callable '); } else { if ($t->isClass() && !$this->scope[0]->declarations[0]->name->isPlaceHolder($t)) { $b->append($this->literal($ptr))->append(' '); } else { if ('{' === $delim) { $defer[] = (new Buffer('', $b->line))->append('if (NULL !== $')->append($param['name'])->append(' && !is("' . $t->name . '", $')->append($param['name'])->append(')) throw new \\lang\\IllegalArgumentException("Argument ')->append($i + 1)->append(' passed to ".__METHOD__." must be of ')->append($t->name)->append(', ".' . $this->core . '::typeOf($')->append($param['name'])->append(')." given");'); } else { // No checks in interfaces } } } } } } } $signature[] = new Parameter($param['name'], new TypeName($ptr->name()), isset($param['default']) ? $param['default'] : null); $genericParams .= ', ' . $t->compoundName(); $this->metadata[0][1][$this->method[0]][DETAIL_ARGUMENTS][$i] = $ptr->name(); if (isset($param['vararg'])) { $genericParams .= '...'; if ($i > 0) { $defer[] = '$' . $param['name'] . '= array_slice(func_get_args(), ' . $i . ');'; } else { $defer[] = '$' . $param['name'] . '= func_get_args();'; } $this->scope[0]->setType(new VariableNode($param['name']), new TypeName($t->name . '[]')); break; } $b->append('$' . $param['name']); if (isset($param['default'])) { $b->append('= '); $resolveable = false; if ($param['default'] instanceof Resolveable) { try { $init = $param['default']->resolve(); $b->append(var_export($init, true)); $resolveable = true; } catch (\lang\IllegalStateException $e) { } } if (!$resolveable) { $b->append('NULL'); $init = new Buffer('', $b->line); $init->append('if (func_num_args() < ')->append($i + 1)->append(') { '); $init->append('$')->append($param['name'])->append('= '); $this->emitOne($init, $param['default']); $init->append('; }'); $defer[] = $init; } } $i < $s && !isset($parameters[$i + 1]['vararg']) && $b->append(','); $this->scope[0]->setType(new VariableNode($param['name']), $t); } $b->append(')'); $b->append($delim); foreach ($defer as $src) { $b->append($src); } if ($usesGenerics) { $this->metadata[0][1][$this->method[0]][DETAIL_ANNOTATIONS]['generic']['params'] = substr($genericParams, 2); } return $signature; }