Skip to content

Instantly share code, notes, and snippets.

@quantizor
Last active August 8, 2017 05:17
Show Gist options
  • Save quantizor/67e399964a92ce97be9da7bfa3a09b7c to your computer and use it in GitHub Desktop.
Save quantizor/67e399964a92ce97be9da7bfa3a09b7c to your computer and use it in GitHub Desktop.

Notes

A loop isn't needed here at all. Just tail call parseDeclarationFlags as needed to replay the logic.

function parseDeclarationFlags(): StatementFlags {
    switch (token) {
        case SyntaxKind.VarKeyword:
        case SyntaxKind.LetKeyword:
        case SyntaxKind.FunctionKeyword:
        case SyntaxKind.ClassKeyword:
            return StatementFlags.Statement;
        case SyntaxKind.EnumKeyword:
            return StatementFlags.ModuleElement;
        case SyntaxKind.ConstKeyword:
            nextToken();
            return token === SyntaxKind.EnumKeyword ? StatementFlags.ModuleElement : StatementFlags.Statement;
        case SyntaxKind.InterfaceKeyword:
        case SyntaxKind.TypeKeyword:
            nextToken();
            return isIdentifierOrKeyword() ? StatementFlags.ModuleElement : 0;
        case SyntaxKind.ModuleKeyword:
        case SyntaxKind.NamespaceKeyword:
            nextToken();
            return isIdentifierOrKeyword() || token === SyntaxKind.StringLiteral ? StatementFlags.ModuleElement : 0;
        case SyntaxKind.ImportKeyword:
            nextToken();
            return token === SyntaxKind.StringLiteral || token === SyntaxKind.AsteriskToken ||
                token === SyntaxKind.OpenBraceToken || isIdentifierOrKeyword() ?
                StatementFlags.ModuleElement : 0;
        case SyntaxKind.ExportKeyword:
            nextToken();
            if (token === SyntaxKind.EqualsToken || token === SyntaxKind.AsteriskToken ||
                token === SyntaxKind.OpenBraceToken || token === SyntaxKind.DefaultKeyword) {
                return StatementFlags.ModuleElement;
            }
            return parseDeclarationFlags();
        case SyntaxKind.DeclareKeyword:
        case SyntaxKind.PublicKeyword:
        case SyntaxKind.PrivateKeyword:
        case SyntaxKind.ProtectedKeyword:
        case SyntaxKind.StaticKeyword:
            return nextToken() && parseDeclarationFlags();
        default:
            return 0;
}

Instead of repeating the logic directly above this line, simply return and call the function again:

nextToken();
return token === SyntaxKind.EnumKeyword ? StatementFlags.ModuleElement : StatementFlags.Statement;

⬇️

return nextToken() && parseDeclarationFlags();

Isolate and coalesce this comparison logic into a separate function. It's too complex to be inline.

function isTokenModuleCompatibleSyntax() {
    return    token === SyntaxKind.StringLiteral
           || token === SyntaxKind.AsteriskToken
           || token === SyntaxKind.OpenBraceToken
           || token === SyntaxKind.EqualsToken
           || token === SyntaxKind.AsteriskToken
           || token === SyntaxKind.OpenBraceToken
           || token === SyntaxKind.DefaultKeyword
           || isIdentifierOrKeyword()
    ;
}

// L3673
case SyntaxKind.ImportKeyword:
    return    nextToken()
           && isTokenModuleCompatibleSyntax()
              ? StatementFlags.ModuleElement
              : 0
    ;

// L3678
case SyntaxKind.ExportKeyword:
    nextToken();

    if (isTokenModuleCompatibleSyntax()) {
        return StatementFlags.ModuleElement;
    } else {
        continue;
    }
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment