fix(compiler): recover from an incomplete open tag at the end of a file (#41054)
The compiler's parsing code has logic to recover from incomplete open tags (i.e. `<div`) but the recovery logic does not handle when the incomplete tag is terminated by an EOF. This commit updates the logic to allow for the EOF character to be interpreted as the end of the tag open so that the parser can continue processing. It will then fail to find the end tag and recover by marking the open tag as incomplete. Part of https://github.com/angular/vscode-ng-language-service/issues/1140 PR Close #41054
This commit is contained in:
parent
ffbacbbc98
commit
736b1f9fd4
|
@ -523,7 +523,7 @@ class _Tokenizer {
|
||||||
tagName = openTagToken.parts[1];
|
tagName = openTagToken.parts[1];
|
||||||
this._attemptCharCodeUntilFn(isNotWhitespace);
|
this._attemptCharCodeUntilFn(isNotWhitespace);
|
||||||
while (this._cursor.peek() !== chars.$SLASH && this._cursor.peek() !== chars.$GT &&
|
while (this._cursor.peek() !== chars.$SLASH && this._cursor.peek() !== chars.$GT &&
|
||||||
this._cursor.peek() !== chars.$LT) {
|
this._cursor.peek() !== chars.$LT && this._cursor.peek() !== chars.$EOF) {
|
||||||
this._consumeAttributeName();
|
this._consumeAttributeName();
|
||||||
this._attemptCharCodeUntilFn(isNotWhitespace);
|
this._attemptCharCodeUntilFn(isNotWhitespace);
|
||||||
if (this._attemptCharCode(chars.$EQ)) {
|
if (this._attemptCharCode(chars.$EQ)) {
|
||||||
|
@ -774,7 +774,8 @@ function isNotWhitespace(code: number): boolean {
|
||||||
|
|
||||||
function isNameEnd(code: number): boolean {
|
function isNameEnd(code: number): boolean {
|
||||||
return chars.isWhitespace(code) || code === chars.$GT || code === chars.$LT ||
|
return chars.isWhitespace(code) || code === chars.$GT || code === chars.$LT ||
|
||||||
code === chars.$SLASH || code === chars.$SQ || code === chars.$DQ || code === chars.$EQ;
|
code === chars.$SLASH || code === chars.$SQ || code === chars.$DQ || code === chars.$EQ ||
|
||||||
|
code === chars.$EOF;
|
||||||
}
|
}
|
||||||
|
|
||||||
function isPrefixEnd(code: number): boolean {
|
function isPrefixEnd(code: number): boolean {
|
||||||
|
|
|
@ -234,6 +234,13 @@ import {ParseLocation, ParseSourceFile, ParseSourceSpan} from '../../src/parse_u
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('tags', () => {
|
describe('tags', () => {
|
||||||
|
it('terminated with EOF', () => {
|
||||||
|
expect(tokenizeAndHumanizeSourceSpans('<div')).toEqual([
|
||||||
|
[lex.TokenType.INCOMPLETE_TAG_OPEN, '<div'],
|
||||||
|
[lex.TokenType.EOF, ''],
|
||||||
|
]);
|
||||||
|
});
|
||||||
|
|
||||||
it('after tag name', () => {
|
it('after tag name', () => {
|
||||||
expect(tokenizeAndHumanizeSourceSpans('<div<span><div</span>')).toEqual([
|
expect(tokenizeAndHumanizeSourceSpans('<div<span><div</span>')).toEqual([
|
||||||
[lex.TokenType.INCOMPLETE_TAG_OPEN, '<div'],
|
[lex.TokenType.INCOMPLETE_TAG_OPEN, '<div'],
|
||||||
|
|
Loading…
Reference in New Issue