/**
  * @param Stmt $classStmt
  * @param $namespace
  * @param $source
  * @return Element\ClassModel
  */
 public function parse(Stmt $classStmt, $namespace, $source)
 {
     $attrs = $classStmt->getAttributes();
     $class = $this->classFactory->create($classStmt->name);
     $class->setNamespace($namespace);
     $class->setSource($source, $attrs['startLine'], 0);
     // annotation
     $this->commentsParser->parse($attrs, $class);
     // property
     $properties = array_filter($classStmt->stmts, function ($stmt) {
         return $this->propertyParser->match($stmt);
     });
     array_map(function (Stmt $propertiesStmt) use($class) {
         $prop = $this->propertyParser->parse($propertiesStmt, $class);
         $this->propertyAnnotationParser->parse($propertiesStmt, $prop, $class);
         $varAnnotations = $prop->annotations->withName('var');
         if (!$varAnnotations->isEmpty()) {
             /** @var Element\Annotation $var */
             $var = $varAnnotations->first();
             $prop->setAccessModifier($var->parameters);
         }
     }, $properties);
     // method
     $methods = array_filter($classStmt->stmts, function ($stmt) {
         return $this->methodParser->match($stmt);
     });
     array_map(function ($methodStmt) use($class) {
         $this->methodParser->parse($methodStmt, $class);
     }, $methods);
     return $class;
 }
Example #2
0
 /**
  * @param Stmt $stmt
  * @param Context $context
  * @return bool
  */
 public function pass(Stmt $stmt, Context $context)
 {
     if ($stmt->getDocComment() === null) {
         $context->notice('missing_docblock', 'Missing Docblock', $stmt);
         return true;
     }
     return false;
 }
Example #3
0
 /**
  * @inheritdoc
  * @param Stmt\ClassMethod $function
  */
 public function createFunction(Stmt $function)
 {
     assert($function instanceof Stmt\ClassMethod, 'Only accepts class methods');
     if ($function->isStatic()) {
         return $this->traitCreateFunction($function);
     } else {
         return $this->instanceEnvironment->createFunction($function);
     }
 }
Example #4
0
 /**
  * @param \PhpParser\Node\Stmt $context
  * @return int
  */
 public static function getForContext(Stmt $context)
 {
     if ($context->isPublic()) {
         return Class_::MODIFIER_PUBLIC;
     } elseif ($context->isProtected()) {
         return Class_::MODIFIER_PROTECTED;
     } else {
         return Class_::MODIFIER_PRIVATE;
     }
 }
Example #5
0
 /**
  * @param Stmt\ClassMethod|Stmt\Function_ $stmt
  * @param Context $context
  * @return bool
  */
 private function inspectParams(Stmt $stmt, Context $context)
 {
     /** @var \PhpParser\Node\Param $param */
     foreach ($stmt->getParams() as $param) {
         if ($param->name === 'this') {
             $context->notice('unexpected_use.this', sprintf('Method/Function %s can not have a parameter named "this".', $stmt->name), $param);
             return true;
         }
     }
     return false;
 }
 /**
  * @param Stmt $func
  * @param Context $context
  * @return bool
  */
 public function pass(Stmt $func, Context $context)
 {
     $prevIsOptional = false;
     foreach ($func->getParams() as $param) {
         if ($prevIsOptional && $param->default === null) {
             $context->notice('optional-param-before-required', 'Optional parameter before required one is always required.', $func);
             return true;
         }
         $prevIsOptional = $param->default !== null;
     }
     return false;
 }
Example #7
0
 /**
  * @param Stmt $stmt
  * @param Context $context
  * @return bool
  */
 public function pass(Stmt $stmt, Context $context)
 {
     // if it is private, protected or public return false
     if ($stmt->isPrivate() || $stmt->isProtected() || ($stmt->type & Class_::MODIFIER_PUBLIC) !== 0) {
         return false;
     }
     if ($stmt instanceof Property) {
         $context->notice('missing_visibility', 'Class property was defined with the deprecated var keyword. Use a visibility modifier instead.', $stmt);
     } elseif ($stmt instanceof ClassMethod) {
         $context->notice('missing_visibility', 'Class method was defined without a visibility modifier.', $stmt);
     }
     return true;
 }
