Skip to content

Add PHP contract extraction - #41

Open
mattsbl wants to merge 3 commits into
spolu:mainfrom
mattsbl:feat/php-support
Open

mattsbl wants to merge 3 commits into
spolu:mainfrom
mattsbl:feat/php-support

Conversation

@mattsbl

@mattsbl mattsbl commented Sep 11, 2026

Copy link
Copy Markdown

Summary

  • Add Lezer-backed PHPDoc @cc extraction and source-location support for PHP files.
  • Attach contracts to classes, interfaces, traits, enums, functions, methods, properties, constants, and enum cases, including attributed declarations and promoted properties.
  • Add CLI integration coverage for listing, location scoping, malformed contracts, and duplicate IDs.
  • Document PHP support in the shared specification and cc-check documentation.

Verification

Passed locally with exit 0:

(cd cc-check && npm run check)
node cc-check/dist/cc-check.js format
php -l cc-check/test/fixtures/php/contracts.php
git diff --check upstream/main...HEAD

Additional corpus smoke scans processed 670 PHP files across two existing applications without errors.

@spolu

spolu commented Nov 3, 2026

Copy link
Copy Markdown
Owner

Sorry for the delay. Checking the PR

@spolu

spolu commented Nov 3, 2026

Copy link
Copy Markdown
Owner

Some small issues detected:

- [P2] readonly class silently loses its contracts. Without final, Lezer places readonly outside the class node, so [attachment discovery (https://github.com/spolu/code-contracts/blob/ca517d25788738acb82e5ded044c2ee1edba0037/cc-check/src/contract-extractors/php.ts#L319-L330)](https://github.com/spolu/code-contracts/blob/ca517d25788738acb82e5ded044c2ee1edba0037/cc-check/src/contract-extractors/php.ts#L319-L330) rejects the preceding PHPDoc. I reproduced missing class contracts in list and duplicate IDs incorrectly passing format.
- [P2] Attributes misattach interface and trait contracts. For PHPDoc followed by #[Example] interface Foo, the parser produces a spurious function node that [declaration collection accepts (https://github.com/spolu/code-contracts/blob/ca517d25788738acb82e5ded044c2ee1edba0037/cc-check/src/contract-extractors/php.ts#L295-L303)](https://github.com/spolu/code-contracts/blob/ca517d25788738acb82e5ded044c2ee1edba0037/cc-check/src/contract-extractors/php.ts#L295-L303). File listing reports the contract on an unnamed function; listing inside a method omits the enclosing interface contract. Traits behave similarly.
- [P2] Multiline enum values break discovery. The [enum workaround (https://github.com/spolu/code-contracts/blob/ca517d25788738acb82e5ded044c2ee1edba0037/cc-check/src/contract-extractors/php.ts#L56-L70)](https://github.com/spolu/code-contracts/blob/ca517d25788738acb82e5ded044c2ee1edba0037/cc-check/src/contract-extractors/php.ts#L56-L70) misses a newline between = and "paid". Parser recovery then truncates the enum: later case contracts disappear, and location queries return nothing. Concatenated string values also reproduce this.

@spolu

spolu commented Nov 3, 2026

Copy link
Copy Markdown
Owner

r? cc

This branch has not been deployed

No deployments
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.

2 participants