@babel/types#isIdentifier TypeScript Examples

The following examples show how to use @babel/types#isIdentifier. You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: webpackParser.ts    From react-native-decompiler with GNU Affero General Public License v3.0 6 votes vote down vote up
private parseObject(file: File, ast: NodePath<ObjectExpression>, modules: Module[]): void {
    ast.get('properties').forEach((property) => {
      if (!property.isObjectProperty() || !isNumericLiteral(property.node.key)) return;

      const element = property.get('value');
      const i = property.node.key.value;
      if (!element.isFunctionExpression()) return;
      if (element.node.body.body.length === 0) return;

      const dependencyValues: number[] = [];
      const requireIdentifer = element.node.params[2];
      if (isIdentifier(requireIdentifer)) {
        element.traverse({
          CallExpression: (dependencyPath) => {
            if (!isIdentifier(dependencyPath.node.callee) || !isNumericLiteral(dependencyPath.node.arguments[0])) return;
            if (dependencyPath.scope.bindingIdentifierEquals(dependencyPath.node.callee.name, requireIdentifer)) {
              dependencyValues[dependencyPath.node.arguments[0].value] = dependencyPath.node.arguments[0].value;
            }
          },
        });
      }

      const newModule = new Module(file, element, i, dependencyValues, this.PARAM_MAPPING);
      newModule.calculateFields();
      modules[i] = newModule;
    });
  }
Example #2
Source File: passthroughModuleRemapper.ts    From react-native-decompiler with GNU Affero General Public License v3.0 6 votes vote down vote up
getVisitor(): Visitor {
    if (this.module.moduleCode.body.length !== 1) return {};

    return {
      AssignmentExpression: (path) => {
        if (!isMemberExpression(path.node.left) || !isIdentifier(path.node.left?.object) || !isIdentifier(path.node.left?.property)) return;
        if (path.scope.getBindingIdentifier(path.node.left.object.name)?.start !== this.module.moduleParam?.start) return;
        if (path.node.left.property.name !== 'exports') return;

        const right = path.get('right');
        if (!right.isCallExpression()) return;
        const rightCallee = right.get('callee');
        if (!rightCallee.isIdentifier() && !rightCallee.isCallExpression()) return;

        const dependency = this.getModuleDependency(rightCallee.isCallExpression() ? rightCallee : right);
        if (!dependency) return;
        if (rightCallee.isCallExpression() && !dependency.moduleStrings.find((str) => str.includes('Calling PropTypes validators directly is not supported'))) return;
        if (!this.moduleList.some((m) => m.dependencies.includes(this.module.moduleId))) return;

        this.debugLog(`bypassing ${this.module.moduleId} for ${dependency.moduleId} ${dependency.moduleName}`);

        const passthroughDependency = this.moduleList[dependency.moduleId];
        this.module.ignored = true;
        this.module.isNpmModule = true; // flag as NPM module in case this module pass through NPM module
        this.module.moduleName = `${this.module.moduleId} PASSTHROUGH TO ${passthroughDependency.moduleName}`;
        this.moduleList.forEach((module) => {
          module.dependencies = module.dependencies.map((dep) => (dep === this.module.moduleId ? passthroughDependency.moduleId : dep));
        });
      },
    };
  }
Example #3
Source File: webpackParser.ts    From react-native-decompiler with GNU Affero General Public License v3.0 6 votes vote down vote up
private parseObject(file: File, ast: NodePath<ObjectExpression>, modules: Module[]): void {
    ast.get('properties').forEach((property) => {
      if (!property.isObjectProperty() || !isNumericLiteral(property.node.key)) return;

      const element = property.get('value');
      const i = property.node.key.value;
      if (!element.isFunctionExpression()) return;
      if (element.node.body.body.length === 0) return;

      const dependencyValues: number[] = [];
      const requireIdentifer = element.node.params[2];
      if (isIdentifier(requireIdentifer)) {
        element.traverse({
          CallExpression: (dependencyPath) => {
            if (!isIdentifier(dependencyPath.node.callee) || !isNumericLiteral(dependencyPath.node.arguments[0])) return;
            if (dependencyPath.scope.bindingIdentifierEquals(dependencyPath.node.callee.name, requireIdentifer)) {
              dependencyValues[dependencyPath.node.arguments[0].value] = dependencyPath.node.arguments[0].value;
            }
          },
        });
      }

      const newModule = new Module(file, element, i, dependencyValues, this.PARAM_MAPPING);
      newModule.calculateFields();
      modules[i] = newModule;
    });
  }
Example #4
Source File: webpackParser.ts    From react-native-decompiler with GNU Affero General Public License v3.0 6 votes vote down vote up
private parseArray(file: File, ast: NodePath<ArrayExpression>, modules: Module[]): void {
    ast.get('elements').forEach((element, i) => {
      if (!element.isFunctionExpression()) return;
      if (element.node.body.body.length === 0) return;

      const dependencyValues: number[] = [];
      const requireIdentifer = element.node.params[2];
      if (isIdentifier(requireIdentifer)) {
        element.traverse({
          CallExpression: (dependencyPath) => {
            if (!isIdentifier(dependencyPath.node.callee) || !isNumericLiteral(dependencyPath.node.arguments[0])) return;
            if (dependencyPath.scope.bindingIdentifierEquals(dependencyPath.node.callee.name, requireIdentifer)) {
              dependencyValues[dependencyPath.node.arguments[0].value] = dependencyPath.node.arguments[0].value;
            }
          },
        });
      }

      const newModule = new Module(file, element, i, dependencyValues, this.PARAM_MAPPING);
      newModule.calculateFields();
      modules[i] = newModule;
    });
  }
Example #5
Source File: webpackParser.ts    From react-native-decompiler with GNU Affero General Public License v3.0 6 votes vote down vote up
protected parseAst(ast: File, modules: Module[]): void {
    traverse(ast, {
      CallExpression: (nodePath) => {
        const firstArg = nodePath.get('arguments')[0];
        if (isFunctionExpression(nodePath.node.callee) && firstArg?.isArrayExpression()) { // entrypoint
          this.parseArray(ast, firstArg, modules);
        } else if (isMemberExpression(nodePath.node.callee) && isAssignmentExpression(nodePath.node.callee.object) && firstArg?.isArrayExpression()) { // chunked
          const assignment = nodePath.node.callee.object;
          if (isMemberExpression(assignment.left)) {
            let leftPropName = '';
            if (isIdentifier(assignment.left.property)) {
              leftPropName = assignment.left.property.name;
            } else if (isStringLiteral(assignment.left.property)) {
              leftPropName = assignment.left.property.value;
            }
            if (leftPropName.startsWith('webpackJsonp')) {
              const modulesObject = firstArg.get('elements')[1];
              if (modulesObject.isArrayExpression()) {
                this.parseArray(ast, modulesObject, modules);
              } else {
                if (!modulesObject || !modulesObject.isObjectExpression()) throw new Error('Failed assertion');
                this.parseObject(ast, modulesObject, modules);
              }
            }
          }
        }
        nodePath.skip();
      },
    });
  }
Example #6
Source File: reactNativeSingleParser.ts    From react-native-decompiler with GNU Affero General Public License v3.0 6 votes vote down vote up
async parse(args: CmdArgs): Promise<Module[]> {
    console.log('Parsing JS...');
    this.startTimer('parse-js');

    const file = await fs.readFile(args.in, 'utf8');
    const ast = babylon.parse(file);

    this.stopAndPrintTime('parse-js');

    const modules: Module[] = [];

    console.log('Finding modules...');
    this.startTimer('find-modules');

    traverse(ast, {
      CallExpression: (nodePath) => {
        if (isIdentifier(nodePath.node.callee) && nodePath.node.callee.name === '__d') {
          const functionArg = nodePath.get('arguments')[0];
          const moduleId = nodePath.get('arguments')[1];
          const dependencies = nodePath.get('arguments')[2];
          if (functionArg.isFunctionExpression() && moduleId.isNumericLiteral() && dependencies.isArrayExpression() && functionArg.node.body.body.length) {
            const dependencyValues = dependencies.node.elements.map((e) => {
              if (!isNumericLiteral(e)) throw new Error('Not numeric literal');
              return e.value;
            });
            const newModule = new Module(ast, functionArg, moduleId.node.value, dependencyValues, this.SEVEN_PARAM_MAPPING);
            newModule.calculateFields();
            modules[newModule.moduleId] = newModule;
          }
        }
        nodePath.skip();
      },
    });

    this.stopAndPrintTime('find-modules');

    return modules;
  }
