@babel/types#VariableDeclarator TypeScript Examples

The following examples show how to use @babel/types#VariableDeclarator. 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: parseRef.ts    From engine with MIT License 6 votes vote down vote up
parseRef: ParseRef = (babel, state, ref) => {
  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 declaration = parent.node as VariableDeclarator;
  const fn = declaration.init as ArrowFunctionExpression;
  const params = fn.params[0] as ObjectPattern;
  const result = paramsParser(params);
  return result;
}
Example #2
Source File: validateRef.ts    From engine with MIT License 6 votes vote down vote up
validateRef = (ref: Babel.NodePath): Result => {
  const result: Result = {
    error: true,
  };
  if (!ref) {
    return result;
  }
  const node = ref.parentPath?.node;
  const refNode = ref.node as Identifier;
  const parent = ref.findParent((p) => p.isVariableDeclarator());
  if (!parent) {
    throw new Error(
      "The producer or view types can only be used with variable declarations e.g. let foo: producer."
    );
  }
  const declaration = parent.node as VariableDeclarator;
  if (!(isTSTypeReference(node) || isTypeAnnotation(node))) {
    result.errorMessage = `\`${refNode.name}\` should be used as a type. Please see the engine documentation`;
  } else if (!isArrowFunctionExpression(declaration.init)) {
    result.errorMessage = `\`${refNode.name}\` should receive an arrow function expression. Please see the engine documentation`;
  } else if (
    declaration.init.params.length > 0 &&
    !isObjectPattern(declaration.init.params[0])
  ) {
    result.errorMessage = `\`${refNode.name}\` should receive a single argument which needs to be an object`;
  } else {
    result.error = false;
    result.success = true;
  }

  return result;
}
Example #3
Source File: traverse.ts    From react-optimized-image with MIT License 6 votes vote down vote up
resolveRequireExportName = (node: VariableDeclarator, binding: Binding): string | undefined => {
  // check for const { Svg } = require('react-optimized-image') calls
  if (node.id.type === 'ObjectPattern') {
    return (node.id.properties.find(
      (property) =>
        property.type === 'ObjectProperty' &&
        property.value.type === 'Identifier' &&
        property.value.name === binding.identifier.name,
    ) as ObjectProperty).key.name;
  }

  // check for require('react-optimized-image').default calls
  if (
    node.init &&
    node.init.type === 'MemberExpression' &&
    node.init.object.type === 'CallExpression' &&
    node.init.property.type === 'Identifier'
  ) {
    return node.init.property.name;
  }
}
Example #4
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 #5
Source File: babel-polyfill.ts    From nota with MIT License 6 votes vote down vote up
variableDeclaration = (
  kind: "var" | "let" | "const",
  declarations: Array<VariableDeclarator>
): VariableDeclaration => ({
  type: "VariableDeclaration",
  kind,
  declarations,
  ...baseNode,
})
Example #6
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 #7
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 #8
Source File: toConsumableArrayCleaner.ts    From react-native-decompiler with GNU Affero General Public License v3.0 5 votes vote down vote up
private moduleVarPath?: NodePath<VariableDeclarator>;
Example #9
Source File: arrayDestructureEvaluator.ts    From react-native-decompiler with GNU Affero General Public License v3.0 5 votes vote down vote up
getVisitor(): Visitor {
    if (!this.destructureUsed) return {};

    return {
      VariableDeclarator: (path) => {
        if (!isIdentifier(path.node.id) || path.node.id.start == null) return;

        const variableDeclaratorData: VariableDeclaratorData = {
          path,
          couldBeDestructure: false,
          couldBeArrayAccess: false,
          varName: path.node.id.name,
          varStart: path.node.id.start,
        };

        if (isCallExpression(path.node.init) && isIdentifier(path.node.init.callee)
          && path.node.init.arguments.length === 2 && isIdentifier(path.node.init.arguments[0]) && isNumericLiteral(path.node.init.arguments[1])) {
          variableDeclaratorData.couldBeDestructure = true;
          variableDeclaratorData.destructureBindingStart = path.scope.getBindingIdentifier(path.node.init.callee.name)?.start ?? undefined;
          variableDeclaratorData.destructureArrayBindingStart = path.scope.getBindingIdentifier(path.node.init.arguments[0].name)?.start ?? undefined;
        }
        if (isMemberExpression(path.node.init) && isIdentifier(path.node.init.object) && isNumericLiteral(path.node.init.property)) {
          variableDeclaratorData.couldBeArrayAccess = true;
          variableDeclaratorData.arrayAccessBindingStart = path.scope.getBindingIdentifier(path.node.init.object.name)?.start ?? undefined;
          variableDeclaratorData.arrayAccessVal = path.node.init.property.value;
        }

        this.variableDeclarators.push(variableDeclaratorData);

        const callExpression = path.get('init');
        if (!callExpression.isCallExpression()) return;

        const moduleDependency = this.getModuleDependency(callExpression);
        if (moduleDependency?.moduleName === '@babel/runtime/helpers/slicedToArray') {
          this.destructureFunction = path;
          this.destructureFunctionStart = path.node.id.start;
        }
      },
    };
  }
