def self.perform_arguments(callable, args, keywords, splat)
desc = "#{callable.type.capitalize} #{callable.name}"
downcase_desc = "#{callable.type} #{callable.name}"
begin
unless keywords.empty?
unknown_args = Sass::Util.array_minus(keywords.keys,
callable.args.map {|var| var.first.underscored_name})
if callable.splat && unknown_args.include?(callable.splat.underscored_name)
raise Sass::SyntaxError.new("Argument $#{callable.splat.name} of #{downcase_desc} cannot be used as a named argument.")
elsif unknown_args.any?
description = unknown_args.length > 1 ? 'the following arguments:' : 'an argument named'
raise Sass::SyntaxError.new("#{desc} doesn't have #{description} #{unknown_args.map {|name| "$#{name}"}.join ', '}.")
end
end
rescue Sass::SyntaxError => keyword_exception
end
return if keyword_exception && !callable.splat
if args.size > callable.args.size && !callable.splat
takes = callable.args.size
passed = args.size
raise Sass::SyntaxError.new(
"#{desc} takes #{takes} argument#{'s' unless takes == 1} " +
"but #{passed} #{passed == 1 ? 'was' : 'were'} passed.")
end
splat_sep = :comma
if splat
args += splat.to_a
splat_sep = splat.separator if splat.is_a?(Sass::Script::List)
keywords = splat.keywords if splat.is_a?(Sass::Script::ArgList)
end
keywords = keywords.dup
env = Sass::Environment.new(callable.environment)
callable.args.zip(args[0...callable.args.length]) do |(var, default), value|
if value && keywords.include?(var.underscored_name)
raise Sass::SyntaxError.new("#{desc} was passed argument $#{var.name} both by position and by name.")
end
value ||= keywords.delete(var.underscored_name)
value ||= default && default.perform(env)
raise Sass::SyntaxError.new("#{desc} is missing argument #{var.inspect}.") unless value
env.set_local_var(var.name, value)
end
if callable.splat
rest = args[callable.args.length..-1]
arg_list = Sass::Script::ArgList.new(rest, keywords.dup, splat_sep)
arg_list.options = env.options
env.set_local_var(callable.splat.name, arg_list)
end
yield env
rescue Exception => e
ensure
if keyword_exception &&
!(arg_list && arg_list.keywords_accessed) &&
(e.nil? || e.is_a?(Sass::SyntaxError))
raise keyword_exception
elsif e
raise e
end
end