fromType() public static method

return Issue
public static fromType ( string $type ) : Issue
$type string
return Issue
示例#1
0
 /**
  * @param string $string String to check against
  *
  * @dataProvider invalidUTF8StringsProvider
  */
 public function testUTF8CharactersDoNotCauseDOMAttrToFail($string)
 {
     $output = new BufferedOutput();
     $printer = new CheckstylePrinter();
     $printer->configureOutput($output);
     $printer->print(new IssueInstance(Issue::fromType(Issue::SyntaxError), 'test.php', 0, [$string]));
     $printer->flush();
 }
示例#2
0
 /**
  * @param string $string String to check against
  * @param string $messageExpected Message component of expected CSV line
  *
  * @dataProvider specialCharacterCasesProvider
  */
 public function testSpecialCharactersAreProperlyEncoded($string, $messageExpected)
 {
     $output = new BufferedOutput();
     $printer = new CSVPrinter();
     $printer->configureOutput($output);
     $printer->print(new IssueInstance(Issue::fromType(Issue::SyntaxError), 'test.php', 0, [$string]));
     $printer->flush();
     $expected = 'test.php,0,10,critical,UndefError,PhanSyntaxError,' . $messageExpected;
     $actual = explode("\n", $output->fetch())[1];
     // Ignore header
     $this->assertEquals($expected, $actual);
 }
示例#3
0
 /**
  * @return Clazz[]
  * A list of classes associated with the given node
  *
  * @throws IssueException
  * An exception is thrown if we can't find a class for
  * the given type
  */
 private function classListFromNode(Node $node)
 {
     // Get the types associated with the node
     $union_type = self::unionTypeFromNode($this->code_base, $this->context, $node);
     // Iterate over each viable class type to see if any
     // have the constant we're looking for
     foreach ($union_type->nonNativeTypes()->getTypeSet() as $class_type) {
         // Get the class FQSEN
         $class_fqsen = $class_type->asFQSEN();
         // See if the class exists
         if (!$this->code_base->hasClassWithFQSEN($class_fqsen)) {
             throw new IssueException(Issue::fromType(Issue::UndeclaredClassReference)($this->context->getFile(), $node->lineno ?? 0, [(string) $class_fqsen]));
         }
         (yield $this->code_base->getClassByFQSEN($class_fqsen));
     }
 }
示例#4
0
 /**
  * @return ClassConstant
  * Get the (non-class) constant associated with this node
  * in this context
  *
  * @throws NodeException
  * An exception is thrown if we can't understand the node
  *
  * @throws CodeBaseExtension
  * An exception is thrown if we can't find the given
  * class
  *
  * @throws UnanalyzableException
  * An exception is thrown if we hit a construct in which
  * we can't determine if the property exists or not
  */
 public function getClassConst() : ClassConstant
 {
     assert($this->node->kind === \ast\AST_CLASS_CONST, "Node must be of type \\ast\\AST_CLASS_CONST");
     $constant_name = $this->node->children['const'];
     // class name fetch
     if ($constant_name == 'class') {
         throw new UnanalyzableException($this->node, "Can't get class constant for implicit 'class'");
     }
     $class_fqsen = null;
     try {
         $class_list = (new ContextNode($this->code_base, $this->context, $this->node->children['class']))->getClassList();
     } catch (CodeBaseException $exception) {
         throw new IssueException(Issue::fromType(Issue::UndeclaredClassConstant)($this->context->getFile(), $this->node->lineno ?? 0, [$constant_name, $exception->getFQSEN()]));
     }
     foreach ($class_list as $i => $class) {
         $class_fqsen = $class->getFQSEN();
         // Check to see if the class has the constant
         if (!$class->hasConstantWithName($this->code_base, $constant_name)) {
             continue;
         }
         return $class->getConstantWithName($this->code_base, $constant_name);
     }
     // If no class is found, we'll emit the error elsewhere
     if ($class_fqsen) {
         throw new IssueException(Issue::fromType(Issue::UndeclaredConstant)($this->context->getFile(), $this->node->lineno ?? 0, ["{$class_fqsen}::{$constant_name}"]));
     }
     throw new NodeException($this->node, "Can't figure out constant {$constant_name} in node");
 }