Example #10
Source File: arrayDestructureEvaluator.ts    From react-native-decompiler with GNU Affero General Public License v3.0 5 votes vote down vote up
private destructureFunction?: NodePath<VariableDeclarator>;
Example #11
Source File: babel-polyfill.ts    From nota with MIT License 5 votes vote down vote up
variableDeclarator = (id: LVal, init?: Expression | null): VariableDeclarator => ({
  type: "VariableDeclarator",
  id,
  init,
  ...baseNode,
})
Example #12
Source File: toConsumableArrayCleaner.ts    From react-native-decompiler with GNU Affero General Public License v3.0 5 votes vote down vote up
private moduleVarPath?: NodePath<VariableDeclarator>;
Example #13
Source File: arrayDestructureEvaluator.ts    From react-native-decompiler with GNU Affero General Public License v3.0 5 votes vote down vote up
getVisitor(): Visitor {
    if (!this.destructureUsed) return {};

    return {
      VariableDeclarator: (path) => {
        if (!isIdentifier(path.node.id) || path.node.id.start == null) return;

        const variableDeclaratorData: VariableDeclaratorData = {
          path,
          couldBeDestructure: false,
          couldBeArrayAccess: false,
          varName: path.node.id.name,
          varStart: path.node.id.start,
        };

        if (isCallExpression(path.node.init) && isIdentifier(path.node.init.callee)
          && path.node.init.arguments.length === 2 && isIdentifier(path.node.init.arguments[0]) && isNumericLiteral(path.node.init.arguments[1])) {
          variableDeclaratorData.couldBeDestructure = true;
          variableDeclaratorData.destructureBindingStart = path.scope.getBindingIdentifier(path.node.init.callee.name)?.start ?? undefined;
          variableDeclaratorData.destructureArrayBindingStart = path.scope.getBindingIdentifier(path.node.init.arguments[0].name)?.start ?? undefined;
        }
        if (isMemberExpression(path.node.init) && isIdentifier(path.node.init.object) && isNumericLiteral(path.node.init.property)) {
          variableDeclaratorData.couldBeArrayAccess = true;
          variableDeclaratorData.arrayAccessBindingStart = path.scope.getBindingIdentifier(path.node.init.object.name)?.start ?? undefined;
          variableDeclaratorData.arrayAccessVal = path.node.init.property.value;
        }

        this.variableDeclarators.push(variableDeclaratorData);

        const callExpression = path.get('init');
        if (!callExpression.isCallExpression()) return;

        const moduleDependency = this.getModuleDependency(callExpression);
        if (moduleDependency?.moduleName === '@babel/runtime/helpers/slicedToArray') {
          this.destructureFunction = path;
          this.destructureFunctionStart = path.node.id.start;
        }
      },
    };
  }
