Skip to content

Commit

Permalink
Extract two methods.
Browse files Browse the repository at this point in the history
  • Loading branch information
yunosh committed Mar 3, 2017
1 parent 30ca240 commit 1a1ab2f
Showing 1 changed file with 115 additions and 92 deletions.
207 changes: 115 additions & 92 deletions framework/Refactor/lib/Horde/Refactor/Rule/Php4Constructor.php
Expand Up @@ -75,105 +75,128 @@ public function run()
// First constructor is PHP5 style, nothing to refactor.
continue;
}

// Constructors need to be swapped.
$this->_tokens->seek($ctor5);
list($start, $end) = $this->_tokens->findFunctionTokens();
$leadingWS = false;
$this->_tokens->seek($start);
$this->_tokens->previous();
if (is_array($this->_tokens->current()) &&
$this->_tokens->current()[0] == T_WHITESPACE &&
$this->_tokens->current()[1][0] == "\n") {
$start--;
$leadingWS = true;
}
$function = $this->_tokens->slice($start, $end - $start + 1);
$this->_swapCtors($ctor5, $start, $ctor4, $extends);
} else {
// Create new BC constructors.
$this->_createPhp5Ctor($ctor4, $start, $extends);
}
}
}

// Do some juggling of whitespace to keep indentions and
// vertical whitespace correct.
$replacement = array();
if ($leadingWS) {
$function->rewind();
$ws1 = $ws2 = $function->current();
$ws1[1] = "\n";
$replacement = array($ws1);
/**
* Swaps the PHP 5 and PHP 4 constructors.
*
* @param int $ctor4 The start position of the PHP 4 constructor.
* @param int $start The start position of the PHP 4 constructor including
* phpdoc.
* @param int $ctor5 The start position of the PHP 5 constructor.
*/
protected function _swapCtors($ctor5, $start, $ctor4)
{
$this->_tokens->seek($ctor5);
list($start, $end) = $this->_tokens->findFunctionTokens();
$leadingWS = false;
$this->_tokens->seek($start);
$this->_tokens->previous();
if (is_array($this->_tokens->current()) &&
$this->_tokens->current()[0] == T_WHITESPACE &&
$this->_tokens->current()[1][0] == "\n") {
$start--;
$leadingWS = true;
}
$function = $this->_tokens->slice($start, $end - $start + 1);

$ws2[1] = substr($ws2[1], 1);
$newlines = strspn($ws2[1], "\n", 1);
$leading = $trailing = $ws2;
$leading[1] = substr($leading[1], $newlines);
$trailing[1] = substr($trailing[1], 0, $newlines);
$function->append($trailing);
$function[0] = $leading;
}
$this->_tokens = $this->_tokens->splice(
$start, $end - $start + 1, $replacement
);
$this->_tokens->seek($ctor4);
list($start, $end) = $this->_tokens->findFunctionTokens();
$this->_tokens->seek($start);
$this->_tokens->previous();
if ($this->_tokens->matchesWhitespace()) {
$start--;
}
$this->_tokens = $this->_tokens->splice(
$start, 0, $function
);
} else {
// Create new BC PHP 4 constructor.
$this->_tokens->seek($ctor4);
list($start, $end) = $this->_tokens->findFunctionTokens();
$this->_tokens->seek($start);
$this->_tokens->find('{');
$this->_tokens->skipWhitespace();
$function = $this->_tokens->slice(
$start, $this->_tokens->key() - $start
);
$function = $function->splice(0, 0, array("\n\n "));
$function->append('$this->__construct(');
// Do some juggling of whitespace to keep indentions and
// vertical whitespace correct.
$replacement = array();
if ($leadingWS) {
$function->rewind();
$ws1 = $ws2 = $function->current();
$ws1[1] = "\n";
$replacement = array($ws1);

// Transfer function parameters.
$this->_tokens->seek($ctor4);
$this->_tokens->skipWhitespace();
$this->_tokens->next();
$afterComma = false;
while ($this->_tokens->valid() &&
!$this->_tokens->matches(')')) {
$token = $this->_tokens->current();
if (is_array($token)) {
if ($token[0] == T_VARIABLE ||
$afterComma && $token[0] == T_WHITESPACE) {
$function->append($token);
$afterComma = false;
}
} elseif ($token == ',') {
$function->append($token);
$afterComma = true;
}
$this->_tokens->next();
}
$function->append(");\n }");
$this->_tokens = $this->_tokens->splice($end, 0, $function);
$ws2[1] = substr($ws2[1], 1);
$newlines = strspn($ws2[1], "\n", 1);
$leading = $trailing = $ws2;
$leading[1] = substr($leading[1], $newlines);
$trailing[1] = substr($trailing[1], 0, $newlines);
$function->append($trailing);
$function[0] = $leading;
}
$this->_tokens = $this->_tokens->splice(
$start, $end - $start + 1, $replacement
);
$this->_tokens->seek($ctor4);
list($start, $end) = $this->_tokens->findFunctionTokens();
$this->_tokens->seek($start);
$this->_tokens->previous();
if ($this->_tokens->matchesWhitespace()) {
$start--;
}
$this->_tokens = $this->_tokens->splice(
$start, 0, $function
);
}

// Rewrite original constructor to PHP 5.
$this->_tokens->seek($ctor4);
$this->_tokens[$this->_tokens->key()] = '__construct';
while ($extends &&
$this->_tokens->valid() &&
$this->_tokens->key() < $end) {
$sequence = array(
array(T_STRING, 'parent'),
array(T_DOUBLE_COLON),
array(T_STRING, $extends),
);
if ($this->_tokens->matchesAll($sequence)) {
$this->_tokens[$this->_tokens->key() + 2] = '__construct';
break;
}
$this->_tokens->next();
/**
* Creates new backward and forward compatible constructors.
*
* @param int $ctor4 The start position of the PHP 4 constructor.
* @param strign $extends The extended class if any.
*/
protected function _createPhp5Ctor($ctor4, $extends)
{
$this->_tokens->seek($ctor4);
list($start, $end) = $this->_tokens->findFunctionTokens();
$this->_tokens->seek($start);
$this->_tokens->find('{');
$this->_tokens->skipWhitespace();
$function = $this->_tokens->slice(
$start, $this->_tokens->key() - $start
);
$function = $function->splice(0, 0, array("\n\n "));
$function->append('$this->__construct(');

// Transfer function parameters.
$this->_tokens->seek($ctor4);
$this->_tokens->skipWhitespace();
$this->_tokens->next();
$afterComma = false;
while ($this->_tokens->valid() &&
!$this->_tokens->matches(')')) {
$token = $this->_tokens->current();
if (is_array($token)) {
if ($token[0] == T_VARIABLE ||
$afterComma && $token[0] == T_WHITESPACE) {
$function->append($token);
$afterComma = false;
}
} elseif ($token == ',') {
$function->append($token);
$afterComma = true;
}
$this->_tokens->next();
}
$function->append(");\n }");
$this->_tokens = $this->_tokens->splice($end, 0, $function);

// Rewrite original constructor to PHP 5.
$this->_tokens->seek($ctor4);
$this->_tokens[$this->_tokens->key()] = '__construct';
while ($extends &&
$this->_tokens->valid() &&
$this->_tokens->key() < $end) {
$sequence = array(
array(T_STRING, 'parent'),
array(T_DOUBLE_COLON),
array(T_STRING, $extends),
);
if ($this->_tokens->matchesAll($sequence)) {
$this->_tokens[$this->_tokens->key() + 2] = '__construct';
break;
}
$this->_tokens->next();
}
}
}

0 comments on commit 1a1ab2f

Please sign in to comment.