vimeo / psalm

A static analysis tool for finding errors in PHP applications
https://psalm.dev
MIT License
5.58k stars 661 forks source link

query re: non-built-in extension functions #2620

Open SignpostMarv opened 4 years ago

SignpostMarv commented 4 years ago

If I were to patch in ext-imap stubs, is there a way that gets the function stubs into scope only if the extension is loaded or if the extension is not loaded but the code is inside an if (extension_loaded('imap')) {} condition- similar to the xdebug stub, except without it being manual?

psalm-github-bot[bot] commented 4 years ago

Hey @SignpostMarv, can you reproduce the issue on https://psalm.dev ?

SignpostMarv commented 4 years ago

Hey @SignpostMarv, can you reproduce the issue on https://psalm.dev ?

nope, see weirdan/psalm-github-bot#22

TysonAndre commented 4 years ago

One option would be to implement an option in psalm.xml mapping extension names to the path of a file to use if the extension isn't loaded.

In addition to that, add a tool to generate stubs from an environment where the extension is enabled - https://github.com/phan/phan/blob/master/tool/make_stubs is how Phan does that.

Phan has a similar config option to what you're requesting, which may be useful to refer to when implementing this

    // You can put paths to internal stubs in this config option.
    // Phan will continue using its detailed type annotations, but load the constants, classes, functions, and classes (and their Reflection types) from these stub files (doubling as valid php files).
    // Use a different extension from php to avoid accidentally loading these.
    // The 'mkstubs' script can be used to generate your own stubs (compatible with php 7.0+ right now)
    'autoload_internal_extension_signatures' => [
        'ast'         => '.phan/internal_stubs/ast.phan_php',
        'ctype'       => '.phan/internal_stubs/ctype.phan_php',
        'igbinary'    => '.phan/internal_stubs/igbinary.phan_php',
        'mbstring'    => '.phan/internal_stubs/mbstring.phan_php',
        'pcntl'       => '.phan/internal_stubs/pcntl.phan_php',
        'posix'       => '.phan/internal_stubs/posix.phan_php',
        'readline'    => '.phan/internal_stubs/readline.phan_php',
        'sysvmsg'     => '.phan/internal_stubs/sysvmsg.phan_php',
        'sysvsem'     => '.phan/internal_stubs/sysvsem.phan_php',
        'sysvshm'     => '.phan/internal_stubs/sysvshm.phan_php',
    ],
weirdan commented 4 years ago

mapping extension names to the path of a file to use if the extension isn't loaded.

I think what's @SignpostMarv is describing is exactly the opposite: a stub that has to be loaded if the extension is loaded. Type information available via reflection is often not enough for what Psalm is doing, so Psalm have to use stubs, CallMap.php, etc.

SignpostMarv commented 4 years ago

@weirdan yes but also if it is not actually loaded but is inside a matching condition.

TysonAndre commented 4 years ago

a stub that has to be loaded if the extension is loaded.

Oh, missed that part of the issue description.

SignpostMarv commented 4 years ago

@TysonAndre @weirdan it occurs to me that the baseline attribute I added in #1936 could be a source of which stubs to load regardless of which extensions were actually loaded?

AndrolGenhald commented 2 years ago

Part of this is accomplished with #7107. I'd love to conditionally load stubs for specific contexts to support if (extension_loaded(...)) {, but that's going to be more difficult.

SignpostMarv commented 2 years ago

Part of this is accomplished with #7107. I'd love to conditionally load stubs for specific contexts to support if (extension_loaded(...)) {, but that's going to be more difficult.

One would assume that doing a #2133 for all the things would spam up the config too much.

Or are you referring to avoiding RedundantCondition being flagged if the stub is always present?

AndrolGenhald commented 2 years ago

7107 uses extensions required in composer.json to decide whether to enable them. I was referring to:

is there a way that gets the function stubs into scope only if the extension is loaded

The conditionally loading part is a lot more difficult, but it would be very nice to have.

alies-dev commented 1 year ago

on a sidenote: I think imap should be moved callmaps to a separate stub as we did with other extensions not available by default:

image

ps: this will not solve the original issue of course