feat(ivy): pass information about used directive selectors on elements (#31782)
Extend indexing API interface to provide information about used directives' selectors on template elements. This enables an indexer to xref element attributes to the directives that match them. The current way this matching is done is by mapping selectors to indexed directives. However, this fails in cases where the directive is not indexed by the indexer API, like for transitive dependencies. This solution is much more general. PR Close #31782
This commit is contained in:
parent
a445826dad
commit
44039a4b16
|
@ -8,6 +8,7 @@
|
|||
|
||||
import {ParseSourceFile} from '@angular/compiler';
|
||||
import * as ts from 'typescript';
|
||||
import {ClassDeclaration} from '../../reflection';
|
||||
|
||||
/**
|
||||
* Describes the kind of identifier found in a template.
|
||||
|
@ -38,6 +39,11 @@ export interface MethodIdentifier extends TemplateIdentifier { kind: IdentifierK
|
|||
/** Describes an element attribute in a template. */
|
||||
export interface AttributeIdentifier extends TemplateIdentifier { kind: IdentifierKind.Attribute; }
|
||||
|
||||
/** A reference to a directive node and its selector. */
|
||||
interface DirectiveReference {
|
||||
node: ClassDeclaration;
|
||||
selector: string;
|
||||
}
|
||||
/**
|
||||
* Describes an indexed element in a template. The name of an `ElementIdentifier` is the entire
|
||||
* element tag, which can be parsed by an indexer to determine where used directives should be
|
||||
|
@ -50,7 +56,7 @@ export interface ElementIdentifier extends TemplateIdentifier {
|
|||
attributes: Set<AttributeIdentifier>;
|
||||
|
||||
/** Directives applied to an element. */
|
||||
usedDirectives: Set<ts.Declaration>;
|
||||
usedDirectives: Set<DirectiveReference>;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -157,7 +157,12 @@ class TemplateVisitor extends TmplAstRecursiveVisitor {
|
|||
span: new AbsoluteSourceSpan(start, start + name.length),
|
||||
kind: IdentifierKind.Element,
|
||||
attributes: new Set(attributes),
|
||||
usedDirectives: new Set(usedDirectives.map(dir => dir.ref.node)),
|
||||
usedDirectives: new Set(usedDirectives.map(dir => {
|
||||
return {
|
||||
node: dir.ref.node,
|
||||
selector: dir.selector,
|
||||
};
|
||||
})),
|
||||
};
|
||||
this.identifiers.add(elId);
|
||||
|
||||
|
|
|
@ -246,7 +246,20 @@ runInEachFileSystem(() => {
|
|||
const refs = getTemplateIdentifiers(boundTemplate);
|
||||
const [ref] = Array.from(refs);
|
||||
const usedDirectives = (ref as ElementIdentifier).usedDirectives;
|
||||
expect(usedDirectives).toEqual(new Set([declA, declB, declC]));
|
||||
expect(usedDirectives).toEqual(new Set([
|
||||
{
|
||||
node: declA,
|
||||
selector: 'a-selector',
|
||||
},
|
||||
{
|
||||
node: declB,
|
||||
selector: '[b-selector]',
|
||||
},
|
||||
{
|
||||
node: declC,
|
||||
selector: ':not(never-selector)',
|
||||
}
|
||||
]));
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
Loading…
Reference in New Issue