当前位置: 首页>>代码示例>>PHP>>正文


PHP UnionType::fromNode方法代码示例

本文整理汇总了PHP中Phan\Language\UnionType::fromNode方法的典型用法代码示例。如果您正苦于以下问题:PHP UnionType::fromNode方法的具体用法?PHP UnionType::fromNode怎么用?PHP UnionType::fromNode使用的例子?那么, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在Phan\Language\UnionType的用法示例。


在下文中一共展示了UnionType::fromNode方法的15个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的PHP代码示例。

示例1: fromNodeInContext

 /**
  * @param Node $node
  * An AST_VAR node
  *
  * @param Context $context
  * The context in which the variable is found
  *
  * @param CodeBase $code_base
  *
  * @return Variable
  * A variable begotten from a node
  */
 public static function fromNodeInContext(Node $node, Context $context, CodeBase $code_base, bool $should_check_type = true) : Variable
 {
     $variable_name = AST::variableName($node);
     // Get the type of the assignment
     $union_type = $should_check_type ? UnionType::fromNode($context, $code_base, $node) : new UnionType();
     $variable = new Variable($context->withLineNumberStart($node->lineno ?? 0)->withLineNumberEnd($node->endLineno ?? 0), $variable_name, $union_type, $node->flags);
     return $variable;
 }
开发者ID:hslatman,项目名称:phan,代码行数:20,代码来源:Variable.php

示例2: get

 /**
  * Force the future to figure out the type of the
  * given object or throw an IssueException if it
  * is unable to do so
  *
  * @return UnionType
  * The type of the future
  *
  * @throws IssueException
  * An exception is thrown if we are unable to determine
  * the type at the time this method is called
  */
 public function get() : UnionType
 {
     return UnionType::fromNode($this->context, $this->code_base, $this->node, false);
 }
开发者ID:Jvbzephir,项目名称:phan,代码行数:16,代码来源:FutureUnionType.php

示例3: visitForeach

 /**
  * @param Node $node
  * A node to parse
  *
  * @return Context
  * A new or an unchanged context resulting from
  * parsing the node
  */
 public function visitForeach(Node $node) : Context
 {
     if ($node->children['value']->kind == \ast\AST_LIST) {
         foreach ($node->children['value']->children as $child_node) {
             $variable = Variable::fromNodeInContext($child_node, $this->context, $this->code_base, false);
             $this->context->addScopeVariable($variable);
         }
         // Otherwise, read the value as regular variable and
         // add it to the scope
     } else {
         // Create a variable for the value
         $variable = Variable::fromNodeInContext($node->children['value'], $this->context, $this->code_base, false);
         // Get the type of the node from the left side
         $type = UnionType::fromNode($this->context, $this->code_base, $node->children['expr']);
         // Filter out the non-generic types of the
         // expression
         $non_generic_type = $type->asNonGenericTypes();
         // If we were able to figure out the type and its
         // a generic type, then set its element types as
         // the type of the variable
         if (!$non_generic_type->isEmpty()) {
             $variable->setUnionType($non_generic_type);
         }
         // Add the variable to the scope
         $this->context->addScopeVariable($variable);
     }
     // If there's a key, make a variable out of that too
     if (!empty($node->children['key'])) {
         if ($node->children['key'] instanceof \ast\Node && $node->children['key']->kind == \ast\AST_LIST) {
             Log::err(Log::EFATAL, "Can't use list() as a key element - aborting", $this->context->getFile(), $node->lineno);
         }
         $variable = Variable::fromNodeInContext($node->children['key'], $this->context, $this->code_base, false);
         $this->context->addScopeVariable($variable);
     }
     // Note that we're not creating a new scope, just
     // adding variables to the existing scope
     return $this->context;
 }
开发者ID:hslatman,项目名称:phan,代码行数:46,代码来源:DepthFirstVisitor.php

