feat(language-service): support hover/definitions for structural directive (#34564)
PR Close #34564
This commit is contained in:
parent
7325053dfa
commit
5260021447
|
@ -150,16 +150,14 @@ function findAttribute(info: AstResult, position: number): Attribute|undefined {
|
|||
|
||||
function findInputBinding(
|
||||
info: AstResult, path: TemplateAstPath, binding: BoundDirectivePropertyAst): Symbol|undefined {
|
||||
const element = path.first(ElementAst);
|
||||
if (element) {
|
||||
for (const directive of element.directives) {
|
||||
const invertedInput = invertMap(directive.directive.inputs);
|
||||
const fieldName = invertedInput[binding.templateName];
|
||||
if (fieldName) {
|
||||
const classSymbol = info.template.query.getTypeSymbol(directive.directive.type.reference);
|
||||
if (classSymbol) {
|
||||
return classSymbol.members().get(fieldName);
|
||||
}
|
||||
const directive = path.parentOf(path.tail);
|
||||
if (directive instanceof DirectiveAst) {
|
||||
const invertedInput = invertMap(directive.directive.inputs);
|
||||
const fieldName = invertedInput[binding.templateName];
|
||||
if (fieldName) {
|
||||
const classSymbol = info.template.query.getTypeSymbol(directive.directive.type.reference);
|
||||
if (classSymbol) {
|
||||
return classSymbol.members().get(fieldName);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -262,6 +262,35 @@ describe('definitions', () => {
|
|||
}
|
||||
});
|
||||
|
||||
it('should be able to find a structural directive', () => {
|
||||
const fileName = mockHost.addCode(`
|
||||
@Component({
|
||||
template: '<div ~{start-my}*«ngIf»="true"~{end-my}></div>'
|
||||
})
|
||||
export class MyComponent { }`);
|
||||
|
||||
// Get the marker for ngIf in the code added above.
|
||||
const marker = mockHost.getReferenceMarkerFor(fileName, 'ngIf');
|
||||
|
||||
const result = ngService.getDefinitionAt(fileName, marker.start);
|
||||
expect(result).toBeDefined();
|
||||
const {textSpan, definitions} = result !;
|
||||
|
||||
// Get the marker for bounded text in the code added above
|
||||
const boundedText = mockHost.getLocationMarkerFor(fileName, 'my');
|
||||
expect(textSpan).toEqual(boundedText);
|
||||
|
||||
expect(definitions).toBeDefined();
|
||||
expect(definitions !.length).toBe(1);
|
||||
|
||||
const refFileName = '/node_modules/@angular/common/common.d.ts';
|
||||
const def = definitions ![0];
|
||||
expect(def.fileName).toBe(refFileName);
|
||||
expect(def.name).toBe('ngIf');
|
||||
expect(def.kind).toBe('property');
|
||||
// Not asserting the textSpan of definition because it's external file
|
||||
});
|
||||
|
||||
it('should be able to find a template from a url', () => {
|
||||
const fileName = mockHost.addCode(`
|
||||
@Component({
|
||||
|
|
|
@ -148,6 +148,20 @@ describe('hover', () => {
|
|||
expect(toText(displayParts)).toBe('(property) TestComponent.name: string');
|
||||
});
|
||||
|
||||
it('should be able to find a structural directive', () => {
|
||||
const fileName = mockHost.addCode(`
|
||||
@Component({
|
||||
template: '<div «*ᐱngIfᐱ="true"»></div>'
|
||||
})
|
||||
export class MyComponent { }`);
|
||||
const marker = mockHost.getDefinitionMarkerFor(fileName, 'ngIf');
|
||||
const quickInfo = ngLS.getHoverAt(fileName, marker.start);
|
||||
expect(quickInfo).toBeTruthy();
|
||||
const {textSpan, displayParts} = quickInfo !;
|
||||
expect(textSpan).toEqual(marker);
|
||||
expect(toText(displayParts)).toBe('(property) NgIf<T>.ngIf: T');
|
||||
});
|
||||
|
||||
it('should be able to ignore a reference declaration', () => {
|
||||
const fileName = mockHost.addCode(`
|
||||
@Component({
|
||||
|
|
Loading…
Reference in New Issue