<commit_before>export interface DeclarationBase {
    jsDocComment?: string;
    comment?: string;
    flags?: DeclarationFlags;
}

export interface EnumMemberDeclaration extends DeclarationBase {
    kind: "enum-value";
    name: string;
}

export interface EnumDeclaration extends DeclarationBase {
    kind: "enum";
    name: string;
    members: EnumMemberDeclaration[];
    constant: boolean;
}

export interface PropertyDeclaration extends DeclarationBase {
    kind: "property";
    name: string;
    type: Type;
}

export interface Parameter {
    kind: "parameter";
    name: string;
    type: Type;
    flags?: ParameterFlags;
}

export interface MethodDeclaration extends DeclarationBase {
    kind: "method";
    name: string;
    parameters: Parameter[];
    returnType: Type;
}

export interface FunctionDeclaration extends DeclarationBase {
    kind: "function";
    name: string;
    parameters: Parameter[];
    returnType: Type;
}

export interface ConstructorDeclaration extends DeclarationBase {
    kind: "constructor";
    parameters: Parameter[];
}

export interface ClassDeclaration extends DeclarationBase {
    kind: "class";
    name: string;
    members: ClassMember[];
    implements: InterfaceDeclaration[];
    baseType?: ObjectTypeReference;
}

export interface InterfaceDeclaration extends DeclarationBase {
    kind: "interface";
    name: string;
    members: ObjectTypeMember[];
    baseTypes?: ObjectTypeReference[];
}

export interface ImportAllDeclaration extends DeclarationBase {
    kind: "importAll";
    name: string;
    from: string;
}

export interface ImportDefaultDeclaration extends DeclarationBase {
    kind: "importDefault";
    name: string;
    from: string;
}

export interface NamespaceDeclaration extends DeclarationBase {
    kind: "namespace";
    name: string;
    members: NamespaceMember[];
}

export interface ConstDeclaration extends DeclarationBase {
    kind: "const";
    name: string;
    type: Type;
}

export interface ExportEqualsDeclaration extends DeclarationBase {
    kind: "export=";
    target: string;
}

export interface ModuleDeclaration extends DeclarationBase {
    kind: "module";
    name: string;
    members: ModuleMember[];
}

export interface ObjectType {
    kind: "object";
    members: ObjectTypeMember[];
}

export interface UnionType {
    kind: "union";
    members: Type[];
}

export interface IntersectionType {
    kind: "intersection";
    members: Type[];
}

export interface FunctionType {
    kind: "function-type";
    parameters: Parameter[];
    returnType: Type;
}

export interface TypeAliasDeclaration extends DeclarationBase {
    kind: "alias";
    name: string;
    type: Type;
}

export interface ArrayTypeReference {
    kind: "array";
    type: Type;
}

export interface NamedTypeReference {
    kind: "name";
    name: string;
}

export interface TypeofReference {
    kind: "typeof";
    type: NamedTypeReference;
}

export type PrimitiveType = "string" | "number" | "boolean" | "any" | "void";

export type TypeReference = TopLevelDeclaration | NamedTypeReference | ArrayTypeReference | PrimitiveType;

export type ObjectTypeReference = ClassDeclaration | InterfaceDeclaration;
export type ObjectTypeMember = PropertyDeclaration | MethodDeclaration;
export type ClassMember = ObjectTypeMember | ConstructorDeclaration;

export type Type = TypeReference | UnionType | IntersectionType | PrimitiveType | ObjectType | TypeofReference | FunctionType;

export type Import = ImportAllDeclaration | ImportDefaultDeclaration;

export type NamespaceMember = InterfaceDeclaration | TypeAliasDeclaration | ClassDeclaration | NamespaceDeclaration | ConstDeclaration | FunctionDeclaration;
export type ModuleMember = InterfaceDeclaration | TypeAliasDeclaration | ClassDeclaration | NamespaceDeclaration | ConstDeclaration | FunctionDeclaration | Import;
export type TopLevelDeclaration =  NamespaceMember | ExportEqualsDeclaration | ModuleDeclaration | EnumDeclaration | Import;

export enum DeclarationFlags {
    None = 0,
    Private = 1 << 0,
    Protected = 1 << 1,
    Static = 1 << 2,
    Optional = 1 << 3,
    Export = 1 << 4,
    Abstract = 1 << 5,
    ExportDefault = 1 << 6,
}

export enum ParameterFlags {
    None = 0,
    Optional = 1 << 0,
    Rest = 1 << 1
}

export const create = {
    interface(name: string): InterfaceDeclaration {
        return {
            name,
            baseTypes: [],
            kind: "interface",
            members: []
        };
    },

    class(name: string): ClassDeclaration {
        return {
            kind: 'class',
            name,
            members: [],
            implements: []
        };
    },

    enum(name: string, constant: boolean = false): EnumDeclaration {
        return {
            kind: 'enum',
            name, constant,
            members: []
        };
    },

    enumValue(name: string): EnumMemberDeclaration {
        return {
            kind: 'enum-value',
            name
        };
    },

    property(name: string, type: Type, flags = DeclarationFlags.None): PropertyDeclaration {
        return {
            kind: "property",
            name, type, flags
        };
    },

    method(name: string, parameters: Parameter[], returnType: Type, flags = DeclarationFlags.None): MethodDeclaration {
        return {
            kind: "method",
            name, parameters, returnType, flags
        };
    },

    function(name: string, parameters: Parameter[], returnType: Type): FunctionDeclaration {
        return {
            kind: "function",
            name, parameters, returnType
        };
    },

    functionType(parameters: Parameter[], returnType: Type): FunctionType {
        return {
            kind: "function-type",
            parameters, returnType
        };
    },

    parameter(name: string, type: Type, flags = ParameterFlags.None): Parameter {
        return {
            kind: "parameter",
            name, type, flags
        };
    },

    constructor(parameters: Parameter[], flags = DeclarationFlags.None): ConstructorDeclaration {
        return {
            kind: "constructor",
            parameters,
            flags
        };
    },

    const(name: string, type: Type): ConstDeclaration {
        return {
            kind: "const", name, type
        };
    },

    alias(name: string, type: Type): TypeAliasDeclaration {
        return {
            kind: "alias", name, type
        };
    },

    namespace(name: string): NamespaceDeclaration {
        return {
            kind: "namespace", name,
            members: []
        };
    },

    objectType(members: ObjectTypeMember[]): ObjectType {
        return {
            kind: "object",
            members
        };
    },

    array(type: Type): ArrayTypeReference {
        return {
            kind: "array",
            type
        };
    },

    namedTypeReference(name: string): NamedTypeReference {
        return {
            kind: 'name',
            name
        };
    },

    exportEquals(target: string): ExportEqualsDeclaration {
        return {
            kind: 'export=',
            target
        };
    },

    module(name: string): ModuleDeclaration {
        return {
            kind: 'module',
            name,
            members: []
        };
    },

    importAll(name: string, from: string): ImportAllDeclaration {
        return {
            kind: 'importAll',
            name,
            from
        };
    },

    importDefault(name: string, from: string): ImportDefaultDeclaration {
        return {
            kind: 'importDefault',
            name,
            from
        };
    },

    union(members: Type[]): UnionType {
        return {
            kind: 'union',
            members
        };
    },

    typeof(type: NamedTypeReference): TypeofReference {
        return {
            kind: 'typeof',
            type
        };
    }
};

export const type = {
    array(type: Type): ArrayTypeReference {
        return {
            kind: "array",
            type
        }
    },
    string: <PrimitiveType>"string",
    number: <PrimitiveType>"number",
    boolean: <PrimitiveType>"boolean",
    any: <PrimitiveType>"any",
    void: <PrimitiveType>"void"
};

export const reservedWords = ['abstract', 'await', 'boolean', 'break', 'byte', 'case',
	'catch', 'char', 'class', 'const', 'continue', 'debugger', 'default',
	'delete', 'do', 'double', 'else', 'enum', 'export', 'extends', 'false',
	'final', 'finally', 'float', 'for', 'function', 'goto', 'if', 'implements',
	'import', 'in', 'instanceof', 'int', 'interface', 'let', 'long', 'native',
	'new', 'null', 'package', 'private', 'protected', 'public', 'return', 'short',
	'static', 'super', 'switch', 'synchronized', 'this', 'throw', 'throws',
	'transient', 'true', 'try', 'typeof', 'var', 'void', 'volatile', 'while', 'with', 'yield'];

/** IdentifierName can be written as unquoted property names, but may be reserved words. */
export function isIdentifierName(s: string) {
    return /^[$A-Z_][0-9A-Z_$]*$/i.test(s);
}

/** Identifiers are e.g. legal variable names. They may not be reserved words */
export function isIdentifier(s: string) {
    return isIdentifierName(s) && reservedWords.indexOf(s) < 0;
}

function quoteIfNeeded(s: string) {
    if (isIdentifierName(s)) {
        return s;
    } else {
        // JSON.stringify handles escaping quotes for us. Handy!
        return JSON.stringify(s);
    }
}

export const enum ContextFlags {
    None = 0,
    Module = 1 << 0,
    InAmbientNamespace = 1 << 1
}

export function never(x: never, err: string): never {
    throw new Error(err);
}

export function emit(rootDecl: TopLevelDeclaration, rootFlags = ContextFlags.None): string {
    let output = "";
    let indentLevel = 0;
    let contextStack: ContextFlags[] = [rootFlags];

    writeDeclaration(rootDecl);
    return output;

    function getContextFlags() {
        return contextStack.reduce((a, b) => a | b, ContextFlags.None);
    }

    function tab() {
        for (let i = 0; i < indentLevel; i++) {
            output = output + '    ';
        }
    }

    function print(s: string) {
        output = output + s;
    }

    function start(s: string) {
        tab();
        print(s);
    }

    function classFlagsToString(flags: DeclarationFlags | undefined): string {
        let out = '';

        if (flags & DeclarationFlags.Abstract) {
            out += 'abstract ';
        }

        return out;
    }

    function memberFlagsToString(flags: DeclarationFlags | undefined): string {
        let out = '';

        if (flags & DeclarationFlags.Private) {
            out += 'private ';
        }
        else if (flags & DeclarationFlags.Protected) {
            out += 'protected ';
        }

        if (flags & DeclarationFlags.Static) {
            out += 'static ';
        }

        if (flags & DeclarationFlags.Abstract) {
            out += 'abstract ';
        }

        return out;
    }

    function startWithDeclareOrExport(s: string, flags: DeclarationFlags | undefined) {
        if (getContextFlags() & ContextFlags.InAmbientNamespace) {
            // Already in an all-export context
            start(s);
        } else if (flags & DeclarationFlags.Export) {
            start(`export ${s}`);
        } else if (flags & DeclarationFlags.ExportDefault) {
            start(`export default ${s}`);
        } else {
            start(`declare ${s}`);
        }
    }

    function newline() {
        output = output + '\r\n';
    }

    function needsParens(d: Type) {
        if (typeof d === 'string') {
            return false;
        }
        switch (d.kind) {
            case "array":
            case "alias":
            case "interface":
            case "class":
                return true;
            default:
                return false;
        }
    }

    function printDeclarationComments(decl: DeclarationBase) {
        if (decl.comment) {
            start(`// ${decl.comment}`);
            newline();
        }
        if (decl.jsDocComment) {
            start('/**');
            newline();
            for(const line of decl.jsDocComment.split(/\n/g)) {
                start(` * ${line}`);
                newline();
            }
            start(' */');
            newline();
        }
    }

    function printObjectTypeMembers(members: ObjectTypeMember[]) {
        print('{');
        newline();
        indentLevel++;
        for (const member of members) {
            printMember(member);
        }
        indentLevel--;
        tab();
        print('}');

        function printMember(member: ObjectTypeMember) {
            switch (member.kind) {
                case 'method':
                    printDeclarationComments(member);
                    tab();
                    print(quoteIfNeeded(member.name));<commit_msg>add config and an option to not wrap jsDoc comments<commit_after>export interface DeclarationBase {
    jsDocComment?: string;
    comment?: string;
    flags?: DeclarationFlags;
}

export interface EnumMemberDeclaration extends DeclarationBase {
    kind: "enum-value";
    name: string;
}

export interface EnumDeclaration extends DeclarationBase {
    kind: "enum";
    name: string;
    members: EnumMemberDeclaration[];
    constant: boolean;
}

export interface PropertyDeclaration extends DeclarationBase {
    kind: "property";
    name: string;
    type: Type;
}

export interface Parameter {
    kind: "parameter";
    name: string;
    type: Type;
    flags?: ParameterFlags;
}

export interface MethodDeclaration extends DeclarationBase {
    kind: "method";
    name: string;
    parameters: Parameter[];
    returnType: Type;
}

export interface FunctionDeclaration extends DeclarationBase {
    kind: "function";
    name: string;
    parameters: Parameter[];
    returnType: Type;
}

export interface ConstructorDeclaration extends DeclarationBase {
    kind: "constructor";
    parameters: Parameter[];
}

export interface ClassDeclaration extends DeclarationBase {
    kind: "class";
    name: string;
    members: ClassMember[];
    implements: InterfaceDeclaration[];
    baseType?: ObjectTypeReference;
}

export interface InterfaceDeclaration extends DeclarationBase {
    kind: "interface";
    name: string;
    members: ObjectTypeMember[];
    baseTypes?: ObjectTypeReference[];
}

export interface ImportAllDeclaration extends DeclarationBase {
    kind: "importAll";
    name: string;
    from: string;
}

export interface ImportDefaultDeclaration extends DeclarationBase {
    kind: "importDefault";
    name: string;
    from: string;
}

export interface NamespaceDeclaration extends DeclarationBase {
    kind: "namespace";
    name: string;
    members: NamespaceMember[];
}

export interface ConstDeclaration extends DeclarationBase {
    kind: "const";
    name: string;
    type: Type;
}

export interface ExportEqualsDeclaration extends DeclarationBase {
    kind: "export=";
    target: string;
}

export interface ModuleDeclaration extends DeclarationBase {
    kind: "module";
    name: string;
    members: ModuleMember[];
}

export interface ObjectType {
    kind: "object";
    members: ObjectTypeMember[];
}

export interface UnionType {
    kind: "union";
    members: Type[];
}

export interface IntersectionType {
    kind: "intersection";
    members: Type[];
}

export interface FunctionType {
    kind: "function-type";
    parameters: Parameter[];
    returnType: Type;
}

export interface TypeAliasDeclaration extends DeclarationBase {
    kind: "alias";
    name: string;
    type: Type;
}

export interface ArrayTypeReference {
    kind: "array";
    type: Type;
}

export interface NamedTypeReference {
    kind: "name";
    name: string;
}

export interface TypeofReference {
    kind: "typeof";
    type: NamedTypeReference;
}

export type PrimitiveType = "string" | "number" | "boolean" | "any" | "void";

export type TypeReference = TopLevelDeclaration | NamedTypeReference | ArrayTypeReference | PrimitiveType;

export type ObjectTypeReference = ClassDeclaration | InterfaceDeclaration;
export type ObjectTypeMember = PropertyDeclaration | MethodDeclaration;
export type ClassMember = ObjectTypeMember | ConstructorDeclaration;

export type Type = TypeReference | UnionType | IntersectionType | PrimitiveType | ObjectType | TypeofReference | FunctionType;

export type Import = ImportAllDeclaration | ImportDefaultDeclaration;

export type NamespaceMember = InterfaceDeclaration | TypeAliasDeclaration | ClassDeclaration | NamespaceDeclaration | ConstDeclaration | FunctionDeclaration;
export type ModuleMember = InterfaceDeclaration | TypeAliasDeclaration | ClassDeclaration | NamespaceDeclaration | ConstDeclaration | FunctionDeclaration | Import;
export type TopLevelDeclaration =  NamespaceMember | ExportEqualsDeclaration | ModuleDeclaration | EnumDeclaration | Import;

export enum DeclarationFlags {
    None = 0,
    Private = 1 << 0,
    Protected = 1 << 1,
    Static = 1 << 2,
    Optional = 1 << 3,
    Export = 1 << 4,
    Abstract = 1 << 5,
    ExportDefault = 1 << 6,
}

export enum ParameterFlags {
    None = 0,
    Optional = 1 << 0,
    Rest = 1 << 1
}

export const config = {
    wrapJsDocComments: true,
};

export const create = {
    interface(name: string): InterfaceDeclaration {
        return {
            name,
            baseTypes: [],
            kind: "interface",
            members: []
        };
    },

    class(name: string): ClassDeclaration {
        return {
            kind: 'class',
            name,
            members: [],
            implements: []
        };
    },

    enum(name: string, constant: boolean = false): EnumDeclaration {
        return {
            kind: 'enum',
            name, constant,
            members: []
        };
    },

    enumValue(name: string): EnumMemberDeclaration {
        return {
            kind: 'enum-value',
            name
        };
    },

    property(name: string, type: Type, flags = DeclarationFlags.None): PropertyDeclaration {
        return {
            kind: "property",
            name, type, flags
        };
    },

    method(name: string, parameters: Parameter[], returnType: Type, flags = DeclarationFlags.None): MethodDeclaration {
        return {
            kind: "method",
            name, parameters, returnType, flags
        };
    },

    function(name: string, parameters: Parameter[], returnType: Type): FunctionDeclaration {
        return {
            kind: "function",
            name, parameters, returnType
        };
    },

    functionType(parameters: Parameter[], returnType: Type): FunctionType {
        return {
            kind: "function-type",
            parameters, returnType
        };
    },

    parameter(name: string, type: Type, flags = ParameterFlags.None): Parameter {
        return {
            kind: "parameter",
            name, type, flags
        };
    },

    constructor(parameters: Parameter[], flags = DeclarationFlags.None): ConstructorDeclaration {
        return {
            kind: "constructor",
            parameters,
            flags
        };
    },

    const(name: string, type: Type): ConstDeclaration {
        return {
            kind: "const", name, type
        };
    },

    alias(name: string, type: Type): TypeAliasDeclaration {
        return {
            kind: "alias", name, type
        };
    },

    namespace(name: string): NamespaceDeclaration {
        return {
            kind: "namespace", name,
            members: []
        };
    },

    objectType(members: ObjectTypeMember[]): ObjectType {
        return {
            kind: "object",
            members
        };
    },

    array(type: Type): ArrayTypeReference {
        return {
            kind: "array",
            type
        };
    },

    namedTypeReference(name: string): NamedTypeReference {
        return {
            kind: 'name',
            name
        };
    },

    exportEquals(target: string): ExportEqualsDeclaration {
        return {
            kind: 'export=',
            target
        };
    },

    module(name: string): ModuleDeclaration {
        return {
            kind: 'module',
            name,
            members: []
        };
    },

    importAll(name: string, from: string): ImportAllDeclaration {
        return {
            kind: 'importAll',
            name,
            from
        };
    },

    importDefault(name: string, from: string): ImportDefaultDeclaration {
        return {
            kind: 'importDefault',
            name,
            from
        };
    },

    union(members: Type[]): UnionType {
        return {
            kind: 'union',
            members
        };
    },

    typeof(type: NamedTypeReference): TypeofReference {
        return {
            kind: 'typeof',
            type
        };
    }
};

export const type = {
    array(type: Type): ArrayTypeReference {
        return {
            kind: "array",
            type
        }
    },
    string: <PrimitiveType>"string",
    number: <PrimitiveType>"number",
    boolean: <PrimitiveType>"boolean",
    any: <PrimitiveType>"any",
    void: <PrimitiveType>"void"
};

export const reservedWords = ['abstract', 'await', 'boolean', 'break', 'byte', 'case',
	'catch', 'char', 'class', 'const', 'continue', 'debugger', 'default',
	'delete', 'do', 'double', 'else', 'enum', 'export', 'extends', 'false',
	'final', 'finally', 'float', 'for', 'function', 'goto', 'if', 'implements',
	'import', 'in', 'instanceof', 'int', 'interface', 'let', 'long', 'native',
	'new', 'null', 'package', 'private', 'protected', 'public', 'return', 'short',
	'static', 'super', 'switch', 'synchronized', 'this', 'throw', 'throws',
	'transient', 'true', 'try', 'typeof', 'var', 'void', 'volatile', 'while', 'with', 'yield'];

/** IdentifierName can be written as unquoted property names, but may be reserved words. */
export function isIdentifierName(s: string) {
    return /^[$A-Z_][0-9A-Z_$]*$/i.test(s);
}

/** Identifiers are e.g. legal variable names. They may not be reserved words */
export function isIdentifier(s: string) {
    return isIdentifierName(s) && reservedWords.indexOf(s) < 0;
}

function quoteIfNeeded(s: string) {
    if (isIdentifierName(s)) {
        return s;
    } else {
        // JSON.stringify handles escaping quotes for us. Handy!
        return JSON.stringify(s);
    }
}

export const enum ContextFlags {
    None = 0,
    Module = 1 << 0,
    InAmbientNamespace = 1 << 1
}

export function never(x: never, err: string): never {
    throw new Error(err);
}

export function emit(rootDecl: TopLevelDeclaration, rootFlags = ContextFlags.None): string {
    let output = "";
    let indentLevel = 0;
    let contextStack: ContextFlags[] = [rootFlags];

    writeDeclaration(rootDecl);
    return output;

    function getContextFlags() {
        return contextStack.reduce((a, b) => a | b, ContextFlags.None);
    }

    function tab() {
        for (let i = 0; i < indentLevel; i++) {
            output = output + '    ';
        }
    }

    function print(s: string) {
        output = output + s;
    }

    function start(s: string) {
        tab();
        print(s);
    }

    function classFlagsToString(flags: DeclarationFlags | undefined): string {
        let out = '';

        if (flags & DeclarationFlags.Abstract) {
            out += 'abstract ';
        }

        return out;
    }

    function memberFlagsToString(flags: DeclarationFlags | undefined): string {
        let out = '';

        if (flags & DeclarationFlags.Private) {
            out += 'private ';
        }
        else if (flags & DeclarationFlags.Protected) {
            out += 'protected ';
        }

        if (flags & DeclarationFlags.Static) {
            out += 'static ';
        }

        if (flags & DeclarationFlags.Abstract) {
            out += 'abstract ';
        }

        return out;
    }

    function startWithDeclareOrExport(s: string, flags: DeclarationFlags | undefined) {
        if (getContextFlags() & ContextFlags.InAmbientNamespace) {
            // Already in an all-export context
            start(s);
        } else if (flags & DeclarationFlags.Export) {
            start(`export ${s}`);
        } else if (flags & DeclarationFlags.ExportDefault) {
            start(`export default ${s}`);
        } else {
            start(`declare ${s}`);
        }
    }

    function newline() {
        output = output + '\r\n';
    }

    function needsParens(d: Type) {
        if (typeof d === 'string') {
            return false;
        }
        switch (d.kind) {
            case "array":
            case "alias":
            case "interface":
            case "class":
                return true;
            default:
                return false;
        }
    }

    function printDeclarationComments(decl: DeclarationBase) {
        if (decl.comment) {
            start(`// ${decl.comment}`);
            newline();
        }
        if (decl.jsDocComment) {
            if (config.wrapJsDocComments) {
                start('/**');
                newline();
                for(const line of decl.jsDocComment.split(/\n/g)) {
                    start(` * ${line}`);
                    newline();
                }
                start(' */');
            }
            else {
                start(decl.jsDocComment);
            }

            newline();
        }
    }

    function printObjectTypeMembers(members: ObjectTypeMember[]) {
        print('{');
        newline();
        indentLevel++;
        for (const member of members) {
            printMember(member);
        }
        indentLevel--;
        tab();
        print('}');

        function printMember(member: ObjectTypeMember) {
            switch (member.kind) {
                case 'method':
                    printDeclarationComments(member);
                    tab();
                    print(quoteIfNeeded(member.name));
{'fraction_non_alphanumeric': 0.11735931903092862, 'fraction_numerical': 0.002310981011439356, 'mean_word_length': 2.247935951963973, 'pattern_counts': {'":': 8, '<': 61, '<?xml version=': 0, '>': 15, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1816436', 'n_tokens_mistral': 6984, 'n_tokens_neox': 6774, 'n_words': 1869}