@ -186,15 +186,15 @@ class Context {
}
}
class ArrayType extends SimpleType {
class ArrayType extends SimpleType {
private /* readonly */ Type $keyType;
private /* readonly */ Stub Type $keyType;
private /* readonly */ Type $valueType;
private /* readonly */ Stub Type $valueType;
public static function createGenericArray(): self
public static function createGenericArray(): self
{
{
return new ArrayType(Type::fromString("int|string"), Type::fromString("mixed|ref"));
return new ArrayType(Stub Type::fromString("int|string"), Stub Type::fromString("mixed|ref"));
}
}
public function __construct(Type $keyType, Type $valueType)
public function __construct(Stub Type $keyType, Stub Type $valueType)
{
{
parent::__construct("array", true);
parent::__construct("array", true);
@ -217,8 +217,8 @@ class ArrayType extends SimpleType {
return false;
return false;
}
}
return Type::equals($this->keyType, $other->keyType) & &
return Stub Type::equals($this->keyType, $other->keyType) & &
Type::equals($this->valueType, $other->valueType);
Stub Type::equals($this->valueType, $other->valueType);
}
}
}
}
@ -299,7 +299,7 @@ class SimpleType {
$matches = [];
$matches = [];
$isArray = preg_match("/(.*)\s*\[\s*\]/", $typeString, $matches);
$isArray = preg_match("/(.*)\s*\[\s*\]/", $typeString, $matches);
if ($isArray) {
if ($isArray) {
return new ArrayType(Type::fromString("int"), Type::fromString($matches[1]));
return new ArrayType(Stub Type::fromString("int"), Stub Type::fromString($matches[1]));
}
}
$matches = [];
$matches = [];
@ -309,7 +309,7 @@ class SimpleType {
throw new Exception("array< > type hint must have both a key and a value");
throw new Exception("array< > type hint must have both a key and a value");
}
}
return new ArrayType(Type::fromString($matches[1]), Type::fromString($matches[3]));
return new ArrayType(Stub Type::fromString($matches[1]), Stub Type::fromString($matches[3]));
}
}
return new SimpleType($typeString, false);
return new SimpleType($typeString, false);
@ -521,27 +521,27 @@ class SimpleType {
}
}
}
}
// Instances of Type are immutable and do not need to be cloned
// Instances of Stub Type are immutable and do not need to be cloned
// when held by an object that is cloned
// when held by an object that is cloned
class Type {
class Stub Type {
/** @var SimpleType[] */
/** @var SimpleType[] */
public /* readonly */ array $types;
public /* readonly */ array $types;
public /* readonly */ bool $isIntersection;
public /* readonly */ bool $isIntersection;
public static function fromNode(Node $node): Type {
public static function fromNode(Node $node): Stub Type {
if ($node instanceof Node\UnionType || $node instanceof Node\IntersectionType) {
if ($node instanceof Node\UnionType || $node instanceof Node\IntersectionType) {
$nestedTypeObjects = array_map(['Type', 'fromNode'], $node->types);
$nestedTypeObjects = array_map(['Stub Type', 'fromNode'], $node->types);
$types = [];
$types = [];
foreach ($nestedTypeObjects as $typeObject) {
foreach ($nestedTypeObjects as $typeObject) {
array_push($types, ...$typeObject->types);
array_push($types, ...$typeObject->types);
}
}
return new Type($types, ($node instanceof Node\IntersectionType));
return new Stub Type($types, ($node instanceof Node\IntersectionType));
}
}
if ($node instanceof Node\NullableType) {
if ($node instanceof Node\NullableType) {
return new Type(
return new Stub Type(
[
[
...Type::fromNode($node->type)->types,
...Stub Type::fromNode($node->type)->types,
SimpleType::null(),
SimpleType::null(),
],
],
false
false
@ -549,7 +549,7 @@ class Type {
}
}
if ($node instanceof Node\Identifier & & $node->toLowerString() === "iterable") {
if ($node instanceof Node\Identifier & & $node->toLowerString() === "iterable") {
return new Type(
return new Stub Type(
[
[
SimpleType::fromString("Traversable"),
SimpleType::fromString("Traversable"),
ArrayType::createGenericArray(),
ArrayType::createGenericArray(),
@ -558,7 +558,7 @@ class Type {
);
);
}
}
return new Type([SimpleType::fromNode($node)], false);
return new Stub Type([SimpleType::fromNode($node)], false);
}
}
public static function fromString(string $typeString): self {
public static function fromString(string $typeString): self {
@ -596,7 +596,7 @@ class Type {
}
}
}
}
return new Type($simpleTypes, $isIntersection);
return new Stub Type($simpleTypes, $isIntersection);
}
}
/**
/**
@ -706,7 +706,7 @@ class Type {
return $typeElement;
return $typeElement;
}
}
public static function equals(?Type $a, ?Type $b): bool {
public static function equals(?Stub Type $a, ?Stub Type $b): bool {
if ($a === null || $b === null) {
if ($a === null || $b === null) {
return $a === $b;
return $a === $b;
}
}
@ -776,8 +776,8 @@ class ArgInfo {
public /* readonly */ string $name;
public /* readonly */ string $name;
public /* readonly */ string $sendBy;
public /* readonly */ string $sendBy;
public /* readonly */ bool $isVariadic;
public /* readonly */ bool $isVariadic;
public ?Type $type;
public ?Stub Type $type;
private /* readonly */ ?Type $phpDocType;
private /* readonly */ ?Stub Type $phpDocType;
public ?string $defaultValue;
public ?string $defaultValue;
/** @var AttributeInfo[] */
/** @var AttributeInfo[] */
public array $attributes;
public array $attributes;
@ -789,8 +789,8 @@ class ArgInfo {
string $name,
string $name,
string $sendBy,
string $sendBy,
bool $isVariadic,
bool $isVariadic,
?Type $type,
?Stub Type $type,
?Type $phpDocType,
?Stub Type $phpDocType,
?string $defaultValue,
?string $defaultValue,
array $attributes
array $attributes
) {
) {
@ -807,11 +807,11 @@ class ArgInfo {
return $this->name === $other->name
return $this->name === $other->name
& & $this->sendBy === $other->sendBy
& & $this->sendBy === $other->sendBy
& & $this->isVariadic === $other->isVariadic
& & $this->isVariadic === $other->isVariadic
& & Type::equals($this->type, $other->type)
& & Stub Type::equals($this->type, $other->type)
& & $this->defaultValue === $other->defaultValue;
& & $this->defaultValue === $other->defaultValue;
}
}
public function getMethodSynopsisType(): Type {
public function getMethodSynopsisType(): Stub Type {
if ($this->type) {
if ($this->type) {
return $this->type;
return $this->type;
}
}
@ -1116,15 +1116,15 @@ class ReturnInfo {
private /* readonly */ bool $byRef;
private /* readonly */ bool $byRef;
// NOT readonly - gets removed when discarding info for older PHP versions
// NOT readonly - gets removed when discarding info for older PHP versions
public ?Type $type;
public ?Stub Type $type;
public /* readonly */ ?Type $phpDocType;
public /* readonly */ ?Stub Type $phpDocType;
public /* readonly */ bool $tentativeReturnType;
public /* readonly */ bool $tentativeReturnType;
public /* readonly */ string $refcount;
public /* readonly */ string $refcount;
public function __construct(
public function __construct(
bool $byRef,
bool $byRef,
?Type $type,
?Stub Type $type,
?Type $phpDocType,
?Stub Type $phpDocType,
bool $tentativeReturnType,
bool $tentativeReturnType,
?string $refcount
?string $refcount
) {
) {
@ -1137,11 +1137,11 @@ class ReturnInfo {
public function equalsApartFromPhpDocAndRefcount(ReturnInfo $other): bool {
public function equalsApartFromPhpDocAndRefcount(ReturnInfo $other): bool {
return $this->byRef === $other->byRef
return $this->byRef === $other->byRef
& & Type::equals($this->type, $other->type)
& & Stub Type::equals($this->type, $other->type)
& & $this->tentativeReturnType === $other->tentativeReturnType;
& & $this->tentativeReturnType === $other->tentativeReturnType;
}
}
public function getMethodSynopsisType(): ?Type {
public function getMethodSynopsisType(): ?Stub Type {
return $this->type ?? $this->phpDocType;
return $this->type ?? $this->phpDocType;
}
}
@ -2513,8 +2513,8 @@ class EvaluatedValue
abstract class VariableLike
abstract class VariableLike
{
{
protected int $flags;
protected int $flags;
public ?Type $type;
public ?Stub Type $type;
public /* readonly */ ?Type $phpDocType;
public /* readonly */ ?Stub Type $phpDocType;
private /* readonly */ ?string $link;
private /* readonly */ ?string $link;
protected ?int $phpVersionIdMinimumCompatibility;
protected ?int $phpVersionIdMinimumCompatibility;
/** @var AttributeInfo[] */
/** @var AttributeInfo[] */
@ -2526,8 +2526,8 @@ abstract class VariableLike
*/
*/
public function __construct(
public function __construct(
int $flags,
int $flags,
?Type $type,
?Stub Type $type,
?Type $phpDocType,
?Stub Type $phpDocType,
?string $link,
?string $link,
?int $phpVersionIdMinimumCompatibility,
?int $phpVersionIdMinimumCompatibility,
array $attributes,
array $attributes,
@ -2684,8 +2684,8 @@ class ConstInfo extends VariableLike
int $flags,
int $flags,
Expr $value,
Expr $value,
?string $valueString,
?string $valueString,
?Type $type,
?Stub Type $type,
?Type $phpDocType,
?Stub Type $phpDocType,
bool $isDeprecated,
bool $isDeprecated,
?string $cond,
?string $cond,
?string $cValue,
?string $cValue,
@ -3212,8 +3212,8 @@ class PropertyInfo extends VariableLike
PropertyName $name,
PropertyName $name,
int $classFlags,
int $classFlags,
int $flags,
int $flags,
?Type $type,
?Stub Type $type,
?Type $phpDocType,
?Stub Type $phpDocType,
?Expr $defaultValue,
?Expr $defaultValue,
?string $defaultValueString,
?string $defaultValueString,
bool $isDocReadonly,
bool $isDocReadonly,
@ -5018,11 +5018,11 @@ function parseFunctionLike(
throw new Exception("Only the last parameter can be variadic");
throw new Exception("Only the last parameter can be variadic");
}
}
$type = $param->type ? Type::fromNode($param->type) : null;
$type = $param->type ? Stub Type::fromNode($param->type) : null;
if ($type === null & & !isset($docParamTypes[$varName])) {
if ($type === null & & !isset($docParamTypes[$varName])) {
$defaultParamType = getMagicMethodDefaultParamType($name, $i);
$defaultParamType = getMagicMethodDefaultParamType($name, $i);
if ($defaultParamType !== null) {
if ($defaultParamType !== null) {
$type = Type::fromString($defaultParamType);
$type = Stub Type::fromString($defaultParamType);
} else {
} else {
$docParamTypes[$varName] = 'mixed';
$docParamTypes[$varName] = 'mixed';
}
}
@ -5052,7 +5052,7 @@ function parseFunctionLike(
$sendBy,
$sendBy,
$param->variadic,
$param->variadic,
$type,
$type,
isset($docParamTypes[$varName]) ? Type::fromString($docParamTypes[$varName]) : null,
isset($docParamTypes[$varName]) ? Stub Type::fromString($docParamTypes[$varName]) : null,
$defaultValue,
$defaultValue,
AttributeInfo::createFromGroups($param->attrGroups)
AttributeInfo::createFromGroups($param->attrGroups)
);
);
@ -5072,8 +5072,8 @@ function parseFunctionLike(
$return = new ReturnInfo(
$return = new ReturnInfo(
$func->returnsByRef(),
$func->returnsByRef(),
$returnType ? Type::fromNode($returnType) : null,
$returnType ? Stub Type::fromNode($returnType) : null,
$docReturnType ? Type::fromString($docReturnType) : null,
$docReturnType ? Stub Type::fromString($docReturnType) : null,
$tentativeReturnType,
$tentativeReturnType,
$refcount
$refcount
);
);
@ -5163,8 +5163,8 @@ function parseConstLike(
}
}
}
}
$constType = $type ? Type::fromNode($type) : null;
$constType = $type ? Stub Type::fromNode($type) : null;
$constPhpDocType = $phpDocType ? Type::fromString($phpDocType) : null;
$constPhpDocType = $phpDocType ? Stub Type::fromString($phpDocType) : null;
if ($const->value instanceof Expr\ConstFetch & &
if ($const->value instanceof Expr\ConstFetch & &
$const->value->name->toLowerString() === "null" & &
$const->value->name->toLowerString() === "null" & &
@ -5225,9 +5225,9 @@ function parseProperty(
}
}
}
}
$propertyType = $type ? Type::fromNode($type) : null;
$propertyType = $type ? Stub Type::fromNode($type) : null;
if ($propertyType === null & & !$phpDocType) {
if ($propertyType === null & & !$phpDocType) {
$propertyType = Type::fromString("mixed");
$propertyType = Stub Type::fromString("mixed");
}
}
if ($property->default instanceof Expr\ConstFetch & &
if ($property->default instanceof Expr\ConstFetch & &
@ -5245,7 +5245,7 @@ function parseProperty(
$classFlags,
$classFlags,
$flags,
$flags,
$propertyType,
$propertyType,
$phpDocType ? Type::fromString($phpDocType) : null,
$phpDocType ? Stub Type::fromString($phpDocType) : null,
$property->default,
$property->default,
$property->default ? $prettyPrinter->prettyPrintExpr($property->default) : null,
$property->default ? $prettyPrinter->prettyPrintExpr($property->default) : null,
$isDocReadonly,
$isDocReadonly,