php-language-server icon indicating copy to clipboard operation
php-language-server copied to clipboard

TypeError: ... in DefinitionResolver.php:444

Open sebet opened this issue 8 years ago • 6 comments

This issue is similar to #252 but it happens inside the if ($expr instanceof Node\Expr\FuncCall) { logic.

This is the error I get in DefinitionResolver.php when the server is parsing this file:

extensionHost.ts:282 [Extension Host] TypeError: Return value of LanguageServer\DefinitionResolver::resolveExpressionNodeToType() must implement interface phpDocumentor\Reflection\Type, null returned in /Users/bcarreco/.vscode/extensions/felixfbecker.php-intellisense-1.1.1/vendor/felixfbecker/language-server/src/DefinitionResolver.php:444

I was able to fix it by adding this code to that line:

            if (strtolower((string)$def) === 'null') {
                return new Types\Null_;
            }

final changed code:

        if ($expr instanceof Node\Expr\FuncCall) {
            // Find the function definition
            if ($expr->name instanceof Node\Expr) {
                // Cannot get type for dynamic function call
                return new Types\Mixed;
            }
            $fqn = (string)($expr->getAttribute('namespacedName') ?? $expr->name);
            $def = $this->index->getDefinition($fqn, true);
            if (strtolower((string)$def) === 'null') {
                return new Types\Null_;
            }
            if ($def !== null) {
                return $def->type;
            }
        }

Not sure that's the right approach but it fixed the problem.

sebet avatar Feb 07 '17 15:02 sebet

I've been experiencing this same issue.

Stack trace:
#0 /Users/christopher_carman/.vscode/extensions/felixfbecker.php-intellisense-1.1.3/vendor/felixfbecker/language-server/src/DefinitionResolver.php(239): LanguageServer\DefinitionResolver->resolveExpressionNodeToType(Object(PhpParser\Node\Expr\FuncCall))
#1 /Users/christopher_carman/.vscode/extensions/felixfbecker.php-intellisense-1.1.3/vendor/felixfbecker/language-server/src/NodeVisitor/ReferencesCollector.php(38): LanguageServer\DefinitionResolver->resolveReferenceNodeToFqn(Object(PhpParser\Node\Expr\MethodCall))
#2 /Users/christopher_carman/.vscode/extensions/felixfbecker.php-intellisense-1.1.3/vendor/nikic/php-parser/lib/PhpParser/NodeTraverser.php(108): LanguageServer\NodeVisitor\ReferencesCollector->enterNode(Object(PhpParser\Node\Expr\MethodCall))
#3 /Users/christopher_carman/.vscode/extensions/felixfbecker.php-intellisense-1.1.3/vendor/nikic/php-parser/lib/PhpParser/NodeTraverser.php(171): PhpParser\NodeTraverser->traverseNode(Object(PhpParser\Node\Stmt\Return_))
#4 /Users/christopher_carman/.vscode/extensions/felixfbecker.php-intellisense-1.1.3/vendor/nikic/php-parser/lib/PhpParser/NodeTraverser.php(101): PhpParser\NodeTraverser->traverseArray(Array)
#5 /Users/christopher_carman/.vscode/extensions/felixfbecker.php-intellisense-1.1.3/vendor/nikic/php-parser/lib/PhpParser/NodeTraverser.php(120): PhpParser\NodeTraverser->traverseNode(Object(PhpParser\Node\Expr\Closure))
#6 /Users/christopher_carman/.vscode/extensions/felixfbecker.php-intellisense-1.1.3/vendor/nikic/php-parser/lib/PhpParser/NodeTraverser.php(171): PhpParser\NodeTraverser->traverseNode(Object(PhpParser\Node\Arg))
#7 /Users/christopher_carman/.vscode/extensions/felixfbecker.php-intellisense-1.1.3/vendor/nikic/php-parser/lib/PhpParser/NodeTraverser.php(101): PhpParser\NodeTraverser->traverseArray(Array)
#8 /Users/christopher_carman/.vscode/extensions/felixfbecker.php-intellisense-1.1.3/vendor/nikic/php-parser/lib/PhpParser/NodeTraverser.php(171): PhpParser\NodeTraverser->traverseNode(Object(PhpParser\Node\Expr\MethodCall))
#9 /Users/christopher_carman/.vscode/extensions/felixfbecker.php-intellisense-1.1.3/vendor/nikic/php-parser/lib/PhpParser/NodeTraverser.php(101): PhpParser\NodeTraverser->traverseArray(Array)
#10 /Users/christopher_carman/.vscode/extensions/felixfbecker.php-intellisense-1.1.3/vendor/nikic/php-parser/lib/PhpParser/NodeTraverser.php(171): PhpParser\NodeTraverser->traverseNode(Object(PhpParser\Node\Stmt\ClassMethod))
#11 /Users/christopher_carman/.vscode/extensions/felixfbecker.php-intellisense-1.1.3/vendor/nikic/php-parser/lib/PhpParser/NodeTraverser.php(101): PhpParser\NodeTraverser->traverseArray(Array)
#12 /Users/christopher_carman/.vscode/extensions/felixfbecker.php-intellisense-1.1.3/vendor/nikic/php-parser/lib/PhpParser/NodeTraverser.php(171): PhpParser\NodeTraverser->traverseNode(Object(PhpParser\Node\Stmt\Class_))
#13 /Users/christopher_carman/.vscode/extensions/felixfbecker.php-intellisense-1.1.3/vendor/nikic/php-parser/lib/PhpParser/NodeTraverser.php(85): PhpParser\NodeTraverser->traverseArray(Array)
#14 /Users/christopher_carman/.vscode/extensions/felixfbecker.php-intellisense-1.1.3/vendor/felixfbecker/language-server/src/PhpDocument.php(205): PhpParser\NodeTraverser->traverse(Array)
#15 /Users/christopher_carman/.vscode/extensions/felixfbecker.php-intellisense-1.1.3/vendor/felixfbecker/language-server/src/PhpDocument.php(119): LanguageServer\PhpDocument->updateContent('<?php\n\nuse Mock...')
#16 /Users/christopher_carman/.vscode/extensions/felixfbecker.php-intellisense-1.1.3/vendor/felixfbecker/language-server/src/PhpDocumentLoader.php(134): LanguageServer\PhpDocument->__construct('file:///Users/c...', '<?php\n\nuse Mock...', Object(LanguageServer\Index\Index), Object(LanguageServer\Parser), Object(phpDocumentor\Reflection\DocBlockFactory), Object(LanguageServer\DefinitionResolver))
#17 /Users/christopher_carman/.vscode/extensions/felixfbecker.php-intellisense-1.1.3/vendor/felixfbecker/language-server/src/PhpDocumentLoader.php(113): LanguageServer\PhpDocumentLoader->create('file:///Users/c...', '<?php\n\nuse Mock...')
#18 [internal function]: LanguageServer\PhpDocumentLoader->LanguageServer\{closure}()
#19 /Users/christopher_carman/.vscode/extensions/felixfbecker.php-intellisense-1.1.3/vendor/sabre/event/lib/coroutine.php(70): Generator->send('<?php\n\nuse Mock...')
#20 /Users/christopher_carman/.vscode/extensions/felixfbecker.php-intellisense-1.1.3/vendor/sabre/event/lib/Promise.php(242): Sabre\Event\{closure}('<?php\n\nuse Mock...')
#21 /Users/christopher_carman/.vscode/extensions/felixfbecker.php-intellisense-1.1.3/vendor/sabre/event/lib/Loop/Loop.php(261): Sabre\Event\Promise->Sabre\Event\{closure}()
#22 /Users/christopher_carman/.vscode/extensions/felixfbecker.php-intellisense-1.1.3/vendor/sabre/event/lib/Loop/Loop.php(215): Sabre\Event\Loop\Loop->runNextTicks()
#23 /Users/christopher_carman/.vscode/extensions/felixfbecker.php-intellisense-1.1.3/vendor/sabre/event/lib/Loop/Loop.php(194): Sabre\Event\Loop\Loop->tick(true)
#24 /Users/christopher_carman/.vscode/extensions/felixfbecker.php-intellisense-1.1.3/vendor/sabre/event/lib/Loop/functions.php(122): Sabre\Event\Loop\Loop->run()
#25 /Users/christopher_carman/.vscode/extensions/felixfbecker.php-intellisense-1.1.3/vendor/felixfbecker/language-server/bin/php-language-server.php(102): Sabre\Event\Loop\run()
#26 {main}d.logExtensionHostMessage @ extensionHost.ts:282(anonymous function) @ extensionHost.ts:137emitTwo @ events.js:106emit @ events.js:191process.nextTick @ internal/child_process.js:744_combinedTickCallback @ internal/process/next_tick.js:67_tickCallback @ internal/process/next_tick.js:98
messageService.ts:126 The PHP Language Server server crashed 5 times in the last 3 minutes. The server will not be restarted.

