diff --git a/src/Handlers/Helpers/ConfigHandler.php b/src/Handlers/Helpers/ConfigHandler.php new file mode 100644 index 00000000..4a33537d --- /dev/null +++ b/src/Handlers/Helpers/ConfigHandler.php @@ -0,0 +1,105 @@ +getCallArgs(); + if (!isset($call_args[0])) { + return new Union([ + new TNamedObject(Repository::class), + ]); + } + + $argumentType = $call_args[0]->value; + + if (!isset($argumentType->value)) { + return null; + } + + $argumentValue = $argumentType->value; + + try { + // dynamic analysis + $returnValue = ApplicationProvider::getApp()->make('config')->get($argumentValue); + } catch (\Throwable $t) { + return null; + } + + // turn actual return value into a psalm type. there's probably a helper in psalm to do this, but i couldn't find one + switch (gettype($returnValue)) { + case 'boolean': + $type = new TBool(); + break; + case 'integer': + $type = new TLiteralInt($returnValue); + break; + case 'double': + $type = new TLiteralFloat($returnValue); + break; + case 'string': + $type = new TLiteralString($returnValue); + break; + case 'array': + $type = new TArray([ + new Union([new TArrayKey()]), + new Union([new TMixed()]), + ]); + break; + case 'object': + $type = new TNamedObject(get_class($returnValue)); + break; + case 'resource': + $type = new TResource(); + break; + case 'resource (closed)': + $type = new TClosedResource(); + break; + case 'NULL': + if (isset($call_args[1])) { + return $event->getStatementsSource()->getNodeTypeProvider()->getType($call_args[1]->value); + } + $type = new TNull(); + break; + case 'unknown type': + default: + $type = new TMixed(); + break; + } + + return new Union([ + $type, + ]); + } +} diff --git a/src/Plugin.php b/src/Plugin.php index c28bc1b5..aa203f6c 100644 --- a/src/Plugin.php +++ b/src/Plugin.php @@ -9,6 +9,7 @@ use Psalm\LaravelPlugin\Handlers\Eloquent\ModelPropertyAccessorHandler; use Psalm\LaravelPlugin\Handlers\Eloquent\ModelRelationshipPropertyHandler; use Psalm\LaravelPlugin\Handlers\Eloquent\RelationsMethodHandler; +use Psalm\LaravelPlugin\Handlers\Helpers\ConfigHandler; use Psalm\LaravelPlugin\Handlers\Helpers\PathHandler; use Psalm\LaravelPlugin\Handlers\Helpers\RedirectHandler; use Psalm\LaravelPlugin\Handlers\Helpers\TransHandler; @@ -99,6 +100,8 @@ private function registerHandlers(RegistrationInterface $registration): void $registration->registerHooksFromClass(RedirectHandler::class); require_once 'Handlers/SuppressHandler.php'; $registration->registerHooksFromClass(SuppressHandler::class); + require_once 'Handlers/Helpers/ConfigHandler.php'; + $registration->registerHooksFromClass(ConfigHandler::class); } private function generateStubFiles(): void diff --git a/tests/acceptance/ConfigTypes.feature b/tests/acceptance/ConfigTypes.feature new file mode 100644 index 00000000..0b8c852b --- /dev/null +++ b/tests/acceptance/ConfigTypes.feature @@ -0,0 +1,54 @@ +Feature: Config helper +The global config helper will return a strict type + +Background: +Given I have the following config +""" + + + + + + + + + + +""" +And I have the following code preamble +""" +