From 00b389d47765f71bbba9ddd9ebd37e06c29d2009 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Arod?= Date: Sat, 31 Oct 2015 23:16:04 +0100 Subject: [PATCH] New commit using TS scanner. This commit uses TS scanner and replaces comments token text by whitespaces to preserve orginal positions. --- src/compiler/commandLineParser.ts | 120 ++++++++--------------- tests/cases/unittests/tsconfigParsing.ts | 24 +---- 2 files changed, 44 insertions(+), 100 deletions(-) diff --git a/src/compiler/commandLineParser.ts b/src/compiler/commandLineParser.ts index 885b3af45f8..840e2a7e584 100644 --- a/src/compiler/commandLineParser.ts +++ b/src/compiler/commandLineParser.ts @@ -421,91 +421,49 @@ namespace ts { * This method replace comment content by whitespace rather than completely remove them to keep positions in json parsing error reporting accurate. */ function removeComments(jsonText: string): string { - let result = ""; - let processingString = false; - let processingSingleLineComment = false; - let processingMultiLineComment = false; - for (let i = 0; i < jsonText.length; i++) { - let currentCharCode = jsonText.charCodeAt(i); - let currentChar = jsonText.charAt(i); - let nextCharCode = (i + 1 < jsonText.length) ? jsonText.charCodeAt(i + 1) : undefined; - if (processingString) { - if (currentCharCode === CharacterCodes.backslash - && nextCharCode !== undefined) { - // Found an escaped character - // consume the \ and the escaped char - result += currentChar; - result += jsonText.charAt(i + 1); - i += 1; - } - else if (currentCharCode === CharacterCodes.doubleQuote) { - // End of string - result += currentChar; - processingString = false; - } - else { - // String content - result += currentChar; - } - } - else if (processingSingleLineComment) { - if (isLineBreak(currentCharCode)) { - // End of single line comment - processingSingleLineComment = false; - // Keep the line breaks to keep line numbers aligned - result += currentChar; - } - else { - // replace comment content by whitespaces - result += " "; - } - } - else if (processingMultiLineComment) { - if (currentCharCode === CharacterCodes.asterisk && nextCharCode === CharacterCodes.slash) { - // End of comment */ - result += " "; - i += 1; - processingMultiLineComment = false; - } - else if (isLineBreak(currentCharCode)) { - // Keep the line breaks to Keep line aligned - result += currentChar; - } - else { - // replace comment content by whitespaces - result += " "; - } - } - else if (currentCharCode === CharacterCodes.doubleQuote) { - // String start - result += currentChar; - processingString = true; - } - else if (currentCharCode === CharacterCodes.hash) { - // Start of # comment - result += " "; - processingSingleLineComment = true; - } - else if (currentCharCode === CharacterCodes.slash && nextCharCode === CharacterCodes.slash) { - // Start of // comment - result += " "; - i += 1; - processingSingleLineComment = true; - } - else if (currentCharCode === CharacterCodes.slash && nextCharCode === CharacterCodes.asterisk) { - // Start of /**/ comment - result += " "; - i += 1; - processingMultiLineComment = true; - } - else { - // Keep other characters - result += currentChar; + let output = ""; + let scanner = createScanner(ScriptTarget.ES5, /* skipTrivia */ false, LanguageVariant.Standard, jsonText); + let token: SyntaxKind; + while ((token = scanner.scan()) !== SyntaxKind.EndOfFileToken) { + switch (token) { + case SyntaxKind.SingleLineCommentTrivia: + case SyntaxKind.MultiLineCommentTrivia: + // replace comments with whitespaces to preserve original characters position + output += replaceWithWhitespaces(scanner.getTokenText()); + break; + default: + output += scanner.getTokenText(); + break; } } - return result; + return output; + + function replaceWithWhitespaces(commentTokenText: string): string { + let result = ""; + let pos = 0; + let start = 0; + while (pos < commentTokenText.length) { + if (isLineBreak(commentTokenText.charCodeAt(pos))) { + let nbCharToReplace = pos - start; + result += nSpaces(nbCharToReplace); + result += commentTokenText.charAt(pos); + pos += 1; + start = pos; + } + else { + pos += 1; + } + } + result += nSpaces(pos - start); + return result; + + function nSpaces(n: number): string { + return new Array(n + 1).join(" "); + }; + } } + /** * Parse the contents of a config file (tsconfig.json). * @param json The contents of the config file to parse diff --git a/tests/cases/unittests/tsconfigParsing.ts b/tests/cases/unittests/tsconfigParsing.ts index f48593b3169..7490b525000 100644 --- a/tests/cases/unittests/tsconfigParsing.ts +++ b/tests/cases/unittests/tsconfigParsing.ts @@ -21,7 +21,6 @@ module ts { it("returns empty config for file with comments only", () => { assertParseResult("// Comment", { config: {} }); - assertParseResult("# Comment", { config: {} }); assertParseResult("/* Comment*/", { config: {} }); }); @@ -37,19 +36,12 @@ module ts { "file.d.ts" ] }`, { config: { exclude: ["file.d.ts"] } }); - assertParseResult( - `{ - # Excluded files - "exclude": [ - # Exclude d.ts - "file.d.ts" - ] - }`, { config: { exclude: ["file.d.ts"] } }); + assertParseResult( `{ /* Excluded - Files - */ + Files + */ "exclude": [ /* multiline comments can be in the middle of a line */"file.d.ts" ] @@ -60,16 +52,10 @@ module ts { assertParseResult( `{ "exclude": [ - "xx//file.d.ts" + "xx//file.d.ts" ] }`, { config: { exclude: ["xx//file.d.ts"] } }); - assertParseResult( - `{ - "exclude": [ - "xx#file.d.ts" - ] - }`, { config: { exclude: ["xx#file.d.ts"] } }); - assertParseResult( + assertParseResult( `{ "exclude": [ "xx/*file.d.ts*/"