public function leaveNode(PhpParser\Node $node)
 {
     if (!$node instanceof FuncCall) {
         return;
     }
     if (!$node->name instanceof Name) {
         return;
     }
     if ($node->name->isUnqualified() && !CIPHPUnitTestFunctionPatcher::isBlacklisted((string) $node->name)) {
         $replacement = new FullyQualified(array());
         $replacement->set('CIPHPUnitTestFunctionPatcherProxy::' . (string) $node->name);
         $pos = $node->getAttribute('startTokenPos');
         CIPHPUnitTestFunctionPatcher::$replacement[$pos] = '\\CIPHPUnitTestFunctionPatcherProxy::' . (string) $node->name;
         $node->name = $replacement;
     }
 }
Пример #2
0
 public function leaveNode(PhpParser\Node $node)
 {
     if ($node->hasAttribute("_insertGetMMethodAfterMe") || $node->hasAttribute("_insertSetMMethodAfterMe")) {
         $statements = [$node];
         if ($node->hasAttribute("_insertGetMMethodAfterMe")) {
             $subStatements = CMap::make();
             $len = CArray::length($this->m_propsToWrap);
             for ($i = 0; $i < $len; $i++) {
                 $propName = $this->m_propsToWrap[$i];
                 $subCondition = new PhpParser\Node\Expr\BooleanNot(new PhpParser\Node\Expr\FuncCall(new PhpParser\Node\Name(self::$ms_isFwCallFuncName)));
                 $return0 = new PhpParser\Node\Stmt\Return_(new PhpParser\Node\Expr\PropertyFetch(new PhpParser\Node\Expr\Variable("this"), $propName));
                 $return1 = new PhpParser\Node\Stmt\Return_(new PhpParser\Node\Expr\FuncCall(new PhpParser\Node\Name(self::$ms_toOopFuncName), [new PhpParser\Node\Expr\PropertyFetch(new PhpParser\Node\Expr\Variable("this"), $propName)]));
                 $else = new PhpParser\Node\Stmt\Else_([$return1]);
                 $subIf = new PhpParser\Node\Stmt\If_($subCondition, ["stmts" => [$return0], "else" => $else]);
                 $condition = new PhpParser\Node\Expr\BinaryOp\Identical(new PhpParser\Node\Expr\Variable("name"), new PhpParser\Node\Scalar\String($propName));
                 $if = new PhpParser\Node\Stmt\If_($condition, ["stmts" => [$subIf]]);
                 CMap::insertValue($subStatements, $if);
             }
             $method = new PhpParser\Node\Stmt\ClassMethod("__get", ["type" => PhpParser\Node\Stmt\Class_::MODIFIER_PUBLIC, "byRef" => true, "params" => [new PhpParser\Node\Param("name")], "stmts" => $subStatements]);
             CMap::insertValue($statements, $method);
         }
         if ($node->hasAttribute("_insertSetMMethodAfterMe")) {
             $subStatements = CMap::make();
             $len = CArray::length($this->m_propsToWrap);
             for ($i = 0; $i < $len; $i++) {
                 $propName = $this->m_propsToWrap[$i];
                 $subCondition = new PhpParser\Node\Expr\BooleanNot(new PhpParser\Node\Expr\FuncCall(new PhpParser\Node\Name(self::$ms_isFwCallFuncName)));
                 $assignment0 = new PhpParser\Node\Expr\Assign(new PhpParser\Node\Expr\PropertyFetch(new PhpParser\Node\Expr\Variable("this"), $propName), new PhpParser\Node\Expr\Variable("value"));
                 $assignment1 = new PhpParser\Node\Expr\Assign(new PhpParser\Node\Expr\PropertyFetch(new PhpParser\Node\Expr\Variable("this"), $propName), new PhpParser\Node\Expr\FuncCall(new PhpParser\Node\Name(self::$ms_fromOopFuncName), [new PhpParser\Node\Expr\Variable("value")]));
                 $else = new PhpParser\Node\Stmt\Else_([$assignment1]);
                 $subIf = new PhpParser\Node\Stmt\If_($subCondition, ["stmts" => [$assignment0], "else" => $else]);
                 $condition = new PhpParser\Node\Expr\BinaryOp\Identical(new PhpParser\Node\Expr\Variable("name"), new PhpParser\Node\Scalar\String($propName));
                 $if = new PhpParser\Node\Stmt\If_($condition, ["stmts" => [$subIf]]);
                 CMap::insertValue($subStatements, $if);
             }
             $method = new PhpParser\Node\Stmt\ClassMethod("__set", ["type" => PhpParser\Node\Stmt\Class_::MODIFIER_PUBLIC, "params" => [new PhpParser\Node\Param("name"), new PhpParser\Node\Param("value")], "stmts" => $subStatements]);
             CMap::insertValue($statements, $method);
         }
         return $statements;
     }
 }
