export function getTransformContext()

in tools/hermes-parser/js/hermes-transform/src/transform/TransformContext.js [304:506]


export function getTransformContext(): TransformContextAdditions {
  /**
   * The mutations in order of collection.
   */
  const mutations: Array<Mutation> = [];
  function pushMutation(mutation: ?Mutation): void {
    if (mutation != null) {
      mutations.push(mutation);
    }
  }

  const cloneAPIs: TransformCloneAPIs = {
    shallowCloneNode: ((
      node: ?ESNode,
    ): // $FlowExpectedError[incompatible-cast]
    ?DetachedNode<ESNode> => {
      if (node == null) {
        return null;
      }

      return shallowCloneNode(node);
    }: TransformCloneAPIs['shallowCloneNode']),

    // $FlowExpectedError[incompatible-exact]
    shallowCloneNodeWithOverrides: ((
      node: ?ESNode,
      newProps?: $ReadOnly<{...}>,
    ): ?DetachedNode<ESNode> => {
      if (node == null) {
        return null;
      }

      return shallowCloneNode(node, newProps);
    }: TransformCloneAPIs['shallowCloneNodeWithOverrides']),

    shallowCloneArray: (<T: ESNode>(
      nodes: ?$ReadOnlyArray<T>,
    ): // $FlowExpectedError[incompatible-cast]
    ?$ReadOnlyArray<DetachedNode<ESNode>> => {
      if (nodes == null) {
        return null;
      }

      return nodes.map(node => shallowCloneNode<T>(node));
    }: TransformCloneAPIs['shallowCloneArray']),

    deepCloneNode: ((
      node: ?ESNode,
    ): // $FlowExpectedError[incompatible-cast]
    ?DetachedNode<ESNode> => {
      if (node == null) {
        return null;
      }

      return deepCloneNode(node);
    }: TransformCloneAPIs['deepCloneNode']),

    // $FlowExpectedError[incompatible-exact]
    deepCloneNodeWithOverrides: ((
      node: ?ESNode,
      newProps?: $ReadOnly<{...}>,
    ): ?DetachedNode<ESNode> => {
      if (node == null) {
        return null;
      }

      return deepCloneNode(node, newProps);
    }: TransformCloneAPIs['deepCloneNodeWithOverrides']),
  };
  const commentAPIs: TransformCommentAPIs = {
    getComments: ((node): Array<Comment> => {
      return [...getCommentsForNode(node)];
    }: TransformCommentAPIs['getComments']),

    getLeadingComments: ((node): Array<Comment> => {
      return getCommentsForNode(node).filter(isLeadingComment);
    }: TransformCommentAPIs['getLeadingComments']),

    getTrailingComments: ((node): Array<Comment> => {
      return getCommentsForNode(node).filter(isTrailingComment);
    }: TransformCommentAPIs['getTrailingComments']),

    cloneCommentsTo: ((target, destination): void => {
      pushMutation(createCloneCommentsToMutation(target, destination));
    }: TransformCommentAPIs['cloneCommentsTo']),

    addLeadingComments: ((node, comments): void => {
      pushMutation(
        createAddCommentsMutation(
          node,
          toArray(comments).map(comment => ({
            comment,
            placement: CommentPlacement.LEADING_OWN_LINE,
          })),
        ),
      );
    }: TransformCommentAPIs['addLeadingComments']),

    addLeadingInlineComments: ((node, comments): void => {
      pushMutation(
        createAddCommentsMutation(
          node,
          toArray(comments).map(comment => ({
            comment,
            placement: CommentPlacement.LEADING_INLINE,
          })),
        ),
      );
    }: TransformCommentAPIs['addLeadingInlineComments']),

    addTrailingComments: ((node, comments): void => {
      pushMutation(
        createAddCommentsMutation(
          node,
          toArray(comments).map(comment => ({
            comment,
            placement: CommentPlacement.TRAILING_OWN_LINE,
          })),
        ),
      );
    }: TransformCommentAPIs['addTrailingComments']),

    addTrailingInlineComments: ((node, comments): void => {
      pushMutation(
        createAddCommentsMutation(
          node,
          toArray(comments).map(comment => ({
            comment,
            placement: CommentPlacement.TRAILING_INLINE,
          })),
        ),
      );
    }: TransformCommentAPIs['addTrailingInlineComments']),

    removeComments: ((comments): void => {
      toArray(comments).forEach(comment => {
        pushMutation(createRemoveCommentMutation(comment));
      });
    }: TransformCommentAPIs['removeComments']),
  };
  const insertAPIs: TransformInsertAPIs = {
    insertAfterStatement: ((target, nodesToInsert): void => {
      pushMutation(
        createInsertStatementMutation('after', target, toArray(nodesToInsert)),
      );
    }: TransformInsertAPIs['insertBeforeStatement']),

    insertBeforeStatement: ((target, nodesToInsert): void => {
      pushMutation(
        createInsertStatementMutation('before', target, toArray(nodesToInsert)),
      );
    }: TransformInsertAPIs['insertBeforeStatement']),
  };
  const removeAPIs: TransformRemoveAPIs = {
    removeNode: ((node): void => {
      pushMutation(createRemoveNodeMutation(node));
    }: TransformRemoveAPIs['removeNode']),

    removeStatement: ((node): void => {
      pushMutation(createRemoveStatementMutation(node));
    }: TransformRemoveAPIs['removeStatement']),
  };
  const replaceAPIs: TransformReplaceAPIs = {
    replaceNode: ((
      target: ESNode,
      nodeToReplaceWith: DetachedNode<ESNode>,
      options?: ReplaceNodeOptions,
    ): void => {
      pushMutation(
        createReplaceNodeMutation(target, nodeToReplaceWith, options),
      );
    }: TransformReplaceAPIs['replaceNode']),

    replaceStatementWithMany: ((
      target,
      nodesToReplaceWith,
      options?: ReplaceNodeOptions,
    ): void => {
      pushMutation(
        createReplaceStatementWithManyMutation(
          target,
          nodesToReplaceWith,
          options,
        ),
      );
    }: TransformReplaceAPIs['replaceStatementWithMany']),
  };

  return {
    mutations,

    // $FlowExpectedError[unsafe-getters-setters]
    get astWasMutated(): boolean {
      return mutations.length > 0;
    },

    ...cloneAPIs,
    ...commentAPIs,
    ...insertAPIs,
    ...removeAPIs,
    ...replaceAPIs,
  };
}