Example #7
Source File: esModuleCleaner.ts    From react-native-decompiler with GNU Affero General Public License v3.0 6 votes vote down vote up
evaluate(path: NodePath<FunctionExpression>): void {
    const bodyPath = this.navigateToModuleBody(path);

    bodyPath.node.body = bodyPath.node.body.filter((line) => {
      const callExpression = isExpressionStatement(line) ? line.expression : line;
      if (!isCallExpression(callExpression)) return true;
      if (!isMemberExpression(callExpression.callee)) return true;
      if (!isIdentifier(callExpression.callee.object) || !isIdentifier(callExpression.callee.property)) return true;
      if (callExpression.callee.object.name !== 'Object' || callExpression.callee.property.name !== 'defineProperty') return true;
      if (!isIdentifier(callExpression.arguments[0]) || !isStringLiteral(callExpression.arguments[1])) return true;
      if (bodyPath.scope.getBindingIdentifier(callExpression.arguments[0].name)?.start !== this.module.exportsParam?.start) return true;
      if (callExpression.arguments[1].value !== '__esModule') return true;

      this.module.tags.push('__esModule');
      return false;
    });
  }
Example #8
Source File: setStateRenamer.ts    From react-native-decompiler with GNU Affero General Public License v3.0 6 votes vote down vote up
getVisitor(): Visitor {
    return {
      VariableDeclaration: (path) => {
        path.node.declarations.forEach((varNode) => {
          // is it array destructure with 2 elements?
          if (!isArrayPattern(varNode.id) || varNode.id.elements.length !== 2 || !isIdentifier(varNode.id.elements[0]) || !isIdentifier(varNode.id.elements[1])) return;

          // is it defined by React.useState?
          if (!isCallExpression(varNode.init) || !isMemberExpression(varNode.init.callee)) return;
          if (!isIdentifier(varNode.init.callee.object) || !isIdentifier(varNode.init.callee.property)) return;
          if (varNode.init.callee.object.name !== 'React' || varNode.init.callee.property.name !== 'useState') return;
          path.parentPath.scope.crawl();
          path.parentPath.scope.rename(varNode.id.elements[1].name, `set${varNode.id.elements[0].name[0].toUpperCase()}${varNode.id.elements[0].name.slice(1)}`);
        });
      },
    };
  }
Example #9
Source File: jsxConverter.ts    From react-native-decompiler with GNU Affero General Public License v3.0 6 votes vote down vote up
getVisitor(): Visitor {
    return {
      CallExpression: (path) => {
        if (!isMemberExpression(path.node.callee) || !isIdentifier(path.node.callee.object) || !isIdentifier(path.node.callee.property)) return;
        if (path.node.callee.object.name !== 'React' || path.node.callee.property.name !== 'createElement') return;

        path.replaceWith(this.parseJsx(path.node));
        this.module.tags.push('jsx');
      },
    };
  }
Example #10
Source File: defaultInteropEvaluator.ts    From react-native-decompiler with GNU Affero General Public License v3.0 6 votes vote down vote up
getVisitor(): Visitor {
    return {
      VariableDeclarator: (path) => {
        if (!isIdentifier(path.node.id)) return;
        if (this.variableIsForDependency(path, ['@babel/runtime/helpers/interopRequireDefault', '@babel/runtime/helpers/interopRequireWildcard'])) {
          const interopVarName = path.node.id.name;
          this.bindingTraverse(path.scope.bindings[interopVarName], interopVarName, {
            CallExpression: (bindingPath) => {
              if (!isIdentifier(bindingPath.node.callee) || bindingPath.node.callee.name !== interopVarName) return;
              if (isCallExpression(bindingPath.node.arguments[0])) {
                bindingPath.replaceWith(bindingPath.node.arguments[0]);
              } else if (isIdentifier(bindingPath.node.arguments[0])) {
                const parent = bindingPath.find((p) => p.isVariableDeclarator());
                if (!parent?.isVariableDeclarator() || !isIdentifier(parent.node.id)) throw new Error('Failed assertion');
                this.mergeBindings(parent, parent.node.id.name, bindingPath.node.arguments[0].name);
              }
            },
          });
          path.remove();
        }
      },
    };
  }
Example #11
Source File: cleanReturns.ts    From react-native-decompiler with GNU Affero General Public License v3.0 6 votes vote down vote up
getVisitor(): Visitor {
    return {
      ReturnStatement: (path) => {
        if (isAssignmentExpression(path.node.argument) && isIdentifier(path.node.argument.left)) {
          path.insertBefore(path.node.argument);
          path.get('argument').replaceWith(path.node.argument.left);
        }
      },
    };
  }
