ronantakizawa/codereview-bench huggingface dataset:
Repository: babel/babel
File: packages/babel-generator/src/generators/flow.ts (TypeScript)

Code before:
  this.word("type");
  this.space();
  this.print(node.id, node);
  this.print(node.typeParameters, node);
  this.space();
  this.token("=");
  this.space();
  this.print(node.right, node);
  this.semicolon();
}

export function TypeAnnotation(this: Printer, node: t.TypeAnnotation) {
  this.token(":");
  this.space();
  // @ts-expect-error todo(flow->ts) can this be removed? `.optional` looks to be not existing property
  if (node.optional) this.token("?");
  this.print(node.typeAnnotation, node);
}

export function TypeParameterInstantiation(
  this: Printer,
  node: t.TypeParameterInstantiation,
): void {
  this.token("<");
  this.printList(node.params, node, {});
  this.token(">");
}

export { TypeParameterInstantiation as TypeParameterDeclaration };

export function TypeParameter(this: Printer, node: t.TypeParameter) {
  this._variance(node);

  this.word(node.name);

  if (node.bound) {
    this.print(node.bound, node);
  }

  if (node.default) {
    this.space();
    this.token("=");
    this.space();
    this.print(node.default, node);
  }
}

export function OpaqueType(
  this: Printer,
  node: t.OpaqueType | t.DeclareOpaqueType,
) {

Review comment (bug):
This looks like the case for:

```js

const ast = Babel.packages.parser.parse("type x = ?    number; /**/", {plugins: ['flow']});
Babel.packages.generator.default(ast);
// Outputs: {code: 'type x = ?number; /**/', decodedMap: undefined}
```

(but I can't test it easily through debugging or stepping into the code, since the repl build is helplessly minified - would be nice if a PR preview was readable/debuggable)

Code after:
) {
  this.word("type");
  this.space();
  this.print(node.id, node);
  this.print(node.typeParameters, node);
  this.space();
  this.token("=");
  this.space();
  this.print(node.right, node);
  this.semicolon();
}

export function TypeAnnotation(
  this: Printer,
  node: t.TypeAnnotation,
  parent: t.Node,
) {
  this.token(":");
  this.space();
  if (parent.type === "ArrowFunctionExpression") {
    this.tokenContext |= TokenContext.arrowFlowReturnType;
  } else if (
    // @ts-expect-error todo(flow->ts) can this be removed? `.optional` looks to be not existing property
    node.optional
  ) {
    this.token("?");
  }
  this.print(node.typeAnnotation, node);
}

export function TypeParameterInstantiation(
  this: Printer,
  node: t.TypeParameterInstantiation,
): void {
  this.token("<");
  this.printList(node.params, node, {});
  this.token(">");
}

export { TypeParameterInstantiation as TypeParameterDeclaration };

export function TypeParameter(this: Printer, node: t.TypeParameter) {
  this._variance(node);

  this.word(node.name);

  if (node.bound) {
    this.print(node.bound, node);
  }

  if (node.default) {
Repository: babel/babel
File: packages/babel-preset-env/src/index.ts (TypeScript)

Code before:
    if (bugfixes) return pluginLists.withProposals.withBugfixes;
    else return pluginLists.withProposals.withoutBugfixes;
  } else {
    if (bugfixes) return pluginLists.withoutProposals.withBugfixes;
    else return pluginLists.withoutProposals.withoutBugfixes;
  }
}

const getPlugin = (pluginName: string) => {
  const plugin =
    // @ts-expect-error plugin name is constructed from available plugin list
    availablePlugins[pluginName]();

  if (!plugin) {
    throw new Error(
      `Could not find plugin "${pluginName}". Ensure there is an entry in ./available-plugins.js for it.`,
    );
  }

  return plugin;
};

export const transformIncludesAndExcludes = (opts: Array<string>): any => {
  return opts.reduce(
    (result, opt) => {
      const target = /^(?:es|es6|es7|esnext|web)\./.exec(opt)
        ? "builtIns"
        : "plugins";
      result[target].add(opt);
      return result;
    },
    {
      all: opts,
      plugins: new Set(),
      builtIns: new Set(),
    },
  );
};

function getSpecialModulesPluginNames(
  modules: Exclude<ModuleOption, "auto">,
  shouldTransformDynamicImport: boolean,
  babelVersion: string,
) {
  const modulesPluginNames = [];
  if (modules) {
    modulesPluginNames.push(moduleTransformations[modules]);
  }

  if (shouldTransformDynamicImport) {
    if (modules && modules !== "umd") {

Review comment (suggestion):
[`unicorn/prefer-regexp-test`](https://github.com/sindresorhus/eslint-plugin-unicorn/blob/main/docs/rules/prefer-regexp-test.md)

Code after:
    if (bugfixes) return pluginLists.withProposals.withBugfixes;
    else return pluginLists.withProposals.withoutBugfixes;
  } else {
    if (bugfixes) return pluginLists.withoutProposals.withBugfixes;
    else return pluginLists.withoutProposals.withoutBugfixes;
  }
}

const getPlugin = (pluginName: string) => {
  const plugin =
    // @ts-expect-error plugin name is constructed from available plugin list
    availablePlugins[pluginName]();

  if (!plugin) {
    throw new Error(
      `Could not find plugin "${pluginName}". Ensure there is an entry in ./available-plugins.js for it.`,
    );
  }

  return plugin;
};

export const transformIncludesAndExcludes = (opts: Array<string>): any => {
  return opts.reduce(
    (result, opt) => {
      const target = /^(?:es|es6|es7|esnext|web)\./.test(opt)
        ? "builtIns"
        : "plugins";
      result[target].add(opt);
      return result;
    },
    {
      all: opts,
      plugins: new Set(),
      builtIns: new Set(),
    },
  );
};

function getSpecialModulesPluginNames(
  modules: Exclude<ModuleOption, "auto">,
  shouldTransformDynamicImport: boolean,
  babelVersion: string,
) {
  const modulesPluginNames = [];
  if (modules) {
    modulesPluginNames.push(moduleTransformations[modules]);
  }

  if (shouldTransformDynamicImport) {
    if (modules && modules !== "umd") {
Repository: babel/babel
File: packages/babel-types/src/converters/valueToNode.ts (TypeScript)

Code before:
    if (Number.isFinite(value)) {
      result = numericLiteral(Math.abs(value));
    } else {
      let numerator;
      if (Number.isNaN(value)) {
        // NaN
        numerator = numericLiteral(0);
      } else {
        // Infinity / -Infinity
        numerator = numericLiteral(1);
      }

      result = binaryExpression("/", numerator, numericLiteral(0));
    }

    if (value < 0 || Object.is(value, -0)) {
      result = unaryExpression("-", result);
    }

    return result;
  }

  // regexes
  if (isRegExp(value)) {
    const pattern = value.source;
    const flags = /\/([a-z]+|)$/.exec(value.toString())[1];
    return regExpLiteral(pattern, flags);
  }

  // array
  if (Array.isArray(value)) {
    return arrayExpression(value.map(valueToNode));
  }

  // object
  if (isPlainObject(value)) {
    const props = [];
    for (const key of Object.keys(value)) {
      let nodeKey;
      if (isValidIdentifier(key)) {
        nodeKey = identifier(key);
      } else {
        nodeKey = stringLiteral(key);
      }
      props.push(
        objectProperty(
          nodeKey,
          valueToNode(
            // @ts-expect-error key must present in value
            value[key],
          ),

Review comment (suggestion):
Aside for future PR: regexp.prototype.flags has been supported since node.js 6. We can use `value.flags` here and manually polyfill it with the regex here when compiling for babel-standalone.

Code after:
    if (Number.isFinite(value)) {
      result = numericLiteral(Math.abs(value));
    } else {
      let numerator;
      if (Number.isNaN(value)) {
        // NaN
        numerator = numericLiteral(0);
      } else {
        // Infinity / -Infinity
        numerator = numericLiteral(1);
      }

      result = binaryExpression("/", numerator, numericLiteral(0));
    }

    if (value < 0 || Object.is(value, -0)) {
      result = unaryExpression("-", result);
    }

    return result;
  }

  // regexes
  if (isRegExp(value)) {
    const pattern = value.source;
    const flags = /\/([a-z]*)$/.exec(value.toString())[1];
    return regExpLiteral(pattern, flags);
  }

  // array
  if (Array.isArray(value)) {
    return arrayExpression(value.map(valueToNode));
  }

  // object
  if (isPlainObject(value)) {
    const props = [];
    for (const key of Object.keys(value)) {
      let nodeKey;
      if (isValidIdentifier(key)) {
        nodeKey = identifier(key);
      } else {
        nodeKey = stringLiteral(key);
      }
      props.push(
        objectProperty(
          nodeKey,
          valueToNode(
            // @ts-expect-error key must present in value
            value[key],
          ),
Repository: babel/babel
File: packages/babel-traverse/src/scope/index.ts (TypeScript)

Code before:
  uids: { [name: string]: boolean };
  data: { [key: string | symbol]: unknown };
  crawling: boolean;

  /**
   * This searches the current "scope" and collects all references/bindings
   * within.
   */
  constructor(path: NodePath<t.Pattern | t.Scopable>) {
    const { node } = path;
    const cached = scopeCache.get(node);
    // Sometimes, a scopable path is placed higher in the AST tree.
    // In these cases, have to create a new Scope.
    if (cached?.path === path) {
      return cached;
    }
    scopeCache.set(node, this);

    this.uid = uid++;

    this.block = node;
    this.path = path;

    if (!process.env.BABEL_8_BREAKING) {
      this.labels = new Map();
    }
    this.inited = false;
  }

  /**
   * Globals.
   */

  static globals = Object.keys(globals.builtin);

  /**
   * Variables available in current context.
   */

  static contextVariables = ["arguments", "undefined", "Infinity", "NaN"];

  get parent() {
    let parent,
      path = this.path;
    do {
      // Skip method scope if coming from inside computed key or decorator expression
      const shouldSkip = path.key === "key" || path.listKey === "decorators";
      path = path.parentPath;
      if (shouldSkip && path.isMethod()) path = path.parentPath;
      if (path?.isScope()) parent = path;
    } while (path && !parent);

Review comment (suggestion):
Initialize it lazily, this should be a bit faster. :)

Update: Undo this change and move it to another PR.

Code after:
  uids: { [name: string]: boolean };
  data: { [key: string | symbol]: unknown };
  crawling: boolean;

  /**
   * This searches the current "scope" and collects all references/bindings
   * within.
   */
  constructor(path: NodePath<t.Pattern | t.Scopable>) {
    const { node } = path;
    const cached = scopeCache.get(node);
    // Sometimes, a scopable path is placed higher in the AST tree.
    // In these cases, have to create a new Scope.
    if (cached?.path === path) {
      return cached;
    }
    scopeCache.set(node, this);

    this.uid = uid++;

    this.block = node;
    this.path = path;

    this.labels = new Map();
    this.inited = false;
  }

  /**
   * Globals.
   */

  static globals = Object.keys(globals.builtin);

  /**
   * Variables available in current context.
   */

  static contextVariables = ["arguments", "undefined", "Infinity", "NaN"];

  get parent() {
    let parent,
      path = this.path;
    do {
      // Skip method scope if coming from inside computed key or decorator expression
      const shouldSkip = path.key === "key" || path.listKey === "decorators";
      path = path.parentPath;
      if (shouldSkip && path.isMethod()) path = path.parentPath;
      if (path?.isScope()) parent = path;
    } while (path && !parent);

    return parent?.scope;
Repository: babel/babel
File: packages/babel-plugin-transform-destructuring/src/util.ts (TypeScript)

Code before:

      if (t.isIdentifier(node)) {
        const binding = scope.getBinding(node.name);
        if (binding?.constant && binding.path.isGenericType("Array")) {
          return node;
        }
      }

      if (t.isArrayExpression(node)) {
        return node;
      }

      if (t.isIdentifier(node, { name: "arguments" })) {
        return t.callExpression(
          t.memberExpression(
            t.memberExpression(
              t.memberExpression(
                t.identifier("Array"),
                t.identifier("prototype"),
              ),
              t.identifier("slice"),
            ),
            t.identifier("call"),
          ),
          [node],
        );
      }

      let helperName;
      const args = [node];
      if (typeof count === "number") {
        args.push(t.numericLiteral(count));

        // Used in array-rest to create an array from a subset of an iterable.
        helperName = "slicedToArray";
        // TODO if (this.hub.isLoose("es6.forOf")) helperName += "-loose";
      } else {
        // Used in array-rest to create an array
        helperName = "toArray";
      }

      if (arrayLikeIsIterable) {
        args.unshift(scope.path.hub.addHelper(helperName));
        helperName = "maybeArrayLike";
      }

      return t.callExpression(scope.path.hub.addHelper(helperName), args);
    }
  }

  pushAssignmentPattern(

Review comment (suggestion):
(feel free to ignore)

This would be easier to read:
```suggestion
        return template.expression.ast`
          Array.prototype.slice.call(${node})
        `;
```

Code after:

      if (t.isIdentifier(node)) {
        const binding = scope.getBinding(node.name);
        if (binding?.constant && binding.path.isGenericType("Array")) {
          return node;
        }
      }

      if (t.isArrayExpression(node)) {
        return node;
      }

      if (t.isIdentifier(node, { name: "arguments" })) {
        return template.expression.ast`
          Array.prototype.slice.call(${node})
        `;
      }

      let helperName;
      const args = [node];
      if (typeof count === "number") {
        args.push(t.numericLiteral(count));

        // Used in array-rest to create an array from a subset of an iterable.
        helperName = "slicedToArray";
        // TODO if (this.hub.isLoose("es6.forOf")) helperName += "-loose";
      } else {
        // Used in array-rest to create an array
        helperName = "toArray";
      }

      if (arrayLikeIsIterable) {
        args.unshift(scope.path.hub.addHelper(helperName));
        helperName = "maybeArrayLike";
      }

      return t.callExpression(scope.path.hub.addHelper(helperName), args);
    }
  }

  pushAssignmentPattern(
    { left, right }: t.AssignmentPattern,
    valueRef: t.Expression | null,
  ) {
    // handle array init with void 0. This also happens when
    // the value was originally a hole.
    // const [x = 42] = [void 0,];
    // -> const x = 42;
    if (isPureVoid(valueRef)) {
      this.push(left, right);
      return;
Repository: babel/babel
File: packages/babel-plugin-transform-spread/src/index.ts (TypeScript)

Code before:

      if (t.isIdentifier(node)) {
        const binding = scope.getBinding(node.name);
        if (binding?.constant && binding.path.isGenericType("Array")) {
          return node;
        }
      }

      if (t.isArrayExpression(node)) {
        return node;
      }

      if (t.isIdentifier(node, { name: "arguments" })) {
        return t.callExpression(
          t.memberExpression(
            t.memberExpression(
              t.memberExpression(
                t.identifier("Array"),
                t.identifier("prototype"),
              ),
              t.identifier("slice"),
            ),
            t.identifier("call"),
          ),
          [node],
        );
      }

      const args = [node];
      let helperName = "toConsumableArray";

      if (arrayLikeIsIterable) {
        args.unshift(scope.path.hub.addHelper(helperName));
        helperName = "maybeArrayLike";
      }

      return t.callExpression(scope.path.hub.addHelper(helperName), args);
    }
  }

  function hasHole(spread: t.ArrayExpression): boolean {
    return spread.elements.some(el => el === null);
  }

  function hasSpread(nodes: Array<t.Node>): boolean {
    for (let i = 0; i < nodes.length; i++) {
      if (t.isSpreadElement(nodes[i])) {
        return true;
      }
    }
    return false;

Review comment (suggestion):
And here
```suggestion
        return template.expression.ast`
          Array.prototype.slice.call(${node})
        `;
```

Code after:

      if (t.isIdentifier(node)) {
        const binding = scope.getBinding(node.name);
        if (binding?.constant && binding.path.isGenericType("Array")) {
          return node;
        }
      }

      if (t.isArrayExpression(node)) {
        return node;
      }

      if (t.isIdentifier(node, { name: "arguments" })) {
        return template.expression.ast`
          Array.prototype.slice.call(${node})
        `;
      }

      const args = [node];
      let helperName = "toConsumableArray";

      if (arrayLikeIsIterable) {
        args.unshift(scope.path.hub.addHelper(helperName));
        helperName = "maybeArrayLike";
      }

      return t.callExpression(scope.path.hub.addHelper(helperName), args);
    }
  }

  function hasHole(spread: t.ArrayExpression): boolean {
    return spread.elements.some(el => el === null);
  }

  function hasSpread(nodes: Array<t.Node>): boolean {
    for (let i = 0; i < nodes.length; i++) {
      if (t.isSpreadElement(nodes[i])) {
        return true;
      }
    }
    return false;
  }

  function push(_props: Array<ListElement>, nodes: Array<t.Expression>) {
    if (!_props.length) return _props;
    nodes.push(t.arrayExpression(_props));
    return [];
  }

  function build(
    props: Array<ListElement>,
Repository: babel/babel
File: packages/babel-generator/src/generators/typescript.ts (TypeScript)

Code before:
export function TSImportType(this: Printer, node: t.TSImportType) {
  const { argument, qualifier, typeParameters } = node;
  this.word("import");
  this.token("(");
  this.print(argument, node);
  this.token(")");
  if (qualifier) {
    this.token(".");
    this.print(qualifier, node);
  }
  if (typeParameters) {
    this.print(typeParameters, node);
  }
}

export function TSImportEqualsDeclaration(
  this: Printer,
  node: t.TSImportEqualsDeclaration,
) {
  const { isExport, id, moduleReference } = node;
  if (isExport) {
    this.word("export");
    this.space();
  }
  this.word("import");
  this.space();
  this.print(id, node);
  this.space();
  this.token("=");
  this.space();
  this.print(moduleReference, node);
  this.semicolon();
}

export function TSExternalModuleReference(
  this: Printer,
  node: t.TSExternalModuleReference,
) {
  this.token("require(");
  this.print(node.expression, node);
  this.token(")");
}

export function TSNonNullExpression(
  this: Printer,
  node: t.TSNonNullExpression,
) {
  this.print(node.expression, node);
  this.token("!");
}


Review comment (suggestion):
Even if we add the kind to the AST I would prefer to not do this change, since we currently always emit "good" code and there is no need to emit `module` (similarly to how we, for example, always emit semicolons even if they are absent in the input code).

Code after:
}

export function TSEnumMember(this: Printer, node: t.TSEnumMember) {
  const { id, initializer } = node;
  this.print(id);
  if (initializer) {
    this.space();
    this.token("=");
    this.space();
    this.print(initializer);
  }
}

export function TSModuleDeclaration(
  this: Printer,
  node: t.TSModuleDeclaration,
) {
  const { declare, id, kind } = node;

  if (declare) {
    this.word("declare");
    this.space();
  }

  if (!node.global) {
    this.word(kind ?? (id.type === "Identifier" ? "namespace" : "module"));
    this.space();
  }
  this.print(id);

  if (!node.body) {
    this.semicolon();
    return;
  }

  let body = node.body;
  while (body.type === "TSModuleDeclaration") {
    this.token(".");
    this.print(body.id);
    body = body.body;
  }

  this.space();
  this.print(body);
}

export function TSModuleBlock(this: Printer, node: t.TSModuleBlock) {
  printBraced(this, node, () =>
    this.printSequence(node.body, { indent: true }),
  );
}
Repository: babel/babel
File: packages/babel-standalone/test/preset-stage-1.test.js (JavaScript)

Code before:
import { createRequire } from "module";
import { itBabel7 } from "$repo-utils";
const require = createRequire(import.meta.url);

describe("stage-1 preset", () => {
  let Babel;
  beforeAll(() => {
    Babel = require("../babel.js");
  });

  itBabel7("should parser decimal literal", () => {
    const output = Babel.transform("0.3m", {
      presets: [["stage-1", { decoratorsLegacy: true }]],
    }).code;
    expect(output).toBe("0.3m;");
  });

  it("should support hack pipeline", () => {
    const output = Babel.transform("x |> %", {
      presets: [
        [
          "stage-1",
          {
            pipelineProposal: "hack",
            decoratorsLegacy: true,
          },
        ],
      ],
    }).code;
    expect(output).toMatchInlineSnapshot(`"x;"`);
  });

  itBabel7("should support hack pipeline with `#` topic token", () => {
    const output = Babel.transform("x |> #", {
      presets: [
        [

Review comment (suggestion):
```suggestion
  itBabel7("should parse decimal literal", () => {
```

Code after:
import { createRequire } from "module";
import { itBabel7 } from "$repo-utils";
const require = createRequire(import.meta.url);

describe("stage-1 preset", () => {
  let Babel;
  beforeAll(() => {
    Babel = require("../babel.js");
  });

  itBabel7("should parse decimal literal", () => {
    const output = Babel.transform("0.3m", {
      presets: [["stage-1", { decoratorsLegacy: true }]],
    }).code;
    expect(output).toBe("0.3m;");
  });

  it("should support hack pipeline", () => {
    const output = Babel.transform("x |> %", {
      presets: [
        [
          "stage-1",
          {
            pipelineProposal: "hack",
            decoratorsLegacy: true,
          },
        ],
      ],
    }).code;
    expect(output).toMatchInlineSnapshot(`"x;"`);
  });

  itBabel7("should support hack pipeline with `#` topic token", () => {
    const output = Babel.transform("x |> #", {
      presets: [
        [
Repository: babel/babel
File: packages/babel-preset-typescript/src/plugin-rewrite-ts-imports.ts (TypeScript)

Code before:
    }
  }

  return {
    name: "preset-typescript/plugin-rewrite-ts-imports",
    visitor: {
      "ImportDeclaration|ExportAllDeclaration|ExportNamedDeclaration"({
        node,
      }: NodePath<
        t.ImportDeclaration | t.ExportAllDeclaration | t.ExportNamedDeclaration
      >) {
        const { source } = node;
        const kind = t.isImportDeclaration(node)
          ? node.importKind
          : node.exportKind;
        if (kind === "value" && source) {
          maybeReplace(source);
        }
      },
      CallExpression(path) {
        if (t.isImport(path.node.callee)) {
          maybeReplace(path.node.arguments[0]);
        }
      },
      ImportExpression(path) {
        maybeReplace(path.node.source);
      },
    },
  };
});


Review comment (refactor):
I saw that the TS team was also considering using a runtime helper to replace the extension in cases where the specifier is not statically analyzable. We should consider doing something like that.

Code after:
        source.value = source.value
          .replace(/(\.[mc]?)ts$/, "$1js")
          .replace(/\.tsx$/, ".js");
      }
      return;
    }

    path.replaceWith(
      template.expression
        .ast`(${source} + "").replace(/([\\/].*\.[mc]?)tsx?$/, "$1js")`,
    );
  }

  return {
    name: "preset-typescript/plugin-rewrite-ts-imports",
    visitor: {
      "ImportDeclaration|ExportAllDeclaration|ExportNamedDeclaration"(
        path: NodePath<
          | t.ImportDeclaration
          | t.ExportAllDeclaration
          | t.ExportNamedDeclaration
        >,
      ) {
        const node = path.node;
        const kind = t.isImportDeclaration(node)
          ? node.importKind
          : node.exportKind;
        if (kind === "value") {
          maybeReplace(node.source, path.get("source"));
        }
      },
      CallExpression(path) {
        if (t.isImport(path.node.callee)) {
          maybeReplace(path.node.arguments[0], path.get("arguments.0"));
        }
      },
      ImportExpression(path) {
        maybeReplace(path.node.source, path.get("source"));
      },
    },
  };
});