Based on the stack trace, it appears that $def->type is null here: https://github.com/felixfbecker/php-language-server/blob/56bd465bf8012e6b8842439ade7683e639ce8f32/src/DefinitionResolver.php#L445

The file triggering the error appears to be this: https://github.com/laravel/lumen-framework/blob/v5.2.9/tests/FullApplicationTest.php

EDIT: Commented out the contents and indexing completed successfully. That seems to be the only problematic file. Strange.

carmanchris31 avatar Mar 01 '17 21:03 carmanchris31

@carmanchris31, I was able to fix this by adding this check before the return $def->type;.

   if ( null === $def->type ) {
         return new Types\Mixed;
   }

The final logic should be something like this:

  if ($def !== null) {
         // CUSTOM.
         if ( null === $def->type ) {
              return new Types\Mixed;
         }
         // 
         return $def->type;
  }

sebet avatar Mar 02 '17 11:03 sebet

I had the same problem. Was able to fix it by:

if ($def !== null) { return $def->type ?: new Types\Mixed; }

Then it all work fine. No error lines in the developer's console.

chenmin201 avatar Apr 21 '17 16:04 chenmin201

@felixfbecker This bug occurs because define() nodes in the stubs file do not have a type set. Also, this only seems to happen when the constant is used in an array that is used to initialize a class member. You can successfuly reproduce the crash with the following code:

class Test {
    private $foo = [PHP_INT_MAX];
}

I would open a PR but I don't know how the stubs file is created.

sunverwerth avatar Apr 22 '17 19:04 sunverwerth

Awesome find! The stuns file is generated in ComposerScripts.php, but the bug likely is in DefinitionResolver

felixfbecker avatar Apr 22 '17 20:04 felixfbecker

Hi, shouldn't this bug be closed as the fix has already been merged?

Vaggal avatar Oct 08 '19 23:10 Vaggal