From 11af82a97f9a08dc3c8c08a36cc06a581a5dffd7 Mon Sep 17 00:00:00 2001 From: Joe Hoyle Date: Sat, 11 Jul 2020 23:12:03 +0200 Subject: [PATCH] Fix jumping to definition on nullable parameters (#3804) Currently it's not possible to "Go to definition" (LSP) on nullable args like `function( ?MyClass )` as the reference is stored a `MyClass|null` in the reference map, which will now resolve to a class name. This PR removed any nullable type from the union before adding it to the reference map (as the reference map is only use to indicate a symbol was used in a given location, I think this makes sense). --- .../Analyzer/FunctionLikeAnalyzer.php | 8 +++-- tests/LanguageServer/SymbolLookupTest.php | 29 +++++++++++++++++++ 2 files changed, 35 insertions(+), 2 deletions(-) diff --git a/src/Psalm/Internal/Analyzer/FunctionLikeAnalyzer.php b/src/Psalm/Internal/Analyzer/FunctionLikeAnalyzer.php index d7b62ee52..8993e8b80 100644 --- a/src/Psalm/Internal/Analyzer/FunctionLikeAnalyzer.php +++ b/src/Psalm/Internal/Analyzer/FunctionLikeAnalyzer.php @@ -977,13 +977,17 @@ abstract class FunctionLikeAnalyzer extends SourceAnalyzer $signature_type_location = $function_param->signature_type_location; if ($signature_type && $signature_type_location && $signature_type->hasObjectType()) { + $referenced_type = $signature_type; + if ($referenced_type->isNullable()) { + $referenced_type = clone $referenced_type; + $referenced_type->removeType('null'); + } list($start, $end) = $signature_type_location->getSelectionBounds(); - $codebase->analyzer->addOffsetReference( $this->getFilePath(), $start, $end, - (string) $signature_type + (string) $referenced_type ); } diff --git a/tests/LanguageServer/SymbolLookupTest.php b/tests/LanguageServer/SymbolLookupTest.php index e19daa6f2..a224e8112 100644 --- a/tests/LanguageServer/SymbolLookupTest.php +++ b/tests/LanguageServer/SymbolLookupTest.php @@ -275,6 +275,35 @@ class SymbolLookupTest extends \Psalm\Tests\TestCase $this->assertSame('B\A::foo()', $symbol_at_position[0]); } + /** + * @return void + */ + public function testGetSymbolPositionNullableArg() + { + $codebase = $this->project_analyzer->getCodebase(); + $config = $codebase->config; + $config->throw_exception = false; + + $this->addFile( + 'somefile.php', + 'file_provider->openFile('somefile.php'); + $codebase->scanFiles(); + $this->analyzeFile('somefile.php', new Context()); + + $symbol_at_position = $codebase->getReferenceAtPosition('somefile.php', new Position(4, 33)); + $this->assertNotNull($symbol_at_position); + + $this->assertSame('B\AClass', $symbol_at_position[0]); + } + /** * @return void */