in src/typescript/ast-utils.ts [231:327]
export function scanText(text: string, start: number, end?: number): TextRange[] {
const ret: TextRange[] = [];
let pos = start;
const stopAtCode = end === undefined;
if (end === undefined) {
end = text.length;
}
while (pos < end) {
const ch = text[pos];
if (WHITESPACE.includes(ch)) {
pos++;
continue;
}
if (ch === '/' && text[pos + 1] === '/') {
accumulateTextBlock();
scanSinglelineComment();
continue;
}
if (ch === '/' && text[pos + 1] === '*') {
accumulateTextBlock();
scanMultilineComment();
continue;
}
// Non-whitespace, non-comment, must be regular token. End if we're not scanning
// to a particular location, otherwise continue.
if (stopAtCode) {
break;
}
pos++;
}
accumulateTextBlock();
return ret;
function scanMultilineComment() {
const endOfComment = findNext('*/', pos + 2);
ret.push({
type: 'blockcomment',
hasTrailingNewLine: ['\n', '\r'].includes(text[endOfComment + 2]),
pos,
end: endOfComment + 2,
});
pos = endOfComment + 2;
start = pos;
}
function scanSinglelineComment() {
const nl = Math.min(findNext('\r', pos + 2), findNext('\n', pos + 2));
if (text[pos + 2] === '/') {
// Special /// comment
ret.push({
type: 'directive',
hasTrailingNewLine: true,
pos: pos + 1,
end: nl,
});
} else {
// Regular // comment
ret.push({
type: 'linecomment',
hasTrailingNewLine: true,
pos,
end: nl,
});
}
pos = nl + 1;
start = pos;
}
function accumulateTextBlock() {
if (pos - start > 0) {
ret.push({
type: 'other',
hasTrailingNewLine: false,
pos: start,
end: pos,
});
start = pos;
}
}
function findNext(sub: string, startPos: number) {
const f = text.indexOf(sub, startPos);
if (f === -1) {
return text.length;
}
return f;
}
}