示例#5
0
 /**
  * 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)
             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(), function (UnionType $node_type) use($context, $method) {
                     // "arg#1(token) is %s but {$method->getFQSEN()}() takes string when passed only one arg"
                     return Issue::fromType(Issue::ParamSpecial2)($context->getFile(), $context->getLineNumberStart(), [1, 'token', (string) $node_type, (string) $method->getFQSEN(), 'string']);
                 });
             }
             // 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(), function (UnionType $node_type) use($context, $method) {
                     // "arg#1(values) is %s but {$method->getFQSEN()}() takes array when passed only one arg"
                     return Issue::fromType(Issue::ParamSpecial2)($context->getFile(), $context->getLineNumberStart(), [1, 'values', (string) $node_type, (string) $method->getFQSEN(), 'array']);
                 })) {
                     return;
                 }
             }
             // The arginfo check will handle the other case
             break;
         default:
             break;
     }
 }
示例#6
0
文件: Clazz.php 项目: etsy/phan
 /**
  * @param string $name
  * The name of the property
  *
  * @param Context $context
  * The context of the caller requesting the property
  *
  * @return Property
  * A property with the given name
  *
  * @throws IssueException
  * An exception may be thrown if the caller does not
  * have access to the given property from the given
  * context
  */
 public function getPropertyByNameInContext(CodeBase $code_base, string $name, Context $context) : Property
 {
     // Get the FQSEN of the property we're looking for
     $property_fqsen = FullyQualifiedPropertyName::make($this->getFQSEN(), $name);
     $property = null;
     // Figure out if we have the property
     $has_property = $code_base->hasPropertyWithFQSEN($property_fqsen);
     // Figure out if the property is accessible
     $is_property_accessible = false;
     if ($has_property) {
         $property = $code_base->getPropertyByFQSEN($property_fqsen);
         $is_remote_access = !$context->isInClassScope() || !$context->getClassInScope($code_base)->getUnionType()->canCastToExpandedUnionType($this->getUnionType(), $code_base);
         $is_property_accessible = !$is_remote_access || $property->isPublic();
     }
     // If the property exists and is accessible, return it
     if ($is_property_accessible) {
         return $property;
     }
     // Check to see if we can use a __get magic method
     if ($this->hasMethodWithName($code_base, '__get')) {
         $method = $this->getMethodByName($code_base, '__get');
         // Make sure the magic method is accessible
         if ($method->isPrivate()) {
             throw new IssueException(Issue::fromType(Issue::AccessPropertyPrivate)($context->getFile(), $context->getLineNumberStart(), [(string) $property_fqsen]));
         } else {
             if ($method->isProtected()) {
                 throw new IssueException(Issue::fromType(Issue::AccessPropertyProtected)($context->getFile(), $context->getLineNumberStart(), [(string) $property_fqsen]));
             }
         }
         $property = new Property($context, $name, $method->getUnionType(), 0, $property_fqsen);
         $this->addProperty($code_base, $property, new None());
         return $property;
     } else {
         if ($has_property) {
             // If we have a property, but its inaccessible, emit
             // an issue
             if ($property->isPrivate()) {
                 throw new IssueException(Issue::fromType(Issue::AccessPropertyPrivate)($context->getFile(), $context->getLineNumberStart(), ["{$this->getFQSEN()}::\${$property->getName()}"]));
             }
             if ($property->isProtected()) {
                 throw new IssueException(Issue::fromType(Issue::AccessPropertyProtected)($context->getFile(), $context->getLineNumberStart(), ["{$this->getFQSEN()}::\${$property->getName()}"]));
             }
         }
     }
     // Check to see if missing properties are allowed
     // or we're stdclass
     if (Config::get()->allow_missing_properties || $this->getFQSEN() == FullyQualifiedClassName::getStdClassFQSEN()) {
         $property = new Property($context, $name, new UnionType(), 0, $property_fqsen);
         $this->addProperty($code_base, $property, new None());
         return $property;
     }
     throw new IssueException(Issue::fromType(Issue::UndeclaredProperty)($context->getFile(), $context->getLineNumberStart(), ["{$this->getFQSEN()}::\${$name}}"]));
 }