Example #8
0
 /**
  * Constructs a try catch node.
  *
  * @param Node[]        $stmts      Statements
  * @param Catch_[]      $catches    Catches
  * @param null|Finally_ $finally    Optionaly finally node
  * @param array|null    $attributes Additional attributes
  */
 public function __construct(array $stmts, array $catches, Finally_ $finally = null, array $attributes = array())
 {
     parent::__construct($attributes);
     $this->stmts = $stmts;
     $this->catches = $catches;
     $this->finally = $finally;
 }
Example #9
0
 /**
  * Constructs a try catch node.
  *
  * @param Node[]     $stmts        Statements
  * @param Catch_[]   $catches      Catches
  * @param Node[]     $finallyStmts Finally statements (null means no finally clause)
  * @param array|null $attributes   Additional attributes
  */
 public function __construct(array $stmts, array $catches, array $finallyStmts = null, array $attributes = array())
 {
     if (empty($catches) && null === $finallyStmts) {
         throw new Error('Cannot use try without catch or finally');
     }
     parent::__construct(array('stmts' => $stmts, 'catches' => $catches, 'finallyStmts' => $finallyStmts), $attributes);
 }
Example #10
0
 /**
  * Constructs a group use node.
  *
  * @param Name $prefix
  *        	Prefix for uses
  * @param UseUse[] $uses
  *        	Uses
  * @param int $type
  *        	Type of group use
  * @param array $attributes
  *        	Additional attributes
  */
 public function __construct(Name $prefix, array $uses, $type = Use_::TYPE_NORMAL, array $attributes = array())
 {
     parent::__construct($attributes);
     $this->type = $type;
     $this->prefix = $prefix;
     $this->uses = $uses;
 }
Example #11
0
 /**
  * Constructs a catch node.
  *
  * @param Node\Name $type
  *        	Class of exception
  * @param string $var
  *        	Variable for exception
  * @param Node[] $stmts
  *        	Statements
  * @param array $attributes
  *        	Additional attributes
  */
 public function __construct(Node\Name $type, $var, array $stmts = array(), array $attributes = array())
 {
     parent::__construct($attributes);
     $this->type = $type;
     $this->var = $var;
     $this->stmts = $stmts;
 }
Example #12
0
 /**
  * Constructs a class property list node.
  *
  * @param int                $flags      Modifiers
  * @param PropertyProperty[] $props      Properties
  * @param array              $attributes Additional attributes
  */
 public function __construct($flags, array $props, array $attributes = array())
 {
     parent::__construct($attributes);
     $this->flags = $flags;
     $this->type = $flags;
     $this->props = $props;
 }
Example #13
0
 /**
  * Constructs a catch node.
  *
  * @param Node\Name[] $types      Types of exceptions to catch
  * @param string      $var        Variable for exception
  * @param Node[]      $stmts      Statements
  * @param array       $attributes Additional attributes
  */
 public function __construct(array $types, $var, array $stmts = array(), array $attributes = array())
 {
     parent::__construct($attributes);
     $this->types = $types;
     $this->var = $var;
     $this->stmts = $stmts;
 }
Example #14
0
 /**
  * Constructs a for loop node.
  *
  * @param array $subNodes   Array of the following optional subnodes:
  *                          'init'  => array(): Init expressions
  *                          'cond'  => array(): Loop conditions
  *                          'loop'  => array(): Loop expressions
  *                          'stmts' => array(): Statements
  * @param array $attributes Additional attributes
  */
 public function __construct(array $subNodes = array(), array $attributes = array())
 {
     parent::__construct(null, $attributes);
     $this->init = isset($subNodes['init']) ? $subNodes['init'] : array();
     $this->cond = isset($subNodes['cond']) ? $subNodes['cond'] : array();
     $this->loop = isset($subNodes['loop']) ? $subNodes['loop'] : array();
     $this->stmts = isset($subNodes['stmts']) ? $subNodes['stmts'] : array();
 }
Example #15
0
 /**
  * Constructs an if node.
  *
  * @param Node\Expr $cond       Condition
  * @param array     $subNodes   Array of the following optional subnodes:
  *                              'stmts'   => array(): Statements
  *                              'elseifs' => array(): Elseif clauses
  *                              'else'    => null   : Else clause
  * @param array     $attributes Additional attributes
  */
 public function __construct(Node\Expr $cond, array $subNodes = array(), array $attributes = array())
 {
     parent::__construct($attributes);
     $this->cond = $cond;
     $this->stmts = isset($subNodes['stmts']) ? $subNodes['stmts'] : array();
     $this->elseifs = isset($subNodes['elseifs']) ? $subNodes['elseifs'] : array();
     $this->else = isset($subNodes['else']) ? $subNodes['else'] : null;
 }
