Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Shadow StaticCallHandler natively
The static call handler with its Closure::bind() scope factory, type,
specify-types, create-types and assert-mapping callbacks as native closures,
registered as the class's handler entry. The PHP collaborator sites and value
helpers it shares with MethodCallHandler (ArgumentsHandler, ArgumentsNormalizer,
ParametersAcceptorSelector, acceptors, Assertions, array_merge(), the explicit
never check, template resolution against an acceptor) move into
CallHandlerSupport.h; its array_merge() now also keeps the engine's shortcut for
an empty side over a string-keyed map ([] + [] stays the shared empty array).
New entries: pt_mutating_scope_resolve_name / _enter_closure_bind,
pt_class_reflection_is / _is_subclass_of_class,
pt_type_specifier_get_static_method_type_specifying_extensions_for_class.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Q3SmhnNkB3pEeVRTxqbdbu
  • Loading branch information
ondrejmirtes and claude committed Sep 22, 2026
commit fce1e134ad8d799171d0d359a82ac1c34dfbc7a4
2 changes: 2 additions & 0 deletions src/Analyser/ExprHandler/StaticCallHandler.php
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@
use PHPStan\Reflection\ParametersAcceptorSelector;
use PHPStan\Reflection\ReflectionProvider;
use PHPStan\ShouldNotHappenException;
use PHPStan\Turbo\ShadowedByTurboExtension;
use PHPStan\Type\ErrorType;
use PHPStan\Type\Generic\TemplateTypeHelper;
use PHPStan\Type\Generic\TemplateTypeVariance;
Expand All @@ -66,6 +67,7 @@
* @implements ExprHandler<StaticCall>
*/
#[AutowiredService]
#[ShadowedByTurboExtension(implementation: __DIR__ . '/../../../turbo-ext/src/StaticCallHandler.cpp')]
final class StaticCallHandler implements ExprHandler
{

Expand Down
2 changes: 1 addition & 1 deletion turbo-ext/config.w32
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ if (PHP_PHPSTAN_TURBO != "no") {
// directory by splitting on backslashes only — with forward slashes the
// objects compile flat while the link list expects the subpath
EXTENSION("phpstan_turbo",
"src\\main.cpp src\\support.cpp src\\AbsorbedTemplateArgumentType.cpp src\\AcceptsResult.cpp src\\AccessoryArrayListType.cpp src\\AccessoryDecimalIntegerStringType.cpp src\\AccessoryLiteralStringType.cpp src\\AccessoryLowercaseStringType.cpp src\\AccessoryNonEmptyStringType.cpp src\\AccessoryNonFalsyStringType.cpp src\\AccessoryNumericStringType.cpp src\\AccessoryUppercaseStringType.cpp src\\ArenaCache.cpp src\\ArgsResult.cpp src\\ArrayFilterArgVisitor.cpp src\\ArrayFindArgVisitor.cpp src\\ArrayMapArgVisitor.cpp src\\ArrayOffsetNormalizingVisitor.cpp src\\ArrayType.cpp src\\ArrayWalkArgVisitor.cpp src\\ArrowFunctionArgVisitor.cpp src\\AssignHandler.cpp src\\AssignOpHandler.cpp src\\AssignTargetWalkMode.cpp src\\BenevolentUnionType.cpp src\\BlockHandler.cpp src\\BooleanNarrowingHelper.cpp src\\BooleanType.cpp src\\CallableType.cpp src\\CallableTypeHelper.cpp src\\CallbackUnresolvedMethodPrototypeReflection.cpp src\\CallbackUnresolvedPropertyPrototypeReflection.cpp src\\CalledOnTypeUnresolvedMethodPrototypeReflection.cpp src\\CalledOnTypeUnresolvedPropertyPrototypeReflection.cpp src\\ChangedTypeMethodReflection.cpp src\\CircularTypeAliasErrorType.cpp src\\ClassConstantAccessType.cpp src\\ClassLikeHandler.cpp src\\ClassMethodHandler.cpp src\\ClassReflection.cpp src\\ClassStatementsGatherer.cpp src\\ClassStringType.cpp src\\ClosureArgVisitor.cpp src\\ClosureBindArgVisitor.cpp src\\ClosureBindToVarVisitor.cpp src\\ClosureType.cpp src\\CombinationsHelper.cpp src\\ConditionalExpressionHolder.cpp src\\ConditionalExpressionHolderHelper.cpp src\\ConditionalExpressionHolderRecipe.cpp src\\ConditionalType.cpp src\\ConditionalTypeForParameter.cpp src\\ConstantArrayType.cpp src\\ConstantArrayTypeBuilder.cpp src\\ConstantBooleanType.cpp src\\ConstantFloatType.cpp src\\ConstantIntegerType.cpp src\\ConstantStringType.cpp src\\ConstantTypeHelper.cpp src\\CurlSetOptArgVisitor.cpp src\\CurlSetOptArrayArgVisitor.cpp src\\DeclarePositionVisitor.cpp src\\DefaultNarrowingHelper.cpp src\\DisjunctionBranchUnionAugment.cpp src\\DisjunctionHolderProjectionAugment.cpp src\\DynamicReturnTypeStoragePrimer.cpp src\\EarlyTerminatingCallHelper.cpp src\\EchoHandler.cpp src\\EndStatementResult.cpp src\\Engine.cpp src\\EnumCaseObjectType.cpp src\\ErrorType.cpp src\\ExpressionContext.cpp src\\ExpressionHandler.cpp src\\ExpressionResult.cpp src\\ExpressionResultStorage.cpp src\\ExpressionResultStorageStack.cpp src\\ExpressionTypeHolder.cpp src\\ExprHandlerRegistry.cpp src\\ExprPrinter.cpp src\\FiniteTypeSet.cpp src\\FloatType.cpp src\\FunctionHandler.cpp src\\GenericClassStringType.cpp src\\GenericObjectType.cpp src\\GenericStaticType.cpp src\\GetTemplateTypeType.cpp src\\HasMethodType.cpp src\\HasOffsetType.cpp src\\HasOffsetValueType.cpp src\\HasPropertyType.cpp src\\IdenticalNarrowingHelper.cpp src\\IfHandler.cpp src\\ImmediatelyInvokedClosureVisitor.cpp src\\ImplodeArgVisitor.cpp src\\ImpurePoint.cpp src\\IntegerRangeType.cpp src\\IntegerType.cpp src\\InternalEndStatementResult.cpp src\\InternalStatementExitPoint.cpp src\\InternalStatementResult.cpp src\\InternalThrowPoint.cpp src\\IntersectionType.cpp src\\IssetabilityDescriptor.cpp src\\IsSuperTypeOfResult.cpp src\\IterableType.cpp src\\KeyOfType.cpp src\\LateResolvableArrayShapeType.cpp src\\LruCache.cpp src\\MagicConstantParamDefaultVisitor.cpp src\\MethodCallHandler.cpp src\\MethodCallReturnTypeHelper.cpp src\\MethodThrowPointHelper.cpp src\\MixedType.cpp src\\MutatingScope.cpp src\\NativeParameterReflection.cpp src\\NeverType.cpp src\\NewAssignedToPropertyVisitor.cpp src\\NewObjectType.cpp src\\NodeScanner.cpp src\\NodeScopeResolver.cpp src\\NodeTraverser.cpp src\\NonAcceptingNeverType.cpp src\\NonEmptyArrayType.cpp src\\NonexistentParentClassType.cpp src\\NonNullabilityHelper.cpp src\\NopHandler.cpp src\\NullType.cpp src\\ObjectShapeType.cpp src\\ObjectType.cpp src\\ObjectWithoutClassType.cpp src\\OffsetAccessType.cpp src\\OversizedArrayType.cpp src\\ParentStmtTypesVisitor.cpp src\\PharForkGuard.cpp src\\PhpClassReflectionExtension.cpp src\\PhpFileCleaner.cpp src\\PreparedAssignTarget.cpp src\\RecordingNodeCallback.cpp src\\RecursionGuard.cpp src\\ReflectionAccess.cpp src\\ResolvedMethodReflection.cpp src\\ResourceType.cpp src\\ReturnHandler.cpp src\\ScalarHandler.cpp src\\ScopeContext.cpp src\\ScopeOps.cpp src\\Shadow.cpp src\\SimpleImpurePoint.cpp src\\SpecifiedTypes.cpp src\\StatementContext.cpp src\\StatementExitPoint.cpp src\\StatementListWalkState.cpp src\\StatementResult.cpp src\\StatementsHandler.cpp src\\StaticType.cpp src\\StaticTypeFactory.cpp src\\StmtHandlerRegistry.cpp src\\StrictMixedType.cpp src\\StringAlwaysAcceptingObjectWithToStringType.cpp src\\StringNeverAcceptingObjectWithToStringType.cpp src\\StringType.cpp src\\SymbolFinderInFiles.cpp src\\TemplateArgumentFrame.cpp src\\TemplateArrayType.cpp src\\TemplateBenevolentUnionType.cpp src\\TemplateBooleanType.cpp src\\TemplateConstantArrayType.cpp src\\TemplateConstantIntegerType.cpp src\\TemplateConstantStringType.cpp src\\TemplateFloatType.cpp src\\TemplateGenericObjectType.cpp src\\TemplateIntegerType.cpp src\\TemplateIntersectionType.cpp src\\TemplateIterableType.cpp src\\TemplateKeyOfType.cpp src\\TemplateMixedType.cpp src\\TemplateNullType.cpp src\\TemplateObjectShapeType.cpp src\\TemplateObjectType.cpp src\\TemplateObjectWithoutClassType.cpp src\\TemplateStrictMixedType.cpp src\\TemplateStringType.cpp src\\TemplateTypeArgumentStrategy.cpp src\\TemplateTypeFactory.cpp src\\TemplateTypeHelper.cpp src\\TemplateTypeMap.cpp src\\TemplateTypeParameterStrategy.cpp src\\TemplateTypeReference.cpp src\\TemplateTypeScope.cpp src\\TemplateTypeVariance.cpp src\\TemplateTypeVarianceMap.cpp src\\TemplateUnionType.cpp src\\ThisType.cpp src\\ThrowPoint.cpp src\\TraitCollectingVisitor.cpp src\\TrinaryLogic.cpp src\\TrustedTypes.cpp src\\TryCatchTypeVisitor.cpp src\\TypeCombinator.cpp src\\TypeCombinatorCache.cpp src\\TypehintHelper.cpp src\\TypeOps.cpp src\\TypeProjectionHelper.cpp src\\TypeResult.cpp src\\TypeSpecifier.cpp src\\TypeSpecifierContext.cpp src\\TypeTraits.cpp src\\TypeTraverser.cpp src\\TypeTraverserInstanceofVisitor.cpp src\\TypeUtils.cpp src\\UnionType.cpp src\\UnionTypeHelper.cpp src\\UnresolvableTypeHelper.cpp src\\UnresolvedTemplateArgumentType.cpp src\\ValueOfType.cpp src\\VariableFlow.cpp src\\VariableFlowBuilder.cpp src\\VariableHandler.cpp src\\VariableLivenessResolver.cpp src\\VerbosityLevel.cpp src\\VoidType.cpp src\\VolatileExpressionHelper.cpp",
"src\\main.cpp src\\support.cpp src\\AbsorbedTemplateArgumentType.cpp src\\AcceptsResult.cpp src\\AccessoryArrayListType.cpp src\\AccessoryDecimalIntegerStringType.cpp src\\AccessoryLiteralStringType.cpp src\\AccessoryLowercaseStringType.cpp src\\AccessoryNonEmptyStringType.cpp src\\AccessoryNonFalsyStringType.cpp src\\AccessoryNumericStringType.cpp src\\AccessoryUppercaseStringType.cpp src\\ArenaCache.cpp src\\ArgsResult.cpp src\\ArrayFilterArgVisitor.cpp src\\ArrayFindArgVisitor.cpp src\\ArrayMapArgVisitor.cpp src\\ArrayOffsetNormalizingVisitor.cpp src\\ArrayType.cpp src\\ArrayWalkArgVisitor.cpp src\\ArrowFunctionArgVisitor.cpp src\\AssignHandler.cpp src\\AssignOpHandler.cpp src\\AssignTargetWalkMode.cpp src\\BenevolentUnionType.cpp src\\BlockHandler.cpp src\\BooleanNarrowingHelper.cpp src\\BooleanType.cpp src\\CallableType.cpp src\\CallableTypeHelper.cpp src\\CallbackUnresolvedMethodPrototypeReflection.cpp src\\CallbackUnresolvedPropertyPrototypeReflection.cpp src\\CalledOnTypeUnresolvedMethodPrototypeReflection.cpp src\\CalledOnTypeUnresolvedPropertyPrototypeReflection.cpp src\\ChangedTypeMethodReflection.cpp src\\CircularTypeAliasErrorType.cpp src\\ClassConstantAccessType.cpp src\\ClassLikeHandler.cpp src\\ClassMethodHandler.cpp src\\ClassReflection.cpp src\\ClassStatementsGatherer.cpp src\\ClassStringType.cpp src\\ClosureArgVisitor.cpp src\\ClosureBindArgVisitor.cpp src\\ClosureBindToVarVisitor.cpp src\\ClosureType.cpp src\\CombinationsHelper.cpp src\\ConditionalExpressionHolder.cpp src\\ConditionalExpressionHolderHelper.cpp src\\ConditionalExpressionHolderRecipe.cpp src\\ConditionalType.cpp src\\ConditionalTypeForParameter.cpp src\\ConstantArrayType.cpp src\\ConstantArrayTypeBuilder.cpp src\\ConstantBooleanType.cpp src\\ConstantFloatType.cpp src\\ConstantIntegerType.cpp src\\ConstantStringType.cpp src\\ConstantTypeHelper.cpp src\\CurlSetOptArgVisitor.cpp src\\CurlSetOptArrayArgVisitor.cpp src\\DeclarePositionVisitor.cpp src\\DefaultNarrowingHelper.cpp src\\DisjunctionBranchUnionAugment.cpp src\\DisjunctionHolderProjectionAugment.cpp src\\DynamicReturnTypeStoragePrimer.cpp src\\EarlyTerminatingCallHelper.cpp src\\EchoHandler.cpp src\\EndStatementResult.cpp src\\Engine.cpp src\\EnumCaseObjectType.cpp src\\ErrorType.cpp src\\ExpressionContext.cpp src\\ExpressionHandler.cpp src\\ExpressionResult.cpp src\\ExpressionResultStorage.cpp src\\ExpressionResultStorageStack.cpp src\\ExpressionTypeHolder.cpp src\\ExprHandlerRegistry.cpp src\\ExprPrinter.cpp src\\FiniteTypeSet.cpp src\\FloatType.cpp src\\FunctionHandler.cpp src\\GenericClassStringType.cpp src\\GenericObjectType.cpp src\\GenericStaticType.cpp src\\GetTemplateTypeType.cpp src\\HasMethodType.cpp src\\HasOffsetType.cpp src\\HasOffsetValueType.cpp src\\HasPropertyType.cpp src\\IdenticalNarrowingHelper.cpp src\\IfHandler.cpp src\\ImmediatelyInvokedClosureVisitor.cpp src\\ImplodeArgVisitor.cpp src\\ImpurePoint.cpp src\\IntegerRangeType.cpp src\\IntegerType.cpp src\\InternalEndStatementResult.cpp src\\InternalStatementExitPoint.cpp src\\InternalStatementResult.cpp src\\InternalThrowPoint.cpp src\\IntersectionType.cpp src\\IssetabilityDescriptor.cpp src\\IsSuperTypeOfResult.cpp src\\IterableType.cpp src\\KeyOfType.cpp src\\LateResolvableArrayShapeType.cpp src\\LruCache.cpp src\\MagicConstantParamDefaultVisitor.cpp src\\MethodCallHandler.cpp src\\MethodCallReturnTypeHelper.cpp src\\MethodThrowPointHelper.cpp src\\MixedType.cpp src\\MutatingScope.cpp src\\NativeParameterReflection.cpp src\\NeverType.cpp src\\NewAssignedToPropertyVisitor.cpp src\\NewObjectType.cpp src\\NodeScanner.cpp src\\NodeScopeResolver.cpp src\\NodeTraverser.cpp src\\NonAcceptingNeverType.cpp src\\NonEmptyArrayType.cpp src\\NonexistentParentClassType.cpp src\\NonNullabilityHelper.cpp src\\NopHandler.cpp src\\NullType.cpp src\\ObjectShapeType.cpp src\\ObjectType.cpp src\\ObjectWithoutClassType.cpp src\\OffsetAccessType.cpp src\\OversizedArrayType.cpp src\\ParentStmtTypesVisitor.cpp src\\PharForkGuard.cpp src\\PhpClassReflectionExtension.cpp src\\PhpFileCleaner.cpp src\\PreparedAssignTarget.cpp src\\RecordingNodeCallback.cpp src\\RecursionGuard.cpp src\\ReflectionAccess.cpp src\\ResolvedMethodReflection.cpp src\\ResourceType.cpp src\\ReturnHandler.cpp src\\ScalarHandler.cpp src\\ScopeContext.cpp src\\ScopeOps.cpp src\\Shadow.cpp src\\SimpleImpurePoint.cpp src\\SpecifiedTypes.cpp src\\StatementContext.cpp src\\StatementExitPoint.cpp src\\StatementListWalkState.cpp src\\StatementResult.cpp src\\StatementsHandler.cpp src\\StaticCallHandler.cpp src\\StaticType.cpp src\\StaticTypeFactory.cpp src\\StmtHandlerRegistry.cpp src\\StrictMixedType.cpp src\\StringAlwaysAcceptingObjectWithToStringType.cpp src\\StringNeverAcceptingObjectWithToStringType.cpp src\\StringType.cpp src\\SymbolFinderInFiles.cpp src\\TemplateArgumentFrame.cpp src\\TemplateArrayType.cpp src\\TemplateBenevolentUnionType.cpp src\\TemplateBooleanType.cpp src\\TemplateConstantArrayType.cpp src\\TemplateConstantIntegerType.cpp src\\TemplateConstantStringType.cpp src\\TemplateFloatType.cpp src\\TemplateGenericObjectType.cpp src\\TemplateIntegerType.cpp src\\TemplateIntersectionType.cpp src\\TemplateIterableType.cpp src\\TemplateKeyOfType.cpp src\\TemplateMixedType.cpp src\\TemplateNullType.cpp src\\TemplateObjectShapeType.cpp src\\TemplateObjectType.cpp src\\TemplateObjectWithoutClassType.cpp src\\TemplateStrictMixedType.cpp src\\TemplateStringType.cpp src\\TemplateTypeArgumentStrategy.cpp src\\TemplateTypeFactory.cpp src\\TemplateTypeHelper.cpp src\\TemplateTypeMap.cpp src\\TemplateTypeParameterStrategy.cpp src\\TemplateTypeReference.cpp src\\TemplateTypeScope.cpp src\\TemplateTypeVariance.cpp src\\TemplateTypeVarianceMap.cpp src\\TemplateUnionType.cpp src\\ThisType.cpp src\\ThrowPoint.cpp src\\TraitCollectingVisitor.cpp src\\TrinaryLogic.cpp src\\TrustedTypes.cpp src\\TryCatchTypeVisitor.cpp src\\TypeCombinator.cpp src\\TypeCombinatorCache.cpp src\\TypehintHelper.cpp src\\TypeOps.cpp src\\TypeProjectionHelper.cpp src\\TypeResult.cpp src\\TypeSpecifier.cpp src\\TypeSpecifierContext.cpp src\\TypeTraits.cpp src\\TypeTraverser.cpp src\\TypeTraverserInstanceofVisitor.cpp src\\TypeUtils.cpp src\\UnionType.cpp src\\UnionTypeHelper.cpp src\\UnresolvableTypeHelper.cpp src\\UnresolvedTemplateArgumentType.cpp src\\ValueOfType.cpp src\\VariableFlow.cpp src\\VariableFlowBuilder.cpp src\\VariableHandler.cpp src\\VariableLivenessResolver.cpp src\\VerbosityLevel.cpp src\\VoidType.cpp src\\VolatileExpressionHelper.cpp",
true,
flags);
ADD_SOURCES(configure_module_dirname + "/src/parser",
Expand Down
Loading