示例#7
0
 /**
  * @param string $name
  * The name of the property
  *
  * @param Context $context
  * The context of the caller requesting the property
  *
  * @return Property
  * A property with the given name
  *
  * @throws IssueException
  * An exception may be thrown if the caller does not
  * have access to the given property from the given
  * context
  */
 public function getPropertyByNameInContext(CodeBase $code_base, string $name, Context $context) : Property
 {
     // Check to see if we have the property
     if (!$code_base->hasProperty($this->getFQSEN(), $name)) {
         // If we don't have the property but do have a
         // __get method, then we can create the property
         if ($this->hasMethodWithName($code_base, '__get')) {
             $property = new Property($context, $name, new UnionType(), 0);
             $property->setFQSEN(FullyQualifiedPropertyName::make($this->getFQSEN(), $name));
             $this->addProperty($code_base, $property);
         } else {
             throw new IssueException(Issue::fromType(Issue::UndeclaredProperty)($context->getFile(), $context->getLineNumberStart(), ["{$this->getFQSEN()}::\${$name}}"]));
         }
     }
     $property = $code_base->getProperty($this->getFQSEN(), $name);
     // If we're getting the property from outside of this
     // class and the property isn't public and we don't
     // have a getter or setter, emit an access error
     if ((!$context->hasClassFQSEN() || $context->getClassFQSEN() != $this->getFQSEN()) && !$property->isPublic() && !$this->hasMethodWithName($code_base, '__get') && !$this->hasMethodWithName($code_base, '__set')) {
         if ($property->isPrivate()) {
             throw new IssueException(Issue::fromType(Issue::AccessPropertyPrivate)($context->getFile(), $context->getLineNumberStart(), ["{$this->getFQSEN()}::\${$property->getName()}"]));
         }
         if ($property->isProtected()) {
             throw new IssueException(Issue::fromType(Issue::AccessPropertyProtected)($context->getFile(), $context->getLineNumberStart(), ["{$this->getFQSEN()}::\${$property->getName()}"]));
         }
     }
     return $property;
 }
示例#8
0
文件: UnionType.php 项目: tpunt/phan
 /**
  * @param CodeBase $code_base
  * The code base in which to find classes
  *
  * @param Context $context
  * The context in which we're resolving this union
  * type.
  *
  * @return Clazz[]
  * A list of classes representing the non-native types
  * associated with this UnionType
  *
  * @throws CodeBaseException
  * An exception is thrown if a non-native type does not have
  * an associated class
  */
 public function asClassList(CodeBase $code_base, Context $context)
 {
     // Iterate over each viable class type to see if any
     // have the constant we're looking for
     foreach ($this->nonNativeTypes()->getTypeSet() as $class_type) {
         // Get the class FQSEN
         $class_fqsen = $class_type->asFQSEN();
         if ($class_type->isStaticType()) {
             if (!$context->isInClassScope()) {
                 throw new IssueException(Issue::fromType(Issue::ContextNotObject)($context->getFile(), $context->getLineNumberStart(), [(string) $class_type]));
             }
             (yield $context->getClassInScope($code_base));
         } else {
             // See if the class exists
             if (!$code_base->hasClassWithFQSEN($class_fqsen)) {
                 throw new CodeBaseException($class_fqsen, "Cannot find class {$class_fqsen}");
             }
             (yield $code_base->getClassByFQSEN($class_fqsen));
         }
     }
 }