Example #12
Source File: toConsumableArrayCleaner.ts    From react-native-decompiler with GNU Affero General Public License v3.0 6 votes vote down vote up
afterPass(): void {
    if (this.moduleBindingLocation != null && this.moduleVarPath) {
      if (!this.moduleVarPath.removed) {
        this.moduleVarPath.remove();
      }

      this.callExpressions.forEachElement(this.moduleBindingLocation, (exp) => {
        if (isVariableDeclarator(exp.parent) && isIdentifier(exp.parent.id) && isIdentifier(exp.node.arguments[0])) {
          exp.scope.rename(exp.parent.id.name, exp.node.arguments[0].name);
          if (!exp.parentPath.removed) {
            exp.parentPath.remove();
          }
        } else {
          exp.replaceWith(exp.node.arguments[0]);
        }
      });
    }
  }
Example #13
Source File: toConsumableArrayCleaner.ts    From react-native-decompiler with GNU Affero General Public License v3.0 6 votes vote down vote up
getVisitor(): Visitor {
    if (!this.moduleUsed) return {};

    return {
      CallExpression: (path) => {
        if (!isIdentifier(path.node.callee)) return;

        const bindingLocation = path.scope.getBindingIdentifier(path.node.callee.name)?.start;
        if (bindingLocation == null) return;

        this.callExpressions.push(bindingLocation, path);
      },
      VariableDeclarator: (path) => {
        if (this.moduleVarPath || !isIdentifier(path.node.id) || !isCallExpression(path.node.init)) return;

        const init = path.get('init');
        if (!init.isCallExpression()) return;
        const moduleDependency = this.getModuleDependency(init);
        if (moduleDependency?.moduleName !== '@babel/runtime/helpers/toConsumableArray') return;

        this.moduleVarPath = path;
        this.moduleBindingLocation = path.scope.getBindingIdentifier(path.node.id.name)?.start ?? undefined;
      },
    };
  }
Example #14
Source File: passthroughModuleRemapper.ts    From react-native-decompiler with GNU Affero General Public License v3.0 6 votes vote down vote up
getVisitor(): Visitor {
    if (this.module.moduleCode.body.length !== 1) return {};

    return {
      AssignmentExpression: (path) => {
        if (!isMemberExpression(path.node.left) || !isIdentifier(path.node.left?.object) || !isIdentifier(path.node.left?.property)) return;
        if (path.scope.getBindingIdentifier(path.node.left.object.name)?.start !== this.module.moduleParam?.start) return;
        if (path.node.left.property.name !== 'exports') return;

        const right = path.get('right');
        if (!right.isCallExpression()) return;
        const rightCallee = right.get('callee');
        if (!rightCallee.isIdentifier() && !rightCallee.isCallExpression()) return;

        const dependency = this.getModuleDependency(rightCallee.isCallExpression() ? rightCallee : right);
        if (!dependency) return;
        if (rightCallee.isCallExpression() && !dependency.moduleStrings.find((str) => str.includes('Calling PropTypes validators directly is not supported'))) return;
        if (!this.moduleList.some((m) => m.dependencies.includes(this.module.moduleId))) return;

        this.debugLog(`bypassing ${this.module.moduleId} for ${dependency.moduleId} ${dependency.moduleName}`);

        const passthroughDependency = this.moduleList[dependency.moduleId];
        this.module.ignored = true;
        this.module.isNpmModule = true; // flag as NPM module in case this module pass through NPM module
        this.module.moduleName = `${this.module.moduleId} PASSTHROUGH TO ${passthroughDependency.moduleName}`;
        this.moduleList.forEach((module) => {
          module.dependencies = module.dependencies.map((dep) => (dep === this.module.moduleId ? passthroughDependency.moduleId : dep));
        });
      },
    };
  }
