by

Where communities thrive


  • Join over 1.5M+ people
  • Join over 100K+ communities
  • Free without limits
  • Create your own community
People
Repo info
Activity
    Tyson Andre
    @TysonAndre
    phan/phan#3826 improves the error message for reflection-docblock requiring php 7.2+ when run in php 7.1.
    Kevin Gregull
    @KevinGregull
    Greetings, I thought I'd come in here to seek some help. I've been trying to get Phan for VS-Code to work for the past 2 Hours, and for some reason it does not seem to work for me. Current steps I've taken: PHP7.2 is installed, got myself AST, disabled all other plugins for vscode, added the analyzed Path in VS-Code. Verified that vs-code can find php by running "php -v". enabled logs for phan. Those tell me that the lang server has started and is accepting connection on localhost:someport (It does also show in vs-codes process explorer). I do have a .phan/config.php file in my project root. Which phan does seem to be able to find, the didChangeWatchedFiles hook does fire on file changes of the config. I have even tried to generate the config with phan --init, because I thought the config might be off. But I am not getting anything. No Error detection, no problems in the problems tab, nothing. If I run my own copy of phan.phar somewhere, it does work and prints a list of errors. I am at a loss here. If you need further info or this is not the place to ask this, please reach out, because I am at a loss. Versions are: Win10 - VS Code 10.43.2 - Analyzer Plugin v 1.2.3
    Tyson Andre
    @TysonAndre

    You could check the console output in Help > "Toggle Developer Tools" (Ctrl+Shift+I). (if you could post a screenshot, that would help)

    I'm assuming you're seeing the path to php 7.2 in vs code's process explorer, but it's worth checking if it's a different installation (e.g. older php, missing php-ast)

    You could also try installing an older version of Phan (Ctrl+Shift+X), click on the settings(gear) icon for phan, then "Install Another Version", e.g. 1.2.2 (vscode-php-phan 1.2.3 started adding a check that the files were actually within the project root directory, so it may be an issue with that. Let me know if that works or doesn't work.)

    Also, do you see any errors in daemon mode, and do expected diagnostics get emitted (e.g. phan --daemonize-tcp-port default in one window within the analyzed project directory, phan_client -l src/some_analyzed_file.php in another

    If 1.2.2 works, you could try setting phan.useRelativePatterns to false in 1.2.3

    There's a remote possibility it's an issue with case sensitivity (Phan expects the case of folder names to match for events sent by the language client) - probably not symlinks. Enabling phan.enableDebugLog would tell you more in developer tools

    Tyson Andre
    @TysonAndre

    no problems in the problems tab

    Also, the vscode plugin limits the problems to the currently open files so that responses are fast. If you don't see problems as you're editing files, though, that is a bug.

    Kevin Gregull
    @KevinGregull
    1.2.2 does indeed work for me
    as does disabling relative Patterns
    kapitanluffy
    @kapitanluffy
    Hi guys. Anyone successfully made phan work with sublime text 3?
    I followed the tutorial here: https://github.com/phan/phan/wiki/Editor-Support
    image.png
    but had an error. here's a screenshot
    Tyson Andre
    @TysonAndre
    That's probably a different error from what the https://github.com/sublimelsp/LSP extension encountered. That's what I'd expect to happen if you ran the same command directly in a terminal and then manually sent the running program invalid input (a single blank line)
    https://lsp.readthedocs.io/en/latest/#server-configuration mentions you can configure LSP to log stderr/payloads - I've never used sublime text, though. The instructions were submitted by a user of Phan.
    Adrian
    @__enspired_twitter
    what version does phan start supporting php 7.4? we're on 2.7.1 and it's showing us PhanSyntaxError syntax error, unexpected '?', expecting function (T_FUNCTION) or const (T_CONST) for a nullable property declaration.
    upgrading to 3 is next, but I didn't expect 2.7 to fail ...?
    Tyson Andre
    @TysonAndre
    You either need to run phan with --allow-polyfill-parser or run Phan with php 7.4+. Phan uses the php-ast PECL, which uses php's native AST
    The polyfill isn't perfectly compatible with the native AST support, due to limitations of tolerant-php-parser and a slight difference in doc comment parsing
    Aleister Cachon
    @aleistercachon
    image.png
    Hey guys, just thought I'd let you know the wiki page for the "Issue types caught by Phan" is not loading anymore. Not sure if it's transient or not. I can file an issue if you'd like. I know it was loading last week.
    Tyson Andre
    @TysonAndre
    It loaded now - similar issues were reported on other large files on unrelated projects
    Ace Pace
    @acepace
    is there any way to get from phan the derived type information to a file?
    Tyson Andre
    @TysonAndre
    There's nothing that does exactly that. There's phan's tool/dump_markdown_preview, which isn't the same thing as type information and isn't structured. There's --dump-signature-file <filename>, but that only dumps method signatures
    It's possible to do that through plugins or a script that starts phan's phases manually
    Ace Pace
    @acepace
    yeah, I looked at that and played around.
    Ace Pace
    @acepace
    @TysonAndre the signature file was actually great for me, I can generate a full structure graph of a project in a few lines from that
    next question is if you have an idea how do I dump the callgraph?
    Ace Pace
    @acepace
    image.png
    just to show what i'm pushing towards
    Tyson Andre
    @TysonAndre
    You'd have to write a plugin for it (AnalyzeFunctionCallCapability would help). tool/pdep is somewhat related, but not what you wanted - it dumps a graph of the dependencies of classes on other classes. Dumping method/property relationships might be within the scope of what pdep could eventually do, but I'm not the owner of pdep
    Tyson Andre
    @TysonAndre
    A more efficient approach would be enable the reference tracking setting or dead code detection and to use the references to classes to build the graph. That would get you everything except internal elements such as strlen, etc
        /**
         * @override
         */
        public function addReference(FileRef $file_ref): void
        {
            if (Config::get_track_references()) {
                // Currently, we don't need to track references to PHP-internal methods/functions/constants
                // such as PHP_VERSION, strlen(), Closure::bind(), etc.
                // This may change in the future.
                if ($this->isPHPInternal()) {
                    return;
                }
                if ($file_ref instanceof Context && $file_ref->isInFunctionLikeScope() && $file_ref->getFunctionLikeFQSEN() === $this->fqsen) {
                    // Don't track functions calling themselves
                    return;
                }
                $this->reference_list[$file_ref->__toString()] = $file_ref;
            }
        }
    Tyson Andre
    @TysonAndre

    I asked about pdep, but I doubt it's going to get implemented any time soon.

    Also, it wouldn't track calls to functions from themselves, etc., because this is focused on dead code detection

    Ace Pace
    @acepace
    awesome ty
    Ace Pace
    @acepace
    @TysonAndre so I've been busy and got a lot of my plugin working

    I noticed phan doesn't know how to parse callbacks of the form
    call_user_func(array('B', 'parent::who'));
    Where B is a class extending class A both defining Who.

    any idea how I can hack this in?

    or less hack, more properly :)
    Tyson Andre
    @TysonAndre
    @acepace phan/phan#1854 - See ArrayShapeType::asFunctionInterfaceOrNull, possibly ContextNode->getFunctionLikeFromDynamicExpression, and possibly CallableParamPlugin
    There's hundreds of open issues and it was low priority relative to them to support that syntax. I'm open to PRs with tests
    Ace Pace
    @acepace
    thanks!
    Patrick Allaert
    @patrickallaert

    Hello,

    With the method below:

    private function getDocumentRoot(): string
    {
        return realpath(__DIR__ . "/web/");
    }

    Phan returns the following error:

    PhanPossiblyFalseTypeReturn Returning realpath((__DIR__ . '/web/')) of type false|string but getDocumentRoot() is declared to return string (false is incompatible)

    It is an entirely valid error: realpath() can return string or false, while getDocumentRoot() is declared to return a string exclusively.

    My question is: how to address this issue in the state of the art?

    The options I thought about are the following:

    1) Specific Exception:

    private function getDocumentRoot(): string
    {
        $result = realpath(__DIR__ . "/web/");
    
        if (!is_string($result)) {
            throw new \RuntimeException("Cannot compute document root");
        }
    
        return $result;
    }

    While this makes the Phan error dissappear, it just changes the way to catch the exception from \TypeError to \RuntimeException. Somehow it feels non natural to remap the \TypeError to something else, this leads to the next option:

    2) Throwing \TypeError manually:

    private function getDocumentRoot(): string
    {
        $result = realpath(__DIR__ . "/web/");
    
        if (!is_string($result)) {
            throw new \TypeError("Cannot compute document root");
        }
    
        return $result;
    }

    As option 1), it "solves" the reported issue, however it re-implements the natural behaviour of PHP itself: it really feels like boilerplate code.

    3) Acknowledging that a TypeError can occur:

    /**
     * @throws \TypeError
     */
    private function getDocumentRoot(): string
    {
        return realpath(__DIR__ . "/web/");
    }

    While potentially no additional code involved, it could "mark" that a \TypeError is possible and should not be reported as something not handled. However, using @throws does not make the issue dissappear.

    4) Suppressing the issue locally:

    /**
     * @suppress PhanPossiblyFalseTypeReturn
     */
    private function getDocumentRoot(): string
    {
        return realpath(__DIR__ . "/web/");
    }

    This is supressing the issue, however, I feel that @suppress is more like a workaround to tackle edge cases while this seems pretty common. It also feels more like silencing it over declaring an intention.

    I'd like to know how you usually deal with that situation and what the best practices are.

    Tyson Andre
    @TysonAndre

    While potentially no additional code involved, it could "mark" that a \TypeError is possible and should not be reported as something not handled. However, using @throws does not make the issue dissappear.

    I don't plan to implement any support for making @throws hide phan errors/notices - In general, in code being analyzed, it's also possible to throw a TypeError explicitly. It's also unclear what @throws Error and @throws Throwable would/should do since they're parent types.

    Again, depending on the specifics of the situation, I've implemented 1/2/4 in the past to work around notices. To add, I'd personally change 4. to add a description such as @suppress PhanPossiblyFalseTypeReturn in abnormal situtations where PHP can't find the directory or the directory was removed, this will throw a TypeError, and there's no great way to handle this (or bad entries in the realpath cache, or nfs wierdness)

    You could also add a helper function/method called realpathOrThrow to a file/class with type-safe utilities - that's what Phan does for StringUtil::jsonEncode()
    Patrick Allaert
    @patrickallaert

    To add, I'd personally change 4. to add a description such as @suppress PhanPossiblyFalseTypeReturn in abnormal situtations where PHP can't find the directory or the directory was removed, this will throw a TypeError, and there's no great way to handle this (or bad entries in the realpath cache, or nfs wierdness)

    I also opted for 4), the extra comment is indeed probably worth it!

    Thank you @TysonAndre for your opinion. I also opted for option 4) as being the most practical, the extra comment can indeed make it more clear!
    I wanted to be sure I wasn't missing another option.
    Patrick Allaert
    @patrickallaert

    Hi!

    FYI, I filled an issue on PHPStorm's tracker: https://youtrack.jetbrains.com/issue/WI-54573
    It is about the lack of understanding:

    /**
     * @return iterable<Foo>
     */

    The IDE doesn't understand that syntax: looping over the results, it doesn't understand that the inner variable's type is Foo, same with: Generics<Foo>.

    Does anyone have a workaround in the mean time? For now it means commenting with /** @var Foo $item */ every loops, but that is duplication and I hate those markers :-(

    Tyson Andre
    @TysonAndre
    1. PHPStorm supports Generator|Foo[] syntax, which phan doesn't because it uses Generator<Foo> - so you can use @return Generator|Foo[] and @phan-return Generator<Foo>, but that's another type of repetition
    2. You could suppress PHPStorm's warnings, but that doesn't work well on projects/files that don't have other static analyzers set up and phpstorm may have its own checks you'd wish to keep using. I forget how that's done
    3. I'm not sure what PHPStorm's plans are for templates in general, and haven't seen anything in their announcements. I don't work on it and primarily use Vim.
    Patrick Allaert
    @patrickallaert
    Thank you for your answer @TysonAndre ! I dislike Generator|Foo[] because that syntax implies that a native array of Foo could possibly be returned. At least I see all alternatives and didn't think about combining @return and @phan-return at the same time! Thanks again!