TysonAndre / vscode-php-phan

Phan - PHP Static Analysis for VS Code
Other
24 stars 4 forks source link

Got 'Called initialized on language server, currently a no-op' on a previously working project after some modification #55

Open AdamMarton opened 5 years ago

AdamMarton commented 5 years ago

Maybe this is more about phan itself again.

I have many Bedrock-enabled WordPress websites where I used to configure each plugin independently across different sites which resulted in a mess in my custom configuration in VSCode, so I went and tried to abstract my configuration to the site root and configure each directory to analyze there (may be not the best use case).

Setup:

<site-root-dir>
  .phan
    config.php
  dir1
  ...
  dirx

config.php has been created with phan's --init command, and it contains only one directory to analyze. It works fine when running it via cli.

VSCode settings' phan.analyzedProjectDirectory points to <site-root-dir> (above), I see no errors during startup:

[Extension Host] starting PHP Phan language server
[Extension Host] starting Phan Language Server
C:\php\php.exe 
Array(8)
0: "c:\Users\Adam_Marton\.vscode\extensions\tysonandre.php-phan-0.8.3\vendor\phan\phan\phan"
1: "--language-server-verbose"
2: "--language-server-allow-missing-pcntl"
3: "--allow-polyfill-parser"
4: "--language-server-completion-vscode"
5: "--language-server-enable-completion"
6: "--use-fallback-parser"
7: "--language-server-tcp-connect=127.0.0.1:51310"

But, when opening a file in the analyzed directory, I'll get the following message:

/C:/Users/Adam_Marton/AppData/Local/Programs/Microsoft VS Code/resources/app/out/vs/workbench/workbench.main.js:303
[Extension Host] Request:
{"Content-Length":"52"}
Data:
{"jsonrpc":"2.0","method":"initialized","params":{}}

Received message in coroutine: {"method":"initialized","params":{},"jsonrpc":"2.0"}
Called initialized on language server, currently a no-op
...
<here I get my custom VSCode settings back in JSON>

I saw that this comes straight from phan, but since it works fine in cli I posted this here instead.

I'm on Windows 10, VSCode is 1.30.2, PHP-Phan is 0.8.3.

Please let me know if you need more details.

TysonAndre commented 5 years ago

That's because you set phan.enableDebug to true while setting it up. You should set that to false normally.

This option is slow and verbose, and only should be used if debugging the extension. It deliberately logs a lot of information to stderr.

AdamMarton commented 5 years ago

Hi,

Thanks for the quick reply. Forgot to mention that I don't have any output under 'Problems' nor tooltips. So basically, phan does not work for now.

TysonAndre commented 5 years ago

Did 0.8.2 work?

What's the filename and extension of the file that failed to be analyzed? E.g. do .php files work?

I'm assuming site-root-dir was in the CLI options and you omitted it.

TysonAndre commented 5 years ago

Also, Phan doesn't automatically restart it you change the configuration (e.g. user configuration especially). So it may be running, but on a different directly. - check in process explorer if that is the case.

There are open tickets for that.

Also, you can set up multiple independent Phan instances by providing an array to analyzed project directory. This may use up a lot of memory due the servers running independently.

AdamMarton commented 5 years ago

Hi,

Even 0.8.3 works with my previous (inconvenient) configuration. No failure/errors, beside what devtools says (included in my original post). Yes, I've restarted VSCode each time I changed anything in the config.

Please let me know how can I clarify the issue even more.

TysonAndre commented 5 years ago

What's the filename and extension of the file that failed to be analyzed? E.g. do .php files work?

AdamMarton commented 5 years ago

I've analyzing a WordPress site with plugins and everything, yes, this has been worked before.

TysonAndre commented 5 years ago

I'm able to see this issue with a file with the suffix .html. I'm not seeing it on files with the suffix .php

AdamMarton commented 5 years ago

As far as I'm concerned, this directive should be more than enough (config.php):

...
    'analyzed_file_extensions' => [
        'php',
    ]
...
TysonAndre commented 5 years ago

And if I change my vscode phan client configuration, I can analyze files with html extensions again.:

    "phan.analyzedFileExtensions": [
        "php",
        "html"
    ],