Example #15
Source File: valueParser.ts    From engine with MIT License 6 votes vote down vote up
processParamValue = (
  babel: typeof Babel,
  node: Babel.types.AssignmentPattern
): Operation | void => {
  const t = babel.types;
  let valueNode;
  if (t.isAssignmentPattern(node)) {
    valueNode = node.right;
  } else {
    valueNode = node;
  }

  if (valueNode && Values[valueNode.type]) {
    return Values[valueNode.type](babel, valueNode);
  } else {
    if (
      isIdentifier(valueNode) &&
      (valueNode.name === PathType.GET ||
        valueNode.name === PathType.OBSERVE ||
        valueNode.name === PathType.UPDATE)
    ) {
      return {
        type: OperationTypes.CONSTRUCTOR,
        value: valueNode.name,
      };
    } else {
      return constValue({ __node__: valueNode });
    }
  }
}
Example #16
Source File: webpackParser.ts    From react-native-decompiler with GNU Affero General Public License v3.0 6 votes vote down vote up
private parseArray(file: File, ast: NodePath<ArrayExpression>, modules: Module[]): void {
    ast.get('elements').forEach((element, i) => {
      if (!element.isFunctionExpression()) return;
      if (element.node.body.body.length === 0) return;

      const dependencyValues: number[] = [];
      const requireIdentifer = element.node.params[2];
      if (isIdentifier(requireIdentifer)) {
        element.traverse({
          CallExpression: (dependencyPath) => {
            if (!isIdentifier(dependencyPath.node.callee) || !isNumericLiteral(dependencyPath.node.arguments[0])) return;
            if (dependencyPath.scope.bindingIdentifierEquals(dependencyPath.node.callee.name, requireIdentifer)) {
              dependencyValues[dependencyPath.node.arguments[0].value] = dependencyPath.node.arguments[0].value;
            }
          },
        });
      }

      const newModule = new Module(file, element, i, dependencyValues, this.PARAM_MAPPING);
      newModule.calculateFields();
      modules[i] = newModule;
    });
  }
Example #17
Source File: reactNativeSingleParser.ts    From react-native-decompiler with GNU Affero General Public License v3.0 6 votes vote down vote up
async parse(args: CmdArgs): Promise<Module[]> {
    console.log('Parsing JS...');
    this.startTimer('parse-js');

    const file = await fs.readFile(args.in, 'utf8');
    const ast = babylon.parse(file);

    this.stopAndPrintTime('parse-js');

    const modules: Module[] = [];

    console.log('Finding modules...');
    this.startTimer('find-modules');

    traverse(ast, {
      CallExpression: (nodePath) => {
        if (isIdentifier(nodePath.node.callee) && nodePath.node.callee.name === '__d') {
          const functionArg = nodePath.get('arguments')[0];
          const moduleId = nodePath.get('arguments')[1];
          const dependencies = nodePath.get('arguments')[2];
          if (functionArg.isFunctionExpression() && moduleId.isNumericLiteral() && dependencies.isArrayExpression() && functionArg.node.body.body.length) {
            const dependencyValues = dependencies.node.elements.map((e) => {
              if (!isNumericLiteral(e)) throw new Error('Not numeric literal');
              return e.value;
            });
            const newModule = new Module(ast, functionArg, moduleId.node.value, dependencyValues, this.SEVEN_PARAM_MAPPING);
            newModule.calculateFields();
            modules[newModule.moduleId] = newModule;
          }
        }
        nodePath.skip();
      },
    });

    this.stopAndPrintTime('find-modules');

    return modules;
  }
Example #18
Source File: webpackParser.ts    From react-native-decompiler with GNU Affero General Public License v3.0 6 votes vote down vote up
protected parseAst(ast: File, modules: Module[]): void {
    traverse(ast, {
      CallExpression: (nodePath) => {
        const firstArg = nodePath.get('arguments')[0];
        if (isFunctionExpression(nodePath.node.callee) && firstArg?.isArrayExpression()) { // entrypoint
          this.parseArray(ast, firstArg, modules);
        } else if (isMemberExpression(nodePath.node.callee) && isAssignmentExpression(nodePath.node.callee.object) && firstArg?.isArrayExpression()) { // chunked
          const assignment = nodePath.node.callee.object;
          if (isMemberExpression(assignment.left)) {
            let leftPropName = '';
            if (isIdentifier(assignment.left.property)) {
              leftPropName = assignment.left.property.name;
            } else if (isStringLiteral(assignment.left.property)) {
              leftPropName = assignment.left.property.value;
            }
            if (leftPropName.startsWith('webpackJsonp')) {
              const modulesObject = firstArg.get('elements')[1];
              if (modulesObject.isArrayExpression()) {
                this.parseArray(ast, modulesObject, modules);
              } else {
                if (!modulesObject || !modulesObject.isObjectExpression()) throw new Error('Failed assertion');
                this.parseObject(ast, modulesObject, modules);
              }
            }
          }
        }
        nodePath.skip();
      },
    });
  }