示例4: analyzeInternalArgumentType

 /**
  * Check to see if the given Clazz is a duplicate
  *
  * @param Method $method
  * The method we're analyzing arguments for
  *
  * @param Node $node
  * The node holding the method call we're looking at
  *
  * @param Context $context
  * The context in which we see the call
  *
  * @param CodeBase $code_base
  *
  * @return null
  *
  * @see \Phan\Deprecated\Pass2::arg_check
  * Formerly `function arg_check`
  */
 private static function analyzeInternalArgumentType(Method $method, Node $node, Context $context, CodeBase $code_base)
 {
     $arglist = $node->children['args'];
     $argcount = count($arglist->children);
     switch ($method->getName()) {
         case 'join':
         case 'implode':
             // (string glue, array pieces),
             // (array pieces, string glue) or
             // (array pieces)
             if ($argcount == 1) {
                 self::analyzeNodeUnionTypeCast($arglist->children[0], $context, $code_base, ArrayType::instance()->asUnionType(), "arg#1(pieces) is %s but {$method->getFQSEN()}() takes array when passed only 1 arg");
                 return;
             } else {
                 if ($argcount == 2) {
                     $arg1_type = UnionType::fromNode($context, $code_base, $arglist->children[0]);
                     $arg2_type = UnionType::fromNode($context, $code_base, $arglist->children[1]);
                     if ((string) $arg1_type == 'array') {
                         if (!$arg1_type->canCastToUnionType(StringType::instance()->asUnionType())) {
                             Log::err(Log::EPARAM, "arg#2(glue) is {$arg2_type} but {$method->getFQSEN()}() takes string when arg#1 is array", $context->getFile(), $context->getLineNumberStart());
                         }
                     } else {
                         if ((string) $arg1_type == 'string') {
                             if (!$arg2_type->canCastToUnionType(ArrayType::instance()->asUnionType())) {
                                 Log::err(Log::EPARAM, "arg#2(pieces) is {$arg2_type} but {$method->getFQSEN()}() takes array when arg#1 is string", $context->getFile(), $context->getLineNumberStart());
                             }
                         }
                     }
                     return;
                 }
             }
             // Any other arg counts we will let the regular
             // checks handle
             break;
         case 'array_udiff':
         case 'array_diff_uassoc':
         case 'array_uintersect_assoc':
         case 'array_intersect_ukey':
             if ($argcount < 3) {
                 Log::err(Log::EPARAM, "call with {$argcount} arg(s) to {$method->getFQSEN()}() which requires {$method->getNumberOfRequiredParameters()} arg(s)", $context->getFile(), $context->getLineNumberStart());
                 return;
             }
             self::analyzeNodeUnionTypeCast($arglist->children[$argcount - 1], $context, $code_base, CallableType::instance()->asUnionType(), "The last argument to {$method->getFQSEN()} must be a callable");
             for ($i = 0; $i < $argcount - 1; $i++) {
                 self::analyzeNodeUnionTypeCast($arglist->children[$i], $context, $code_base, CallableType::instance()->asUnionType(), "arg#" . ($i + 1) . " is %s but {$method->getFQSEN()}() takes array");
             }
             return;
         case 'array_diff_uassoc':
         case 'array_uintersect_uassoc':
             if ($argcount < 4) {
                 Log::err(Log::EPARAM, "call with {$argcount} arg(s) to {$method->getFQSEN()}() which requires {$method->getNumberOfRequiredParameters()} arg(s)", $context->getFile(), $context->getLineNumberStart());
                 return;
             }
             // The last 2 arguments must be a callable and there
             // can be a variable number of arrays before it
             self::analyzeNodeUnionTypeCast($arglist->children[$argcount - 1], $context, $code_base, CallableType::instance()->asUnionType(), "The last argument to {$method->getFQSEN()} must be a callable");
             self::analyzeNodeUnionTypeCast($arglist->children[$argcount - 2], $context, $code_base, CallableType::instance()->asUnionType(), "The second last argument to {$method->getFQSEN()} must be a callable");
             for ($i = 0; $i < $argcount - 2; $i++) {
                 self::analyzeNodeUnionTypeCast($arglist->children[$i], $context, $code_base, ArrayType::instance()->asUnionType(), "arg#" . ($i + 1) . " is %s but {$method->getFQSEN()}() takes array");
             }
             return;
         case 'strtok':
             // (string str, string token) or (string token)
             if ($argcount == 1) {
                 // If we have just one arg it must be a string token
                 self::analyzeNodeUnionTypeCast($arglist->children[0], $context, $code_base, ArrayType::instance()->asUnionType(), "arg#1(token) is %s but {$method->getFQSEN()}() takes string when passed only one arg");
             }
             // The arginfo check will handle the other case
             break;
         case 'min':
         case 'max':
             if ($argcount == 1) {
                 // If we have just one arg it must be an array
                 if (!self::analyzeNodeUnionTypeCast($arglist->children[0], $context, $code_base, ArrayType::instance()->asUnionType(), "arg#1(values) is %s but {$method->getFQSEN()}() takes array when passed only one arg")) {
                     return;
                 }
             }
             // The arginfo check will handle the other case
             break;
         default:
             break;
//.........这里部分代码省略.........
开发者ID:mgonyan,项目名称:phan,代码行数:101,代码来源:ArgumentType.php

示例5: visitMethodCall

 /**
  * Visit a node with kind `\ast\AST_METHOD_CALL`
  *
  * @param Node $node
  * A node of the type indicated by the method name that we'd
  * like to figure out the type that it produces.
  *
  * @return UnionType
  * The set of types that are possibly produced by the
  * given node
  */
 public function visitMethodCall(Node $node) : UnionType
 {
     $method_name = $node->children['method'] ?? '';
     // Give up on any complicated nonsense where the
     // method name is a variable such as in
     // `$variable->$function_name()`.
     if ($method_name instanceof Node) {
         return new UnionType();
     }
     // Method names can some times turn up being
     // other method calls.
     assert(is_string($method_name), "Method name must be a string. Something else given.");
     try {
         $class_fqsen = null;
         foreach ($this->classListFromNode($node->children['class'] ?? $node->children['expr']) as $i => $class) {
             $class_fqsen = $class->getFQSEN();
             if (!$class->hasMethodWithName($this->code_base, $method_name)) {
                 continue;
             }
             try {
                 $method = $class->getMethodByNameInContext($this->code_base, $method_name, $this->context);
                 $union_type = $method->getUnionType();
                 // Map template types to concrete types
                 if ($union_type->hasTemplateType()) {
                     // Get the type of the object calling the property
                     $expression_type = UnionType::fromNode($this->context, $this->code_base, $node->children['expr']);
                     // Map template types to concrete types
                     $union_type = $union_type->withTemplateParameterTypeMap($expression_type->getTemplateParameterTypeMap($this->code_base));
                 }
                 // Remove any references to \static or \static[]
                 // once we're talking about the method's return
                 // type outside of its class
                 if ($union_type->hasStaticType()) {
                     $union_type = clone $union_type;
                     $union_type->removeType(\Phan\Language\Type\StaticType::instance());
                 }
                 if ($union_type->genericArrayElementTypes()->hasStaticType()) {
                     $union_type = clone $union_type;
                     // Find the static type on the list
                     $static_type = $union_type->getTypeSet()->find(function (Type $type) : bool {
                         return $type->isGenericArray() && $type->genericArrayElementType()->isStaticType();
                     });
                     // Remove it from the list
                     $union_type->removeType($static_type);
                 }
                 return $union_type;
             } catch (IssueException $exception) {
                 return new UnionType();
             }
         }
     } catch (IssueException $exception) {
         // Swallow it
     } catch (CodeBaseException $exception) {
         $this->emitIssue(Issue::UndeclaredClassMethod, $node->lineno ?? 0, $method_name, (string) $exception->getFQSEN());
     }
     return new UnionType();
 }
开发者ID:tpunt,项目名称:phan,代码行数:68,代码来源:UnionTypeVisitor.php

示例6: analyzeCallToMethod


//.........这里部分代码省略.........
             }
         }
     }
     // Confirm the argument types are clean
     ArgumentType::analyze($method, $node, $this->context, $this->code_base);
     // Take another pass over pass-by-reference parameters
     // and assign types to passed in variables
     foreach ($argument_list->children as $i => $argument) {
         $parameter = $method->getParameterList()[$i] ?? null;
         if (!$parameter) {
             continue;
         }
         // If the parameter is pass-by-reference and we're
         // passing a variable in, see if we should pass
         // the parameter and variable types to eachother
         $variable = null;
         if ($parameter->isPassByReference()) {
             if ($argument->kind == \ast\AST_VAR) {
                 $variable = AST::getOrCreateVariableFromNodeInContext($argument, $this->context, $this->code_base);
             } else {
                 if ($argument->kind == \ast\AST_STATIC_PROP || $argument->kind == \ast\AST_PROP) {
                     $property_name = $argument->children['prop'];
                     if (is_string($property_name)) {
                         // We don't do anything with it; just create it
                         // if it doesn't exist
                         try {
                             $variable = AST::getOrCreatePropertyFromNodeInContext($argument->children['prop'], $argument, $this->context, $this->code_base);
                         } catch (CodeBaseException $exception) {
                             Log::err(Log::EUNDEF, $exception->getMessage(), $this->context->getFile(), $node->lineno);
                         } catch (NodeException $exception) {
                             // If we can't figure out what kind of a call
                             // this is, don't worry about it
                         }
                     } else {
                         // This is stuff like `Class->$foo`. I'm ignoring
                         // it.
                     }
                 }
             }
             if ($variable) {
                 $variable->getUnionType()->addUnionType($parameter->getUnionType());
             }
         }
     }
     // If we're in quick mode, don't retest methods based on
     // parameter types passed in
     if (Config::get()->quick_mode) {
         return;
     }
     // We're going to hunt to see if any of the arguments
     // have a mismatch with the parameters. If so, we'll
     // re-check the method to see how the parameters impact
     // its return type
     $has_argument_parameter_mismatch = false;
     // Now that we've made sure the arguments are sufficient
     // for definitions on the method, we iterate over the
     // arguments again and add their types to the parameter
     // types so we can test the method again
     $argument_list = $node->children['args'];
     // We create a copy of the parameter list so we can switch
     // back to it after
     $original_parameter_list = $method->getParameterList();
     foreach ($argument_list->children as $i => $argument) {
         $parameter = $method->getParameterList()[$i] ?? null;
         if (!$parameter) {
             continue;
         }
         // If the parameter has no type, pass the
         // argument's type to it
         if ($parameter->getUnionType()->isEmpty()) {
             $has_argument_parameter_mismatch = true;
             $argument_type = UnionType::fromNode($this->context, $this->code_base, $argument);
             // If this isn't an internal function or method
             // and it has no type, add the argument's type
             // to it so we can compare it to subsequent
             // calls
             if (!$parameter->getContext()->isInternal()) {
                 // Clone the parameter in the original
                 // parameter list so we can reset it
                 // later
                 $original_parameter_list[$i] = clone $parameter;
                 // Then set the new type on that parameter based
                 // on the argument's type. We'll use this to
                 // retest the method with the passed in types
                 $parameter->getUnionType()->addUnionType($argument_type);
             }
         }
     }
     // Now that we know something about the parameters used
     // to call the method, we can reanalyze the method with
     // the types of the parameter, making sure we don't get
     // into an infinite loop of checking calls to the current
     // method in scope
     if ($has_argument_parameter_mismatch && !$method->getContext()->isInternal() && (!$this->context->isMethodScope() || $method->getFQSEN() !== $this->context->getMethodFQSEN())) {
         $method->analyze($method->getContext(), $code_base);
     }
     // Reset to the original parameter list after having
     // tested the parameters with the types passed in
     $method->setParameterList($original_parameter_list);
 }
