Skip to content

Commit c721763

Browse files
committed
Use a scanning algorithm for closing tags map
1 parent 72178d6 commit c721763

File tree

2 files changed

+35
-24
lines changed

2 files changed

+35
-24
lines changed

src/compiler/parser.ts

Lines changed: 1 addition & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -3104,31 +3104,9 @@ module ts {
31043104
return "";
31053105
}
31063106

3107-
function retrieveClosingTagsMap(): Map<number[]> {
3108-
const closingTagsMap: Map<number[]> = {};
3109-
// Unfortunately this regex won't catch linebreak inside the tagName
3110-
// ie: </MyModule.\nmyProperty>
3111-
// We could use [\s\S], but it could cause matching gigantic tagname
3112-
// of multiple lines of valid typescript code.
3113-
const jsxClosingTagRegEx = /<\/\s*(.+?)\s*>/g;
3114-
while (true) {
3115-
const match = jsxClosingTagRegEx.exec(sourceText)
3116-
if (match) {
3117-
const tag = match[1].replace(/\s/g, "");
3118-
if (!hasProperty(closingTagsMap, tag)) {
3119-
closingTagsMap[tag] = [];
3120-
}
3121-
closingTagsMap[tag].push(match.index);
3122-
} else {
3123-
break;
3124-
}
3125-
}
3126-
return closingTagsMap;
3127-
}
3128-
31293107
function hasClosingTagAfterPos(tagName: string, currentPos: number): boolean {
31303108
if (!closingTagsMap) {
3131-
closingTagsMap = retrieveClosingTagsMap();
3109+
closingTagsMap = retrieveClosingTagsMap(sourceText, sourceFile.languageVersion);
31323110
}
31333111
return hasProperty(closingTagsMap, tagName) && forEach(closingTagsMap[tagName], p => p >= currentPos);
31343112
}

src/compiler/scanner.ts

Lines changed: 34 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -601,7 +601,40 @@ module ts {
601601
ch >= CharacterCodes._0 && ch <= CharacterCodes._9 || ch === CharacterCodes.$ || ch === CharacterCodes._ ||
602602
ch > CharacterCodes.maxAsciiCharacter && isUnicodeIdentifierPart(ch, languageVersion);
603603
}
604-
604+
605+
/* @internal */
606+
export function retrieveClosingTagsMap(text: string, languageVersion: ScriptTarget): Map<number[]> {
607+
let pos = 0;
608+
let end = text.length;
609+
const closingTags: Map<number[]> = {};
610+
while (pos < end) {
611+
if (text.charCodeAt(pos) === CharacterCodes.lessThan && text.charCodeAt(pos + 1) === CharacterCodes.slash) {
612+
let p = pos + 2;
613+
let ch: number;
614+
while (p < end) {
615+
ch = text.charCodeAt(p);
616+
if (!isIdentifierPart(ch, languageVersion) &&
617+
ch !== CharacterCodes.minus &&
618+
ch !== CharacterCodes.dot &&
619+
ch !== CharacterCodes.backslash) {
620+
break;
621+
}
622+
p++;
623+
}
624+
if (ch === CharacterCodes.greaterThan) {
625+
let tagName = text.substring(pos + 2, p).replace(/\s/g, '');
626+
if (!hasProperty(closingTags, tagName)) {
627+
closingTags[tagName] = [];
628+
}
629+
closingTags[tagName].push(pos);
630+
pos = p + 1;
631+
}
632+
}
633+
pos++;
634+
}
635+
return closingTags;
636+
}
637+
605638
// Creates a scanner over a (possibly unspecified) range of a piece of text.
606639
/* @internal */
607640
export function createScanner(languageVersion: ScriptTarget, skipTrivia: boolean, text?: string, onError?: ErrorCallback, start?: number, length?: number): Scanner {

0 commit comments

Comments
 (0)