Example #19
Source File: esModuleCleaner.ts    From react-native-decompiler with GNU Affero General Public License v3.0 6 votes vote down vote up
evaluate(path: NodePath<FunctionExpression>): void {
    const bodyPath = this.navigateToModuleBody(path);

    bodyPath.node.body = bodyPath.node.body.filter((line) => {
      const callExpression = isExpressionStatement(line) ? line.expression : line;
      if (!isCallExpression(callExpression)) return true;
      if (!isMemberExpression(callExpression.callee)) return true;
      if (!isIdentifier(callExpression.callee.object) || !isIdentifier(callExpression.callee.property)) return true;
      if (callExpression.callee.object.name !== 'Object' || callExpression.callee.property.name !== 'defineProperty') return true;
      if (!isIdentifier(callExpression.arguments[0]) || !isStringLiteral(callExpression.arguments[1])) return true;
      if (bodyPath.scope.getBindingIdentifier(callExpression.arguments[0].name)?.start !== this.module.exportsParam?.start) return true;
      if (callExpression.arguments[1].value !== '__esModule') return true;

      this.module.tags.push('__esModule');
      return false;
    });
  }
Example #20
Source File: setStateRenamer.ts    From react-native-decompiler with GNU Affero General Public License v3.0 6 votes vote down vote up
getVisitor(): Visitor {
    return {
      VariableDeclaration: (path) => {
        path.node.declarations.forEach((varNode) => {
          // is it array destructure with 2 elements?
          if (!isArrayPattern(varNode.id) || varNode.id.elements.length !== 2 || !isIdentifier(varNode.id.elements[0]) || !isIdentifier(varNode.id.elements[1])) return;

          // is it defined by React.useState?
          if (!isCallExpression(varNode.init) || !isMemberExpression(varNode.init.callee)) return;
          if (!isIdentifier(varNode.init.callee.object) || !isIdentifier(varNode.init.callee.property)) return;
          if (varNode.init.callee.object.name !== 'React' || varNode.init.callee.property.name !== 'useState') return;
          path.parentPath.scope.crawl();
          path.parentPath.scope.rename(varNode.id.elements[1].name, `set${varNode.id.elements[0].name[0].toUpperCase()}${varNode.id.elements[0].name.slice(1)}`);
        });
      },
    };
  }
Example #21
Source File: jsxConverter.ts    From react-native-decompiler with GNU Affero General Public License v3.0 6 votes vote down vote up
getVisitor(): Visitor {
    return {
      CallExpression: (path) => {
        if (!isMemberExpression(path.node.callee) || !isIdentifier(path.node.callee.object) || !isIdentifier(path.node.callee.property)) return;
        if (path.node.callee.object.name !== 'React' || path.node.callee.property.name !== 'createElement') return;

        path.replaceWith(this.parseJsx(path.node));
        this.module.tags.push('jsx');
      },
    };
  }
Example #22
Source File: defaultInteropEvaluator.ts    From react-native-decompiler with GNU Affero General Public License v3.0 6 votes vote down vote up
getVisitor(): Visitor {
    return {
      VariableDeclarator: (path) => {
        if (!isIdentifier(path.node.id)) return;
        if (this.variableIsForDependency(path, ['@babel/runtime/helpers/interopRequireDefault', '@babel/runtime/helpers/interopRequireWildcard'])) {
          const interopVarName = path.node.id.name;
          this.bindingTraverse(path.scope.bindings[interopVarName], interopVarName, {
            CallExpression: (bindingPath) => {
              if (!isIdentifier(bindingPath.node.callee) || bindingPath.node.callee.name !== interopVarName) return;
              if (isCallExpression(bindingPath.node.arguments[0])) {
                bindingPath.replaceWith(bindingPath.node.arguments[0]);
              } else if (isIdentifier(bindingPath.node.arguments[0])) {
                const parent = bindingPath.find((p) => p.isVariableDeclarator());
                if (!parent?.isVariableDeclarator() || !isIdentifier(parent.node.id)) throw new Error('Failed assertion');
                this.mergeBindings(parent, parent.node.id.name, bindingPath.node.arguments[0].name);
              }
            },
          });
          path.remove();
        }
      },
    };
  }
