@@ -586,35 +586,28 @@ class Config
586586 public $ threads ;
587587
588588 /**
589+ * A list of php extensions supported by Psalm.
590+ * Where key - extension name (without ext- prefix), value - whether to load extension’s stub.
591+ *
589592 * @psalm-readonly-allow-private-mutation
590- * @var array{
591- * decimal: bool,
592- * dom: bool,
593- * ds: bool,
594- * geos: bool,
595- * gmp: bool,
596- * mongodb: bool,
597- * mysqli: bool,
598- * pdo: bool,
599- * simplexml: bool,
600- * soap: bool,
601- * xdebug: bool,
602- * ffi: bool,
603- * }
593+ * @var array<string, bool>
604594 */
605595 public $ php_extensions = [
596+ "apcu " => false ,
606597 "decimal " => false ,
607598 "dom " => false ,
608599 "ds " => false ,
600+ "ffi " => false ,
609601 "geos " => false ,
610602 "gmp " => false ,
611603 "mongodb " => false ,
612604 "mysqli " => false ,
613605 "pdo " => false ,
606+ "random " => false ,
607+ "redis " => false ,
614608 "simplexml " => false ,
615609 "soap " => false ,
616610 "xdebug " => false ,
617- "ffi " => false ,
618611 ];
619612
620613 /**
@@ -1038,7 +1031,6 @@ private static function fromXmlAndPaths(
10381031 }
10391032 foreach ($ required_extensions as $ required_ext => $ _ ) {
10401033 if (isset ($ config ->php_extensions [$ required_ext ])) {
1041- /** @psalm-suppress PropertyTypeCoercion isset doesn't narrow $required_ext like it should */
10421034 $ config ->php_extensions [$ required_ext ] = true ;
10431035 } else {
10441036 $ config ->php_extensions_not_supported [$ required_ext ] = true ;
@@ -2138,28 +2130,24 @@ public function visitStubFiles(Codebase $codebase, ?Progress $progress = null):
21382130 $ this ->internal_stubs [] = $ stringable_path ;
21392131 }
21402132
2133+ $ ext_stubs_dir = $ dir_lvl_2 . DIRECTORY_SEPARATOR . "stubs " . DIRECTORY_SEPARATOR . "extensions " ;
21412134 foreach ($ this ->php_extensions as $ ext => $ enabled ) {
21422135 if ($ enabled ) {
2143- $ this ->internal_stubs [] = $ dir_lvl_2 . DIRECTORY_SEPARATOR . "stubs "
2144- . DIRECTORY_SEPARATOR . "extensions " . DIRECTORY_SEPARATOR . "$ ext.phpstub " ;
2136+ $ this ->internal_stubs [] = $ ext_stubs_dir . DIRECTORY_SEPARATOR . "$ ext.phpstub " ;
21452137 }
21462138 }
21472139
2148- // phpredis
2149- if (extension_loaded ('redis ' )) {
2150- $ ext_phpredis_path = $ dir_lvl_2 . DIRECTORY_SEPARATOR . 'stubs ' . DIRECTORY_SEPARATOR . 'phpredis.phpstub ' ;
2151- $ this ->internal_stubs [] = $ ext_phpredis_path ;
2152- }
2153-
2154- if (extension_loaded ('apcu ' )) {
2155- $ ext_apcu_path = $ dir_lvl_2 . DIRECTORY_SEPARATOR . 'stubs ' . DIRECTORY_SEPARATOR . 'ext-apcu.phpstub ' ;
2156- $ this ->internal_stubs [] = $ ext_apcu_path ;
2157- }
2158-
2159- if (extension_loaded ('random ' )) {
2160- $ ext_random_path = $ dir_lvl_2 . DIRECTORY_SEPARATOR . 'stubs ' . DIRECTORY_SEPARATOR
2161- . 'extensions ' . DIRECTORY_SEPARATOR . 'ext-random.phpstub ' ;
2162- $ this ->internal_stubs [] = $ ext_random_path ;
2140+ /** @deprecated Will be removed in Psalm 6 */
2141+ $ extensions_to_load_stubs_using_deprecated_way = ['apcu ' , 'random ' , 'redis ' ];
2142+ foreach ($ extensions_to_load_stubs_using_deprecated_way as $ ext_name ) {
2143+ $ ext_stub_path = $ ext_stubs_dir . DIRECTORY_SEPARATOR . "$ ext_name.phpstub " ;
2144+ $ is_stub_already_loaded = in_array ($ ext_stub_path , $ this ->internal_stubs , true );
2145+ if (! $ is_stub_already_loaded && extension_loaded ($ ext_name )) {
2146+ $ this ->internal_stubs [] = $ ext_stub_path ;
2147+ $ progress ->write ("Deprecation: Psalm stubs for ext- $ ext_name loaded using legacy way. "
2148+ . " Instead, please declare ext- $ ext_name as dependency in composer.json "
2149+ . " or use <enableExtensions> directive in Psalm config. \n" );
2150+ }
21632151 }
21642152
21652153 foreach ($ this ->internal_stubs as $ stub_path ) {
0 commit comments