Пример #3
0
 public function leaveNode(PhpParser\Node $node)
 {
     if ($node instanceof PhpParser\Node\Stmt\Property && $node->type === 2) {
         // Move property initialization in constructor if default value
         foreach ($node->props as $prop) {
             if (is_null($prop->default)) {
                 continue;
             }
             $this->constructorInitializedProperties[] = $prop;
         }
         return false;
     } else {
         if ($node instanceof PhpParser\Node\Expr\StaticCall && $node->class->parts[0] === "parent") {
             if ($this->isInConstructor && $node->name === "__construct") {
                 // Cas 1: méthode courante === constructor => super()
                 return array(new PhpParser\Node\Expr\FuncCall(new PhpParser\Node\Name('super'), $node->args));
             } else {
                 // Cas 2: méthode courante !== constructor => super.
                 // On transforme l'appel statique en appel d'instance
                 return new PhpParser\Node\Expr\MethodCall(new PhpParser\Node\Expr\Variable(new PhpParser\Node\Name('super')), $node->name, $node->args);
             }
         } else {
             if ($node instanceof PhpParser\Node\Stmt\ClassMethod && $node->name === '__construct') {
                 $this->isInConstructor = false;
             } else {
                 if ($node instanceof PhpParser\Node\Stmt\ClassMethod && $node->isAbstract()) {
                     // exclude abstract methods;
                     return false;
                 } else {
                     if ($node instanceof PhpParser\Node\Stmt\Class_) {
                         if (!empty($this->constructorInitializedProperties)) {
                             // il faut déterminer si la classe définit un constructeur
                             $constructor = null;
                             foreach ($node->stmts as $classstmt) {
                                 if ($classstmt instanceof PhpParser\Node\Stmt\ClassMethod && $classstmt->name === '__construct') {
                                     $constructor =& $classstmt;
                                     break;
                                 }
                             }
                             if (is_null($constructor)) {
                                 // si aucun constructeur n'est défini, il faut l'ajouter
                                 if (!is_null($node->extends)) {
                                     // la classe dispose d'un parent
                                     // le constructeur doit appeler super() pour transférer l'initialisation au parent
                                     throw new \Exception('TODO:' . __LINE__);
                                 }
                             }
                             // on ajoute l'initialisation des propriétés d'instance au constructeur
                             foreach (array_reverse($this->constructorInitializedProperties) as $prop) {
                                 # reverse because of unshift
                                 array_unshift($constructor->stmts, new PhpParser\Node\Expr\Assign(new PhpParser\Node\Expr\PropertyFetch(new PhpParser\Node\Expr\Variable(new PhpParser\Node\Name('this')), $prop->name), $prop->default));
                             }
                             $this->constructorInitializedProperties = array();
                         }
                     } else {
                         if ($node instanceof PhpParser\Node\Expr\FuncCall) {
                             if ($node->name->__toString() === 'is_null') {
                                 return new PhpParser\Node\Expr\BinaryOp\Identical($node->args[0]->value, new PhpParser\Node\Expr\ConstFetch(new PhpParser\Node\Name('null')));
                             }
                         }
                     }
                 }
             }
         }
     }
     if ($node instanceof PhpParser\Node\Expr\Instanceof_) {
         return new PhpParser\Node\Expr\BinaryOp\BooleanOr($node, new PhpParser\Node\Expr\BinaryOp\BooleanAnd(new PhpParser\Node\Expr\BinaryOp\BooleanAnd(new PhpParser\Node\Expr\PropertyFetch($node->expr, new PhpParser\Node\Name('constructor')), new PhpParser\Node\Expr\PropertyFetch(new PhpParser\Node\Expr\PropertyFetch($node->expr, new PhpParser\Node\Name('constructor')), new PhpParser\Node\Name('_implements'))), new PhpParser\Node\Expr\MethodCall(new PhpParser\Node\Expr\PropertyFetch($node->expr, new PhpParser\Node\Name('constructor')), '_implements', array($node->class))));
     }
     if ($node instanceof PhpParser\Node\Stmt\Interface_ || $node instanceof PhpParser\Node\Stmt\Class_) {
         /*
         class Edible {
             static _implements(what) {
                 const ifaces = [Burnable];
                 return !!(
                     ifaces.indexOf(what) > -1 ||
                     ifaces.map(v => v._implements(what)).reduce((a, v) => a || v, false) ||
                     (super._implements && super._implements(what))
                 );
             }
         }
         */
         $ifaces = array();
         if ($node instanceof PhpParser\Node\Stmt\Interface_ && $node->extends) {
             $ifaces = $node->extends;
         } else {
             if ($node instanceof PhpParser\Node\Stmt\Class_ && $node->implements) {
                 $ifaces = $node->implements;
             }
         }
         $implementsmethod = new PhpParser\Node\Stmt\ClassMethod(new PhpParser\Node\Name('_implements'), array('type' => PhpParser\Node\Stmt\Class_::MODIFIER_STATIC, 'params' => array(new PhpParser\Node\Param(new PhpParser\Node\Name('what'))), 'stmts' => array(new PhpParser\Node\Expr\Assign(new PhpParser\Node\Expr\Variable(new PhpParser\Node\Name('ifaces')), new PhpParser\Node\Expr\Array_(array_map(function ($iface) {
             return new PhpParser\Node\Expr\ArrayItem(new PhpParser\Node\Expr\Variable($iface));
         }, $ifaces))), new PhpParser\Node\Stmt\Return_(new PhpParser\Node\Expr\BooleanNot(new PhpParser\Node\Expr\BooleanNot(new PhpParser\Node\Expr\BinaryOp\BooleanOr(new PhpParser\Node\Expr\BinaryOp\Greater(new PhpParser\Node\Expr\MethodCall(new PhpParser\Node\Expr\Variable(new PhpParser\Node\Name('ifaces')), 'indexOf', array(new PhpParser\Node\Arg(new PhpParser\Node\Expr\Variable(new PhpParser\Node\Name('what'))))), new PhpParser\Node\Scalar\LNumber(-1)), new PhpParser\Node\Expr\BinaryOp\BooleanOr(new PhpParser\Node\Expr\MethodCall(new PhpParser\Node\Expr\MethodCall(new PhpParser\Node\Expr\Variable(new PhpParser\Node\Name('ifaces')), 'map', array(new PhpParser\Node\Arg(new PhpParser\Node\Expr\Closure(array('params' => array(new PhpParser\Node\Param(new PhpParser\Node\Name('v'))), 'stmts' => array(new PhpParser\Node\Stmt\Return_(new PhpParser\Node\Expr\MethodCall(new PhpParser\Node\Expr\Variable(new PhpParser\Node\Name('v')), '_implements', array(new PhpParser\Node\Arg(new PhpParser\Node\Expr\Variable(new PhpParser\Node\Name('what')))))))))))), 'reduce', array(new PhpParser\Node\Arg(new PhpParser\Node\Expr\Closure(array('params' => array(new PhpParser\Node\Param(new PhpParser\Node\Name('a')), new PhpParser\Node\Param(new PhpParser\Node\Name('v'))), 'stmts' => array(new PhpParser\Node\Stmt\Return_(new PhpParser\Node\Expr\BinaryOp\BooleanOr(new PhpParser\Node\Expr\Variable(new PhpParser\Node\Name('a')), new PhpParser\Node\Expr\Variable(new PhpParser\Node\Name('v')))))))), new PhpParser\Node\Arg(new PhpParser\Node\Expr\ConstFetch(new PhpParser\Node\Name('false'))))), new PhpParser\Node\Expr\BinaryOp\BooleanAnd(new PhpParser\Node\Expr\PropertyFetch(new PhpParser\Node\Expr\Variable(new PhpParser\Node\Name('super')), new PhpParser\Node\Name('_implements')), new PhpParser\Node\Expr\MethodCall(new PhpParser\Node\Expr\Variable(new PhpParser\Node\Name('super')), '_implements', array(new PhpParser\Node\Arg(new PhpParser\Node\Expr\Variable(new PhpParser\Node\Name('what'))))))))))))));
         if ($node instanceof PhpParser\Node\Stmt\Interface_) {
             return new PhpParser\Node\Stmt\Class_(new PhpParser\Node\Name($node->name), array('stmts' => array($implementsmethod)));
         } else {
             if ($node instanceof PhpParser\Node\Stmt\Class_) {
                 $node->stmts = array_merge(array($implementsmethod), $node->stmts);
                 $node->implements = null;
                 return $node;
             }
         }
     }
 }
Пример #4
0
 /**
  * Set some attributes to their appropriate values
  *
  * This includes the 'path', 'line(s)', and 'documentation' attributes.
  * @return string
  */
 public function set_attributes()
 {
     $this->attributes['path'] = $this->node->getAttribute('scope');
     $this->set_lines_attribute();
     $this->set_doc_attribute();
 }