psalm-plugin-wordpress icon indicating copy to clipboard operation
psalm-plugin-wordpress copied to clipboard

Fatal error: calling toString() on null

Open schlessera opened this issue 7 months ago • 1 comments

I'm seeing the following error with the latest version:

Uncaught Exception: Error Call to a member function toString() on null
Emitted in <root>/vendor/humanmade/psalm-plugin-wordpress/Plugin.php:1362
Stack trace in the forked worker:
#0 <root>/vendor/nikic/php-parser/lib/PhpParser/NodeTraverser.php(200): PsalmWordPress\HookNodeVisitor->enterNode()
#1 <root>/vendor/nikic/php-parser/lib/PhpParser/NodeTraverser.php(91): PhpParser\NodeTraverser->traverseArray()
#2 <root>/vendor/humanmade/psalm-plugin-wordpress/Plugin.php(368): PhpParser\NodeTraverser->traverse()
#3 <root>/vendor/vimeo/psalm/src/Psalm/Internal/EventDispatcher.php(419): PsalmWordPress\Plugin::beforeAnalyzeFile()
#4 <root>/vendor/vimeo/psalm/src/Psalm/Internal/Analyzer/FileAnalyzer.php(154): Psalm\Internal\EventDispatcher->dispatchBeforeFileAnalysis()
#5 <root>/vendor/vimeo/psalm/src/Psalm/Internal/Codebase/Analyzer.php(1587): Psalm\Internal\Analyzer\FileAnalyzer->analyze()
#6 <root>/vendor/vimeo/psalm/src/Psalm/Internal/Fork/Pool.php(189): Psalm\Internal\Codebase\Analyzer->analysisWorker()
#7 <root>/vendor/vimeo/psalm/src/Psalm/Internal/Codebase/Analyzer.php(372): Psalm\Internal\Fork\Pool->__construct()
#8 <root>/vendor/vimeo/psalm/src/Psalm/Internal/Codebase/Analyzer.php(272): Psalm\Internal\Codebase\Analyzer->doAnalysis()
#9 <root>/vendor/vimeo/psalm/src/Psalm/Internal/Analyzer/ProjectAnalyzer.php(538): Psalm\Internal\Codebase\Analyzer->analyzeFiles()
#10 <root>/vendor/vimeo/psalm/src/Psalm/Internal/Cli/Psalm.php(379): Psalm\Internal\Analyzer\ProjectAnalyzer->check()
#11 <root>/vendor/vimeo/psalm/psalm(9): Psalm\Internal\Cli\Psalm::run()
#12 <root>/vendor/bin/psalm(119): include('...')
#13 {main} in <root>/vendor/vimeo/psalm/src/Psalm/Internal/Fork/Pool.php:383
Stack trace:
#0 <root>/vendor/vimeo/psalm/src/Psalm/Internal/Fork/Pool.php(417): Psalm\Internal\Fork\Pool->readResultsFromChildren()
#1 <root>/vendor/vimeo/psalm/src/Psalm/Internal/Codebase/Analyzer.php(406): Psalm\Internal\Fork\Pool->wait()
#2 <root>/vendor/vimeo/psalm/src/Psalm/Internal/Codebase/Analyzer.php(272): Psalm\Internal\Codebase\Analyzer->doAnalysis()
#3 <root>/vendor/vimeo/psalm/src/Psalm/Internal/Analyzer/ProjectAnalyzer.php(538): Psalm\Internal\Codebase\Analyzer->analyzeFiles()
#4 <root>/vendor/vimeo/psalm/src/Psalm/Internal/Cli/Psalm.php(379): Psalm\Internal\Analyzer\ProjectAnalyzer->check()
#5 <root>/vendor/vimeo/psalm/psalm(9): Psalm\Internal\Cli\Psalm::run()
#6 <root>/vendor/bin/psalm(119): include('...')
#7 {main}
(Psalm 5.26.1@d747f6500b38ac4f7dfc5edbcae6e4b637d7add0 crashed due to an uncaught Throwable)

To get around this, I did the following change:

		// see visitor.php for original code
		if ( ( $this->useNamespace !== '' || $this->useStatements !== [] || $this->useStatementsNonClass !== false ) && $this->maxLine > $node->getStartLine() ) {
			$this->useNamespace = '';
			$this->useStatements = [];
			$this->useStatementsNonClass = false;
		}

		$this->maxLine = $node->getStartLine();

-		if ( $node instanceof Namespace_ ) {
+		if ( $node instanceof Namespace_ && $node->name instanceof Name ) {
			// as soon as there is a new namespace, we need to empty the useStatements, as there will be new ones for the given namespace
			$this->useNamespace = $node->name->toString();
			$this->useStatements = [];
			$this->useStatementsNonClass = false;
			return null;
		}

schlessera avatar May 26 '25 19:05 schlessera

Added a PR for the change I did to get unblocked: #59

schlessera avatar May 26 '25 19:05 schlessera