开发者ID:jazzdan,项目名称:phan,代码行数:101,代码来源:BreadthFirstVisitor.php

示例7: visitPropDecl

 /**
  * Visit a node with kind `\ast\AST_PROP_DECL`
  *
  * @param Node $node
  * A node to parse
  *
  * @return Context
  * A new or an unchanged context resulting from
  * parsing the node
  */
 public function visitPropDecl(Node $node) : Context
 {
     // Bomb out if we're not in a class context
     $clazz = $this->getContextClass();
     // Get a comment on the property declaration
     $comment = Comment::fromStringInContext($node->children[0]->docComment ?? '', $this->context);
     foreach ($node->children ?? [] as $i => $child_node) {
         // Ignore children which are not property elements
         if (!$child_node || $child_node->kind != \ast\AST_PROP_ELEM) {
             continue;
         }
         // If something goes wrong will getting the type of
         // a property, we'll store it as a future union
         // type and try to figure it out later
         $future_union_type = null;
         try {
             // Get the type of the default
             $union_type = UnionType::fromNode($this->context, $this->code_base, $child_node->children['default'], false);
         } catch (IssueException $exception) {
             $future_union_type = new FutureUnionType($this->code_base, $this->context, $child_node->children['default']);
             $union_type = new UnionType();
         }
         // Don't set 'null' as the type if thats the default
         // given that its the default default.
         if ($union_type->isType(NullType::instance())) {
             $union_type = new UnionType();
         }
         $property_name = $child_node->children['name'];
         assert(is_string($property_name), 'Property name must be a string. ' . 'Got ' . print_r($property_name, true) . ' at ' . $this->context);
         $property = new Property(clone $this->context->withLineNumberStart($child_node->lineno ?? 0), is_string($child_node->children['name']) ? $child_node->children['name'] : '_error_', $union_type, $node->flags ?? 0);
         $property->setFQSEN(FullyQualifiedPropertyName::make($clazz->getFQSEN(), $property->getName()));
         // Add the property to the class
         $clazz->addProperty($this->code_base, $property);
         $property->setSuppressIssueList($comment->getSuppressIssueList());
         // Look for any @var declarations
         if ($variable = $comment->getVariableList()[$i] ?? null) {
             if ((string) $union_type != 'null' && !$union_type->canCastToUnionType($variable->getUnionType())) {
                 $this->emitIssue(Issue::TypeMismatchProperty, $child_node->lineno ?? 0, (string) $union_type, (string) $property->getFQSEN(), (string) $variable->getUnionType());
             }
             // Set the declared type to the doc-comment type and add
             // |null if the default value is null
             $property->getUnionType()->addUnionType($variable->getUnionType());
         }
         // Wait until after we've added the (at)var type
         // before setting the future so that calling
         // $property->getUnionType() doesn't force the
         // future to be reified.
         if (!empty($future_union_type)) {
             $property->setFutureUnionType($future_union_type);
         }
     }
     return $this->context;
 }
