@babel/types#ObjectExpression TypeScript Examples

The following examples show how to use @babel/types#ObjectExpression. 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: constructorOperationCompiler.ts    From engine with MIT License 6 votes vote down vote up
constructorOperationCompiler = (
  babel: typeof Babel,
  op: ConstructorOperation
): ObjectExpression => {
  const t = babel.types;
  let value = t.objectProperty(
    t.identifier("value"),
    t.stringLiteral(op.value)
  );
  const type = t.objectProperty(t.identifier("type"), t.stringLiteral(op.type));
  return t.objectExpression([type, value]);
}
Example #2
Source File: structOperationCompiler.ts    From engine with MIT License 6 votes vote down vote up
structOperationCompiler = (
  opOrig: StructOperation
): ObjectExpression => {
  const type = objectProperty(identifier("type"), stringLiteral(opOrig.type));
  const keys: ObjectProperty[] = Object.keys(opOrig.value)
    .map((x) => {
      const op = opOrig.value[x];
      let result;
      if (op.type === OperationTypes.GET) {
        result = pathOperationCompiler(op);
      } else if (op.type === OperationTypes.OBSERVE) {
        result = pathOperationCompiler(op);
      } else if (op.type === OperationTypes.UPDATE) {
        result = pathOperationCompiler(op);
      } else if (op.type === OperationTypes.FUNC) {
        result = funcOperationCompiler(op);
      } else if (op.type === OperationTypes.STRUCT) {
        result = structOperationCompiler(op);
      } else if (op.type === OperationTypes.VALUE) {
        result = valueOperationCompiler(op);
      } else {
        throw new Error(`Operation ${op} not supported`);
      }
      return objectProperty(identifier(x), result, false, true);
    })
    .filter((x) => !!x);
  const value = objectProperty(identifier("value"), objectPattern(keys));
  if (opOrig.meta) {
    const meta = objectProperty(
      identifier("meta"),
      rawObjectCompiler(opOrig.meta)
    );
    return objectExpression([type, value, meta]);
  } else {
    return objectExpression([type, value]);
  }
}
Example #3
Source File: rawObjectCompiler.ts    From engine with MIT License 6 votes vote down vote up
rawObjectCompiler = (obj: any): ObjectExpression => {
  const props = Object.keys(obj).reduce((acc, x) => {
    let val: any = obj[x];
    let result;
    if (isString(val)) {
      result = stringLiteral(val);
    } else if (typeof val === "number") {
      result = numericLiteral(toNumber(val));
    } else if (isArray(val)) {
      let list = val.map((x) => stringLiteral(x));
      result = arrayExpression(list);
    } else if (isPlainObject(val)) {
      result = rawObjectCompiler(val);
    } else {
      throw new Error("Meta type for " + val + " not supported");
    }
    if (result) {
      acc.push(objectProperty(identifier(x), result));
    }
    return acc;
  }, [] as ObjectProperty[]);

  return objectExpression(props);
}
Example #4
Source File: pathCompiler.ts    From engine with MIT License 6 votes vote down vote up
pathCompiler = (path: InvokablePath): ArrayExpression => {
  const parts = path.map((x) => {
    let type = objectProperty(identifier("type"), stringLiteral(x.type));
    let value = objectProperty(identifier("ignored"), nullLiteral());
    if (x.type === ValueTypes.CONST) {
      let paramValue;
      if (x.value.__node__) {
        paramValue = x.value.__node__;
      } else {
        paramValue = stringLiteral(x.value.toString());
      }
      value = objectProperty(identifier("value"), paramValue);
    } else if (
      x.type === ValueTypes.INTERNAL ||
      x.type === ValueTypes.EXTERNAL
    ) {
      const path = x.path.map((y: string) => stringLiteral(y));
      value = objectProperty(identifier("path"), arrayExpression(path));
    } else if (x.type === ValueTypes.INVOKE) {
      const path = x.path.map((y: string) => stringLiteral(y));
      value = objectProperty(identifier("path"), arrayExpression(path));
    }
    return objectExpression([type, value]);
  });
  const result = arrayExpression(parts);
  return result;
}
Example #5
Source File: funcOperationCompiler.ts    From engine with MIT License 6 votes vote down vote up
funcOperationCompiler = (op: FuncOperation): ObjectExpression => {
  const type = objectProperty(identifier("type"), stringLiteral(op.type));
  const paramsList = op.value.params.map((x) => {
    const type = objectProperty(identifier("type"), stringLiteral(x.type));
    const value = objectProperty(identifier("value"), stringLiteral("value"));
    return objectExpression([type, value]);
  });
  const fn = objectProperty(identifier("fn"), stringLiteral("fn"));
  const paramsArray = arrayExpression(paramsList);
  const params = objectProperty(identifier("params"), paramsArray);
  const internal = objectExpression([params, fn]);
  const value = objectProperty(identifier("value"), internal);
  return objectExpression([type, value]);
}
Example #6
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 #7
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 #8
Source File: resolveJsxComponent.ts    From react-optimized-image with MIT License 6 votes vote down vote up
resolveObjectProperty = (path: NodePath<ObjectExpression>, property: ObjectProperty): string[] => {
  let bindings: string[] = [];
  const parent = path.findParent(() => true);

  if (parent.node.type === 'ObjectProperty') {
    bindings = [...resolveObjectProperty(parent.findParent(() => true) as NodePath<ObjectExpression>, parent.node)];
  } else if (parent.node.type === 'VariableDeclarator' && parent.node.id.type === 'Identifier') {
    bindings.push(parent.node.id.name);
  }

  bindings.push(property.key.name);

  return bindings;
}
Example #9
Source File: structOperationCompiler.ts    From engine with MIT License 6 votes vote down vote up
structOperationCompiler = (
  opOrig: StructOperation
): ObjectExpression => {
  const type = objectProperty(identifier("type"), stringLiteral(opOrig.type));
  const keys: ObjectProperty[] = Object.keys(opOrig.value)
    .map((x) => {
      const op = opOrig.value[x];
      let result;
      if (op.type === OperationTypes.GET) {
        result = pathOperationCompiler(op);
      } else if (op.type === OperationTypes.OBSERVE) {
        result = pathOperationCompiler(op);
      } else if (op.type === OperationTypes.UPDATE) {
        result = pathOperationCompiler(op);
      } else if (op.type === OperationTypes.FUNC) {
        result = funcOperationCompiler(op);
      } else if (op.type === OperationTypes.STRUCT) {
        result = structOperationCompiler(op);
      } else if (op.type === OperationTypes.VALUE) {
        result = valueOperationCompiler(op);
      } else {
        throw new Error(`Operation ${op} not supported`);
      }
      return objectProperty(identifier(x), result, false, true);
    })
    .filter((x) => !!x);
  const value = objectProperty(identifier("value"), objectPattern(keys));
  if (opOrig.meta) {
    const meta = objectProperty(
      identifier("meta"),
      rawObjectCompiler(opOrig.meta)
    );
    return objectExpression([type, value, meta]);
  } else {
    return objectExpression([type, value]);
  }
}
Example #10
Source File: rawObjectCompiler.ts    From engine with MIT License 6 votes vote down vote up
rawObjectCompiler = (obj: any): ObjectExpression => {
  const props = Object.keys(obj).reduce((acc, x) => {
    let val: any = obj[x];
    let result;
    if (isString(val)) {
      result = stringLiteral(val);
    } else if (typeof val === "number") {
      result = numericLiteral(toNumber(val));
    } else if (isArray(val)) {
      let list = val.map((x) => stringLiteral(x));
      result = arrayExpression(list);
    } else if (isPlainObject(val)) {
      result = rawObjectCompiler(val);
    } else {
      throw new Error("Meta type for " + val + " not supported");
    }
    if (result) {
      acc.push(objectProperty(identifier(x), result));
    }
    return acc;
  }, [] as ObjectProperty[]);

  return objectExpression(props);
}
Example #11
Source File: funcOperationCompiler.ts    From engine with MIT License 6 votes vote down vote up
funcOperationCompiler = (op: FuncOperation): ObjectExpression => {
  const type = objectProperty(identifier("type"), stringLiteral(op.type));
  const paramsList = op.value.params.map((x) => {
    const type = objectProperty(identifier("type"), stringLiteral(x.type));
    const value = objectProperty(identifier("value"), stringLiteral("value"));
    return objectExpression([type, value]);
  });
  const fn = objectProperty(identifier("fn"), stringLiteral("fn"));
  const paramsArray = arrayExpression(paramsList);
  const params = objectProperty(identifier("params"), paramsArray);
  const internal = objectExpression([params, fn]);
  const value = objectProperty(identifier("value"), internal);
  return objectExpression([type, value]);
}
Example #12
Source File: structOperationCompiler.ts    From engine with MIT License 6 votes vote down vote up
structOperationCompiler = (
  babel: typeof Babel,
  opOrig: StructOperation
): ObjectExpression => {
  const t = babel.types;
  const type = t.objectProperty(
    t.identifier("type"),
    t.stringLiteral(opOrig.type)
  );
  const keys: ObjectProperty[] = Object.keys(opOrig.value)
    .map((x) => {
      const op = opOrig.value[x];
      let result;
      if (op.type === OperationTypes.GET) {
        result = pathOperationCompiler(babel, op);
      } else if (op.type === OperationTypes.OBSERVE) {
        result = pathOperationCompiler(babel, op);
      } else if (op.type === OperationTypes.UPDATE) {
        result = pathOperationCompiler(babel, op);
      } else if (op.type === OperationTypes.FUNC) {
        result = funcOperationCompiler(babel, op);
      } else if (op.type === OperationTypes.STRUCT) {
        result = structOperationCompiler(babel, op);
      } else if (op.type === OperationTypes.VALUE) {
        result = valueOperationCompiler(babel, op);
      } else if (op.type === OperationTypes.CONSTRUCTOR) {
        result = constructorOperationCompiler(babel, op);
      } else {
        throw new Error(`Operation ${op} not supported`);
      }
      return t.objectProperty(t.identifier(x), result, false, true);
    })
    .filter((x) => !!x);

  const value = t.objectProperty(t.identifier("value"), t.objectPattern(keys));
  return t.objectExpression([type, value]);
}
Example #13
Source File: rawObjectCompiler.ts    From engine with MIT License 6 votes vote down vote up
rawObjectCompiler = (
  babel: typeof Babel,
  obj: any
): ObjectExpression => {
  const t = babel.types;
  const props = Object.keys(obj).reduce((acc, x) => {
    let val: any = obj[x];
    let result;
    if (isString(val)) {
      result = t.stringLiteral(val);
    } else if (typeof val === "number") {
      result = t.numericLiteral(toNumber(val));
    } else if (isArray(val)) {
      let list = val.map((x) => t.stringLiteral(x));
      result = t.arrayExpression(list);
    } else if (isPlainObject(val)) {
      result = rawObjectCompiler(babel, val);
    } else if (val === undefined) {
      result = t.identifier("undefined");
    } else {
      throw new Error("Meta type for " + val + " not supported");
    }
    if (result) {
      acc.push(t.objectProperty(t.identifier(x), result));
    }
    return acc;
  }, [] as ObjectProperty[]);

  return t.objectExpression(props);
}
Example #14
Source File: pathOperationCompiler.ts    From engine with MIT License 6 votes vote down vote up
pathOperationCompiler = (
  babel: typeof Babel,
  op: GetOperation | UpdateOperation | ObserveOperation
): ObjectExpression => {
  const t = babel.types;
  const type = t.objectProperty(t.identifier("type"), t.stringLiteral(op.type));
  let value = t.objectProperty(t.identifier("path"), t.stringLiteral("___"));
  value = t.objectProperty(t.identifier("path"), pathCompiler(babel, op.path));
  return t.objectExpression([type, value]);
}
Example #15
Source File: passthroughOperationCompiler.ts    From engine with MIT License 6 votes vote down vote up
passthroughOperationCompiler = (
  babel: typeof Babel
): ObjectExpression => {
  const t = babel.types;
  const type = t.objectProperty(
    t.identifier("type"),
    t.stringLiteral(OperationTypes.PASSTHROUGH)
  );
  return t.objectExpression([type]);
}
Example #16
Source File: funcOperationCompiler.ts    From engine with MIT License 6 votes vote down vote up
funcOperationCompiler = (
  babel: typeof Babel,
  op: FuncOperation
): ObjectExpression => {
  const t = babel.types;
  const type = t.objectProperty(t.identifier("type"), t.stringLiteral(op.type));
  const paramsList = op.value.params.map((x) => {
    const type = t.objectProperty(
      t.identifier("type"),
      t.stringLiteral(x.type)
    );
    const value = t.objectProperty(
      t.identifier("value"),
      t.stringLiteral("value")
    );
    return t.objectExpression([type, value]);
  });
  const fn = t.objectProperty(t.identifier("fn"), t.stringLiteral("fn"));
  const paramsArray = t.arrayExpression(paramsList);
  const params = t.objectProperty(t.identifier("params"), paramsArray);
  const internal = t.objectExpression([params, fn]);
  const value = t.objectProperty(t.identifier("value"), internal);
  return t.objectExpression([type, value]);
}
Example #17
Source File: js.ts    From css-to-js with MIT License 6 votes vote down vote up
export function parseJsObject(input: string): [ObjectExpression, string] {
  let rawLines: string;
  if (input.trim().match(/^\{.*\}$/s)) {
    rawLines = input;
  } else {
    // Wrap the input in curly braces before parsing
    // This is to support input without curly braces
    rawLines = `{${input}}`;
  }

  let expression: Expression;
  try {
    expression = babelParser.parseExpression(rawLines);
  } catch (e) {
    if (e instanceof SyntaxError) {
      const location = getErrorLocation(e);
      const codeFrame = codeFrameColumns(rawLines, { start: location });
      throw new SyntaxError(`${e.message}\n\n${codeFrame}`);
    }
    throw e;
  }

  if (expression.type !== "ObjectExpression") {
    throw new Error("Expression is not an object expression");
  }

  return [expression, rawLines];
}
Example #18
Source File: pathOperationCompiler.ts    From engine with MIT License 5 votes vote down vote up
pathOperationCompiler = (
  op: GetOperation | UpdateOperation | ObserveOperation
): ObjectExpression => {
  const type = objectProperty(identifier("type"), stringLiteral(op.type));
  let value = objectProperty(identifier("path"), stringLiteral("___"));
  value = objectProperty(identifier("path"), pathCompiler(op.path));
  return objectExpression([type, value]);
}
Example #19
Source File: valueOperationCompiler.ts    From engine with MIT License 5 votes vote down vote up
valueOperationCompiler = (
  op: ValueOperation
): ObjectExpression => {
  let value = objectProperty(identifier("path"), stringLiteral("___"));
  const type = objectProperty(identifier("type"), stringLiteral(op.type));
  if (op.value.type === ValueTypes.CONST) {
    const val = op.value.value;

    let valType;
    if (val && val.__node__) {
      valType = val.__node__;
    } else if (typeof val === "string") {
      valType = stringLiteral(val);
    } else if (typeof val === "number") {
      valType = numericLiteral(val);
    } else if (typeof val === "boolean") {
      valType = booleanLiteral(val);
    } else {
      throw new Error("Value type not supported yet: " + typeof val);
    }

    value = objectProperty(
      identifier("value"),
      objectExpression([
        objectProperty(identifier("type"), stringLiteral(ValueTypes.CONST)),
        objectProperty(identifier("value"), valType),
      ])
    );
  } else if (
    op.value.type === ValueTypes.EXTERNAL ||
    op.value.type === ValueTypes.INTERNAL
  ) {
    const path = arrayExpression(op.value.path.map((x) => stringLiteral(x)));
    value = objectProperty(
      identifier("value"),
      objectExpression([
        objectProperty(identifier("type"), stringLiteral(op.value.type)),
        objectProperty(identifier("path"), path),
      ])
    );
  }
  return objectExpression([type, value]);
}
Example #20
Source File: valueOperationCompiler.ts    From engine with MIT License 5 votes vote down vote up
valueOperationCompiler = (
  babel: typeof Babel,
  op: ValueOperation
): ObjectExpression => {
  const t = babel.types;
  let value = t.objectProperty(t.identifier("path"), t.stringLiteral("___"));
  const type = t.objectProperty(t.identifier("type"), t.stringLiteral(op.type));
  if (op.value.type === ValueTypes.CONST) {
    const val = op.value.value;

    let valType;
    if (val && val.__node__) {
      valType = val.__node__;
    } else if (typeof val === "string") {
      valType = t.stringLiteral(val);
    } else if (typeof val === "number") {
      valType = t.numericLiteral(val);
    } else if (typeof val === "boolean") {
      valType = t.booleanLiteral(val);
    } else {
      throw new Error("Value type not supported yet: " + typeof val);
    }

    value = t.objectProperty(
      t.identifier("value"),
      t.objectExpression([
        t.objectProperty(
          t.identifier("type"),
          t.stringLiteral(ValueTypes.CONST)
        ),
        t.objectProperty(t.identifier("value"), valType),
      ])
    );
  } else if (
    op.value.type === ValueTypes.EXTERNAL ||
    op.value.type === ValueTypes.INTERNAL
  ) {
    const path = t.arrayExpression(
      op.value.path.map((x) => t.stringLiteral(x))
    );
    value = t.objectProperty(
      t.identifier("value"),
      t.objectExpression([
        t.objectProperty(t.identifier("type"), t.stringLiteral(op.value.type)),
        t.objectProperty(t.identifier("path"), path),
      ])
    );
  }
  return t.objectExpression([type, value]);
}
Example #21
Source File: resolveJsxComponent.ts    From react-optimized-image with MIT License 5 votes vote down vote up
resolveObject = (types: Babel['types'], path: NodePath<JSXElement>, bindings: string[]): Binding | undefined => {
  if (bindings.length < 2) {
    return;
  }

  const variableName = bindings[bindings.length - 1];
  const object = path.scope.getBinding(bindings[0]);
  if (!object) {
    return;
  }

  const program = path.findParent((node) => node.isProgram());
  let declarationPath: any = null; // eslint-disable-line
  let initializer;

  // search for object declaration
  program.traverse({
    // styles.StyledImg = ...
    MemberExpression(exPath: NodePath<MemberExpression>) {
      if (exPath.node.property && exPath.node.property.name === variableName) {
        const exBindings = resolveMemberExpression(exPath.node);

        if (arraysMatch(bindings, exBindings) && exPath.parent.type === 'AssignmentExpression') {
          declarationPath = exPath;
          initializer = exPath.parent.right;
          exPath.stop();
        }
      }
    },

    // const styles = { StyledImg: ... }
    ObjectProperty(opPath: NodePath<ObjectProperty>) {
      if (opPath.node.key && opPath.node.key.type === 'Identifier' && opPath.node.key.name === variableName) {
        const exBindings = resolveObjectProperty(
          opPath.findParent(() => true) as NodePath<ObjectExpression>,
          opPath.node,
        );

        if (arraysMatch(bindings, exBindings)) {
          declarationPath = opPath;
          initializer = opPath.node.value;
          opPath.stop();
        }
      }
    },
  });

  if (!declarationPath) {
    return;
  }

  declarationPath = declarationPath as NodePath<MemberExpression>;

  // mock a binding
  const binding: Partial<Binding> = {
    kind: 'const',
    scope: declarationPath.scope,
    identifier: types.identifier(variableName),
    path: {
      ...(declarationPath as any), // eslint-disable-line
      node: types.variableDeclarator(
        types.objectPattern([types.objectProperty(types.identifier(variableName), types.identifier(variableName))]),
        initializer,
      ),
    },
  };

  return binding as Binding;
}
Example #22
Source File: babel-polyfill.ts    From nota with MIT License 5 votes vote down vote up
objectExpression = (
  properties: Array<ObjectMethod | ObjectProperty | SpreadElement>
): ObjectExpression => ({
  type: "ObjectExpression",
  properties,
  ...baseNode,
})
Example #23
Source File: pathOperationCompiler.ts    From engine with MIT License 5 votes vote down vote up
pathOperationCompiler = (
  op: GetOperation | UpdateOperation | ObserveOperation
): ObjectExpression => {
  const type = objectProperty(identifier("type"), stringLiteral(op.type));
  let value = objectProperty(identifier("path"), stringLiteral("___"));
  value = objectProperty(identifier("path"), pathCompiler(op.path));
  return objectExpression([type, value]);
}
Example #24
Source File: valueOperationCompiler.ts    From engine with MIT License 5 votes vote down vote up
valueOperationCompiler = (
  op: ValueOperation
): ObjectExpression => {
  let value = objectProperty(identifier("path"), stringLiteral("___"));
  const type = objectProperty(identifier("type"), stringLiteral(op.type));
  if (op.value.type === ValueTypes.CONST) {
    const val = op.value.value;

    let valType;
    if (val && val.__node__) {
      valType = val.__node__;
    } else if (typeof val === "string") {
      valType = stringLiteral(val);
    } else if (typeof val === "number") {
      valType = numericLiteral(val);
    } else if (typeof val === "boolean") {
      valType = booleanLiteral(val);
    } else {
      throw new Error("Value type not supported yet: " + typeof val);
    }

    value = objectProperty(
      identifier("value"),
      objectExpression([
        objectProperty(identifier("type"), stringLiteral(ValueTypes.CONST)),
        objectProperty(identifier("value"), valType),
      ])
    );
  } else if (
    op.value.type === ValueTypes.EXTERNAL ||
    op.value.type === ValueTypes.INTERNAL
  ) {
    const path = arrayExpression(op.value.path.map((x) => stringLiteral(x)));
    value = objectProperty(
      identifier("value"),
      objectExpression([
        objectProperty(identifier("type"), stringLiteral(op.value.type)),
        objectProperty(identifier("path"), path),
      ])
    );
  }
  return objectExpression([type, value]);
}
Example #25
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 #26
Source File: add-exports-array.ts    From mpflow with MIT License 4 votes vote down vote up
/**
 * 向配置文件如
 * module.exports = { plugins: [] }
 * 中的 plugins 添加插件信息
 */
