import NodePatcher from './NodePatcher';

export default class FunctionApplicationPatcher extends NodePatcher {
  constructor(node, context, editor, fn, args) {
    super(node, context, editor);
    this.fn = fn;
    this.args = args;
    fn.setRequiresExpression();
    args.forEach(arg => arg.setRequiresExpression());
  }

  patch() {
    let { fn, args } = this;
    let implicitCall = this.isImplicitCall();
    fn.patch();
    if (implicitCall) {
      this.overwrite(fn.after, args[0].before, '(');
    }
    args.forEach(arg => arg.patch());
    if (implicitCall) {
      this.insertAfter(')');
    }
  }

  isImplicitCall() {
    return !this.fn.hasTokenAfter('CALL_START');
  }
}

import NodePatcher from './NodePatcher';
import type { Editor, Node, ParseContext } from './types';

export default class FunctionApplicationPatcher extends NodePatcher {
  constructor(node: Node, context: ParseContext, editor: Editor, fn: NodePatcher, args: Array<NodePatcher>) {
    super(node, context, editor);
    this.fn = fn;
    this.args = args;
  }

  initialize() {
    this.fn.setRequiresExpression();
    this.args.forEach(arg => arg.setRequiresExpression());
  }

  patch() {
    let implicitCall = this.isImplicitCall();
    this.fn.patch();
    if (implicitCall) {
      this.overwrite(this.fn.after, this.args[0].before, '(');
    }
    this.args.forEach(arg => arg.patch());
    if (implicitCall) {
      this.insertAfter(')');
    }
  }

  isImplicitCall() {
    return !this.fn.hasTokenAfter('CALL_START');
  }
}

Clean up `FunctionApplicationPatcher`.