Example #14
Source File: arrayDestructureEvaluator.ts    From react-native-decompiler with GNU Affero General Public License v3.0 5 votes vote down vote up
private destructureFunction?: NodePath<VariableDeclarator>;
Example #15
Source File: js-treeshaking-plugin.ts    From dm with MIT License 4 votes vote down vote up
private treeshaking (WPModule: IWebpackModule, code: string): string {
    if (!WPModule) return code; // 生成的NPM包资源没有经过webpack构建,没有WPModule
    const providedExports: boolean|string[] = WPModule.buildMeta.providedExports || [];
    const usedExports = WPModule.usedExports;
    if (!Array.isArray(usedExports) || !Array.isArray(providedExports)) return code;

    let unused = providedExports.filter(item => {
      return !usedExports.includes(item);
    })

    if (!unused.length) return code;
    log.debug('blue', chalk.blue('执行 treeShaking', WPModule.resource));
    log.debug('unused', '[ ' + unused.join(' , ') + ' ]');
    const _removeUnused = function (key: string): void {
      unused = unused.filter((name: string) => !(name === key));
    }
    // TODO 性能提升:想办法拿到 webpack 已经解析好的AST
    try {
      const ast = parser.parse(code, {
        sourceType: 'module'
      });

      traverse(ast, {
        ExportNamedDeclaration (path) {
          const declaration = path.node.declaration;
          if (!declaration) return;
          if (declaration.type === 'FunctionDeclaration') {
            unused.some(exportItem => {
              // references=1表示仅有一次引用,即export的引用,没有在别处调用
              if (declaration.id!.name === exportItem && path.scope.bindings[exportItem] && path.scope.bindings[exportItem].references === 1) {
                log.debug('treeShaking 内联导出方法', exportItem);
                _removeUnused(exportItem);
                path.remove();
                return true;
              }
              return false;
            });
          } else if (declaration.type === 'VariableDeclaration') {
            unused.some((exportItem: string) => {
              // references=1表示仅有一次引用,即export的引用,没有在别处调用
              if (declaration.declarations && path.scope.bindings[exportItem] && path.scope.bindings[exportItem].references === 1) {
                if (declaration.declarations.some((d: VariableDeclarator) => {
                  if ((d.id as Identifier).name === exportItem) {
                    return true;
                  }
                  return false;
                })) {
                  log.debug('treeShaking 变量', exportItem);
                  _removeUnused(exportItem);
                  path.remove();
                  return true;
                }
              }
              return false;
            });
          }
        },
        ExportSpecifier (path) {
          unused.some((exportItem: string) => {
            if (!path.node.exported) {
              log.warn('ExportSpecifier has no exported');
            }
            if (path.node.exported && (path.node.exported.name === exportItem)) {
              // references=1表示仅有一次引用,即export的引用,没有在别处调用
              if (path.scope.bindings[exportItem] && path.scope.bindings[exportItem] && path.scope.bindings[exportItem].references === 1) {
                path.scope.bindings[exportItem].path.remove();
                path.remove();
              }
              log.debug('treeShaking 标识导出方法', exportItem);
              _removeUnused(exportItem);
              return true;
            }
            return false;
          });
        },
        ExportDefaultDeclaration (path) {
          const declaration: any = path.node.declaration;
          if (!declaration || declaration.type === 'ObjectExpression') return;
          unused.some(exportItem => {
            // 如果有default ,说明是default没有引用,直接删除
            if (exportItem === 'default') {
              const name = declaration.name;
              if (name && path.scope.bindings[name] && path.scope.bindings[name].references === 1) {
                // cosnt c = 3;
                // export deafult c;
                path.scope.bindings[name].path.remove();
              }

              path.remove();
              log.debug('treeShaking 默认导出', name || (declaration.id && declaration.id.name) || '');
              _removeUnused(exportItem);
              return true;
            }
            return false;
          })
        }
      })
      code = generate(ast).code
    } catch (error) {
      log.error('treeShaking 异常', error)
    }
    return code;
  }