Example #16
0
 /**
  * @param Stmt $stmt
  * @param Context $context
  * @return bool
  */
 public function pass(Stmt $stmt, Context $context)
 {
     if ($stmt instanceof Stmt\ClassMethod && $stmt->isAbstract()) {
         // abstract classes are ok
         return false;
     }
     if ($stmt instanceof Stmt\Switch_) {
         $counting = $stmt->cases;
     } else {
         $counting = $stmt->stmts;
     }
     if (count($counting) === 0) {
         $context->notice('missing_body', 'Missing Body', $stmt);
         return true;
     }
     return false;
 }
Example #17
0
 /**
  * Constructs a function node.
  *
  * @param string $name       Name
  * @param array  $subNodes   Array of the following optional subnodes:
  *                           'byRef'      => false  : Whether to return by reference
  *                           'params'     => array(): Parameters
  *                           'returnType' => null   : Return type
  *                           'stmts'      => array(): Statements
  * @param array  $attributes Additional attributes
  */
 public function __construct($name, array $subNodes = array(), array $attributes = array()) {
     parent::__construct($attributes);
     $this->byRef = isset($subNodes['byRef']) ? $subNodes['byRef'] : false;
     $this->name = $name;
     $this->params = isset($subNodes['params']) ? $subNodes['params'] : array();
     $this->returnType = isset($subNodes['returnType']) ? $subNodes['returnType'] : null;
     $this->stmts = isset($subNodes['stmts']) ? $subNodes['stmts'] : array();
 }
Example #18
0
 /**
  * Constructs a foreach node.
  *
  * @param Node\Expr $expr
  *        	Expression to iterate
  * @param Node\Expr $valueVar
  *        	Variable to assign value to
  * @param array $subNodes
  *        	Array of the following optional subnodes:
  *        	'keyVar' => null : Variable to assign key to
  *        	'byRef' => false : Whether to assign value by reference
  *        	'stmts' => array(): Statements
  * @param array $attributes
  *        	Additional attributes
  */
 public function __construct(Node\Expr $expr, Node\Expr $valueVar, array $subNodes = array(), array $attributes = array())
 {
     parent::__construct(null, $attributes);
     $this->expr = $expr;
     $this->keyVar = isset($subNodes['keyVar']) ? $subNodes['keyVar'] : null;
     $this->byRef = isset($subNodes['byRef']) ? $subNodes['byRef'] : false;
     $this->valueVar = $valueVar;
     $this->stmts = isset($subNodes['stmts']) ? $subNodes['stmts'] : array();
 }
Example #19
0
 /**
  * Constructs an alias (use) node.
  *
  * @param Node\Name   $name       Namespace/Class to alias
  * @param null|string $alias      Alias
  * @param int         $type       Type of the use element (for mixed group use declarations only)
  * @param array       $attributes Additional attributes
  */
 public function __construct(Node\Name $name, $alias = null, $type = Use_::TYPE_UNKNOWN, array $attributes = array())
 {
     if (null === $alias) {
         $alias = $name->getLast();
     }
     parent::__construct($attributes);
     $this->type = $type;
     $this->name = $name;
     $this->alias = $alias;
 }
Example #20
0
 /**
  * Constructs an alias (use) node.
  *
  * @param Node\Name   $name       Namespace/Class to alias
  * @param null|string $alias      Alias
  * @param array       $attributes Additional attributes
  */
 public function __construct(Node\Name $name, $alias = null, array $attributes = array())
 {
     if (null === $alias) {
         $alias = $name->getLast();
     }
     if ('self' == $alias || 'parent' == $alias) {
         throw new Error(sprintf('Cannot use %s as %s because \'%2$s\' is a special class name', $name, $alias));
     }
     parent::__construct(array('name' => $name, 'alias' => $alias), $attributes);
 }
Example #21
0
 /**
  * Constructs a try catch node.
  *
  * @param Node[] $stmts
  *        	Statements
  * @param Catch_[] $catches
  *        	Catches
  * @param null|Node[] $finallyStmts
  *        	Finally statements (null means no finally clause)
  * @param array|null $attributes
  *        	Additional attributes
  */
 public function __construct(array $stmts, array $catches, array $finallyStmts = null, array $attributes = array())
 {
     if (empty($catches) && null === $finallyStmts) {
         throw new Error('Cannot use try without catch or finally');
     }
     parent::__construct($attributes);
     $this->stmts = $stmts;
     $this->catches = $catches;
     $this->finallyStmts = $finallyStmts;
 }
