fromNode() public static method

See also: Phan\Deprecated\Pass1::node_param Formerly `function node_param`
public static fromNode ( Context $context, CodeBase $code_base, ast\Node $node ) : Parameter
$context Phan\Language\Context
$code_base Phan\CodeBase
$node ast\Node
return Parameter A parameter built from a node
Exemplo n.º 1
0
 /**
  * @return Parameter[]
  * A list of parameters from an AST node.
  *
  * @see \Phan\Deprecated\Pass1::node_paramlist
  * Formerly `function node_paramlist`
  */
 public static function listFromNode(Context $context, CodeBase $code_base, Node $node) : array
 {
     assert($node instanceof Node, "node was not an \\ast\\Node");
     $parameter_list = [];
     $is_optional_seen = false;
     foreach ($node->children ?? [] as $i => $child_node) {
         $parameter = Parameter::fromNode($context, $code_base, $child_node);
         if (!$parameter->isOptional() && $is_optional_seen) {
             Issue::maybeEmit($code_base, $context, Issue::ParamReqAfterOpt, $node->lineno ?? 0);
         } elseif ($parameter->isOptional() && !$is_optional_seen && $parameter->getVariadicElementUnionType()->isEmpty()) {
             $is_optional_seen = true;
         }
         $parameter_list[] = $parameter;
     }
     return $parameter_list;
 }
Exemplo n.º 2
0
 /**
  * @return Parameter[]
  * A list of parameters from an AST node.
  *
  * @see \Phan\Deprecated\Pass1::node_paramlist
  * Formerly `function node_paramlist`
  */
 public static function listFromNode(Context $context, CodeBase $code_base, Node $node) : array
 {
     assert($node instanceof Node, "node was not an \\ast\\Node");
     $parameter_list = [];
     $is_optional_seen = false;
     foreach ($node->children ?? [] as $i => $child_node) {
         $parameter = Parameter::fromNode($context, $code_base, $child_node);
         if (!$parameter->isOptional() && $is_optional_seen) {
             Log::err(Log::EPARAM, "required arg follows optional", $context->getFile(), $node->lineno ?? 0);
         } else {
             if ($parameter->isOptional() && !$is_optional_seen && $parameter->getUnionType()->isEmpty()) {
                 $is_optional_seen = true;
             }
         }
         $parameter_list[] = $parameter;
     }
     return $parameter_list;
 }
Exemplo n.º 3
0
 /**
  * Visit a node with kind `\ast\AST_CLOSURE`
  *
  * @param Node $node
  * A node to parse
  *
  * @return Context
  * A new or an unchanged context resulting from
  * parsing the node
  */
 public function visitClosure(Decl $node) : Context
 {
     $closure_fqsen = FullyQualifiedFunctionName::fromClosureInContext($this->context->withLineNumberStart($node->lineno ?? 0));
     // If we have a 'this' variable in our current scope,
     // pass it down into the closure
     $context = $this->context->withScope(new Scope());
     if ($this->context->getScope()->hasVariableWithName('this')) {
         $context->addScopeVariable($this->context->getScope()->getVariableWithName('this'));
     }
     $method = Method::fromNode($context, $this->code_base, $node);
     // Override the FQSEN with the found alternate ID
     $method->setFQSEN($closure_fqsen);
     // Make the closure reachable by FQSEN from anywhere
     $this->code_base->addMethod($method);
     if (!empty($node->children['uses']) && $node->children['uses']->kind == \ast\AST_CLOSURE_USES) {
         $uses = $node->children['uses'];
         foreach ($uses->children as $use) {
             if ($use->kind != \ast\AST_CLOSURE_VAR) {
                 Issue::emit(Issue::VariableUseClause, $this->context->getFile(), $node->lineno ?? 0);
                 continue;
             }
             $variable_name = (new ContextNode($this->code_base, $this->context, $use->children['name']))->getVariableName();
             if (empty($variable_name)) {
                 continue;
             }
             $variable = null;
             // Check to see if the variable exists in this scope
             if (!$this->context->getScope()->hasVariableWithName($variable_name)) {
                 // If this is not pass-by-reference variable we
                 // have a problem
                 if (!($use->flags & \ast\flags\PARAM_REF)) {
                     Issue::emit(Issue::UndeclaredVariable, $this->context->getFile(), $node->lineno ?? 0, $variable_name);
                     continue;
                 } else {
                     // If the variable doesn't exist, but its
                     // a pass-by-reference variable, we can
                     // just create it
                     $variable = Variable::fromNodeInContext($use, $this->context, $this->code_base, false);
                 }
             } else {
                 $variable = $this->context->getScope()->getVariableWithName($variable_name);
                 // If this isn't a pass-by-reference variable, we
                 // clone the variable so state within this scope
                 // doesn't update the outer scope
                 if (!($use->flags & \ast\flags\PARAM_REF)) {
                     $variable = clone $variable;
                 }
             }
             // Pass the variable into a new scope
             $context = $context->withScopeVariable($variable);
         }
     }
     // Add all parameters to the scope
     if (!empty($node->children['params']) && $node->children['params']->kind == \ast\AST_PARAM_LIST) {
         $params = $node->children['params'];
         foreach ($params->children as $param) {
             // Read the parameter
             $parameter = Parameter::fromNode($this->context, $this->code_base, $param);
             // Add it to the scope
             $context = $context->withScopeVariable($parameter);
         }
     }
     return $context->withClosureFQSEN($closure_fqsen);
 }