Skip to content

Commit cf55d1b

Browse files
ivanwonderkirjs
authored andcommitted
feat(language-service): Support importing the external module's export about the angular metadata. (#61122)
This works for the code actions and completion. When the ls wants to complete all importable angular metadata in the template, the ls will invoke the function `ls.getCompletionsAtPosition` and filter the item about the angular. When the developer selects an item, the ls will get the module specifier from the code action return by the `ls.getCompletionEntryDetails`. PR Close #61122
1 parent 460b41b commit cf55d1b

File tree

16 files changed

+779
-304
lines changed

16 files changed

+779
-304
lines changed

packages/compiler-cli/src/ngtsc/testing/fake_common/index.ts

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -129,3 +129,17 @@ export declare class CommonModule {
129129
[typeof NgForOf, typeof NgIf, typeof DatePipe, typeof IndexPipe, typeof NgTemplateOutlet]
130130
>;
131131
}
132+
133+
export declare class MatCard {
134+
static ɵcmp: ɵɵDirectiveDeclaration<
135+
MatCard,
136+
'mat-card',
137+
['matCard'],
138+
{'appearance': {'alias': 'appearance'; 'required': false}},
139+
{},
140+
never,
141+
never,
142+
true,
143+
never
144+
>;
145+
}

packages/compiler-cli/src/ngtsc/typecheck/api/api.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -424,3 +424,7 @@ export interface FullSourceMapping {
424424
sourceMapping: SourceMapping;
425425
span: ParseSourceSpan;
426426
}
427+
428+
export interface GetPotentialAngularMetaOptions {
429+
includeExternalModule: boolean;
430+
}

packages/compiler-cli/src/ngtsc/typecheck/api/checker.ts

Lines changed: 46 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -29,9 +29,20 @@ import {Reference} from '../../imports';
2929
import {NgModuleMeta, PipeMeta} from '../../metadata';
3030
import {ClassDeclaration} from '../../reflection';
3131

32-
import {FullSourceMapping, NgTemplateDiagnostic, TypeCheckableDirectiveMeta} from './api';
32+
import {
33+
FullSourceMapping,
34+
GetPotentialAngularMetaOptions,
35+
NgTemplateDiagnostic,
36+
TypeCheckableDirectiveMeta,
37+
} from './api';
3338
import {GlobalCompletion} from './completion';
34-
import {PotentialDirective, PotentialImport, PotentialImportMode, PotentialPipe} from './scope';
39+
import {
40+
PotentialDirective,
41+
PotentialImport,
42+
PotentialImportMode,
43+
PotentialPipe,
44+
TsCompletionEntryInfo,
45+
} from './scope';
3546
import {
3647
ElementSymbol,
3748
SelectorlessComponentSymbol,
@@ -153,6 +164,11 @@ export interface TemplateTypeChecker {
153164
node: AST | TmplAstNode,
154165
): GlobalCompletion | null;
155166

167+
/**
168+
* Get the `TcbLocation` for the global context, which is the location of the `this` variable.
169+
*/
170+
getGlobalTsContext(component: ts.ClassDeclaration): TcbLocation | null;
171+
156172
/**
157173
* For the given expression node, retrieve a `TcbLocation` that can be used to perform
158174
* autocompletion at that point in the expression, if such a location exists.
@@ -176,7 +192,11 @@ export interface TemplateTypeChecker {
176192
* Get basic metadata on the directives which are in scope or can be imported for the given
177193
* component.
178194
*/
179-
getPotentialTemplateDirectives(component: ts.ClassDeclaration): PotentialDirective[];
195+
getPotentialTemplateDirectives(
196+
component: ts.ClassDeclaration,
197+
tsLs: ts.LanguageService,
198+
options: GetPotentialAngularMetaOptions,
199+
): PotentialDirective[];
180200

181201
/**
182202
* Get basic metadata on the pipes which are in scope or can be imported for the given component.
@@ -188,7 +208,29 @@ export interface TemplateTypeChecker {
188208
* declares them (if the tag is from a directive/component), or `null` if the tag originates from
189209
* the DOM schema.
190210
*/
191-
getPotentialElementTags(component: ts.ClassDeclaration): Map<string, PotentialDirective | null>;
211+
getPotentialElementTags(
212+
component: ts.ClassDeclaration,
213+
tsLs: ts.LanguageService,
214+
options: GetPotentialAngularMetaOptions,
215+
): Map<string, PotentialDirective | null>;
216+
217+
/**
218+
* Retrieve a `Map` of potential template element tags that includes in the current component's file
219+
* scope, or in the component's NgModule scope.
220+
*
221+
* The different with the `getPotentialElementTags` is that the directives in the map do not need
222+
* to update the import statement.
223+
*/
224+
getElementsInFileScope(component: ts.ClassDeclaration): Map<string, PotentialDirective | null>;
225+
226+
/**
227+
* Get the scope data for a directive.
228+
*/
229+
getDirectiveScopeData(
230+
component: ts.ClassDeclaration,
231+
isInScope: boolean,
232+
tsCompletionEntryInfo: TsCompletionEntryInfo | null,
233+
): PotentialDirective | null;
192234

193235
/**
194236
* In the context of an Angular trait, generate potential imports for a directive.

packages/compiler-cli/src/ngtsc/typecheck/api/scope.ts

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,21 @@ export enum PotentialImportKind {
3232
Standalone,
3333
}
3434

35+
export interface TsCompletionEntryInfo {
36+
/**
37+
* Sometimes, the location of the tsCompletionEntry symbol does not match the location of the Angular symbol.
38+
*
39+
* For example, the BarComponent is declared in `bar.ts` and exported from there. The `public_api.ts` also
40+
* reexports the BarComponent from `bar.ts`, so the `tsCompletionEntrySymbolFileName` will be `public_api.ts`.
41+
*/
42+
tsCompletionEntrySymbolFileName: string;
43+
/**
44+
* This data is from the tsLs completion entry, and
45+
* will be used in the `ls.getCompletionEntryDetails`.
46+
*/
47+
tsCompletionEntryData?: ts.CompletionEntryData;
48+
}
49+
3550
/**
3651
* Metadata on a directive which is available in a template.
3752
*/
@@ -67,6 +82,8 @@ export interface PotentialDirective {
6782
* Whether or not this directive is in scope.
6883
*/
6984
isInScope: boolean;
85+
86+
tsCompletionEntryInfo: TsCompletionEntryInfo | null;
7087
}
7188

7289
/**
@@ -89,6 +106,8 @@ export interface PotentialPipe {
89106
* Whether or not this pipe is in scope.
90107
*/
91108
isInScope: boolean;
109+
110+
tsCompletionEntryInfo: TsCompletionEntryInfo | null;
92111
}
93112

94113
/**

0 commit comments

Comments
 (0)