<commit_before>module.exports = function(babel) {

  var t = babel.types;

  function isGoogDefineClass(path) {
    try {
      const callee = path.node.declarations[0].init.callee;
      return callee.object.name === 'goog' &&
          callee.property.name === 'defineClass';
    } catch (e) {
      return false;
    }
  }

  function getBody(prop) {
    let body = t.blockStatement([]);
    if (prop.value.body) {
      body = prop.value.body;
    }
    return body;
  }

  function createExpressionStatementForStatics(className, objProp) {
    // Generate ClassName.staticName
    let left = t.MemberExpression(className, objProp.key);
    // Assign the key and value defined in the statics.
    const expressionStatement = t.expressionStatement(
        t.assignmentExpression('=', left, objProp.value));
    // Comments?
    if (objProp.leadingComments) {
      expressionStatement.leadingComments = objProp.leadingComments;
    }
    return expressionStatement;
  }

  /**
   * t.classMethod(kind, key, params, body, computed, static)
   * @param prop
   * @return {*}
   */
  function toClassMethod(prop) {
    const name = prop.key.name;
    const kind = name === 'constructor' ? 'constructor' : 'method';

    const method = t.classMethod(kind, prop.key, prop.value.params, getBody(prop));
    // Copy comments, if any.
    const comments = prop.leadingComments;
    if (comments) {
      method.leadingComments = comments;
    }

    return method
  }

  /**
   * Find the parent class in goog.defineClass(PARENT, {...});
   */
  function findParent(declaration) {
    try {
      const argument = declaration.init.arguments[0];
      return t.isNullLiteral(argument) ? null : argument;
    } catch (e) {
      return null;
    }
  }

  return {
    visitor: {
      VariableDeclaration: function(path) {
        if (path.parentKey !== 'body' || !isGoogDefineClass(path)) {
          return;
        }

        const declaration = path.node.declarations[0];
        const objectExpression = declaration.init.arguments[1];
        const className = t.Identifier(declaration.id.name);

        // Turn all the properties in the goog.defineClass object arg into
        // ClassMethod methods. Filter out statics.
        let statics = null;
        let classMethods = [];
        objectExpression.properties.forEach(prop => {
          if (t.isFunctionExpression(prop.value)) {
            classMethods.push(toClassMethod(prop));
          } else if (prop.key.name === 'statics') {
            statics = prop.value.properties;
          }
        });

        const classBody = t.ClassBody(classMethods);
        const superClass = findParent(declaration);
        const decorators = [];

        // Need to add a super() class in the body.
        if (superClass !== null) {
          // Find the constructor.
          const constructorMethod = classMethods
              .find(method => method.kind === 'constructor');
          if (constructorMethod) {
            // Add the super(<constructor params>) at the beginning of the fn.
            constructorMethod.body.body.unshift(
                t.ExpressionStatement(
                    t.CallExpression(t.super(), constructorMethod.params)));
          }
        }

        const classDeclaration = t.classDeclaration(className,
            superClass,
            classBody,
            decorators<commit_msg>rename to findParentClass<commit_after>module.exports = function(babel) {

  var t = babel.types;

  function isGoogDefineClass(path) {
    try {
      const callee = path.node.declarations[0].init.callee;
      return callee.object.name === 'goog' &&
          callee.property.name === 'defineClass';
    } catch (e) {
      return false;
    }
  }

  function getBody(prop) {
    let body = t.blockStatement([]);
    if (prop.value.body) {
      body = prop.value.body;
    }
    return body;
  }

  function createExpressionStatementForStatics(className, objProp) {
    // Generate ClassName.staticName
    let left = t.MemberExpression(className, objProp.key);
    // Assign the key and value defined in the statics.
    const expressionStatement = t.expressionStatement(
        t.assignmentExpression('=', left, objProp.value));
    // Comments?
    if (objProp.leadingComments) {
      expressionStatement.leadingComments = objProp.leadingComments;
    }
    return expressionStatement;
  }

  /**
   * t.classMethod(kind, key, params, body, computed, static)
   * @param prop
   * @return {*}
   */
  function toClassMethod(prop) {
    const name = prop.key.name;
    const kind = name === 'constructor' ? 'constructor' : 'method';

    const method = t.classMethod(kind, prop.key, prop.value.params, getBody(prop));
    // Copy comments, if any.
    const comments = prop.leadingComments;
    if (comments) {
      method.leadingComments = comments;
    }

    return method
  }

  /**
   * Find the parent class in goog.defineClass(PARENT, {...});
   */
  function findParentClass(declaration) {
    try {
      const argument = declaration.init.arguments[0];
      return t.isNullLiteral(argument) ? null : argument;
    } catch (e) {
      return null;
    }
  }

  return {
    visitor: {
      VariableDeclaration: function(path) {
        if (path.parentKey !== 'body' || !isGoogDefineClass(path)) {
          return;
        }

        const declaration = path.node.declarations[0];
        const objectExpression = declaration.init.arguments[1];
        const className = t.Identifier(declaration.id.name);

        // Turn all the properties in the goog.defineClass object arg into
        // ClassMethod methods. Filter out statics.
        let statics = null;
        let classMethods = [];
        objectExpression.properties.forEach(prop => {
          if (t.isFunctionExpression(prop.value)) {
            classMethods.push(toClassMethod(prop));
          } else if (prop.key.name === 'statics') {
            statics = prop.value.properties;
          }
        });

        const classBody = t.ClassBody(classMethods);
        const superClass = findParentClass(declaration);
        const decorators = [];

        // Need to add a super() class in the body.
        if (superClass !== null) {
          // Find the constructor.
          const constructorMethod = classMethods
              .find(method => method.kind === 'constructor');
          if (constructorMethod) {
            // Add the super(<constructor params>) at the beginning of the fn.
            constructorMethod.body.body.unshift(
                t.ExpressionStatement(
                    t.CallExpression(t.super(), constructorMethod.params)));
          }
        }

        const classDeclaration = t.classDeclaration(className,
            superClass,
            classBody,
            decorators
{'fraction_non_alphanumeric': 0.1150781941575686, 'fraction_numerical': 0.0011802891708468574, 'mean_word_length': 2.311675622862726, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 9, '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': '7453012', 'n_tokens_mistral': 1895, 'n_tokens_neox': 1841, 'n_words': 441}