class Sass::Script::Tree::Funcall

A SassScript parse node representing a function call.

A function call either calls one of the functions in {Sass::Script::Functions}, or if no function with the given name exists it returns a string representation of the function call.

Attributes

args[R]

The arguments to the function.

@return [Array<Node>]

keywords[R]

The keyword arguments to the function.

@return [Sass::Util::NormalizedMap<Node>]

kwarg_splat[RW]

The second splat argument for this function, if one exists.

If this exists, it's always a map of keyword arguments, and {#splat} is always either a list or an arglist.

@return [Node?]

name[R]

The name of the function.

@return [String]

splat[RW]

The first splat argument for this function, if one exists.

This could be a list of positional arguments, a map of keyword arguments, or an arglist containing both.

@return [Node?]

Public Class Methods

new(name, args, keywords, splat, kwarg_splat) click to toggle source

@param name [String] See {#name} @param args [Array<Node>] See {#args} @param keywords [Sass::Util::NormalizedMap<Node>] See {#keywords} @param splat [Node] See {#splat} @param #kwarg_splat [Node] See {#kwarg_splat}

Calls superclass method
# File lib/sass/script/tree/funcall.rb, line 47
def initialize(name, args, keywords, splat, kwarg_splat)
  @name = name
  @args = args
  @keywords = keywords
  @splat = splat
  @kwarg_splat = kwarg_splat
  super()
end

Public Instance Methods

children() click to toggle source

Returns the arguments to the function.

@return [Array<Node>] @see Sass::Script::Tree::Node#children

# File lib/sass/script/tree/funcall.rb, line 98
def children
  res = @args + @keywords.values
  res << @splat if @splat
  res << @kwarg_splat if @kwarg_splat
  res
end
deep_copy() click to toggle source

@see Sass::Script::Tree::Node#deep_copy

# File lib/sass/script/tree/funcall.rb, line 106
def deep_copy
  node = dup
  node.instance_variable_set('@args', args.map {|a| a.deep_copy})
  copied_keywords = Sass::Util::NormalizedMap.new
  @keywords.as_stored.each {|k, v| copied_keywords[k] = v.deep_copy}
  node.instance_variable_set('@keywords', copied_keywords)
  node
end
inspect() click to toggle source

@return [String] A string representation of the function call

# File lib/sass/script/tree/funcall.rb, line 57
def inspect
  args = @args.map {|a| a.inspect}.join(', ')
  keywords = Sass::Util.hash_to_a(@keywords.as_stored).
      map {|k, v| "$#{k}: #{v.inspect}"}.join(', ')
  # rubocop:disable RedundantSelf
  if self.splat
    splat = args.empty? && keywords.empty? ? "" : ", "
    splat = "#{splat}#{self.splat.inspect}..."
    splat = "#{splat}, #{kwarg_splat.inspect}..." if kwarg_splat
  end
  # rubocop:enable RedundantSelf
  "#{name}(#{args}#{', ' unless args.empty? || keywords.empty?}#{keywords}#{splat})"
end
to_sass(opts = {}) click to toggle source

@see Sass::Script::Tree::Node#to_sass

# File lib/sass/script/tree/funcall.rb, line 72
def to_sass(opts = {})
  arg_to_sass = lambda do |arg|
    sass = arg.to_sass(opts)
    sass = "(#{sass})" if arg.is_a?(Sass::Script::Tree::ListLiteral) && arg.separator == :comma
    sass
  end

  args = @args.map(&arg_to_sass)
  keywords = Sass::Util.hash_to_a(@keywords.as_stored).
    map {|k, v| "$#{dasherize(k, opts)}: #{arg_to_sass[v]}"}

  # rubocop:disable RedundantSelf
  if self.splat
    splat = "#{arg_to_sass[self.splat]}..."
    kwarg_splat = "#{arg_to_sass[self.kwarg_splat]}..." if self.kwarg_splat
  end
  # rubocop:enable RedundantSelf

  arglist = [args, splat, keywords, kwarg_splat].flatten.compact.join(', ')
  "#{dasherize(name, opts)}(#{arglist})"
end

Protected Instance Methods

_perform(environment) click to toggle source

Evaluates the function call.

@param environment [Sass::Environment] The environment in which to evaluate the SassScript @return [Sass::Script::Value] The SassScript object that is the value of the function call @raise [Sass::SyntaxError] if the function call raises an ArgumentError

# File lib/sass/script/tree/funcall.rb, line 122
def _perform(environment)
  args = Sass::Util.enum_with_index(@args).
    map {|a, i| perform_arg(a, environment, signature && signature.args[i])}
  keywords = Sass::Util.map_hash(@keywords) do |k, v|
    [k, perform_arg(v, environment, k.tr('-', '_'))]
  end
  splat = Sass::Tree::Visitors::Perform.perform_splat(
    @splat, keywords, @kwarg_splat, environment)
  if (fn = environment.function(@name))
    css_variable_warning.warn! if css_variable_warning
    return without_original(perform_sass_fn(fn, args, splat, environment))
  end

  args = construct_ruby_args(ruby_name, args, splat, environment)

  if Sass::Script::Functions.callable?(ruby_name)
    css_variable_warning.warn! if css_variable_warning

    local_environment = Sass::Environment.new(environment.global_env, environment.options)
    local_environment.caller = Sass::ReadOnlyEnvironment.new(environment, environment.options)
    result = opts(Sass::Script::Functions::EvaluationContext.new(
      local_environment).send(ruby_name, *args))
    without_original(result)
  else
    opts(to_literal(args))
  end
rescue ArgumentError => e
  reformat_argument_error(e)
end
to_literal(args) click to toggle source

Compass historically overrode this before it changed name to {Funcall#to_value}. We should get rid of it in the future.

# File lib/sass/script/tree/funcall.rb, line 154
def to_literal(args)
  to_value(args)
end
to_value(args) click to toggle source

This method is factored out from `_perform` so that compass can override it with a cross-browser implementation for functions that require vendor prefixes in the generated css.

# File lib/sass/script/tree/funcall.rb, line 161
def to_value(args)
  Sass::Script::Value::String.new("#{name}(#{args.join(', ')})")
end