fix(language-service): CRLF offset in inline template (#34737)

This commit fixes incorrect CRLF offsets in inline template.

PR closes https://github.com/angular/vscode-ng-language-service/issues/520

PR Close #34737
This commit is contained in:
Keen Yee Liau 2020-01-10 17:22:59 -08:00 committed by atscott
parent 6d534f10e6
commit bfe9bc912a
2 changed files with 22 additions and 6 deletions

View File

@ -98,7 +98,9 @@ export class InlineTemplate extends BaseTemplate {
throw new Error(`Inline template and component class should belong to the same source file`);
}
this.fileName = sourceFile.fileName;
this.source = templateNode.text;
// node.text returns the TS internal representation of the normalized text,
// and all CR characters are stripped. node.getText() returns the raw text.
this.source = templateNode.getText().slice(1, -1); // strip leading and trailing quotes
this.span = {
// TS string literal includes surrounding quotes in the start/end offsets.
start: templateNode.getStart() + 1,

View File

@ -796,16 +796,15 @@ describe('diagnostics', () => {
});
});
it('should work correctly with CRLF endings', () => {
it('should work correctly with CRLF endings in external template', () => {
// https://github.com/angular/vscode-ng-language-service/issues/235
// In the example below, the string
// `\r\n{{line0}}\r\n{{line1}}\r\n{{line2}}` is tokenized as a whole,
// and then CRLF characters are converted to LF.
// Source span information is lost in the process.
const fileName = '/app/test.ng';
const content =
mockHost.override(fileName, '\r\n<div>\r\n{{line0}}\r\n{{line1}}\r\n{{line2}}\r\n</div>');
const ngDiags = ngLS.getDiagnostics(fileName);
const content = mockHost.override(
TEST_TEMPLATE, '\r\n<div>\r\n{{line0}}\r\n{{line1}}\r\n{{line2}}\r\n</div>');
const ngDiags = ngLS.getDiagnostics(TEST_TEMPLATE);
expect(ngDiags.length).toBe(3);
for (let i = 0; i < 3; ++i) {
const {messageText, start, length} = ngDiags[i];
@ -820,6 +819,21 @@ describe('diagnostics', () => {
}
});
it('should work correctly with CRLF endings in inline template', () => {
const fileName = mockHost.addCode(
'\n@Component({template:`\r\n\r\n{{line}}`})export class ComponentCRLF {}');
const content = mockHost.readFile(fileName) !;
const ngDiags = ngLS.getDiagnostics(fileName);
expect(ngDiags.length).toBeGreaterThan(0);
const {messageText, start, length} = ngDiags[0];
expect(messageText)
.toBe(
`Identifier 'line' is not defined. ` +
`The component declaration, template variable declarations, and ` +
`element references do not contain such a member`);
expect(content.substring(start !, start ! + length !)).toBe('line');
});
it('should not produce diagnostics for non-exported directives', () => {
const fileName = '/app/test.component.ts';
mockHost.addScript(fileName, `