Example #23
Source File: toConsumableArrayCleaner.ts    From react-native-decompiler with GNU Affero General Public License v3.0 6 votes vote down vote up
getVisitor(): Visitor {
    if (!this.moduleUsed) return {};

    return {
      CallExpression: (path) => {
        if (!isIdentifier(path.node.callee)) return;

        const bindingLocation = path.scope.getBindingIdentifier(path.node.callee.name)?.start;
        if (bindingLocation == null) return;

        this.callExpressions.push(bindingLocation, path);
      },
      VariableDeclarator: (path) => {
        if (this.moduleVarPath || !isIdentifier(path.node.id) || !isCallExpression(path.node.init)) return;

        const init = path.get('init');
        if (!init.isCallExpression()) return;
        const moduleDependency = this.getModuleDependency(init);
        if (moduleDependency?.moduleName !== '@babel/runtime/helpers/toConsumableArray') return;

        this.moduleVarPath = path;
        this.moduleBindingLocation = path.scope.getBindingIdentifier(path.node.id.name)?.start ?? undefined;
      },
    };
  }
Example #24
Source File: toConsumableArrayCleaner.ts    From react-native-decompiler with GNU Affero General Public License v3.0 6 votes vote down vote up
afterPass(): void {
    if (this.moduleBindingLocation != null && this.moduleVarPath) {
      if (!this.moduleVarPath.removed) {
        this.moduleVarPath.remove();
      }

      this.callExpressions.forEachElement(this.moduleBindingLocation, (exp) => {
        if (isVariableDeclarator(exp.parent) && isIdentifier(exp.parent.id) && isIdentifier(exp.node.arguments[0])) {
          exp.scope.rename(exp.parent.id.name, exp.node.arguments[0].name);
          if (!exp.parentPath.removed) {
            exp.parentPath.remove();
          }
        } else {
          exp.replaceWith(exp.node.arguments[0]);
        }
      });
    }
  }
Example #25
Source File: cleanReturns.ts    From react-native-decompiler with GNU Affero General Public License v3.0 6 votes vote down vote up
getVisitor(): Visitor {
    return {
      ReturnStatement: (path) => {
        if (isAssignmentExpression(path.node.argument) && isIdentifier(path.node.argument.left)) {
          path.insertBefore(path.node.argument);
          path.get('argument').replaceWith(path.node.argument.left);
        }
      }
    };
  }
