Sitelet https://github.com/SanderRonde/phpstan-vscode/pull/158
Skip to content

Support blade files - #158

Open
SanderRonde wants to merge 2 commits into
masterfrom
blade-language-support
Open

SanderRonde wants to merge 2 commits into
masterfrom
blade-language-support

Conversation

@SanderRonde

Copy link
Copy Markdown
Owner

Summary

Blade templates are never analyzed automatically today. Laravel syntax extensions reassign .blade.php files to the blade language ID, and every trigger path in the extension gated strictly on php, so the extension neither activated nor synced those documents — even for setups where PHPStan itself can analyze them (e.g. via Bladestan).

This adds blade alongside php everywhere a language gate exists, and pulls the list into shared/languages.ts so the client and server share one definition:

  • package.json — onLanguage:blade activation event
  • client/src/extension.ts — documentSelector built from the shared list
  • client/src/notificationSenders/documentManager.ts — _shouldSyncDocument, which gated open/change/save/active/close
  • server/src/lib/documentManager.ts — the five languageId !== 'php' handler gates
  • client/src/lib/commands.ts — scan-file and reload commands
  • client/src/notificationReceivers/configResolveLanguageStatus.ts — status item selector

Two things that aren't plain gate swaps:

  • _checkValid now skips non-PHP languages. php-parser can't parse Blade directives, and a file marked invalid blocks all project checks (checkManager._checkProject). Without this, opening a blade file with phpstan.checkValidity enabled would wedge every check.
  • providerUtil.ts passes the document's real language ID instead of a hardcoded 'php' for the hover check. Behavior-neutral as far as I can tell — languageId isn't read downstream of checkIfChanged beyond the gates above — but it was the one place still fabricating the value.

Deliberately left alone:

  • registerCodeActionsProvider('php') in errorManager.ts. The quick fix inserts @phpstan-ignore-next-line / docblock comments, which would corrupt template markup outside a @php block. Blade needs different ignore syntax, so it seemed better to leave the quick fix PHP-only than to emit bad edits.
  • The *.php file system watcher, which already matches .blade.php.
  • CHANGELOG / version bump, left for your release flow.

Notes / open questions

  • Untested with phpstan.singleFileMode: true. In that mode a blade save now triggers a single-file check on the template path; I didn't verify what PHPStan does with an explicit .blade.php argument. Previously blade files simply did nothing. If that turns out to be noisy, the fix is a language condition on the shouldCheckProject decisions in checkManager.ts — I left it out rather than guard against an unconfirmed failure mode.
  • activationEvents is a hand-maintained duplicate of SUPPORTED_LANGUAGE_IDS; generate-package-json only covers commands and config. There's a comment in shared/languages.ts noting this.
  • Only blade is added, not other Blade-flavored language IDs some extensions register.

Test plan

  • bun run compile, bun run lint, bun run build all pass
  • Not verified in a live Extension Development Host (no GUI available where this was written) — worth a manual check that saving a .blade.php file with a Laravel Blade extension installed triggers a project check
  • Confirm a plain .php workflow is unchanged

🤖 Generated with Claude Code

SanderRonde and others added 2 commits September 18, 2026 01:00
Blade templates get the `blade` language ID from Laravel syntax
extensions, so PHPStan checks never triggered for them even though
Bladestan can analyze them. Activate on `blade` too and share the list
of supported language IDs between client and server.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant