<commit_before>var assert = require("assert"),
    Syntax = require("./syntax"),
    printComment = require("./comments").print,
    linesModule = require("./lines"),
    fromString = linesModule.fromString,
    concat = linesModule.concat,
    normalizeOptions = require("./options").normalize,
    Parser = require("./parser").Parser;

function Printer(parser, options) {
    assert.ok(this instanceof Printer);
    assert.ok(parser instanceof Parser);

    options = normalizeOptions(options);

    function printWithComments(node) {
        if (!node)
            return fromString("");

        var without = print(node),
            orig = node.original;

        if (orig && orig.comments) {
            var printed = orig.comments.map(printComment);
            if (without)
                printed.push(without);
            return fromString("\n").join(printed);
        }

        return without;
    }

    function print(node, includeComments) {
        if (!node)
            return fromString("");

        if (includeComments)
            return printWithComments(node);

        var reprinter = parser.getReprinter(node);
        if (reprinter)
            return reprinter(print);

        return genericPrint(node, options, printWithComments);
    }

    function printGenerically(node) {
        return genericPrint(node, options, printGenerically);
    }

    this.print = print;
    this.printGenerically = printGenerically;
}

exports.Printer = Printer;

var types = require("./types").namedTypes;

function genericPrint(n, options, print) {
    if (!n)
        return fromString("");

    if (typeof n === "string")
        return fromString(n, options.tabWidth);

    types.Node.assert(n);

    switch (n.type) {
    case Syntax.File:
        n = n.program;
        types.Program.assert(n);

        // intentionally fall through...

    case Syntax.Program:
        return maybeAddSemicolon(
            fromString("\n\n").join(n.body.map(print)));

    case Syntax.EmptyStatement:
        return fromString("");

    case Syntax.ExpressionStatement:
        return print(n.expression);

    case Syntax.BinaryExpression:
    case Syntax.LogicalExpression:
    case Syntax.AssignmentExpression:
        return fromString(" ").join([
            print(n.left),
            print(n.operator),
            print(n.right)
        ]);

    case Syntax.MemberExpression:
        var parts = [print(n.object)];

        if (n.computed)
            parts.push("[", print(n.property), "]");
        else
            parts.push(".", print(n.property));

        return concat(parts);

    case Syntax.Identifier:
        return fromString(n.name, options.tabWidth);

    case Syntax.FunctionDeclaration:
    case Syntax.FunctionExpression:
        var parts = ["function"];

        if (n.id)
            parts.push(" ", print(n.id));

        parts.push(
            "(",
            fromString(", ").join(n.params.map(print)),
            ") ",
            print(n.body));

        return concat(parts);

    case Syntax.ArrowFunctionExpression:
        var parts = [];

        if (n.params.length === 1) {
            parts.push(print(n.params[0]));
        } else {
            parts.push(
                "(",
                fromString(", ").join(n.params.map(print)),
                ")"
            );
        }

        parts.push(" => ", print(n.body));

        return concat(parts);

    case Syntax.BlockStatement:
        var naked = printNakedBlockStatement(n, print);
        if (naked.isEmpty())<commit_msg>Implement a printer for ModuleDeclaration.<commit_after>var assert = require("assert"),
    Syntax = require("./syntax"),
    printComment = require("./comments").print,
    linesModule = require("./lines"),
    fromString = linesModule.fromString,
    concat = linesModule.concat,
    normalizeOptions = require("./options").normalize,
    Parser = require("./parser").Parser;

function Printer(parser, options) {
    assert.ok(this instanceof Printer);
    assert.ok(parser instanceof Parser);

    options = normalizeOptions(options);

    function printWithComments(node) {
        if (!node)
            return fromString("");

        var without = print(node),
            orig = node.original;

        if (orig && orig.comments) {
            var printed = orig.comments.map(printComment);
            if (without)
                printed.push(without);
            return fromString("\n").join(printed);
        }

        return without;
    }

    function print(node, includeComments) {
        if (!node)
            return fromString("");

        if (includeComments)
            return printWithComments(node);

        var reprinter = parser.getReprinter(node);
        if (reprinter)
            return reprinter(print);

        return genericPrint(node, options, printWithComments);
    }

    function printGenerically(node) {
        return genericPrint(node, options, printGenerically);
    }

    this.print = print;
    this.printGenerically = printGenerically;
}

exports.Printer = Printer;

var types = require("./types").namedTypes;

function genericPrint(n, options, print) {
    if (!n)
        return fromString("");

    if (typeof n === "string")
        return fromString(n, options.tabWidth);

    types.Node.assert(n);

    switch (n.type) {
    case Syntax.File:
        n = n.program;
        types.Program.assert(n);

        // intentionally fall through...

    case Syntax.Program:
        return maybeAddSemicolon(
            fromString("\n\n").join(n.body.map(print)));

    case Syntax.EmptyStatement:
        return fromString("");

    case Syntax.ExpressionStatement:
        return print(n.expression);

    case Syntax.BinaryExpression:
    case Syntax.LogicalExpression:
    case Syntax.AssignmentExpression:
        return fromString(" ").join([
            print(n.left),
            print(n.operator),
            print(n.right)
        ]);

    case Syntax.MemberExpression:
        var parts = [print(n.object)];

        if (n.computed)
            parts.push("[", print(n.property), "]");
        else
            parts.push(".", print(n.property));

        return concat(parts);

    case Syntax.Identifier:
        return fromString(n.name, options.tabWidth);

    case Syntax.FunctionDeclaration:
    case Syntax.FunctionExpression:
        var parts = ["function"];

        if (n.id)
            parts.push(" ", print(n.id));

        parts.push(
            "(",
            fromString(", ").join(n.params.map(print)),
            ") ",
            print(n.body));

        return concat(parts);

    case Syntax.ArrowFunctionExpression:
        var parts = [];

        if (n.params.length === 1) {
            parts.push(print(n.params[0]));
        } else {
            parts.push(
                "(",
                fromString(", ").join(n.params.map(print)),
                ")"
            );
        }

        parts.push(" => ", print(n.body));

        return concat(parts);

    case Syntax.ModuleDeclaration:
        var parts = ["module", print(n.id)];

        if (n.from) {
            assert.ok(!n.body);
            parts.push("=", print(n.from));
        } else {
            parts.push(print(n.body));
        }

        return fromString(" ").join(parts);

    case Syntax.BlockStatement:
        var naked = printNakedBlockStatement(n, print);
        if (naked.isEmpty())
{'fraction_non_alphanumeric': 0.13401783301810322, 'fraction_numerical': 0.0005403944879762226, 'mean_word_length': 2.0465020576131687, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 5, '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': '3460687', 'n_tokens_mistral': 2110, 'n_tokens_neox': 2022, 'n_words': 419}