Class: SyntaxTree::CallNode

Inherits:
Node
  • Object
show all
Defined in:
lib/syntax_tree/node.rb

Overview

CallNode represents a method call.

receiver.message

Instance Attribute Summary collapse

Attributes inherited from Node

#location

Instance Method Summary collapse

Methods inherited from Node

#construct_keys, #pretty_print, #to_json

Constructor Details

#initialize(receiver:, operator:, message:, arguments:, location:) ⇒ CallNode

Returns a new instance of CallNode.



2931
2932
2933
2934
2935
2936
2937
2938
# File 'lib/syntax_tree/node.rb', line 2931

def initialize(receiver:, operator:, message:, arguments:, location:)
  @receiver = receiver
  @operator = operator
  @message = message
  @arguments = arguments
  @location = location
  @comments = []
end

Instance Attribute Details

#argumentsObject (readonly)

nil | ArgParen | Args

the arguments to the method call



2926
2927
2928
# File 'lib/syntax_tree/node.rb', line 2926

def arguments
  @arguments
end

#commentsObject (readonly)

Array[ Comment | EmbDoc ]

the comments attached to this node



2929
2930
2931
# File 'lib/syntax_tree/node.rb', line 2929

def comments
  @comments
end

#messageObject (readonly)

:call | Backtick | Const | Ident | Op

the message being sent



2923
2924
2925
# File 'lib/syntax_tree/node.rb', line 2923

def message
  @message
end

#operatorObject (readonly)

nil | :“::” | Op | Period

the operator being used to send the message



2920
2921
2922
# File 'lib/syntax_tree/node.rb', line 2920

def operator
  @operator
end

#receiverObject (readonly)

nil | untyped

the receiver of the method call



2917
2918
2919
# File 'lib/syntax_tree/node.rb', line 2917

def receiver
  @receiver
end

Instance Method Details

#===(other) ⇒ Object



3017
3018
3019
3020
3021
# File 'lib/syntax_tree/node.rb', line 3017

def ===(other)
  other.is_a?(CallNode) && receiver === other.receiver &&
    operator === other.operator && message === other.message &&
    arguments === other.arguments
end

#accept(visitor) ⇒ Object



2940
2941
2942
# File 'lib/syntax_tree/node.rb', line 2940

def accept(visitor)
  visitor.visit_call(self)
end

#child_nodesObject Also known as: deconstruct



2944
2945
2946
2947
2948
2949
2950
2951
# File 'lib/syntax_tree/node.rb', line 2944

def child_nodes
  [
    receiver,
    (operator if operator != :"::"),
    (message if message != :call),
    arguments
  ]
end

#copy(receiver: nil, operator: nil, message: nil, arguments: nil, location: nil) ⇒ Object



2953
2954
2955
2956
2957
2958
2959
2960
2961
2962
2963
2964
2965
2966
2967
2968
2969
2970
2971
# File 'lib/syntax_tree/node.rb', line 2953

def copy(
  receiver: nil,
  operator: nil,
  message: nil,
  arguments: nil,
  location: nil
)
  node =
    CallNode.new(
      receiver: receiver || self.receiver,
      operator: operator || self.operator,
      message: message || self.message,
      arguments: arguments || self.arguments,
      location: location || self.location
    )

  node.comments.concat(comments.map(&:copy))
  node
end

#deconstruct_keys(_keys) ⇒ Object



2975
2976
2977
2978
2979
2980
2981
2982
2983
2984
# File 'lib/syntax_tree/node.rb', line 2975

def deconstruct_keys(_keys)
  {
    receiver: receiver,
    operator: operator,
    message: message,
    arguments: arguments,
    location: location,
    comments: comments
  }
end

#format(q) ⇒ Object



2986
2987
2988
2989
2990
2991
2992
2993
2994
2995
2996
2997
2998
2999
3000
3001
3002
3003
3004
3005
3006
3007
3008
3009
3010
3011
3012
3013
3014
3015
# File 'lib/syntax_tree/node.rb', line 2986

def format(q)
  if receiver
    # If we're at the top of a call chain, then we're going to do some
    # specialized printing in case we can print it nicely. We _only_ do this
    # at the top of the chain to avoid weird recursion issues.
    if CallChainFormatter.chained?(receiver) &&
         !CallChainFormatter.chained?(q.parent)
      q.group do
        q
          .if_break { CallChainFormatter.new(self).format(q) }
          .if_flat { format_contents(q) }
      end
    else
      format_contents(q)
    end
  else
    q.format(message)

    if arguments.is_a?(ArgParen) && arguments.arguments.nil? &&
         !message.is_a?(Const)
      # If you're using an explicit set of parentheses on something that
      # looks like a constant, then we need to match that in order to
      # maintain valid Ruby. For example, you could do something like Foo(),
      # on which we would need to keep the parentheses to make it look like
      # a method call.
    else
      q.format(arguments)
    end
  end
end

#format_arguments(q) ⇒ Object

Print out the arguments to this call. If there are no arguments, then do nothing.



3025
3026
3027
3028
3029
3030
3031
3032
3033
# File 'lib/syntax_tree/node.rb', line 3025

def format_arguments(q)
  case arguments
  when ArgParen
    q.format(arguments)
  when Args
    q.text(" ")
    q.format(arguments)
  end
end

#format_contents(q) ⇒ Object



3035
3036
3037
3038
3039
3040
3041
3042
3043
3044
3045
3046
3047
3048
3049
3050
3051
3052
3053
3054
3055
3056
3057
3058
3059
3060
3061
# File 'lib/syntax_tree/node.rb', line 3035

def format_contents(q)
  call_operator = CallOperatorFormatter.new(operator)

  q.group do
    q.format(receiver)

    # If there are trailing comments on the call operator, then we need to
    # use the trailing form as opposed to the leading form.
    q.format(call_operator) if call_operator.comments.any?

    q.group do
      q.indent do
        if receiver.comments.any? || call_operator.comments.any?
          q.breakable_force
        end

        if call_operator.comments.empty?
          q.format(call_operator, stackable: false)
        end

        q.format(message) if message != :call
      end

      format_arguments(q)
    end
  end
end