fix(language-service): use the `HtmlAst` to get the span of HTML tag (#36371)
The HTML tag may include `-` (e.g. `app-root`), so use the `HtmlAst` to get the span. PR Close #36371
This commit is contained in:
parent
96a3de6364
commit
81195a238b
|
@ -55,12 +55,22 @@ function isIdentifierPart(code: number) {
|
|||
* Gets the span of word in a template that surrounds `position`. If there is no word around
|
||||
* `position`, nothing is returned.
|
||||
*/
|
||||
function getBoundedWordSpan(templateInfo: AstResult, position: number): ts.TextSpan|undefined {
|
||||
function getBoundedWordSpan(
|
||||
templateInfo: AstResult, position: number, ast: HtmlAst|undefined): ts.TextSpan|undefined {
|
||||
const {template} = templateInfo;
|
||||
const templateSrc = template.source;
|
||||
|
||||
if (!templateSrc) return;
|
||||
|
||||
if (ast instanceof Element) {
|
||||
// The HTML tag may include `-` (e.g. `app-root`),
|
||||
// so use the HtmlAst to get the span before ayazhafiz refactor the code.
|
||||
return {
|
||||
start: templateInfo.template.span.start + ast.startSourceSpan!.start.offset + 1,
|
||||
length: ast.name.length
|
||||
};
|
||||
}
|
||||
|
||||
// TODO(ayazhafiz): A solution based on word expansion will always be expensive compared to one
|
||||
// based on ASTs. Whatever penalty we incur is probably manageable for small-length (i.e. the
|
||||
// majority of) identifiers, but the current solution involes a number of branchings and we can't
|
||||
|
@ -185,7 +195,7 @@ export function getTemplateCompletions(
|
|||
null);
|
||||
}
|
||||
|
||||
const replacementSpan = getBoundedWordSpan(templateInfo, position);
|
||||
const replacementSpan = getBoundedWordSpan(templateInfo, position, mostSpecific);
|
||||
return result.map(entry => {
|
||||
return {
|
||||
...entry,
|
||||
|
|
|
@ -670,18 +670,18 @@ describe('completions', () => {
|
|||
@Component({
|
||||
selector: 'foo-component',
|
||||
template: \`
|
||||
<di~{div}></div>
|
||||
<test-comp~{test-comp}></test-comp>
|
||||
\`,
|
||||
})
|
||||
export class FooComponent {}
|
||||
`);
|
||||
const location = mockHost.getLocationMarkerFor(fileName, 'div');
|
||||
const location = mockHost.getLocationMarkerFor(fileName, 'test-comp');
|
||||
const completions = ngLS.getCompletionsAtPosition(fileName, location.start)!;
|
||||
expect(completions).toBeDefined();
|
||||
const completion = completions.entries.find(entry => entry.name === 'div')!;
|
||||
const completion = completions.entries.find(entry => entry.name === 'test-comp')!;
|
||||
expect(completion).toBeDefined();
|
||||
expect(completion.kind).toBe('html element');
|
||||
expect(completion.replacementSpan).toEqual({start: location.start - 2, length: 2});
|
||||
expect(completion.kind).toBe('component');
|
||||
expect(completion.replacementSpan).toEqual({start: location.start - 9, length: 9});
|
||||
});
|
||||
|
||||
it('should work for bindings', () => {
|
||||
|
|
Loading…
Reference in New Issue