From 76979e12c97ee4eef9bc93e315a78649792ce4a8 Mon Sep 17 00:00:00 2001 From: Pete Bacon Darwin Date: Tue, 26 Feb 2019 13:05:54 +0000 Subject: [PATCH] refactor(compiler): remove not-null operator hack from lexer (#28978) The parts of a token are supposed to be an array of not-null strings, but we were using `null` for tags that had no prefix. This has been fixed to use the empty string in such cases, which allows the `null !` hack to be removed. PR Close #28978 --- packages/compiler/src/ml_parser/lexer.ts | 24 +-- packages/compiler/src/ml_parser/parser.ts | 6 +- .../compiler/test/ml_parser/lexer_spec.ts | 142 +++++++++--------- 3 files changed, 86 insertions(+), 86 deletions(-) diff --git a/packages/compiler/src/ml_parser/lexer.ts b/packages/compiler/src/ml_parser/lexer.ts index 1c92f03072..0e2f44f2b0 100644 --- a/packages/compiler/src/ml_parser/lexer.ts +++ b/packages/compiler/src/ml_parser/lexer.ts @@ -623,7 +623,7 @@ class _Tokenizer { private _consumePrefixAndName(): string[] { const nameOrPrefixStart = this._index; - let prefix: string = null !; + let prefix: string = ''; while (this._peek !== chars.$COLON && !isPrefixEnd(this._peek)) { this._advance(); } @@ -643,15 +643,15 @@ class _Tokenizer { private _consumeTagOpen(start: ParseLocation) { const savedPos = this._savePosition(); let tagName: string; - let lowercaseTagName: string; + let prefix: string; + let openTagToken: Token|undefined; try { if (!chars.isAsciiLetter(this._peek)) { throw this._createError(_unexpectedCharacterErrorMsg(this._peek), this._getSpan()); } - const nameStart = this._index; - this._consumeTagOpenStart(start); - tagName = this._input.substring(nameStart, this._index); - lowercaseTagName = tagName.toLowerCase(); + openTagToken = this._consumeTagOpenStart(start); + prefix = openTagToken.parts[0]; + tagName = openTagToken.parts[1]; this._attemptCharCodeUntilFn(isNotWhitespace); while (this._peek !== chars.$SLASH && this._peek !== chars.$GT) { this._consumeAttributeName(); @@ -679,28 +679,28 @@ class _Tokenizer { const contentTokenType = this._getTagDefinition(tagName).contentType; if (contentTokenType === TagContentType.RAW_TEXT) { - this._consumeRawTextWithTagClose(lowercaseTagName, false); + this._consumeRawTextWithTagClose(prefix, tagName, false); } else if (contentTokenType === TagContentType.ESCAPABLE_RAW_TEXT) { - this._consumeRawTextWithTagClose(lowercaseTagName, true); + this._consumeRawTextWithTagClose(prefix, tagName, true); } } - private _consumeRawTextWithTagClose(lowercaseTagName: string, decodeEntities: boolean) { + private _consumeRawTextWithTagClose(prefix: string, tagName: string, decodeEntities: boolean) { const textToken = this._consumeRawText(decodeEntities, chars.$LT, () => { if (!this._attemptCharCode(chars.$SLASH)) return false; this._attemptCharCodeUntilFn(isNotWhitespace); - if (!this._attemptStrCaseInsensitive(lowercaseTagName)) return false; + if (!this._attemptStrCaseInsensitive(tagName)) return false; this._attemptCharCodeUntilFn(isNotWhitespace); return this._attemptCharCode(chars.$GT); }); this._beginToken(TokenType.TAG_CLOSE, textToken.sourceSpan.end); - this._endToken([null !, lowercaseTagName]); + this._endToken([prefix, tagName]); } private _consumeTagOpenStart(start: ParseLocation) { this._beginToken(TokenType.TAG_OPEN_START, start); const parts = this._consumePrefixAndName(); - this._endToken(parts); + return this._endToken(parts); } private _consumeAttributeName() { diff --git a/packages/compiler/src/ml_parser/parser.ts b/packages/compiler/src/ml_parser/parser.ts index 845adea5a7..d1fe41608f 100644 --- a/packages/compiler/src/ml_parser/parser.ts +++ b/packages/compiler/src/ml_parser/parser.ts @@ -402,9 +402,9 @@ class _TreeBuilder { private _getElementFullName(prefix: string, localName: string, parentElement: html.Element|null): string { - if (prefix == null) { - prefix = this.getTagDefinition(localName).implicitNamespacePrefix !; - if (prefix == null && parentElement != null) { + if (prefix === '') { + prefix = this.getTagDefinition(localName).implicitNamespacePrefix || ''; + if (prefix === '' && parentElement != null) { prefix = getNsPrefix(parentElement.name); } } diff --git a/packages/compiler/test/ml_parser/lexer_spec.ts b/packages/compiler/test/ml_parser/lexer_spec.ts index 68dcf391fe..7f527d4e65 100644 --- a/packages/compiler/test/ml_parser/lexer_spec.ts +++ b/packages/compiler/test/ml_parser/lexer_spec.ts @@ -184,7 +184,7 @@ import {ParseLocation, ParseSourceFile, ParseSourceSpan} from '../../src/parse_u describe('open tags', () => { it('should parse open tags without prefix', () => { expect(tokenizeAndHumanizeParts('')).toEqual([ - [lex.TokenType.TAG_OPEN_START, null, 'test'], + [lex.TokenType.TAG_OPEN_START, '', 'test'], [lex.TokenType.TAG_OPEN_END], [lex.TokenType.EOF], ]); @@ -200,7 +200,7 @@ import {ParseLocation, ParseSourceFile, ParseSourceSpan} from '../../src/parse_u it('should parse void tags', () => { expect(tokenizeAndHumanizeParts('')).toEqual([ - [lex.TokenType.TAG_OPEN_START, null, 'test'], + [lex.TokenType.TAG_OPEN_START, '', 'test'], [lex.TokenType.TAG_OPEN_END_VOID], [lex.TokenType.EOF], ]); @@ -208,7 +208,7 @@ import {ParseLocation, ParseSourceFile, ParseSourceSpan} from '../../src/parse_u it('should allow whitespace after the tag name', () => { expect(tokenizeAndHumanizeParts('')).toEqual([ - [lex.TokenType.TAG_OPEN_START, null, 'test'], + [lex.TokenType.TAG_OPEN_START, '', 'test'], [lex.TokenType.TAG_OPEN_END], [lex.TokenType.EOF], ]); @@ -227,8 +227,8 @@ import {ParseLocation, ParseSourceFile, ParseSourceSpan} from '../../src/parse_u describe('attributes', () => { it('should parse attributes without prefix', () => { expect(tokenizeAndHumanizeParts('')).toEqual([ - [lex.TokenType.TAG_OPEN_START, null, 't'], - [lex.TokenType.ATTR_NAME, null, 'a'], + [lex.TokenType.TAG_OPEN_START, '', 't'], + [lex.TokenType.ATTR_NAME, '', 'a'], [lex.TokenType.TAG_OPEN_END], [lex.TokenType.EOF], ]); @@ -236,16 +236,16 @@ import {ParseLocation, ParseSourceFile, ParseSourceSpan} from '../../src/parse_u it('should parse attributes with interpolation', () => { expect(tokenizeAndHumanizeParts('')).toEqual([ - [lex.TokenType.TAG_OPEN_START, null, 't'], - [lex.TokenType.ATTR_NAME, null, 'a'], + [lex.TokenType.TAG_OPEN_START, '', 't'], + [lex.TokenType.ATTR_NAME, '', 'a'], [lex.TokenType.ATTR_QUOTE, '"'], [lex.TokenType.ATTR_VALUE, '{{v}}'], [lex.TokenType.ATTR_QUOTE, '"'], - [lex.TokenType.ATTR_NAME, null, 'b'], + [lex.TokenType.ATTR_NAME, '', 'b'], [lex.TokenType.ATTR_QUOTE, '"'], [lex.TokenType.ATTR_VALUE, 's{{m}}e'], [lex.TokenType.ATTR_QUOTE, '"'], - [lex.TokenType.ATTR_NAME, null, 'c'], + [lex.TokenType.ATTR_NAME, '', 'c'], [lex.TokenType.ATTR_QUOTE, '"'], [lex.TokenType.ATTR_VALUE, 's{{m//c}}e'], [lex.TokenType.ATTR_QUOTE, '"'], @@ -256,7 +256,7 @@ import {ParseLocation, ParseSourceFile, ParseSourceSpan} from '../../src/parse_u it('should parse attributes with prefix', () => { expect(tokenizeAndHumanizeParts('')).toEqual([ - [lex.TokenType.TAG_OPEN_START, null, 't'], + [lex.TokenType.TAG_OPEN_START, '', 't'], [lex.TokenType.ATTR_NAME, 'ns1', 'a'], [lex.TokenType.TAG_OPEN_END], [lex.TokenType.EOF], @@ -265,8 +265,8 @@ import {ParseLocation, ParseSourceFile, ParseSourceSpan} from '../../src/parse_u it('should parse attributes whose prefix is not valid', () => { expect(tokenizeAndHumanizeParts('')).toEqual([ - [lex.TokenType.TAG_OPEN_START, null, 't'], - [lex.TokenType.ATTR_NAME, null, '(ns1:a)'], + [lex.TokenType.TAG_OPEN_START, '', 't'], + [lex.TokenType.ATTR_NAME, '', '(ns1:a)'], [lex.TokenType.TAG_OPEN_END], [lex.TokenType.EOF], ]); @@ -274,8 +274,8 @@ import {ParseLocation, ParseSourceFile, ParseSourceSpan} from '../../src/parse_u it('should parse attributes with single quote value', () => { expect(tokenizeAndHumanizeParts('')).toEqual([ - [lex.TokenType.TAG_OPEN_START, null, 't'], - [lex.TokenType.ATTR_NAME, null, 'a'], + [lex.TokenType.TAG_OPEN_START, '', 't'], + [lex.TokenType.ATTR_NAME, '', 'a'], [lex.TokenType.ATTR_QUOTE, '\''], [lex.TokenType.ATTR_VALUE, 'b'], [lex.TokenType.ATTR_QUOTE, '\''], @@ -286,8 +286,8 @@ import {ParseLocation, ParseSourceFile, ParseSourceSpan} from '../../src/parse_u it('should parse attributes with double quote value', () => { expect(tokenizeAndHumanizeParts('')).toEqual([ - [lex.TokenType.TAG_OPEN_START, null, 't'], - [lex.TokenType.ATTR_NAME, null, 'a'], + [lex.TokenType.TAG_OPEN_START, '', 't'], + [lex.TokenType.ATTR_NAME, '', 'a'], [lex.TokenType.ATTR_QUOTE, '"'], [lex.TokenType.ATTR_VALUE, 'b'], [lex.TokenType.ATTR_QUOTE, '"'], @@ -298,8 +298,8 @@ import {ParseLocation, ParseSourceFile, ParseSourceSpan} from '../../src/parse_u it('should parse attributes with unquoted value', () => { expect(tokenizeAndHumanizeParts('')).toEqual([ - [lex.TokenType.TAG_OPEN_START, null, 't'], - [lex.TokenType.ATTR_NAME, null, 'a'], + [lex.TokenType.TAG_OPEN_START, '', 't'], + [lex.TokenType.ATTR_NAME, '', 'a'], [lex.TokenType.ATTR_VALUE, 'b'], [lex.TokenType.TAG_OPEN_END], [lex.TokenType.EOF], @@ -308,8 +308,8 @@ import {ParseLocation, ParseSourceFile, ParseSourceSpan} from '../../src/parse_u it('should allow whitespace', () => { expect(tokenizeAndHumanizeParts('')).toEqual([ - [lex.TokenType.TAG_OPEN_START, null, 't'], - [lex.TokenType.ATTR_NAME, null, 'a'], + [lex.TokenType.TAG_OPEN_START, '', 't'], + [lex.TokenType.ATTR_NAME, '', 'a'], [lex.TokenType.ATTR_VALUE, 'b'], [lex.TokenType.TAG_OPEN_END], [lex.TokenType.EOF], @@ -318,8 +318,8 @@ import {ParseLocation, ParseSourceFile, ParseSourceSpan} from '../../src/parse_u it('should parse attributes with entities in values', () => { expect(tokenizeAndHumanizeParts('')).toEqual([ - [lex.TokenType.TAG_OPEN_START, null, 't'], - [lex.TokenType.ATTR_NAME, null, 'a'], + [lex.TokenType.TAG_OPEN_START, '', 't'], + [lex.TokenType.ATTR_NAME, '', 'a'], [lex.TokenType.ATTR_QUOTE, '"'], [lex.TokenType.ATTR_VALUE, 'AA'], [lex.TokenType.ATTR_QUOTE, '"'], @@ -330,12 +330,12 @@ import {ParseLocation, ParseSourceFile, ParseSourceSpan} from '../../src/parse_u it('should not decode entities without trailing ";"', () => { expect(tokenizeAndHumanizeParts('')).toEqual([ - [lex.TokenType.TAG_OPEN_START, null, 't'], - [lex.TokenType.ATTR_NAME, null, 'a'], + [lex.TokenType.TAG_OPEN_START, '', 't'], + [lex.TokenType.ATTR_NAME, '', 'a'], [lex.TokenType.ATTR_QUOTE, '"'], [lex.TokenType.ATTR_VALUE, '&'], [lex.TokenType.ATTR_QUOTE, '"'], - [lex.TokenType.ATTR_NAME, null, 'b'], + [lex.TokenType.ATTR_NAME, '', 'b'], [lex.TokenType.ATTR_QUOTE, '"'], [lex.TokenType.ATTR_VALUE, 'c&&d'], [lex.TokenType.ATTR_QUOTE, '"'], @@ -346,8 +346,8 @@ import {ParseLocation, ParseSourceFile, ParseSourceSpan} from '../../src/parse_u it('should parse attributes with "&" in values', () => { expect(tokenizeAndHumanizeParts('')).toEqual([ - [lex.TokenType.TAG_OPEN_START, null, 't'], - [lex.TokenType.ATTR_NAME, null, 'a'], + [lex.TokenType.TAG_OPEN_START, '', 't'], + [lex.TokenType.ATTR_NAME, '', 'a'], [lex.TokenType.ATTR_QUOTE, '"'], [lex.TokenType.ATTR_VALUE, 'b && c &'], [lex.TokenType.ATTR_QUOTE, '"'], @@ -358,8 +358,8 @@ import {ParseLocation, ParseSourceFile, ParseSourceSpan} from '../../src/parse_u it('should parse values with CR and LF', () => { expect(tokenizeAndHumanizeParts('')).toEqual([ - [lex.TokenType.TAG_OPEN_START, null, 't'], - [lex.TokenType.ATTR_NAME, null, 'a'], + [lex.TokenType.TAG_OPEN_START, '', 't'], + [lex.TokenType.ATTR_NAME, '', 'a'], [lex.TokenType.ATTR_QUOTE, '\''], [lex.TokenType.ATTR_VALUE, 't\ne\ns\nt'], [lex.TokenType.ATTR_QUOTE, '\''], @@ -383,7 +383,7 @@ import {ParseLocation, ParseSourceFile, ParseSourceSpan} from '../../src/parse_u describe('closing tags', () => { it('should parse closing tags without prefix', () => { expect(tokenizeAndHumanizeParts('')).toEqual([ - [lex.TokenType.TAG_CLOSE, null, 'test'], + [lex.TokenType.TAG_CLOSE, '', 'test'], [lex.TokenType.EOF], ]); }); @@ -397,7 +397,7 @@ import {ParseLocation, ParseSourceFile, ParseSourceSpan} from '../../src/parse_u it('should allow whitespace', () => { expect(tokenizeAndHumanizeParts('')).toEqual([ - [lex.TokenType.TAG_CLOSE, null, 'test'], + [lex.TokenType.TAG_CLOSE, '', 'test'], [lex.TokenType.EOF], ]); }); @@ -543,9 +543,9 @@ import {ParseLocation, ParseSourceFile, ParseSourceSpan} from '../../src/parse_u it('should parse valid start tag in interpolation', () => { expect(tokenizeAndHumanizeParts('{{ a d }}')).toEqual([ [lex.TokenType.TEXT, '{{ a '], - [lex.TokenType.TAG_OPEN_START, null, 'b'], - [lex.TokenType.ATTR_NAME, null, '&&'], - [lex.TokenType.ATTR_NAME, null, 'c'], + [lex.TokenType.TAG_OPEN_START, '', 'b'], + [lex.TokenType.ATTR_NAME, '', '&&'], + [lex.TokenType.ATTR_NAME, '', 'c'], [lex.TokenType.TAG_OPEN_END], [lex.TokenType.TEXT, ' d }}'], [lex.TokenType.EOF], @@ -570,10 +570,10 @@ import {ParseLocation, ParseSourceFile, ParseSourceSpan} from '../../src/parse_u expect(tokenizeAndHumanizeParts( '{a, b, =4 {c}}', {tokenizeExpansionForms: false})) .toEqual([ - [lex.TokenType.TAG_OPEN_START, null, 'span'], + [lex.TokenType.TAG_OPEN_START, '', 'span'], [lex.TokenType.TAG_OPEN_END], [lex.TokenType.TEXT, '{a, b, =4 {c}}'], - [lex.TokenType.TAG_CLOSE, null, 'span'], + [lex.TokenType.TAG_CLOSE, '', 'span'], [lex.TokenType.EOF], ]); }); @@ -582,40 +582,40 @@ import {ParseLocation, ParseSourceFile, ParseSourceSpan} from '../../src/parse_u describe('raw text', () => { it('should parse text', () => { expect(tokenizeAndHumanizeParts(``)).toEqual([ - [lex.TokenType.TAG_OPEN_START, null, 'script'], + [lex.TokenType.TAG_OPEN_START, '', 'script'], [lex.TokenType.TAG_OPEN_END], [lex.TokenType.RAW_TEXT, 't\ne\ns\nt'], - [lex.TokenType.TAG_CLOSE, null, 'script'], + [lex.TokenType.TAG_CLOSE, '', 'script'], [lex.TokenType.EOF], ]); }); it('should not detect entities', () => { expect(tokenizeAndHumanizeParts(``)).toEqual([ - [lex.TokenType.TAG_OPEN_START, null, 'script'], + [lex.TokenType.TAG_OPEN_START, '', 'script'], [lex.TokenType.TAG_OPEN_END], [lex.TokenType.RAW_TEXT, '&'], - [lex.TokenType.TAG_CLOSE, null, 'script'], + [lex.TokenType.TAG_CLOSE, '', 'script'], [lex.TokenType.EOF], ]); }); it('should ignore other opening tags', () => { expect(tokenizeAndHumanizeParts(``)).toEqual([ - [lex.TokenType.TAG_OPEN_START, null, 'script'], + [lex.TokenType.TAG_OPEN_START, '', 'script'], [lex.TokenType.TAG_OPEN_END], [lex.TokenType.RAW_TEXT, 'a
'], - [lex.TokenType.TAG_CLOSE, null, 'script'], + [lex.TokenType.TAG_CLOSE, '', 'script'], [lex.TokenType.EOF], ]); }); it('should ignore other closing tags', () => { expect(tokenizeAndHumanizeParts(``)).toEqual([ - [lex.TokenType.TAG_OPEN_START, null, 'script'], + [lex.TokenType.TAG_OPEN_START, '', 'script'], [lex.TokenType.TAG_OPEN_END], [lex.TokenType.RAW_TEXT, 'a'], - [lex.TokenType.TAG_CLOSE, null, 'script'], + [lex.TokenType.TAG_CLOSE, '', 'script'], [lex.TokenType.EOF], ]); }); @@ -634,40 +634,40 @@ import {ParseLocation, ParseSourceFile, ParseSourceSpan} from '../../src/parse_u describe('escapable raw text', () => { it('should parse text', () => { expect(tokenizeAndHumanizeParts(`t\ne\rs\r\nt`)).toEqual([ - [lex.TokenType.TAG_OPEN_START, null, 'title'], + [lex.TokenType.TAG_OPEN_START, '', 'title'], [lex.TokenType.TAG_OPEN_END], [lex.TokenType.ESCAPABLE_RAW_TEXT, 't\ne\ns\nt'], - [lex.TokenType.TAG_CLOSE, null, 'title'], + [lex.TokenType.TAG_CLOSE, '', 'title'], [lex.TokenType.EOF], ]); }); it('should detect entities', () => { expect(tokenizeAndHumanizeParts(`&`)).toEqual([ - [lex.TokenType.TAG_OPEN_START, null, 'title'], + [lex.TokenType.TAG_OPEN_START, '', 'title'], [lex.TokenType.TAG_OPEN_END], [lex.TokenType.ESCAPABLE_RAW_TEXT, '&'], - [lex.TokenType.TAG_CLOSE, null, 'title'], + [lex.TokenType.TAG_CLOSE, '', 'title'], [lex.TokenType.EOF], ]); }); it('should ignore other opening tags', () => { expect(tokenizeAndHumanizeParts(`a<div>`)).toEqual([ - [lex.TokenType.TAG_OPEN_START, null, 'title'], + [lex.TokenType.TAG_OPEN_START, '', 'title'], [lex.TokenType.TAG_OPEN_END], [lex.TokenType.ESCAPABLE_RAW_TEXT, 'a
'], - [lex.TokenType.TAG_CLOSE, null, 'title'], + [lex.TokenType.TAG_CLOSE, '', 'title'], [lex.TokenType.EOF], ]); }); it('should ignore other closing tags', () => { expect(tokenizeAndHumanizeParts(`a</test>`)).toEqual([ - [lex.TokenType.TAG_OPEN_START, null, 'title'], + [lex.TokenType.TAG_OPEN_START, '', 'title'], [lex.TokenType.TAG_OPEN_END], [lex.TokenType.ESCAPABLE_RAW_TEXT, 'a'], - [lex.TokenType.TAG_CLOSE, null, 'title'], + [lex.TokenType.TAG_CLOSE, '', 'title'], [lex.TokenType.EOF], ]); }); @@ -732,9 +732,9 @@ import {ParseLocation, ParseSourceFile, ParseSourceSpan} from '../../src/parse_u expect(tokenizeAndHumanizeParts( '
{a, b, =4 {c}}
', {tokenizeExpansionForms: true})) .toEqual([ - [lex.TokenType.TAG_OPEN_START, null, 'div'], + [lex.TokenType.TAG_OPEN_START, '', 'div'], [lex.TokenType.TAG_OPEN_END], - [lex.TokenType.TAG_OPEN_START, null, 'span'], + [lex.TokenType.TAG_OPEN_START, '', 'span'], [lex.TokenType.TAG_OPEN_END], [lex.TokenType.EXPANSION_FORM_START], [lex.TokenType.RAW_TEXT, 'a'], @@ -744,8 +744,8 @@ import {ParseLocation, ParseSourceFile, ParseSourceSpan} from '../../src/parse_u [lex.TokenType.TEXT, 'c'], [lex.TokenType.EXPANSION_CASE_EXP_END], [lex.TokenType.EXPANSION_FORM_END], - [lex.TokenType.TAG_CLOSE, null, 'span'], - [lex.TokenType.TAG_CLOSE, null, 'div'], + [lex.TokenType.TAG_CLOSE, '', 'span'], + [lex.TokenType.TAG_CLOSE, '', 'div'], [lex.TokenType.EOF], ]); }); @@ -760,10 +760,10 @@ import {ParseLocation, ParseSourceFile, ParseSourceSpan} from '../../src/parse_u [lex.TokenType.EXPANSION_CASE_VALUE, '=4'], [lex.TokenType.EXPANSION_CASE_EXP_START], [lex.TokenType.TEXT, 'four '], - [lex.TokenType.TAG_OPEN_START, null, 'b'], + [lex.TokenType.TAG_OPEN_START, '', 'b'], [lex.TokenType.TAG_OPEN_END], [lex.TokenType.TEXT, 'a'], - [lex.TokenType.TAG_CLOSE, null, 'b'], + [lex.TokenType.TAG_CLOSE, '', 'b'], [lex.TokenType.EXPANSION_CASE_EXP_END], [lex.TokenType.EXPANSION_FORM_END], [lex.TokenType.EOF], @@ -996,10 +996,10 @@ import {ParseLocation, ParseSourceFile, ParseSourceSpan} from '../../src/parse_u expect(tokenizeAndHumanizeParts( '', {escapedString: true})) .toEqual([ - [lex.TokenType.TAG_OPEN_START, null, 'script'], + [lex.TokenType.TAG_OPEN_START, '', 'script'], [lex.TokenType.TAG_OPEN_END], [lex.TokenType.RAW_TEXT, 'abc\ndef\nghi\tjkl`\'"mno'], - [lex.TokenType.TAG_CLOSE, null, 'script'], + [lex.TokenType.TAG_CLOSE, '', 'script'], [lex.TokenType.EOF], ]); }); @@ -1008,10 +1008,10 @@ import {ParseLocation, ParseSourceFile, ParseSourceSpan} from '../../src/parse_u expect(tokenizeAndHumanizeParts( 'abc\ndef\\nghi\\tjkl\\`\\\'\\"mno', {escapedString: true})) .toEqual([ - [lex.TokenType.TAG_OPEN_START, null, 'title'], + [lex.TokenType.TAG_OPEN_START, '', 'title'], [lex.TokenType.TAG_OPEN_END], [lex.TokenType.ESCAPABLE_RAW_TEXT, 'abc\ndef\nghi\tjkl`\'"mno'], - [lex.TokenType.TAG_CLOSE, null, 'title'], + [lex.TokenType.TAG_CLOSE, '', 'title'], [lex.TokenType.EOF], ]); }); @@ -1019,12 +1019,12 @@ import {ParseLocation, ParseSourceFile, ParseSourceSpan} from '../../src/parse_u it('should parse over escape sequences in tag definitions', () => { expect(tokenizeAndHumanizeParts('', {escapedString: true})) .toEqual([ - [lex.TokenType.TAG_OPEN_START, null, 't'], - [lex.TokenType.ATTR_NAME, null, 'a'], + [lex.TokenType.TAG_OPEN_START, '', 't'], + [lex.TokenType.ATTR_NAME, '', 'a'], [lex.TokenType.ATTR_QUOTE, '"'], [lex.TokenType.ATTR_VALUE, 'b'], [lex.TokenType.ATTR_QUOTE, '"'], - [lex.TokenType.ATTR_NAME, null, 'c'], + [lex.TokenType.ATTR_NAME, '', 'c'], [lex.TokenType.ATTR_QUOTE, '\''], [lex.TokenType.ATTR_VALUE, 'd'], [lex.TokenType.ATTR_QUOTE, '\''], @@ -1059,17 +1059,17 @@ import {ParseLocation, ParseSourceFile, ParseSourceSpan} from '../../src/parse_u ''; expect(tokenizeAndHumanizeParts(text, {escapedString: true})).toEqual([ - [lex.TokenType.TAG_OPEN_START, null, 't'], [lex.TokenType.TAG_OPEN_END], - [lex.TokenType.TEXT, 'line 1'], [lex.TokenType.TAG_CLOSE, null, 't'], + [lex.TokenType.TAG_OPEN_START, '', 't'], [lex.TokenType.TAG_OPEN_END], + [lex.TokenType.TEXT, 'line 1'], [lex.TokenType.TAG_CLOSE, '', 't'], [lex.TokenType.TEXT, '\n'], - [lex.TokenType.TAG_OPEN_START, null, 't'], [lex.TokenType.TAG_OPEN_END], - [lex.TokenType.TEXT, 'line 2'], [lex.TokenType.TAG_CLOSE, null, 't'], + [lex.TokenType.TAG_OPEN_START, '', 't'], [lex.TokenType.TAG_OPEN_END], + [lex.TokenType.TEXT, 'line 2'], [lex.TokenType.TAG_CLOSE, '', 't'], [lex.TokenType.TEXT, '\n'], - [lex.TokenType.TAG_OPEN_START, null, 't'], [lex.TokenType.TAG_OPEN_END], + [lex.TokenType.TAG_OPEN_START, '', 't'], [lex.TokenType.TAG_OPEN_END], [lex.TokenType.TEXT, 'line 3'], // <- line continuation does not appear in token - [lex.TokenType.TAG_CLOSE, null, 't'], + [lex.TokenType.TAG_CLOSE, '', 't'], [lex.TokenType.EOF] ]);