Example #22
0
 /**
  * Constructs a class node.
  *
  * @param string $name       Name
  * @param array  $subNodes   Array of the following optional subnodes:
  *                           'extends' => array(): Name of extended interfaces
  *                           'stmts'   => array(): Statements
  * @param array  $attributes Additional attributes
  */
 public function __construct($name, array $subNodes = array(), array $attributes = array())
 {
     parent::__construct(array('name' => $name, 'extends' => isset($subNodes['extends']) ? $subNodes['extends'] : array(), 'stmts' => isset($subNodes['stmts']) ? $subNodes['stmts'] : array()), $attributes);
     if (isset(self::$specialNames[(string) $this->name])) {
         throw new Error(sprintf('Cannot use \'%s\' as class name as it is reserved', $this->name));
     }
     foreach ($this->extends as $interface) {
         if (isset(self::$specialNames[(string) $interface])) {
             throw new Error(sprintf('Cannot use \'%s\' as interface name as it is reserved', $interface));
         }
     }
 }
Example #23
0
 /**
  * Constructs an alias (use) node.
  *
  * @param Node\Name $name Namespace/Class to alias
  * @param null|string $alias Alias
  * @param array $attributes Additional attributes
  */
 public function __construct(Node\Name $name, $alias = null, array $attributes = array())
 {
     if (null === $alias) {
         $alias = $name->getLast();
     }
     if ('self' == strtolower($alias) || 'parent' == strtolower($alias)) {
         throw new Error(sprintf('Cannot use %s as %s because \'%2$s\' is a special class name', $name, $alias));
     }
     parent::__construct(null, $attributes);
     $this->name = $name;
     $this->alias = $alias;
 }
Example #24
0
 /**
  * Constructs a class property list node.
  *
  * @param int $type
  *        	Modifiers
  * @param PropertyProperty[] $props
  *        	Properties
  * @param array $attributes
  *        	Additional attributes
  */
 public function __construct($type, array $props, array $attributes = array())
 {
     if ($type & Class_::MODIFIER_ABSTRACT) {
         throw new Error('Properties cannot be declared abstract');
     }
     if ($type & Class_::MODIFIER_FINAL) {
         throw new Error('Properties cannot be declared final');
     }
     parent::__construct($attributes);
     $this->type = $type;
     $this->props = $props;
 }
 /**
  * Constructs a namespace node.
  *
  * @param null|Node\Name $name       Name
  * @param Node[]         $stmts      Statements
  * @param array          $attributes Additional attributes
  */
 public function __construct(Node\Name $name = null, $stmts = array(), array $attributes = array())
 {
     parent::__construct(array('name' => $name, 'stmts' => $stmts), $attributes);
     if (isset(self::$specialNames[(string) $this->name])) {
         throw new Error(sprintf('Cannot use \'%s\' as namespace name', $this->name));
     }
     if (null !== $this->stmts) {
         foreach ($this->stmts as $stmt) {
             if ($stmt instanceof self) {
                 throw new Error('Namespace declarations cannot be nested', $stmt->getLine());
             }
         }
     }
 }
Example #26
0
 /**
  * Constructs a class property list node.
  *
  * @param int                $type       Modifiers
  * @param PropertyProperty[] $props      Properties
  * @param array              $attributes Additional attributes
  */
 public function __construct($type, array $props, array $attributes = array())
 {
     if (0 === ($type & Class_::VISIBILITY_MODIFER_MASK)) {
         // If no visibility modifier given, PHP defaults to public
         $type |= Class_::MODIFIER_PUBLIC;
     }
     if ($type & Class_::MODIFIER_ABSTRACT) {
         throw new Error('Properties cannot be declared abstract');
     }
     if ($type & Class_::MODIFIER_FINAL) {
         throw new Error('Properties cannot be declared final');
     }
     parent::__construct(array('type' => $type, 'props' => $props), $attributes);
 }