I'd agree that it'd be useful to do that, but the vscode client doesn't do that

TysonAndre commented 5 years ago

Will continue looking into this later tonight

I tried reverting the upgrade to npm dependencies, but that didn't seem to help. The issue with analyzedFileExtensions may be unrelated.

Maybe the extensions check is case sensitive, but I doubt it's that.

Is the file you're analyzing a .inc file?

AdamMarton commented 5 years ago

No, there are no .inc file in the given folder.

TysonAndre commented 5 years ago

Can you attach a full screenshot of the VS code window with a file that should be analyzed that isn't?

AdamMarton commented 5 years ago

Oops! We're getting there...

So I've modified the path to be analyzed (because I cannot post the source, sorry) and it works with a different dir to be analyzed. So it's something(?) in the other folder.

How can I get more debug info in the devtools?

TysonAndre commented 5 years ago

Setting phan.enableDebug to true is usually as much info as possibly needed.

If you don't see anything in one directory, that may be because didChange events and didSave events aren't being sent by this client (the library it uses)

Any special characters in the other folder? Did you exclude a directory from analysis?

Phan had a recent change to limit emitting warnings just to the files to be analyzed, it could be that

TysonAndre commented 5 years ago

Also, the phan language server had a bug where it would analyze files not included in the directory_list in .phan/config.php (because they weren't excluded)

It's possible that what you're seeing is a symptom of that changing. (Then again, I don't think I've fixed that yet)


It could also be an issue normalizing the paths on Windows (e.g. \\ vs / - Which are you using as a directory separator in .phan/config.php? / is recommended).

https://github.com/phan/phan/blob/1.2.2/NEWS.md

Language Server/Daemon mode:

Limit analysis results of the language server to only the currently open files. (#1722)

TysonAndre commented 5 years ago

So it's something(?) in the other folder.

Do you have any workspace settings in that other folder (or it's parent folders), e.g. in .vscode/settings.json (hidden directory)? Are you referring to two folders of the same workspace or a different workspace?

TysonAndre commented 5 years ago
  // Optional (Advanced). If provided, this overrides the Phan script to use, e.g. `/path/to/phan_git_checkout/phan`. (Modifying requires restart)
  "phan.phanScriptPath": null,

If you want to check if your issues are caused by upgrading the server with 0.8.3 of this extension, you can download phan.phar for Phan 1.2.1 and point "phan.phanScriptPath" to the path to the phar file (then restart): https://github.com/phan/phan/releases/tag/1.2.1

AdamMarton commented 5 years ago

Setting phan.enableDebug to true is usually as much info as possibly needed.

If you don't see anything in one directory, that may be because didChange events and didSave events aren't being sent by this client (the library it uses)

Any special characters in the other folder? Did you exclude a directory from analysis?

Phan had a recent change to limit emitting warnings just to the files to be analyzed, it could be that

This is what I'm seeing in the debug log:

Phan Language Server starts without any errors (see original post)

Next, I'm seeing an error in the log twice (formatted for readability):

[Extension Host] Request:
{"Content-Length":"592"}
Data:
{
  "jsonrpc":"2.0",
  "method":"workspace/didChangeConfiguration",
  "params":{
    "settings":{
      "phan":{
        "phpExecutablePath":"C:\\php\\php.exe",
        "analyzedProjectDirectory":["<site-root-dir>"],
        "enableDebugLog":true,
        "enableGoToDefinition":false,
        "enableHover":false,
        "enableCompletion":true,
        "analyzedFileExtensions":["php"],
        "useFallbackParser":true,
        "analyzeOnlyOnSave":false,
        "quick":false,
        "unusedVariableDetection":false,
        "memoryLimit":null,
        "connectToServerWithStdio":false,
        "additionalCLIFlags":[],
        "phanScriptPath":null,
        "allowPolyfillParser":true,
        "allowMissingPcntl":true,
        "forceMissingPcntl":false
      }
    }
  }
}

Then I'm getting this:

[Extension Host] Request:
{"Content-Length":"445"}
Data:
{
  "jsonrpc":"2.0",
  "method":"textDocument/didOpen",
  "params":{
    "textDocument":{
      "uri":"file:///<site-root-dir>/.phan/config.php",
      "languageId":"php",
      "version":1,
      "text":"<?php\n\nreturn [\n    'target_php_version' => '7.2',\n    'suppress_issue_types' => [\n        'PhanCommentParamWithoutRealParam',\n        'PhanUnextractableAnnotationElementName'\n    ],\n    'directory_list' => [\n        '<plugin-directory>',\n    ],\n];\n"
    }
  }
}

where <plugin-directory> is in the following path:

<site-root-dir>/
  .phan/
    config.php
  web/
    app/
      plugins/
        <plugin-directory>/

Opening a file from under <plugin-directory> results in this:

[Extension Host] Called textDocument/didOpen, uri=file:///<site-root-dir>/.phan/config.php

t.log @ console.ts:134
t._logExtensionHostMessage @ extensionHost.ts:453
(anonymous) @ extensionHost.ts:244
emitTwo @ events.js:126
emit @ events.js:214
emit @ internal/child_process.js:772
_combinedTickCallback @ internal/process/next_tick.js:141
_tickCallback @ internal/process/next_tick.js:180
console.ts:134 [Extension Host] Called analyzeURIAsync, uri=file:///<site-root-dir>/.phan/config.php, path=<site-root-dir>\.phan\config.php

t.log @ console.ts:134
t._logExtensionHostMessage @ extensionHost.ts:453
(anonymous) @ extensionHost.ts:244
emitTwo @ events.js:126
emit @ events.js:214
emit @ internal/child_process.js:772
_combinedTickCallback @ internal/process/next_tick.js:141
_tickCallback @ internal/process/next_tick.js:180
console.ts:134 [Extension Host] Path '.phan\config.php' (URI 'file:///<site-root-dir>/.phan/config.php') not in parse list, skipping

No matter how much I limit directory_list scope in config.php (eg point to a directory containing a single file only), it doesn't work in VSCode but in cli.

On the other hand, if I set directory_list to <site-root-dir>/<example-php-dir>, it works without any flaws.

AdamMarton commented 5 years ago

No exclusions defined (yet), and I'm using / as a directory separator. Contents of my config.php included in my previous comment.

Yes, there are some other .<dir> kind of directories in the <site-root-dir> but see my previous comment: it works via cli, and works if I point to a directory immediately under <site-root-dir>.

If I'm using a previous version of Phan, we're getting back to this issue (which is interesting, because you fixed that in a previous version already).

TysonAndre commented 5 years ago

console.ts:134 [Extension Host] Called analyzeURIAsync, uri=file:////.phan/config.php, path=.phan\config.php

Okay, it looks like the conversion to \ is done in the Phan server itself (uriToPath), which may need to be undone in the callers for the relative path for checks to work. It's done that since the start, but that might have become a problem due to other patches - e.g. https://github.com/phan/phan/pull/2377/files#diff-e99ee11beaf4695259109515f81c13e6

AdamMarton commented 5 years ago

Just updated to 42668be6cf25a633fe7571d3fee483408edae80d, no luck so far:

Called analyzeURIAsync,
uri=file:///<site-root-dir>/.phan/config.php,
path=<site-root-dir>\.phan\config.php

Is this expected?

AdamMarton commented 4 years ago

Maybe it's unrelated, but I'm still getting errors from the languageserver itself:

Saw Throwable: Error: Class 'array' not found
#0 C:\Users\Adam_Marton\.vscode\extensions\tysonandre.php-phan-1.1.4\vendor\phan\phan\src\Phan\LanguageServer\LanguageServer.php(202): AdvancedJsonRpc\Dispatcher->dispatch(Object(AdvancedJsonRpc\Notification))

The accompanying message:

Received message in coroutine: {
    "method": "workspace\/didChangeConfiguration",
    "params": {
        "settings": {
            "phan": {
                "phpExecutablePath": "C:\\php\\php.exe",
                "analyzedProjectDirectory": ["C:\\Users\\Adam_Marton\\Documents\\Code\\health-check\\a-wp-plugin"],
                "enableDebugLog": true,
                "enableGoToDefinition": false,
                "enableHover": true,
                "enableCompletion": true,
                "analyzedFileExtensions": ["php"],
                "useFallbackParser": true,
                "analyzeOnlyOnSave": false,
                "quick": false,
                "unusedVariableDetection": false,
                "redundantConditionDetection": false,
                "memoryLimit": null,
                "connectToServerWithStdio": false,
                "additionalCLIFlags": [],
                "phanScriptPath": null,
                "allowPolyfillParser": true,
                "allowMissingPcntl": true,
                "forceMissingPcntl": false
            }
        }
    },
    "jsonrpc": "2.0"
}
TysonAndre commented 4 years ago

Yes, it's a different issue.

Does the language server work other than that?

Dispatcher.php calls json_decode, and passes it to JsonMapper. It turns out not to expect a regular associative array, and either expects no reflection type or a named class reflection type.

didChangeConfiguration is a no-op, so it's easy enough to fix the log by removing the real type.

                    // If the type is structured (array or object), map it with JsonMapper
                    if (is_object($value)) {
                        // Does the parameter have a type hint?
                        $param = $parameters[$position];
                        if ($param->hasType()) {
                            $paramType = $param->getType();
                            if ($paramType instanceof ReflectionNamedType) {
                                // We have object data to map and want the class name.
                                // This should not include the `?` if the type was nullable.
                                $class = $paramType->getName();
                            } else {
                                // Fallback for php 7.0, which is still supported (and doesn't have nullable).
                                $class = (string)$paramType;
                            }
                            $value = $this->mapper->map($value, new $class());
                        }
                    } else if (is_array($value) && isset($docBlock)) {
                        // Get the array type from the DocBlock
                        $type = $paramTags[$position]->getType();

That's from a newer version of php-advanced-json-rpc, but the old one was equivalent - checking for ReflectionNamedType just avoids deprecation notices and bugs with nullable

TysonAndre commented 4 years ago

Aside: There were a few recent fixes to directory handling on windows since February, including

  • Fix a bug converting absolute paths to relative paths when the project directory is a substring of a subdirectory (#3158)
  • Don't parse src/a.php and src\a.php twice if both paths are generated from config or CLI options (#3166)
AdamMarton commented 4 years ago

Hi @TysonAndre,

Thank you very much for your response. Yes, Phan works from CLI, but not with VSCode. I'm using 1.1.4 btw.

AdamMarton commented 4 years ago

Also, removing typehint from signature of didChangeConfiguration() didn't helped. The exception is gone, but still doesn't works with the IDE.

TysonAndre commented 4 years ago

I'm also seeing the same error in didChangeConfiguration, but the language server continues running normally for me anyway, so I don't think didChangeConfiguration is the cause of the issue.

Is the site root directory something really short, like C:\app? Does it include the drive? Does it end with a slash (I don't know if that'd matter, I usually don't do that). Are you using forward or backwards slashes in the configured root directory?

AdamMarton commented 4 years ago

This is the directory I'm trying to analyze in the IDE:

"C:\\Users\\Adam_Marton\\Documents\\Code\\health-check\\a-wp-plugin"

TysonAndre commented 4 years ago

And what's the full directory in the directory_list (with forward or backward slashes) in .phan/config.php and where is .phan/config.php located?

It may be a bug in the language server normalizing slashes, since the testing on Windows was done with a single part directory, not a multi part directory with slashes

AdamMarton commented 4 years ago

The config is placed under C:\\Users\\Adam_Marton\\Documents\\Code\\health-check\\a-wp-plugin\.phan\config.php

    'directory_list' => [
        'includes/classes', // where the code actually is
        'vendor/aws/aws-sdk-php/src',
        'vendor/edsonmedina/php_testability/src',
        'vendor/monolog/monolog/src/Monolog',
        'vendor/nunomaduro/phpinsights/src',
        'vendor/phploc/phploc/src',
        'vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet',
        'vendor/sebastian/phpcpd/src',
        'vendor/symfony/yaml',
    ],