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 {ParseSourceFile} from '@angular/compiler';
|
||||||
import * as ts from 'typescript';
|
import * as ts from 'typescript';
|
||||||
|
import {ClassDeclaration} from '../../reflection';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Describes the kind of identifier found in a template.
|
* 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. */
|
/** Describes an element attribute in a template. */
|
||||||
export interface AttributeIdentifier extends TemplateIdentifier { kind: IdentifierKind.Attribute; }
|
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
|
* 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
|
* 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>;
|
attributes: Set<AttributeIdentifier>;
|
||||||
|
|
||||||
/** Directives applied to an element. */
|
/** 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),
|
span: new AbsoluteSourceSpan(start, start + name.length),
|
||||||
kind: IdentifierKind.Element,
|
kind: IdentifierKind.Element,
|
||||||
attributes: new Set(attributes),
|
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);
|
this.identifiers.add(elId);
|
||||||
|
|
||||||
|
@ -246,7 +246,20 @@ runInEachFileSystem(() => {
|
|||||||
const refs = getTemplateIdentifiers(boundTemplate);
|
const refs = getTemplateIdentifiers(boundTemplate);
|
||||||
const [ref] = Array.from(refs);
|
const [ref] = Array.from(refs);
|
||||||
const usedDirectives = (ref as ElementIdentifier).usedDirectives;
|
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…
x
Reference in New Issue
Block a user