angular / angular

Deliver web apps with confidence 🚀
https://angular.dev
MIT License
95.11k stars 24.9k forks source link

signals (or function calls in the templates) in language service #56476

Open eneajaho opened 1 week ago

eneajaho commented 1 week ago

Which @angular/* package(s) are relevant/related to the feature request?

language-service

Description

  1. Quick Info for signal works only if that signal is a field of the component CleanShot 2024-06-17 at 13 09 04@2x

While for some signal in a service it's not working (it doesn't get the definition) CleanShot 2024-06-17 at 13 10 01@2x

  1. Calling a method in the template doesn't work (doesn't go to definition) CleanShot 2024-06-17 at 13 11 44@2x

These are either issues with function calling or getting the correct definition for function calls in the template.

Tested with this code:

import { Component, Injectable, inject, signal } from '@angular/core';

@Injectable()
export class SomeService {
  someSignal = signal(0);

  someMethod() {
    console.log('hello world!');
  }
}

@Component({
  selector: 'app-root',
  standalone: true,
  template: `
    <div>{{ someProp }}</div>
    <div>{{ someSignal() }}</div>
    <div>{{ someService.someSignal() }}</div>

    <div>{{ someObject.someProp }}</div>
    <div>{{ someObject.someSignalProp() }}</div>

    <button (click)="someSignal.set(1)">Increment</button>
    <button (click)="someService.someSignal.set(1)">Increment Service</button>
    <button (click)="someObject.someSignalProp.set('hello world!')">Change Object</button>

    <button (click)="someService.someMethod()">Call Service Method</button>
  `,
})
export class AppComponent {
  someService = inject(SomeService);

  someProp = 'hello world!';
  someSignal = signal(0);

  someObject = {
    someSignalProp: signal('hello world!'),
    someProp: 'hello world!',
  }
}

Proposed solution

Add better handling for function calls in language-service

Alternatives considered

-

eneajaho commented 1 week ago

I'd also like to try to work on this one.

eneajaho commented 1 week ago

Looks like getSymbolOfNode doesn't return any result at all

it('should work for accessed function calls', () => {
  expectQuickInfo({
    templateOverride: `<div (click)="someObject.some¦Method()"></div>`,
    expectedSpanText: 'someMethod',
    expectedDisplayString: '(property) someMethod: () => number',
  });
});

CleanShot 2024-06-17 at 14 45 40@2x

alxhub commented 1 week ago

This seems like a bug (or set of bugs), not a feature request.