Class: Sass::Script::Funcall
Overview
A SassScript parse node representing a function call.
A function call either calls one of the functions in Functions, or if no function with the given name exists it returns a string representation of the function call.
Instance Attribute Summary collapse
-
#args ⇒ Array<Script::Node>
readonly
The arguments to the function.
-
#keywords ⇒ {String => Script::Node}
readonly
The keyword arguments to the function.
-
#name ⇒ String
readonly
The name of the function.
-
#splat ⇒ Script::Node?
The splat argument for this function, if one exists.
Attributes inherited from Node
Instance Method Summary collapse
-
#_perform(environment) ⇒ Literal
protected
Evaluates the function call.
-
#children ⇒ Array<Node>
Returns the arguments to the function.
- #deep_copy
-
#initialize(name, args, keywords, splat) ⇒ Funcall
constructor
A new instance of Funcall.
-
#inspect ⇒ String
A string representation of the function call.
-
#to_literal(args)
protected
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. - #to_sass(opts = {})
Methods inherited from Node
Constructor Details
#initialize(name, args, keywords, splat) ⇒ Funcall
Returns a new instance of Funcall.
35 36 37 38 39 40 41 |
# File 'lib/sass/script/funcall.rb', line 35
def initialize(name, args, keywords, splat)
@name = name
@args = args
@keywords = keywords
@splat = splat
super()
end
|
Instance Attribute Details
#args ⇒ Array<Script::Node> (readonly)
The arguments to the function.
19 20 21 |
# File 'lib/sass/script/funcall.rb', line 19
def args
@args
end
|
#keywords ⇒ {String => Script::Node} (readonly)
The keyword arguments to the function.
24 25 26 |
# File 'lib/sass/script/funcall.rb', line 24
def keywords
@keywords
end
|
#name ⇒ String (readonly)
The name of the function.
14 15 16 |
# File 'lib/sass/script/funcall.rb', line 14
def name
@name
end
|
#splat ⇒ Script::Node?
The splat argument for this function, if one exists.
29 30 31 |
# File 'lib/sass/script/funcall.rb', line 29
def splat
@splat
end
|
Instance Method Details
#_perform(environment) ⇒ Literal (protected)
Evaluates the function call.
98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 |
# File 'lib/sass/script/funcall.rb', line 98
def _perform(environment)
args = @args.map {|a| a.perform(environment)}
splat = @splat.perform(environment) if @splat
if fn = environment.function(@name)
keywords = Sass::Util.map_hash(@keywords) {|k, v| [k, v.perform(environment)]}
return perform_sass_fn(fn, args, keywords, splat)
end
ruby_name = @name.tr('-', '_')
args = construct_ruby_args(ruby_name, args, splat, environment)
unless Functions.callable?(ruby_name)
opts(to_literal(args))
else
opts(Functions::EvaluationContext.new(environment.options).send(ruby_name, *args))
end
rescue ArgumentError => e
message = e.message
# If this is a legitimate Ruby-raised argument error, re-raise it.
# Otherwise, it's an error in the user's stylesheet, so wrap it.
if Sass::Util.rbx?
# Rubinius has a different error report string than vanilla Ruby. It
# also doesn't put the actual method for which the argument error was
# thrown in the backtrace, nor does it include `send`, so we look for
# `_perform`.
if e.message =~ /^method '([^']+)': given (\d+), expected (\d+)/
error_name, given, expected = $1, $2, $3
raise e if error_name != ruby_name || e.backtrace[0] !~ /:in `_perform'$/
message = "wrong number of arguments (#{given} for #{expected})"
end
elsif Sass::Util.jruby?
if Sass::Util.jruby1_6?
should_maybe_raise = e.message =~ /^wrong number of arguments \((\d+) for (\d+)\)/ &&
# The one case where JRuby does include the Ruby name of the function
# is manually-thrown ArgumentErrors, which are indistinguishable from
# legitimate ArgumentErrors. We treat both of these as
# Sass::SyntaxErrors even though it can hide Ruby errors.
e.backtrace[0] !~ /:in `(block in )?#{ruby_name}'$/
else
should_maybe_raise = e.message =~ /^wrong number of arguments calling `[^`]+` \((\d+) for (\d+)\)/
given, expected = $1, $2
end
if should_maybe_raise
# JRuby 1.7 includes __send__ before send and _perform.
trace = e.backtrace.dup
raise e if !Sass::Util.jruby1_6? && trace.shift !~ /:in `__send__'$/
# JRuby (as of 1.7.2) doesn't put the actual method
# for which the argument error was thrown in the backtrace, so we
# detect whether our send threw an argument error.
if !(trace[0] =~ /:in `send'$/ && trace[1] =~ /:in `_perform'$/)
raise e
elsif !Sass::Util.jruby1_6?
# JRuby 1.7 doesn't use standard formatting for its ArgumentErrors.
message = "wrong number of arguments (#{given} for #{expected})"
end
end
elsif e.message =~ /^wrong number of arguments \(\d+ for \d+\)/ &&
e.backtrace[0] !~ /:in `(block in )?#{ruby_name}'$/
raise e
end
raise Sass::SyntaxError.new("#{message} for `#{name}'")
end
|
#children ⇒ Array<Node>
Returns the arguments to the function.
77 78 79 80 81 |
# File 'lib/sass/script/funcall.rb', line 77
def children
res = @args + @keywords.values
res << @splat if @splat
res
end
|
#deep_copy
84 85 86 87 88 89 |
# File 'lib/sass/script/funcall.rb', line 84
def deep_copy
node = dup
node.instance_variable_set('@args', args.map {|a| a.deep_copy})
node.instance_variable_set('@keywords', Hash[keywords.map {|k, v| [k, v.deep_copy]}])
node
end
|
#inspect ⇒ String
Returns A string representation of the function call.
44 45 46 47 48 49 50 51 52 53 |
# File 'lib/sass/script/funcall.rb', line 44
def inspect
args = @args.map {|a| a.inspect}.join(', ')
keywords = Sass::Util.hash_to_a(@keywords).
map {|k, v| "$#{k}: #{v.inspect}"}.join(', ')
if self.splat
splat = (args.empty? && keywords.empty?) ? "" : ", "
splat = "#{splat}#{self.splat.inspect}..."
end
"#{name}(#{args}#{', ' unless args.empty? || keywords.empty?}#{keywords}#{splat})"
end
|
#to_literal(args) (protected)
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.
167 168 169 |
# File 'lib/sass/script/funcall.rb', line 167
def to_literal(args)
Script::String.new("#{name}(#{args.join(', ')})")
end
|
#to_sass(opts = {})
56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 |
# File 'lib/sass/script/funcall.rb', line 56
def to_sass(opts = {})
arg_to_sass = lambda do |arg|
sass = arg.to_sass(opts)
sass = "(#{sass})" if arg.is_a?(Sass::Script::List) && arg.separator == :comma
sass
end
args = @args.map(&arg_to_sass).join(', ')
keywords = Sass::Util.hash_to_a(@keywords).
map {|k, v| "$#{dasherize(k, opts)}: #{arg_to_sass[v]}"}.join(', ')
if self.splat
splat = (args.empty? && keywords.empty?) ? "" : ", "
splat = "#{splat}#{arg_to_sass[self.splat]}..."
end
"#{dasherize(name, opts)}(#{args}#{', ' unless args.empty? || keywords.empty?}#{keywords}#{splat})"
end
|