export default function (api: typeof babel, options: Options): PluginObj {
  const { types: t, template } = api
  const { fieldName, items } = options

  let pluginsArrayExpression: NodePath<ArrayExpression> | null

  if (!fieldName || !items || !items.length)
    return {
      name: 'add-exports-array',
      visitor: {},
    }

  return {
    name: 'add-exports-array',
    pre() {
      pluginsArrayExpression = null
    },
    visitor: {
      AssignmentExpression(p) {
        // 寻找 module.exports = { plugins: [] }
        if (
          !m
            .assignmentExpression(
              '=',
              m.memberExpression(m.identifier('module'), m.identifier('exports')),
              m.objectExpression(),
            )
            .match(p.node)
        )
          return

        const objectExpression = p.get('right') as NodePath<ObjectExpression>
        const properties = objectExpression.get('properties')

        properties.forEach(property => {
          if (
            !m
              .objectProperty(m.or(m.stringLiteral(fieldName), m.identifier(fieldName)), m.arrayExpression())
              .match(property.node)
          )
            return

          pluginsArrayExpression = property.get('value') as NodePath<ArrayExpression>
        })
      },
      Program: {
        exit(p) {
          if (!pluginsArrayExpression) {
            // 如果找不到 module.exports = { plugins: [] }
            // 则在末尾加一句 exports.plugins = (exports.plugins || []).concat([])
            const statement = template.statement(`
              exports.FIELD_NAME = (exports.FIELD_NAME || []).concat([]);
            `)({
              FIELD_NAME: t.identifier(fieldName),
            })
            const [statementPath] = p.pushContainer('body', statement)
            pluginsArrayExpression = statementPath.get('expression.right.arguments.0') as NodePath<ArrayExpression>
          }
          const targetArray = pluginsArrayExpression
          // 添加 item
          items.forEach(item => {
            const [pluginName, option] = Array.isArray(item) ? item : [item]
            if (!option) {
              targetArray.pushContainer('elements', t.stringLiteral(pluginName))
            } else {
              targetArray.pushContainer(
                'elements',
                t.arrayExpression([t.stringLiteral(pluginName), template.expression(JSON.stringify(option))()]),
              )
            }
          })
        },
      },
    },
  }
}