Skip to content

Commit c675acd

Browse files
atscottzarend
authored andcommitted
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 angular/vscode-ng-language-service#1140 PR Close #41054
1 parent 95f748c commit c675acd

File tree

2 files changed

+10
-2
lines changed

2 files changed

+10
-2
lines changed

packages/compiler/src/ml_parser/lexer.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -523,7 +523,7 @@ class _Tokenizer {
523523
tagName = openTagToken.parts[1];
524524
this._attemptCharCodeUntilFn(isNotWhitespace);
525525
while (this._cursor.peek() !== chars.$SLASH && this._cursor.peek() !== chars.$GT &&
526-
this._cursor.peek() !== chars.$LT) {
526+
this._cursor.peek() !== chars.$LT && this._cursor.peek() !== chars.$EOF) {
527527
this._consumeAttributeName();
528528
this._attemptCharCodeUntilFn(isNotWhitespace);
529529
if (this._attemptCharCode(chars.$EQ)) {
@@ -774,7 +774,8 @@ function isNotWhitespace(code: number): boolean {
774774

775775
function isNameEnd(code: number): boolean {
776776
return chars.isWhitespace(code) || code === chars.$GT || code === chars.$LT ||
777-
code === chars.$SLASH || code === chars.$SQ || code === chars.$DQ || code === chars.$EQ;
777+
code === chars.$SLASH || code === chars.$SQ || code === chars.$DQ || code === chars.$EQ ||
778+
code === chars.$EOF;
778779
}
779780

780781
function isPrefixEnd(code: number): boolean {

packages/compiler/test/ml_parser/lexer_spec.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -234,6 +234,13 @@ import {ParseLocation, ParseSourceFile, ParseSourceSpan} from '../../src/parse_u
234234
});
235235

236236
describe('tags', () => {
237+
it('terminated with EOF', () => {
238+
expect(tokenizeAndHumanizeSourceSpans('<div')).toEqual([
239+
[lex.TokenType.INCOMPLETE_TAG_OPEN, '<div'],
240+
[lex.TokenType.EOF, ''],
241+
]);
242+
});
243+
237244
it('after tag name', () => {
238245
expect(tokenizeAndHumanizeSourceSpans('<div<span><div</span>')).toEqual([
239246
[lex.TokenType.INCOMPLETE_TAG_OPEN, '<div'],

0 commit comments

Comments
 (0)