Example #27
0
 /**
  * Constructs a class method node.
  *
  * @param string      $name       Name
  * @param array       $subNodes   Array of the following optional subnodes:
  *                                'type'   => MODIFIER_PUBLIC: Type
  *                                'byRef'  => false          : Whether to return by reference
  *                                'params' => array()        : Parameters
  *                                'stmts'  => array()        : Statements
  * @param array       $attributes Additional attributes
  */
 public function __construct($name, array $subNodes = array(), array $attributes = array())
 {
     parent::__construct(array('type' => isset($subNodes['type']) ? $subNodes['type'] : Class_::MODIFIER_PUBLIC, 'byRef' => isset($subNodes['byRef']) ? $subNodes['byRef'] : false, 'name' => $name, 'params' => isset($subNodes['params']) ? $subNodes['params'] : array(), 'stmts' => array_key_exists('stmts', $subNodes) ? $subNodes['stmts'] : array()), $attributes);
     if ($this->type & Class_::MODIFIER_STATIC) {
         switch (strtolower($this->name)) {
             case '__construct':
                 throw new Error(sprintf('Constructor %s() cannot be static', $this->name));
             case '__destruct':
                 throw new Error(sprintf('Destructor %s() cannot be static', $this->name));
             case '__clone':
                 throw new Error(sprintf('Clone method %s() cannot be static', $this->name));
         }
     }
 }
 /**
  * @param Stmt $propertyStmt
  * @param Element\Property $property
  * @param Element\ClassModel $class
  * @return Element\Annotation\AnnotationCollection
  */
 public function parse(Stmt $propertyStmt, Element\Property $property, Element\ClassModel $class)
 {
     // annotation
     $attrs = $propertyStmt->getAttributes();
     $this->commentsParser->parse($attrs, $property);
     $vars = $property->annotations->withName('var');
     if ($vars->count()) {
         /** @var Element\Annotation $var */
         $var = $vars->first();
         if (!is_array($var->parameters)) {
             // classのuseにあるものだけにする(FQCN形式等は要検討)
             //  型が単純なクラス名ではなくて Element\Annotation のような形式になっている場合は、Element 部分が use にあればOK
             if ($searchAlias = strstr($var->parameters, '\\', true) === false) {
                 $searchAlias = $var->parameters;
             }
             $classReferences = $class->references->withAlias($searchAlias);
             if ($classReferences->count()) {
                 $ref = $this->referenceFactory->create($var->parameters, null);
                 $property->reference = $ref;
             }
         }
     }
     return $property->annotations;
 }
Example #29
0
 /**
  * Constructs a namespace node.
  *
  * @param null|Node\Name $name       Name
  * @param null|Node[]    $stmts      Statements
  * @param array          $attributes Additional attributes
  */
 public function __construct(Node\Name $name = null, $stmts = array(), array $attributes = array())
 {
     parent::__construct(null, $attributes);
     $this->name = $name;
     $this->stmts = $stmts;
     if (isset(self::$specialNames[strtolower($this->name)])) {
         throw new Error(sprintf('Cannot use \'%s\' as namespace name', $this->name), $this->name->getAttributes());
     }
     if (null !== $this->stmts) {
         foreach ($this->stmts as $stmt) {
             if ($stmt instanceof self) {
                 throw new Error('Namespace declarations cannot be nested', $stmt->getAttributes());
             }
         }
     }
 }
Example #30
0
 /**
  * Constructs a class method node.
  *
  * @param string      $name       Name
  * @param array       $subNodes   Array of the following optional subnodes:
  *                                'type'   => MODIFIER_PUBLIC: Type
  *                                'byRef'  => false          : Whether to return by reference
  *                                'params' => array()        : Parameters
  *                                'stmts'  => array()        : Statements
  * @param array       $attributes Additional attributes
  */
 public function __construct($name, array $subNodes = array(), array $attributes = array())
 {
     $type = isset($subNodes['type']) ? $subNodes['type'] : 0;
     if (0 === ($type & Class_::VISIBILITY_MODIFER_MASK)) {
         // If no visibility modifier given, PHP defaults to public
         $type |= Class_::MODIFIER_PUBLIC;
     }
     parent::__construct(array('type' => $type, 'byRef' => isset($subNodes['byRef']) ? $subNodes['byRef'] : false, 'name' => $name, 'params' => isset($subNodes['params']) ? $subNodes['params'] : array(), 'stmts' => array_key_exists('stmts', $subNodes) ? $subNodes['stmts'] : array()), $attributes);
     if ($this->type & Class_::MODIFIER_STATIC) {
         switch (strtolower($this->name)) {
             case '__construct':
                 throw new Error(sprintf('Constructor %s() cannot be static', $this->name));
             case '__destruct':
                 throw new Error(sprintf('Destructor %s() cannot be static', $this->name));
             case '__clone':
                 throw new Error(sprintf('Clone method %s() cannot be static', $this->name));
         }
     }
 }