From bfe9bc912a7a9cafc181cc5b42e57d3aaeb4e0f9 Mon Sep 17 00:00:00 2001 From: Keen Yee Liau Date: Fri, 10 Jan 2020 17:22:59 -0800 Subject: [PATCH] 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 --- packages/language-service/src/template.ts | 4 +++- .../language-service/test/diagnostics_spec.ts | 24 +++++++++++++++---- 2 files changed, 22 insertions(+), 6 deletions(-) diff --git a/packages/language-service/src/template.ts b/packages/language-service/src/template.ts index afd13214e1..e882b1ca81 100644 --- a/packages/language-service/src/template.ts +++ b/packages/language-service/src/template.ts @@ -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, diff --git a/packages/language-service/test/diagnostics_spec.ts b/packages/language-service/test/diagnostics_spec.ts index afff120cd1..4eabe54caa 100644 --- a/packages/language-service/test/diagnostics_spec.ts +++ b/packages/language-service/test/diagnostics_spec.ts @@ -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
\r\n{{line0}}\r\n{{line1}}\r\n{{line2}}\r\n
'); - const ngDiags = ngLS.getDiagnostics(fileName); + const content = mockHost.override( + TEST_TEMPLATE, '\r\n
\r\n{{line0}}\r\n{{line1}}\r\n{{line2}}\r\n
'); + 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, `