Example #26
Source File: paramsParser.ts    From engine with MIT License 5 votes vote down vote up
paramsParser = (params: ObjectPattern): StructOperation => {
  if (!params) {
    return {
      type: OperationTypes.STRUCT,
      value: {},
    };
  }
  const result = params.properties.reduce(
    (acc, x, idx) => {
      if (isObjectProperty(x)) {
        if (isIdentifier(x.value)) {
          const node = x.value as Identifier;
          const propName = node.name;
          const propValue = {
            type: OperationTypes.VALUE,
            value: {
              type: ValueTypes.EXTERNAL,
              path: [propName],
            },
          } as ValueOperation;
          acc.value[propName] = propValue;
        } else if (isAssignmentPattern(x.value)) {
          const node = x.value as AssignmentPattern;
          const left = node.left as Identifier;
          const propName = left.name;
          const propValue = processParamValue(node);
          if (propValue) {
            acc.value[propName] = propValue;
          } else {
            throw new Error(
              "Property " + propName + " could not be processed."
            );
          }
        } else {
          console.log("Not object property", x);
        }
      } else if (isRestElement(x)) {
        throw new Error("Rest operator is not supported.");
      }
      return acc;
    },
    {
      type: OperationTypes.STRUCT,
      value: {},
    } as StructOperation
  );

  result.meta = {};

  return result;
}
Example #27
Source File: getMemberExpressionParams.ts    From engine with MIT License 5 votes vote down vote up
getMemberExpressionParams = (node: Node): any[] => {
  if (node.type === "MemberExpression") {
    if (node.property.type === "MemberExpression") {
      let result = getMemberExpressionParams(node.property.object);
      if (node.property.property) {
        const params = getMemberExpressionParams(node.property.property);
        result = result.concat(params);
      }
      let pathArg;
      if (result[0] === PathProps.EXTERNAL) {
        result.shift();
        pathArg = "@" + result.join(".");
      } else if (result[0] === PathProps.INTERNAL) {
        result.shift();
        pathArg = "$" + result.join(".");
      } else if (result[0] === PathProps.PARAM) {
        result.shift();
        pathArg = ":" + result.join(".");
      } else {
        pathArg = {
          __node__: node.property,
        };
      }
      return [...getMemberExpressionParams(node.object), pathArg];
    } else {
      let value;
      if (isIdentifier(node.property) && node.computed) {
        value = { __node__: node.property };
      } else if (isTemplateLiteral(node.property)) {
        value = { __node__: node.property };
      } else {
        value = (node.property as any).name || (node.property as any).value;
      }

      return [...getMemberExpressionParams(node.object), value];
    }
  } else if (node.hasOwnProperty("value")) {
    return [(node as ValueNodes).value];
  } else if (node.hasOwnProperty("name")) {
    return [(node as Identifier).name];
  } else {
    return [];
  }
}
Example #28
Source File: prepareForEngine.ts    From engine with MIT License 5 votes vote down vote up
prepareForEngine: PrepareForEngine = (babel, state, ref, type) => {
  const validation = validateRef(ref);
  if (validation.error) {
    throw new Error(validation.errorMessage);
  }

  const config = getConfig(state);

  const op = parseRef(babel, state, ref);
  const props = structOperationCompiler(op);
  const parent = ref.findParent((p) => p.isVariableDeclarator());
  if (!parent) {
    throw new Error(
      "Misuse of the view/producer keyword. It needs to be a variable declaration e.g. let foo: view = ..."
    );
  }
  const node = parent.node as VariableDeclarator;
  const fn = node.init as ArrowFunctionExpression;

  fn.params = paramsCompiler(op);
  const result = objectExpression([
    objectProperty(identifier("props"), props),
    objectProperty(identifier("fn"), fn),
  ]);

  if (type === TransformType.PRODUCER) {
    node.init = result;
  } else if (type === TransformType.VIEW) {
    const viewCall = callExpression(identifier("view"), [result]);
    node.init = viewCall;
    const viewImport = config.view.importFrom;
    const program = ref.findParent((p) => p.isProgram());
    if (!program) {
      throw new Error("Internal error. Cannot find program node");
    }
    const macroImport = program.get("body").find((p) => {
      const result =
        p.isImportDeclaration() &&
        p.node.source.value.indexOf("@c11/engine.macro") !== -1;
      return result;
    });

    const engineImport = program.get("body").find((p) => {
      const result =
        p.isImportDeclaration() &&
        p.node.source.value.indexOf(viewImport) !== -1;
      return result;
    });

    if (macroImport) {
      if (!engineImport) {
        const importView = importDeclaration(
          [importSpecifier(identifier("view"), identifier("view"))],
          stringLiteral(viewImport)
        );
        // @ts-ignore
        macroImport.insertAfter(importView);
      } else {
        const node = engineImport.node as ImportDeclaration;
        const viewNode = node.specifiers.find((node) => {
          return (
            isImportSpecifier(node) &&
            isIdentifier(node.imported) &&
            node.imported.name === "view"
          );
        });
        if (!viewNode) {
          node.specifiers.push(
            importSpecifier(identifier("view"), identifier("view"))
          );
        }
      }
    } else {
      throw new Error("Could not find macro import");
    }
  }
}
Example #29
Source File: reactNativeFolderParser.ts    From react-native-decompiler with GNU Affero General Public License v3.0 5 votes vote down vote up
async parse(args: CmdArgs): Promise<Module[]> {
    const fileNames = (await fs.readdir(args.in)).filter((fileName) => fileName.endsWith('.js'));

    console.log('Parsing folder...');
    this.startTimer('parse');
    this.progressBar.start(0, fileNames.length);

    const modules: Module[] = [];

    await Promise.all(fileNames.map(async (fileName) => {
      const file = await fs.readFile(path.join(args.in, fileName), 'utf8');
      const ast = babylon.parse(file);

      traverse(ast, {
        CallExpression: (nodePath) => {
          if (isIdentifier(nodePath.node.callee) && nodePath.node.callee.name === '__d') {
            const functionArg = nodePath.get('arguments')[0];
            const moduleId = nodePath.get('arguments')[1];
            const dependencies = nodePath.get('arguments')[2];
            if (functionArg.isFunctionExpression() && moduleId.isNumericLiteral() && dependencies.isArrayExpression() && functionArg.node.body.body.length) {
              const dependencyValues = dependencies.node.elements.map((e) => {
                if (!isNumericLiteral(e)) throw new Error('Not numeric literal');
                return e.value;
              });
              const newModule = new Module(ast, functionArg, moduleId.node.value, dependencyValues, this.SEVEN_PARAM_MAPPING);
              newModule.calculateFields();
              modules[newModule.moduleId] = newModule;
            }
          }
          nodePath.skip();
        },
      });

      this.progressBar.increment();
    }));

    this.progressBar.stop();
    this.stopAndPrintTime('parse');

    return modules;
  }