diff --git a/src/compiler/scanner.ts b/src/compiler/scanner.ts index 00966b12f2a..e7313481bc0 100644 --- a/src/compiler/scanner.ts +++ b/src/compiler/scanner.ts @@ -354,6 +354,81 @@ module ts { } } + // Extract comments from the given source text starting at the given position. If trailing is false, whitespace is skipped until + // the first line break and comments between that location and the next token are returned. If trailing is true, comments occurring + // between the given position and the next line break are returned. The return value is an array containing a TextRange for each + // comment. Single-line comment ranges include the the beginning '//' characters but not the ending line break. Multi-line comment + // ranges include the beginning '/* and ending '*/' characters. The return value is undefined if no comments were found. + function getCommentRanges(text: string, pos: number, trailing: boolean): TextRange[] { + var result: TextRange[]; + var collecting = trailing; + while (true) { + var ch = text.charCodeAt(pos); + switch (ch) { + case CharacterCodes.carriageReturn: + if (text.charCodeAt(pos + 1) === CharacterCodes.lineFeed) pos++; + case CharacterCodes.lineFeed: + pos++; + if (trailing) { + return result; + } + collecting = true; + continue; + case CharacterCodes.tab: + case CharacterCodes.verticalTab: + case CharacterCodes.formFeed: + case CharacterCodes.space: + pos++; + continue; + case CharacterCodes.slash: + var nextChar = text.charCodeAt(pos + 1); + if (nextChar === CharacterCodes.slash || nextChar === CharacterCodes.asterisk) { + var startPos = pos; + var comment: string = undefined; + pos += 2; + if (nextChar === CharacterCodes.slash) { + while (pos < text.length) { + if (isLineBreak(text.charCodeAt(pos))) { + break; + } + pos++; + } + } + else { + while (pos < text.length) { + if (text.charCodeAt(pos) === CharacterCodes.asterisk && text.charCodeAt(pos + 1) === CharacterCodes.slash) { + pos += 2; + break; + } + pos++; + } + } + if (collecting) { + if (!result) result = []; + result.push({ pos: startPos, end: pos }); + } + continue; + } + break; + default: + if (ch > CharacterCodes.maxAsciiCharacter && (isWhiteSpace(ch) || isLineBreak(ch))) { + pos++; + continue; + } + break; + } + return result; + } + } + + export function getLeadingComments(text: string, pos: number): TextRange[] { + return getCommentRanges(text, pos, /*trailing*/ false); + } + + export function getTrailingComments(text: string, pos: number): TextRange[] { + return getCommentRanges(text, pos, /*trailing*/ true); + } + export function createScanner(languageVersion: ScriptTarget, text?: string, onError?: ErrorCallback, onComment?: CommentCallback): Scanner { var pos: number; // Current position (end position of text of current token) var len: number; // Length of text