Skip to content

feat: macro hover with origin indicator and inferred return types#244

Merged
calebdw merged 1 commit into
mainfrom
calebdw/push-mkrtkqzuxxyr
Jul 17, 2026
Merged

feat: macro hover with origin indicator and inferred return types#244
calebdw merged 1 commit into
mainfrom
calebdw/push-mkrtkqzuxxyr

Conversation

@calebdw

@calebdw calebdw commented Jul 17, 2026

Copy link
Copy Markdown
Collaborator

Macro methods now show a "macro" origin indicator in hover instead of the generic "virtual" label, helping users distinguish ::macro() registrations from @method/@mixin synthesized members.

When a macro closure has no explicit return type hint, the return type is inferred from the closure body and displayed with an "(inferred)" annotation. This also applies to regular methods whose return types are inferred at hover time.

A new preserve_static flag on ResolutionCtx controls whether $this/self/static resolve to their keyword form or the concrete class name. For method chains like $this->transform(...), the last method's declared return type is used directly via resolve_chain_declared_return(), preserving $this, static, and generic parameters that the general expression resolver would flatten to a bare class name. Raw class methods are checked before the fully-resolved class so template parameter names (e.g. TValue) are preserved instead of being replaced with their bounds.

Key changes:

  • is_macro and is_inferred_return fields on MethodInfo
  • MemberOrigin::Macro variant for hover rendering
  • preserve_static on ResolutionCtx with chain-aware resolution
  • resolve_chain_declared_return() for declared return type lookup
  • 4 new integration tests for hover behavior

@AJenbo

AJenbo commented Jul 17, 2026

Copy link
Copy Markdown
Contributor

Macro methods now show a "macro" origin indicator in hover instead of the generic "virtual" label, helping users distinguish ::macro() registrations from @method/@mixin synthesized members.

This makes me much less annoyed with them

@AJenbo

AJenbo commented Jul 17, 2026

Copy link
Copy Markdown
Contributor

When a macro closure has no explicit return type hint, the return type is inferred from the closure body and displayed with an "(inferred)" annotation. This also applies to regular methods whose return types are inferred at hover time.

Probably a good way to remind people to go fix it

Macro methods now show a "macro" origin indicator in hover instead
of the generic "virtual" label, helping users distinguish ::macro()
registrations from @method/@mixin synthesized members.

When a macro closure has no explicit return type hint, the return
type is inferred from the closure body and displayed with an
"(inferred)" annotation. This also applies to regular methods
whose return types are inferred at hover time.

A new preserve_static flag on ResolutionCtx controls whether
$this/self/static resolve to their keyword form or the concrete
class name. For method chains like $this->transform(...), the
last method's declared return type is used directly via
resolve_chain_declared_return(), preserving $this, static, and
generic parameters that the general expression resolver would
flatten to a bare class name. Raw class methods are checked
before the fully-resolved class so template parameter names
(e.g. TValue) are preserved instead of being replaced with
their bounds.

Key changes:
- is_macro and is_inferred_return fields on MethodInfo
- MemberOrigin::Macro variant for hover rendering
- preserve_static on ResolutionCtx with chain-aware resolution
- resolve_chain_declared_return() for declared return type lookup
- 4 new integration tests for hover behavior
@calebdw
calebdw force-pushed the calebdw/push-mkrtkqzuxxyr branch from 157ee19 to d3f45ed Compare July 17, 2026 20:48
@calebdw

calebdw commented Jul 17, 2026

Copy link
Copy Markdown
Collaborator Author

Probably a good way to remind people to go fix it

Yeah, this is mainly because I wanted the server to know about $this return types, and phpstan doesn't really like a closure returning static when the closure is in another class (could be opportunity to fix at phpstan).

E.g.:

final class CollectionMacros
{
    public static function boot(): void
    {
        Collection::macro(
            'asValueLabel',
            // phpstan errors with: Anonymous function should return static(Eagle\Common\Macros\CollectionMacros) but returns Illuminate\Support\Collection<int, array<string, mixed>>
            fn (): static => $this->map(fn ($l, $v) => ['value' => $v, 'label' => $l])->values(),
        );
    }
}

@codecov-commenter

Copy link
Copy Markdown

⚠️ Please install the 'codecov app svg image' to ensure uploads and comments are reliably processed by Codecov.

Codecov Report

❌ Patch coverage is 65.04854% with 36 lines in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
src/completion/call_resolution.rs 18.18% 36 Missing ⚠️

📢 Thoughts on this report? Let us know!

@calebdw
calebdw merged commit 14fc0b8 into main Jul 17, 2026
7 checks passed
@calebdw
calebdw deleted the calebdw/push-mkrtkqzuxxyr branch July 17, 2026 20:59
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.

3 participants