开发者ID:ablyler,项目名称:phan,代码行数:63,代码来源:ParseVisitor.php

示例8: visitInstanceof

 /**
  * @param Node $node
  * A node to parse
  *
  * @return Context
  * A new or an unchanged context resulting from
  * parsing the node
  */
 public function visitInstanceof(Node $node) : Context
 {
     // Only look at things of the form
     // `$variable instanceof ClassName`
     if ($node->children['expr']->kind !== \ast\AST_VAR) {
         return $this->context;
     }
     $context = $this->context;
     try {
         // Get the variable we're operating on
         $variable = (new ContextNode($this->code_base, $this->context, $node->children['expr']))->getVariable();
         // Get the type that we're checking it against
         $type = UnionType::fromNode($this->context, $this->code_base, $node->children['class']);
         // Make a copy of the variable
         $variable = clone $variable;
         // Add the type to the variable
         $variable->getUnionType()->addUnionType($type);
         // Overwrite the variable with its new type
         $context = $context->withScopeVariable($variable);
     } catch (\Exception $exception) {
         // Swallow it
     }
     return $context;
 }
开发者ID:tpunt,项目名称:phan,代码行数:32,代码来源:ConditionVisitor.php

示例9: analyzeInternalArgumentType

 /**
  * Check to see if the given Clazz is a duplicate
  *
  * @param Method $method
  * The method we're analyzing arguments for
  *
  * @param Node $node
  * The node holding the method call we're looking at
  *
  * @param Context $context
  * The context in which we see the call
  *
  * @param CodeBase $code_base
  *
  * @return null
  *
  * @see \Phan\Deprecated\Pass2::arg_check
  * Formerly `function arg_check`
  */
 private static function analyzeInternalArgumentType(Method $method, Node $node, Context $context, CodeBase $code_base)
 {
     $arglist = $node->children['args'];
     $argcount = count($arglist->children);
     switch ($method->getName()) {
         case 'join':
         case 'implode':
             // (string glue, array pieces),
             // (array pieces, string glue) or
             // (array pieces)
             if ($argcount == 1) {
                 self::analyzeNodeUnionTypeCast($arglist->children[0], $context, $code_base, ArrayType::instance()->asUnionType(), function (UnionType $node_type) use($context, $method) {
                     // "arg#1(pieces) is %s but {$method->getFQSEN()}() takes array when passed only 1 arg"
                     return Issue::fromType(Issue::ParamSpecial2)($context->getFile(), $context->getLineNumberStart(), [1, 'pieces', (string) $method->getFQSEN(), 'string', 'array']);
                 });
                 return;
             } else {
                 if ($argcount == 2) {
                     $arg1_type = UnionType::fromNode($context, $code_base, $arglist->children[0]);
                     $arg2_type = UnionType::fromNode($context, $code_base, $arglist->children[1]);
                     if ((string) $arg1_type == 'array') {
                         if (!$arg1_type->canCastToUnionType(StringType::instance()->asUnionType())) {
                             Issue::emit(Issue::ParamSpecial1, $context->getFile(), $context->getLineNumberStart(), 2, 'glue', (string) $arg2_type, (string) $method->getFQSEN(), 'string', 1, 'array');
                         }
                     } else {
                         if ((string) $arg1_type == 'string') {
                             if (!$arg2_type->canCastToUnionType(ArrayType::instance()->asUnionType())) {
                                 Issue::emit(Issue::ParamSpecial1, $context->getFile(), $context->getLineNumberStart(), 2, 'pieces', (string) $arg2_type, (string) $method->getFQSEN(), 'array', 1, 'string');
                             }
                         }
                     }
                     return;
                 }
             }
             // Any other arg counts we will let the regular
             // checks handle
             break;
         case 'array_udiff':
         case 'array_diff_uassoc':
         case 'array_uintersect_assoc':
         case 'array_intersect_ukey':
             if ($argcount < 3) {
                 Issue::emit(Issue::ParamTooFewInternal, $context->getFile(), $context->getLineNumberStart(), $argcount, (string) $method->getFQSEN(), $method->getNumberOfRequiredParameters());
                 return;
             }
             self::analyzeNodeUnionTypeCast($arglist->children[$argcount - 1], $context, $code_base, CallableType::instance()->asUnionType(), function (UnionType $node_type) use($context, $method) {
                 // "The last argument to {$method->getFQSEN()} must be a callable"
                 return Issue::fromType(Issue::ParamSpecial3)($context->getFile(), $context->getLineNumberStart(), [(string) $method->getFQSEN(), 'callable']);
             });
             for ($i = 0; $i < $argcount - 1; $i++) {
                 self::analyzeNodeUnionTypeCast($arglist->children[$i], $context, $code_base, CallableType::instance()->asUnionType(), function (UnionType $node_type) use($context, $method, $i) {
                     // "arg#".($i+1)." is %s but {$method->getFQSEN()}() takes array"
                     return Issue::fromType(Issue::ParamTypeMismatch)($context->getFile(), $context->getLineNumberStart(), [$i + 1, (string) $node_type, (string) $method->getFQSEN(), 'array']);
                 });
             }
             return;
         case 'array_diff_uassoc':
         case 'array_uintersect_uassoc':
             if ($argcount < 4) {
                 Issue::emit(Issue::ParamTooFewInternal, $context->getFile(), $context->getLineNumberStart(), $argcount, (string) $method->getFQSEN(), $method->getNumberOfRequiredParameters());
                 return;
             }
             // The last 2 arguments must be a callable and there
             // can be a variable number of arrays before it
             self::analyzeNodeUnionTypeCast($arglist->children[$argcount - 1], $context, $code_base, CallableType::instance()->asUnionType(), function (UnionType $node_type) use($context, $method) {
                 // "The last argument to {$method->getFQSEN()} must be a callable"
                 return Issue::fromType(Issue::ParamSpecial3)($context->getFile(), $context->getLineNumberStart(), [(string) $method->getFQSEN(), 'callable']);
             });
             self::analyzeNodeUnionTypeCast($arglist->children[$argcount - 2], $context, $code_base, CallableType::instance()->asUnionType(), function (UnionType $node_type) use($context, $method) {
                 // "The second last argument to {$method->getFQSEN()} must be a callable"
                 return Issue::fromType(Issue::ParamSpecial4)($context->getFile(), $context->getLineNumberStart(), [(string) $method->getFQSEN(), 'callable']);
             });
             for ($i = 0; $i < $argcount - 2; $i++) {
                 self::analyzeNodeUnionTypeCast($arglist->children[$i], $context, $code_base, ArrayType::instance()->asUnionType(), function (UnionType $node_type) use($context, $method, $i) {
                     // "arg#".($i+1)." is %s but {$method->getFQSEN()}() takes array"
                     return Issue::fromType(Issue::ParamTypeMismatch)($context->getFile(), $context->getLineNumberStart(), [$i + 1, (string) $node_type, (string) $method->getFQSEN(), 'array']);
                 });
             }
             return;
         case 'strtok':
             // (string str, string token) or (string token)
//.........这里部分代码省略.........
开发者ID:actank,项目名称:phan,代码行数:101,代码来源:ArgumentType.php

示例10: visitMethodCall

 /**
  * @param Node $node
  * A node of the type indicated by the method name that we'd
  * like to figure out the type that it produces.
  *
  * @return string
  * The class name represented by the given call
  */
 public function visitMethodCall(Node $node) : string
 {
     if ($node->children['expr']->kind == \ast\AST_VAR) {
         if ($node->children['expr']->children['name'] instanceof Node) {
             return '';
         }
         // $var->method()
         if ($node->children['expr']->children['name'] == 'this') {
             if (!$this->context->isInClassScope()) {
                 Log::err(Log::ESTATIC, 'Using $this when not in object context', $this->context->getFile(), $node->lineno);
                 return '';
             }
             return (string) $this->context->getClassFQSEN();
         }
         $variable_name = $node->children['expr']->children['name'];
         if (!$this->context->getScope()->hasVariableWithName($variable_name)) {
             // Got lost, couldn't find the variable in the current scope
             // If it really isn't defined, it will be caught by the
             // undefined var error
             return '';
         }
         $variable = $this->context->getScope()->getVariableWithName($variable_name);
         // Hack - loop through the possible types of the var and assume
         // first found class is correct
         foreach ($variable->getUnionType()->nonGenericArrayTypes()->getTypeList() as $type) {
             $child_class_fqsen = FullyQualifiedClassName::fromStringInContext((string) $type, $this->context);
             if ($this->code_base->hasClassWithFQSEN($child_class_fqsen)) {
                 return (string) FullyQualifiedClassName::fromStringInContext((string) $type, $this->context);
             }
         }
         // Could not find name
         return '';
     }
     if ($node->children['expr']->kind == \ast\AST_PROP) {
         $prop = $node->children['expr'];
         if (!($prop->children['expr']->kind == \ast\AST_VAR && !$prop->children['expr']->children['name'] instanceof Node)) {
             return '';
         }
         // $var->prop->method()
         $var = $prop->children['expr'];
         if ($var->children['name'] == 'this') {
             // If we're not in a class scope, 'this' won't work
             if (!$this->context->isInClassScope()) {
                 Log::err(Log::ESTATIC, 'Using $this when not in object context', $this->context->getFile(), $node->lineno);
                 return '';
             }
             // Get the class in scope
             $clazz = $this->code_base->getClassByFQSEN($this->context->getClassFQSEN());
             if ($prop->children['prop'] instanceof Node) {
                 // $this->$prop->method() - too dynamic, give up
                 return '';
             }
             $property_name = $prop->children['prop'];
             if ($clazz->hasPropertyWithName($this->code_base, $property_name)) {
                 try {
                     $property = $clazz->getPropertyByNameInContext($this->code_base, $property_name, $this->context);
                 } catch (AccessException $exception) {
                     Log::err(Log::EACCESS, $exception->getMessage(), $this->context->getFile(), $node->lineno);
                     return '';
                 }
                 // Find the first viable property type
                 foreach ($property->getUnionType()->nonGenericArrayTypes()->getTypeList() as $type) {
                     $class_fqsen = FullyQualifiedClassName::fromStringInContext((string) $type, $this->context);
                     if ($this->code_base->hasClassWithFQSEN($class_fqsen)) {
                         return (string) $class_fqsen;
                     }
                 }
             }
             // No such property was found, or none were classes
             // that could be found
             return '';
         }
         return '';
     }
     if ($node->children['expr']->kind == \ast\AST_METHOD_CALL) {
         // Get the type returned by the first method
         // call.
         $union_type = UnionType::fromNode($this->context, $this->code_base, $node->children['expr']);
         // Find the subset of types that are viable
         // classes
         $viable_class_types = $union_type->nonNativeTypes()->nonGenericArrayTypes();
         // If there are no non-native types, give up
         if ($viable_class_types->isEmpty()) {
             return '';
         }
         // Return the first non-native type in the
         // list and hope its a class
         return (string) $viable_class_types->head();
     }
     return '';
 }
开发者ID:PHPforks,项目名称:phan,代码行数:99,代码来源:ClassNameVisitor.php

示例11: visitUnaryOp

 /**
  * Visit a node with kind `\ast\AST_UNARY_OP`
  *
  * @param Node $node
  * A node of the type indicated by the method name that we'd
  * like to figure out the type that it produces.
  *
  * @return UnionType
  * The set of types that are possibly produced by the
  * given node
  */
 public function visitUnaryOp(Node $node) : UnionType
 {
     // Shortcut some easy operators
     switch ($node->flags) {
         case \ast\flags\UNARY_BOOL_NOT:
             return BoolType::instance()->asUnionType();
     }
     return UnionType::fromNode($this->context, $this->code_base, $node->children['expr']);
 }
开发者ID:themarios,项目名称:phan,代码行数:20,代码来源:UnionTypeVisitor.php

示例12: visitIfElem

 /**
  * @param Node $node
  * A node to parse
  *
  * @return Context
  * A new or an unchanged context resulting from
  * parsing the node
  */
 public function visitIfElem(Node $node) : Context
 {
     if (!isset($node->children['cond']) || !$node->children['cond'] instanceof Node) {
         return $this->context;
     }
     // Get the type just to make sure everything
     // is defined.
     $expression_type = UnionType::fromNode($this->context, $this->code_base, $node->children['cond']);
     // Look to see if any proofs we do within the condition
     // can say anything about types within the statement
     // list.
     return (new ConditionVisitor($this->code_base, $this->context))($node->children['cond']);
 }
开发者ID:etsy,项目名称:phan,代码行数:21,代码来源:PreOrderAnalysisVisitor.php

示例13: analyzeCallToMethod


//.........这里部分代码省略.........
     // We're going to hunt to see if any of the arguments
     // have a mismatch with the parameters. If so, we'll
     // re-check the method to see how the parameters impact
     // its return type
     $has_argument_parameter_mismatch = false;
     // Now that we've made sure the arguments are sufficient
     // for definitions on the method, we iterate over the
     // arguments again and add their types to the parameter
     // types so we can test the method again
     $argument_list = $node->children['args'];
     // We create a copy of the parameter list so we can switch
     // back to it after
     $original_parameter_list = $method->getParameterList();
     // Create a backup of the method's scope so that we can
     // reset it after fucking with it below
     $original_method_scope = $method->getInternalScope();
     foreach ($argument_list->children as $i => $argument) {
         // TODO(Issue #376): Support inference on the child in **the set of vargs**, not just the first vararg
         // This is just testing the first vararg.
         // The implementer will also need to restore the original parameter list.
         $parameter = $original_parameter_list[$i] ?? null;
         if (!$parameter) {
             continue;
         }
         // If the parameter has no type, pass the
         // argument's type to it
         if ($parameter->getVariadicElementUnionType()->isEmpty()) {
             $has_argument_parameter_mismatch = true;
             // If this isn't an internal function or method
             // and it has no type, add the argument's type
             // to it so we can compare it to subsequent
             // calls
             if (!$parameter->isInternal()) {
                 $argument_type = UnionType::fromNode($this->context, $this->code_base, $argument);
                 // Clone the parameter in the original
                 // parameter list so we can reset it
                 // later
                 // TODO: If there are varargs and this is beyond the end, ensure last arg is cloned.
                 $original_parameter_list[$i] = clone $original_parameter_list[$i];
                 // Then set the new type on that parameter based
                 // on the argument's type. We'll use this to
                 // retest the method with the passed in types
                 $parameter->getVariadicElementUnionType()->addUnionType($argument_type);
                 if (!is_object($argument)) {
                     continue;
                 }
                 // If we're passing by reference, get the variable
                 // we're dealing with wrapped up and shoved into
                 // the scope of the method
                 if ($parameter->isPassByReference()) {
                     if ($original_parameter_list[$i]->isVariadic()) {
                         // For now, give up and work on it later.
                         // TODO(Issue #376): It's possible to have a parameter `&...$args`. Analysing that is going to be a problem.
                         // Is it possible to create `PassByReferenceVariableCollection extends Variable` or something similar?
                     } elseif ($argument->kind == \ast\AST_VAR) {
                         // Get the variable
                         $variable = (new ContextNode($this->code_base, $this->context, $argument))->getOrCreateVariable();
                         $pass_by_reference_variable = new PassByReferenceVariable($parameter, $variable);
                         $parameter_list = $method->getParameterList();
                         $parameter_list[$i] = $pass_by_reference_variable;
                         $method->setParameterList($parameter_list);
                         // Add it to the scope of the function wrapped
                         // in a way that makes it addressable as the
                         // parameter its mimicking
                         $method->getInternalScope()->addVariable($pass_by_reference_variable);
                     } else {
开发者ID:etsy,项目名称:phan,代码行数:67,代码来源:PostOrderAnalysisVisitor.php

示例14: visitClassConstDecl

 /**
  * Visit a node with kind `\ast\AST_CLASS_CONST_DECL`
  *
  * @param Node $node
  * A node to parse
  *
  * @return Context
  * A new or an unchanged context resulting from
  * parsing the node
  */
 public function visitClassConstDecl(Node $node) : Context
 {
     $clazz = $this->getContextClass();
     foreach ($node->children ?? [] as $child_node) {
         $constant = new Constant($this->context->withLineNumberStart($child_node->lineno ?? 0)->withLineNumberEnd($child_node->endLineno ?? 0), $child_node->children['name'], UnionType::fromNode($this->context, $this->code_base, $child_node->children['value']), $child_node->flags ?? 0);
         $clazz->addConstant($this->code_base, $constant);
     }
     return $this->context;
 }
开发者ID:tmli3b3rm4n,项目名称:phan,代码行数:19,代码来源:ParseVisitor.php

示例15: visitArray

 /**
  * Visit a node with kind `\ast\AST_ARRAY`
  *
  * @param Node $node
  * A node of the type indicated by the method name that we'd
  * like to figure out the type that it produces.
  *
  * @return UnionType
  * The set of types that are possibly produced by the
  * given node
  */
 public function visitArray(Node $node) : UnionType
 {
     if (!empty($node->children) && $node->children[0] instanceof Node && $node->children[0]->kind == \ast\AST_ARRAY_ELEM) {
         $element_types = [];
         // Check the first 5 (completely arbitrary) elements
         // and assume the rest are the same type
         for ($i = 0; $i < 5; $i++) {
             // Check to see if we're out of elements
             if (empty($node->children[$i])) {
                 break;
             }
             if ($node->children[$i]->children['value'] instanceof Node) {
                 $element_types[] = UnionType::fromNode($this->context, $this->code_base, $node->children[$i]->children['value']);
             } else {
                 $element_types[] = Type::fromObject($node->children[$i]->children['value'])->asUnionType();
             }
         }
         $element_types = array_values(array_unique($element_types));
         if (count($element_types) == 1) {
             return $element_types[0]->asGenericArrayTypes();
         }
     }
     return ArrayType::instance()->asUnionType();
 }
开发者ID:gitter-badger,项目名称:phan,代码行数:35,代码来源:UnionTypeVisitor.php


注:本文中的Phan\Language\UnionType::fromNode方法示例由纯净天空整理自Github/MSDocs等开源代码及文档管理平台,相关代码片段筛选自各路编程大神贡献的开源项目,源码版权归原作者所有,传播和使用请参考对应项目的License;未经允许,请勿转载。