Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow comments in tsconfig.json #5450

Merged
merged 5 commits into from
Nov 2, 2015

Conversation

sarod
Copy link
Contributor

@sarod sarod commented Oct 29, 2015

This pull requests allows comments in tsconfig.json #4987
Comments can be single line comments using // or multiline comments using / * * /

@msftclas
Copy link

Hi @sarod, I'm your friendly neighborhood Microsoft Pull Request Bot (You can call me MSBOT). Thanks for your contribution!

In order for us to evaluate and accept your PR, we ask that you sign a contribution license agreement. It's all electronic and will take just minutes. I promise there's no faxing. https://cla.microsoft.com.

TTYL, MSBOT;

@msftclas
Copy link

@sarod, Thanks for signing the contribution license agreement so quickly! Actual humans will now validate the agreement and then evaluate the PR.

Thanks, MSBOT;

@sarod sarod changed the title Allow comments in tsconfig.json issue #4987 Allow comments in tsconfig.json Oct 29, 2015
}
}
else if (processingSingleLineComment) {
if (currentChar === "\n") {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

use isLineBreak instead.

@weswigham
Copy link
Member

VSCode only allows // and /**/ comments in its json parser - we should do the same (or it won't be able to validate our tsconfigs).

// consume the \ and the escaped char
result += currentChar;
result += jsonText.charAt(i + 1);
i += 1;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This doesn't technically capture all escape patterns - specifically, this ignores the unicode escape sequences of the form \u0000. It probably doesn't matter for just parsing out comments - in fact, we really only care if we see \", so we know to continue processing the string.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it is functionally equivalent to handle this the way it is without dealing with \u special case.
However have to at least handle \ in addition to " in order to handle the second assertion in "it("handles escaped characters in strings correctly")".

@DanielRosenwasser
Copy link
Member

I don't think this is necessarily the right approach. Why are we building a scanner to handle a JSON file instead of leveraging the existing scanner and writing a resilient JSON parser?

}
else {
// Keep other characters
result += currentChar;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This implies you're going to be concatenating a string for every character in your tsconfig.json. You should instead concatenate the longest sequences of non-comment substrings.

For an example of where we do this, check out scanString in scanner.ts. We just loop on an index and check the character code at every index. When we hit something like a backslash, we just concatenate a range:

function scanString(): string {
    let quote = text.charCodeAt(pos++);
    let result = "";
    let start = pos;
    while (true) {
        if (pos >= end) {
            result += text.substring(start, pos);
            tokenIsUnterminated = true;
            error(Diagnostics.Unterminated_string_literal);
            break;
        }
        let ch = text.charCodeAt(pos);
        if (ch === quote) {
            result += text.substring(start, pos);
            pos++;
            break;
        }
        if (ch === CharacterCodes.backslash) {
            result += text.substring(start, pos);
            result += scanEscapeSequence();
            start = pos;
            continue;
        }
        if (isLineBreak(ch)) {
            result += text.substring(start, pos);
            tokenIsUnterminated = true;
            error(Diagnostics.Unterminated_string_literal);
            break;
        }
        pos++;
    }
    return result;
}

@sarod
Copy link
Contributor Author

sarod commented Oct 30, 2015

@DanielRosenwasser What do you mean exactly by

I don't think this is necessarily the right approach. Why are we building a scanner to handle a JSON file instead of leveraging the existing scanner and writing a resilient JSON parser?

Are you talking about using elements of typescript scanner instead of using comment removal than JSON.parse?

If that's the case could you please clarify what direction I should follow between:

  1. Restarting from scratch using the typescript scanner
  2. Applying other suggestions on top of my current PR

@mhegazy
Copy link
Contributor

mhegazy commented Oct 30, 2015

One nice thing about using the TS parser/scanner, is you can be much more forgiving with invalid input, and you can give helpful messages too.

@DanielRosenwasser
Copy link
Member

I think it would be a lot better to create a custom parser, however, if you don't feel entirely comfortable with that, I think the current approach isn't too bad. Still, I think the long-term vision is to use our scanner to parse things out.

@vladima
Copy link
Contributor

vladima commented Oct 31, 2015

I don't think we should be putting yet another scanner in our codebase unless we have a very compelling reason. Given that implementation that uses existing scanner can be as simple as code below I would vote to reuse code that we already have

    function stripComments(text: string): string {
        let output = "";
        let scanner = createScanner(ScriptTarget.ES5, /* skipTrivia */ false, LanguageVariant.Standard, text);
        let token: SyntaxKind;
        let newLine: string;
        while((token = scanner.scan()) !== SyntaxKind.EndOfFileToken) {
            switch(token) {
                case SyntaxKind.SingleLineCommentTrivia:
                case SyntaxKind.MultiLineCommentTrivia:
                    break;
                default:
                    output += scanner.getTokenText();
                    break;
            }
        }
        return output;
    }

@DanielRosenwasser
Copy link
Member

👍 for Vlad's solution. You can still have the same behavior where you pad any trivia with spaces the same way you did.

@sarod
Copy link
Contributor Author

sarod commented Oct 31, 2015

OK. I'll give a try to Vlad's solution.

This commit uses TS scanner and replaces comments token text
by whitespaces to preserve orginal positions.
}

it("returns empty config for file with only whitespaces", () => {
assertParseResult("", { config : {} });
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There's a tab on this line


module ts {
describe('parseConfigFileTextToJson', () => {
function assertParseResult(jsonText: string, expectedConfigObject: { config?: any; error?: Diagnostic }) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you switch this file to use 4 spaces per indentation?

@vladima
Copy link
Contributor

vladima commented Nov 2, 2015

👍

mhegazy added a commit that referenced this pull request Nov 2, 2015
@mhegazy mhegazy merged commit 3e63144 into microsoft:master Nov 2, 2015
@mhegazy
Copy link
Contributor

mhegazy commented Nov 2, 2015

Thanks @sarod!

@sarod
Copy link
Contributor Author

sarod commented Nov 2, 2015

Thanks for the guidance and suggestions.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants