xass 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (242) hide show
  1. checksums.yaml +7 -0
  2. data/.yardopts +11 -0
  3. data/CONTRIBUTING +3 -0
  4. data/MIT-LICENSE +20 -0
  5. data/README.md +201 -0
  6. data/Rakefile +349 -0
  7. data/VERSION +1 -0
  8. data/VERSION_NAME +1 -0
  9. data/bin/push +13 -0
  10. data/bin/sass +13 -0
  11. data/bin/sass-convert +12 -0
  12. data/bin/scss +13 -0
  13. data/extra/update_watch.rb +13 -0
  14. data/init.rb +18 -0
  15. data/lib/sass/cache_stores/base.rb +88 -0
  16. data/lib/sass/cache_stores/chain.rb +33 -0
  17. data/lib/sass/cache_stores/filesystem.rb +64 -0
  18. data/lib/sass/cache_stores/memory.rb +47 -0
  19. data/lib/sass/cache_stores/null.rb +25 -0
  20. data/lib/sass/cache_stores.rb +15 -0
  21. data/lib/sass/callbacks.rb +66 -0
  22. data/lib/sass/css.rb +409 -0
  23. data/lib/sass/engine.rb +930 -0
  24. data/lib/sass/environment.rb +101 -0
  25. data/lib/sass/error.rb +201 -0
  26. data/lib/sass/exec.rb +707 -0
  27. data/lib/sass/importers/base.rb +139 -0
  28. data/lib/sass/importers/filesystem.rb +186 -0
  29. data/lib/sass/importers.rb +22 -0
  30. data/lib/sass/logger/base.rb +32 -0
  31. data/lib/sass/logger/log_level.rb +49 -0
  32. data/lib/sass/logger.rb +15 -0
  33. data/lib/sass/media.rb +213 -0
  34. data/lib/sass/plugin/compiler.rb +406 -0
  35. data/lib/sass/plugin/configuration.rb +123 -0
  36. data/lib/sass/plugin/generic.rb +15 -0
  37. data/lib/sass/plugin/merb.rb +48 -0
  38. data/lib/sass/plugin/rack.rb +60 -0
  39. data/lib/sass/plugin/rails.rb +47 -0
  40. data/lib/sass/plugin/staleness_checker.rb +199 -0
  41. data/lib/sass/plugin.rb +133 -0
  42. data/lib/sass/railtie.rb +10 -0
  43. data/lib/sass/repl.rb +57 -0
  44. data/lib/sass/root.rb +7 -0
  45. data/lib/sass/script/arg_list.rb +52 -0
  46. data/lib/sass/script/bool.rb +18 -0
  47. data/lib/sass/script/color.rb +606 -0
  48. data/lib/sass/script/css_lexer.rb +29 -0
  49. data/lib/sass/script/css_parser.rb +31 -0
  50. data/lib/sass/script/funcall.rb +245 -0
  51. data/lib/sass/script/functions.rb +1543 -0
  52. data/lib/sass/script/interpolation.rb +79 -0
  53. data/lib/sass/script/lexer.rb +345 -0
  54. data/lib/sass/script/list.rb +85 -0
  55. data/lib/sass/script/literal.rb +221 -0
  56. data/lib/sass/script/node.rb +99 -0
  57. data/lib/sass/script/null.rb +37 -0
  58. data/lib/sass/script/number.rb +453 -0
  59. data/lib/sass/script/operation.rb +110 -0
  60. data/lib/sass/script/parser.rb +502 -0
  61. data/lib/sass/script/string.rb +51 -0
  62. data/lib/sass/script/string_interpolation.rb +103 -0
  63. data/lib/sass/script/unary_operation.rb +69 -0
  64. data/lib/sass/script/variable.rb +58 -0
  65. data/lib/sass/script.rb +39 -0
  66. data/lib/sass/scss/css_parser.rb +36 -0
  67. data/lib/sass/scss/parser.rb +1180 -0
  68. data/lib/sass/scss/rx.rb +133 -0
  69. data/lib/sass/scss/script_lexer.rb +15 -0
  70. data/lib/sass/scss/script_parser.rb +25 -0
  71. data/lib/sass/scss/static_parser.rb +54 -0
  72. data/lib/sass/scss.rb +16 -0
  73. data/lib/sass/selector/abstract_sequence.rb +94 -0
  74. data/lib/sass/selector/comma_sequence.rb +92 -0
  75. data/lib/sass/selector/sequence.rb +507 -0
  76. data/lib/sass/selector/simple.rb +119 -0
  77. data/lib/sass/selector/simple_sequence.rb +215 -0
  78. data/lib/sass/selector.rb +452 -0
  79. data/lib/sass/shared.rb +76 -0
  80. data/lib/sass/supports.rb +229 -0
  81. data/lib/sass/tree/charset_node.rb +22 -0
  82. data/lib/sass/tree/comment_node.rb +82 -0
  83. data/lib/sass/tree/content_node.rb +9 -0
  84. data/lib/sass/tree/css_import_node.rb +60 -0
  85. data/lib/sass/tree/debug_node.rb +18 -0
  86. data/lib/sass/tree/directive_node.rb +42 -0
  87. data/lib/sass/tree/each_node.rb +24 -0
  88. data/lib/sass/tree/extend_node.rb +36 -0
  89. data/lib/sass/tree/for_node.rb +36 -0
  90. data/lib/sass/tree/function_node.rb +34 -0
  91. data/lib/sass/tree/if_node.rb +52 -0
  92. data/lib/sass/tree/import_node.rb +75 -0
  93. data/lib/sass/tree/media_node.rb +58 -0
  94. data/lib/sass/tree/mixin_def_node.rb +38 -0
  95. data/lib/sass/tree/mixin_node.rb +39 -0
  96. data/lib/sass/tree/node.rb +196 -0
  97. data/lib/sass/tree/prop_node.rb +152 -0
  98. data/lib/sass/tree/return_node.rb +18 -0
  99. data/lib/sass/tree/root_node.rb +78 -0
  100. data/lib/sass/tree/rule_node.rb +132 -0
  101. data/lib/sass/tree/supports_node.rb +51 -0
  102. data/lib/sass/tree/trace_node.rb +32 -0
  103. data/lib/sass/tree/variable_node.rb +30 -0
  104. data/lib/sass/tree/visitors/base.rb +75 -0
  105. data/lib/sass/tree/visitors/check_nesting.rb +147 -0
  106. data/lib/sass/tree/visitors/convert.rb +316 -0
  107. data/lib/sass/tree/visitors/cssize.rb +241 -0
  108. data/lib/sass/tree/visitors/deep_copy.rb +102 -0
  109. data/lib/sass/tree/visitors/extend.rb +68 -0
  110. data/lib/sass/tree/visitors/perform.rb +446 -0
  111. data/lib/sass/tree/visitors/set_options.rb +125 -0
  112. data/lib/sass/tree/visitors/to_css.rb +228 -0
  113. data/lib/sass/tree/warn_node.rb +18 -0
  114. data/lib/sass/tree/while_node.rb +18 -0
  115. data/lib/sass/util/multibyte_string_scanner.rb +155 -0
  116. data/lib/sass/util/subset_map.rb +109 -0
  117. data/lib/sass/util/test.rb +10 -0
  118. data/lib/sass/util.rb +948 -0
  119. data/lib/sass/version.rb +126 -0
  120. data/lib/sass.rb +95 -0
  121. data/rails/init.rb +1 -0
  122. data/test/Gemfile +3 -0
  123. data/test/Gemfile.lock +10 -0
  124. data/test/sass/cache_test.rb +89 -0
  125. data/test/sass/callbacks_test.rb +61 -0
  126. data/test/sass/conversion_test.rb +1760 -0
  127. data/test/sass/css2sass_test.rb +458 -0
  128. data/test/sass/data/hsl-rgb.txt +319 -0
  129. data/test/sass/engine_test.rb +3244 -0
  130. data/test/sass/exec_test.rb +86 -0
  131. data/test/sass/extend_test.rb +1482 -0
  132. data/test/sass/fixtures/test_staleness_check_across_importers.css +1 -0
  133. data/test/sass/fixtures/test_staleness_check_across_importers.scss +1 -0
  134. data/test/sass/functions_test.rb +1139 -0
  135. data/test/sass/importer_test.rb +192 -0
  136. data/test/sass/logger_test.rb +58 -0
  137. data/test/sass/mock_importer.rb +49 -0
  138. data/test/sass/more_results/more1.css +9 -0
  139. data/test/sass/more_results/more1_with_line_comments.css +26 -0
  140. data/test/sass/more_results/more_import.css +29 -0
  141. data/test/sass/more_templates/_more_partial.sass +2 -0
  142. data/test/sass/more_templates/more1.sass +23 -0
  143. data/test/sass/more_templates/more_import.sass +11 -0
  144. data/test/sass/plugin_test.rb +564 -0
  145. data/test/sass/results/alt.css +4 -0
  146. data/test/sass/results/basic.css +9 -0
  147. data/test/sass/results/cached_import_option.css +3 -0
  148. data/test/sass/results/compact.css +5 -0
  149. data/test/sass/results/complex.css +86 -0
  150. data/test/sass/results/compressed.css +1 -0
  151. data/test/sass/results/expanded.css +19 -0
  152. data/test/sass/results/filename_fn.css +3 -0
  153. data/test/sass/results/if.css +3 -0
  154. data/test/sass/results/import.css +31 -0
  155. data/test/sass/results/import_charset.css +5 -0
  156. data/test/sass/results/import_charset_1_8.css +5 -0
  157. data/test/sass/results/import_charset_ibm866.css +5 -0
  158. data/test/sass/results/import_content.css +1 -0
  159. data/test/sass/results/line_numbers.css +49 -0
  160. data/test/sass/results/mixins.css +95 -0
  161. data/test/sass/results/multiline.css +24 -0
  162. data/test/sass/results/nested.css +22 -0
  163. data/test/sass/results/options.css +1 -0
  164. data/test/sass/results/parent_ref.css +13 -0
  165. data/test/sass/results/script.css +16 -0
  166. data/test/sass/results/scss_import.css +31 -0
  167. data/test/sass/results/scss_importee.css +2 -0
  168. data/test/sass/results/subdir/nested_subdir/nested_subdir.css +1 -0
  169. data/test/sass/results/subdir/subdir.css +3 -0
  170. data/test/sass/results/units.css +11 -0
  171. data/test/sass/results/warn.css +0 -0
  172. data/test/sass/results/warn_imported.css +0 -0
  173. data/test/sass/script_conversion_test.rb +299 -0
  174. data/test/sass/script_test.rb +622 -0
  175. data/test/sass/scss/css_test.rb +1100 -0
  176. data/test/sass/scss/rx_test.rb +156 -0
  177. data/test/sass/scss/scss_test.rb +2106 -0
  178. data/test/sass/scss/test_helper.rb +37 -0
  179. data/test/sass/templates/_cached_import_option_partial.scss +1 -0
  180. data/test/sass/templates/_double_import_loop2.sass +1 -0
  181. data/test/sass/templates/_filename_fn_import.scss +11 -0
  182. data/test/sass/templates/_imported_charset_ibm866.sass +4 -0
  183. data/test/sass/templates/_imported_charset_utf8.sass +4 -0
  184. data/test/sass/templates/_imported_content.sass +3 -0
  185. data/test/sass/templates/_partial.sass +2 -0
  186. data/test/sass/templates/_same_name_different_partiality.scss +1 -0
  187. data/test/sass/templates/alt.sass +16 -0
  188. data/test/sass/templates/basic.sass +23 -0
  189. data/test/sass/templates/bork1.sass +2 -0
  190. data/test/sass/templates/bork2.sass +2 -0
  191. data/test/sass/templates/bork3.sass +2 -0
  192. data/test/sass/templates/bork4.sass +2 -0
  193. data/test/sass/templates/bork5.sass +3 -0
  194. data/test/sass/templates/cached_import_option.scss +3 -0
  195. data/test/sass/templates/compact.sass +17 -0
  196. data/test/sass/templates/complex.sass +305 -0
  197. data/test/sass/templates/compressed.sass +15 -0
  198. data/test/sass/templates/double_import_loop1.sass +1 -0
  199. data/test/sass/templates/expanded.sass +17 -0
  200. data/test/sass/templates/filename_fn.scss +18 -0
  201. data/test/sass/templates/if.sass +11 -0
  202. data/test/sass/templates/import.sass +12 -0
  203. data/test/sass/templates/import_charset.sass +9 -0
  204. data/test/sass/templates/import_charset_1_8.sass +6 -0
  205. data/test/sass/templates/import_charset_ibm866.sass +11 -0
  206. data/test/sass/templates/import_content.sass +4 -0
  207. data/test/sass/templates/importee.less +2 -0
  208. data/test/sass/templates/importee.sass +19 -0
  209. data/test/sass/templates/line_numbers.sass +13 -0
  210. data/test/sass/templates/mixin_bork.sass +5 -0
  211. data/test/sass/templates/mixins.sass +76 -0
  212. data/test/sass/templates/multiline.sass +20 -0
  213. data/test/sass/templates/nested.sass +25 -0
  214. data/test/sass/templates/nested_bork1.sass +2 -0
  215. data/test/sass/templates/nested_bork2.sass +2 -0
  216. data/test/sass/templates/nested_bork3.sass +2 -0
  217. data/test/sass/templates/nested_bork4.sass +2 -0
  218. data/test/sass/templates/nested_import.sass +2 -0
  219. data/test/sass/templates/nested_mixin_bork.sass +6 -0
  220. data/test/sass/templates/options.sass +2 -0
  221. data/test/sass/templates/parent_ref.sass +25 -0
  222. data/test/sass/templates/same_name_different_ext.sass +2 -0
  223. data/test/sass/templates/same_name_different_ext.scss +1 -0
  224. data/test/sass/templates/same_name_different_partiality.scss +1 -0
  225. data/test/sass/templates/script.sass +101 -0
  226. data/test/sass/templates/scss_import.scss +11 -0
  227. data/test/sass/templates/scss_importee.scss +1 -0
  228. data/test/sass/templates/single_import_loop.sass +1 -0
  229. data/test/sass/templates/subdir/import_up1.scss +1 -0
  230. data/test/sass/templates/subdir/import_up2.scss +1 -0
  231. data/test/sass/templates/subdir/nested_subdir/_nested_partial.sass +2 -0
  232. data/test/sass/templates/subdir/nested_subdir/nested_subdir.sass +3 -0
  233. data/test/sass/templates/subdir/subdir.sass +6 -0
  234. data/test/sass/templates/units.sass +11 -0
  235. data/test/sass/templates/warn.sass +3 -0
  236. data/test/sass/templates/warn_imported.sass +4 -0
  237. data/test/sass/test_helper.rb +8 -0
  238. data/test/sass/util/multibyte_string_scanner_test.rb +147 -0
  239. data/test/sass/util/subset_map_test.rb +91 -0
  240. data/test/sass/util_test.rb +382 -0
  241. data/test/test_helper.rb +80 -0
  242. metadata +354 -0
@@ -0,0 +1,245 @@
1
+ require 'sass/script/functions'
2
+
3
+ module Sass
4
+ module Script
5
+ # A SassScript parse node representing a function call.
6
+ #
7
+ # A function call either calls one of the functions in {Script::Functions},
8
+ # or if no function with the given name exists
9
+ # it returns a string representation of the function call.
10
+ class Funcall < Node
11
+ # The name of the function.
12
+ #
13
+ # @return [String]
14
+ attr_reader :name
15
+
16
+ # The arguments to the function.
17
+ #
18
+ # @return [Array<Script::Node>]
19
+ attr_reader :args
20
+
21
+ # The keyword arguments to the function.
22
+ #
23
+ # @return [{String => Script::Node}]
24
+ attr_reader :keywords
25
+
26
+ # The splat argument for this function, if one exists.
27
+ #
28
+ # @return [Script::Node?]
29
+ attr_accessor :splat
30
+
31
+ # @param name [String] See \{#name}
32
+ # @param args [Array<Script::Node>] See \{#args}
33
+ # @param splat [Script::Node] See \{#splat}
34
+ # @param keywords [{String => Script::Node}] See \{#keywords}
35
+ def initialize(name, args, keywords, splat)
36
+ @name = name
37
+ @args = args
38
+ @keywords = keywords
39
+ @splat = splat
40
+ super()
41
+ end
42
+
43
+ # @return [String] A string representation of the function call
44
+ def inspect
45
+ args = @args.map {|a| a.inspect}.join(', ')
46
+ keywords = Sass::Util.hash_to_a(@keywords).
47
+ map {|k, v| "$#{k}: #{v.inspect}"}.join(', ')
48
+ if self.splat
49
+ splat = (args.empty? && keywords.empty?) ? "" : ", "
50
+ splat = "#{splat}#{self.splat.inspect}..."
51
+ end
52
+ "#{name}(#{args}#{', ' unless args.empty? || keywords.empty?}#{keywords}#{splat})"
53
+ end
54
+
55
+ # @see Node#to_sass
56
+ def to_sass(opts = {})
57
+ arg_to_sass = lambda do |arg|
58
+ sass = arg.to_sass(opts)
59
+ sass = "(#{sass})" if arg.is_a?(Sass::Script::List) && arg.separator == :comma
60
+ sass
61
+ end
62
+
63
+ args = @args.map(&arg_to_sass).join(', ')
64
+ keywords = Sass::Util.hash_to_a(@keywords).
65
+ map {|k, v| "$#{dasherize(k, opts)}: #{arg_to_sass[v]}"}.join(', ')
66
+ if self.splat
67
+ splat = (args.empty? && keywords.empty?) ? "" : ", "
68
+ splat = "#{splat}#{arg_to_sass[self.splat]}..."
69
+ end
70
+ "#{dasherize(name, opts)}(#{args}#{', ' unless args.empty? || keywords.empty?}#{keywords}#{splat})"
71
+ end
72
+
73
+ # Returns the arguments to the function.
74
+ #
75
+ # @return [Array<Node>]
76
+ # @see Node#children
77
+ def children
78
+ res = @args + @keywords.values
79
+ res << @splat if @splat
80
+ res
81
+ end
82
+
83
+ # @see Node#deep_copy
84
+ def deep_copy
85
+ node = dup
86
+ node.instance_variable_set('@args', args.map {|a| a.deep_copy})
87
+ node.instance_variable_set('@keywords', Hash[keywords.map {|k, v| [k, v.deep_copy]}])
88
+ node
89
+ end
90
+
91
+ protected
92
+
93
+ # Evaluates the function call.
94
+ #
95
+ # @param environment [Sass::Environment] The environment in which to evaluate the SassScript
96
+ # @return [Literal] The SassScript object that is the value of the function call
97
+ # @raise [Sass::SyntaxError] if the function call raises an ArgumentError
98
+ def _perform(environment)
99
+ args = @args.map {|a| a.perform(environment)}
100
+ splat = @splat.perform(environment) if @splat
101
+ if fn = environment.function(@name)
102
+ keywords = Sass::Util.map_hash(@keywords) {|k, v| [k, v.perform(environment)]}
103
+ return without_original(perform_sass_fn(fn, args, keywords, splat))
104
+ end
105
+
106
+ ruby_name = @name.tr('-', '_')
107
+ args = construct_ruby_args(ruby_name, args, splat, environment)
108
+
109
+ unless Functions.callable?(ruby_name)
110
+ without_original(opts(to_literal(args)))
111
+ else
112
+ without_original(opts(Functions::EvaluationContext.new(environment.options).
113
+ send(ruby_name, *args)))
114
+ end
115
+ rescue ArgumentError => e
116
+ message = e.message
117
+
118
+ # If this is a legitimate Ruby-raised argument error, re-raise it.
119
+ # Otherwise, it's an error in the user's stylesheet, so wrap it.
120
+ if Sass::Util.rbx?
121
+ # Rubinius has a different error report string than vanilla Ruby. It
122
+ # also doesn't put the actual method for which the argument error was
123
+ # thrown in the backtrace, nor does it include `send`, so we look for
124
+ # `_perform`.
125
+ if e.message =~ /^method '([^']+)': given (\d+), expected (\d+)/
126
+ error_name, given, expected = $1, $2, $3
127
+ raise e if error_name != ruby_name || e.backtrace[0] !~ /:in `_perform'$/
128
+ message = "wrong number of arguments (#{given} for #{expected})"
129
+ end
130
+ elsif Sass::Util.jruby?
131
+ if Sass::Util.jruby1_6?
132
+ should_maybe_raise = e.message =~ /^wrong number of arguments \((\d+) for (\d+)\)/ &&
133
+ # The one case where JRuby does include the Ruby name of the function
134
+ # is manually-thrown ArgumentErrors, which are indistinguishable from
135
+ # legitimate ArgumentErrors. We treat both of these as
136
+ # Sass::SyntaxErrors even though it can hide Ruby errors.
137
+ e.backtrace[0] !~ /:in `(block in )?#{ruby_name}'$/
138
+ else
139
+ should_maybe_raise = e.message =~ /^wrong number of arguments calling `[^`]+` \((\d+) for (\d+)\)/
140
+ given, expected = $1, $2
141
+ end
142
+
143
+ if should_maybe_raise
144
+ # JRuby 1.7 includes __send__ before send and _perform.
145
+ trace = e.backtrace.dup
146
+ raise e if !Sass::Util.jruby1_6? && trace.shift !~ /:in `__send__'$/
147
+
148
+ # JRuby (as of 1.7.2) doesn't put the actual method
149
+ # for which the argument error was thrown in the backtrace, so we
150
+ # detect whether our send threw an argument error.
151
+ if !(trace[0] =~ /:in `send'$/ && trace[1] =~ /:in `_perform'$/)
152
+ raise e
153
+ elsif !Sass::Util.jruby1_6?
154
+ # JRuby 1.7 doesn't use standard formatting for its ArgumentErrors.
155
+ message = "wrong number of arguments (#{given} for #{expected})"
156
+ end
157
+ end
158
+ elsif e.message =~ /^wrong number of arguments \(\d+ for \d+\)/ &&
159
+ e.backtrace[0] !~ /:in `(block in )?#{ruby_name}'$/
160
+ raise e
161
+ end
162
+ raise Sass::SyntaxError.new("#{message} for `#{name}'")
163
+ end
164
+
165
+ # This method is factored out from `_perform` so that compass can override
166
+ # it with a cross-browser implementation for functions that require vendor prefixes
167
+ # in the generated css.
168
+ def to_literal(args)
169
+ Script::String.new("#{name}(#{args.join(', ')})")
170
+ end
171
+
172
+ private
173
+
174
+ def without_original(value)
175
+ return value unless value.is_a?(Number)
176
+ value = value.dup
177
+ value.original = nil
178
+ return value
179
+ end
180
+
181
+ def construct_ruby_args(name, args, splat, environment)
182
+ args += splat.to_a if splat
183
+
184
+ # If variable arguments were passed, there won't be any explicit keywords.
185
+ if splat.is_a?(Sass::Script::ArgList)
186
+ kwargs_size = splat.keywords.size
187
+ splat.keywords_accessed = false
188
+ else
189
+ kwargs_size = @keywords.size
190
+ end
191
+
192
+ unless signature = Functions.signature(name.to_sym, args.size, kwargs_size)
193
+ return args if @keywords.empty?
194
+ raise Sass::SyntaxError.new("Function #{name} doesn't support keyword arguments")
195
+ end
196
+ keywords = splat.is_a?(Sass::Script::ArgList) ? splat.keywords :
197
+ Sass::Util.map_hash(@keywords) {|k, v| [k, v.perform(environment)]}
198
+
199
+ # If the user passes more non-keyword args than the function expects,
200
+ # but it does expect keyword args, Ruby's arg handling won't raise an error.
201
+ # Since we don't want to make functions think about this,
202
+ # we'll handle it for them here.
203
+ if signature.var_kwargs && !signature.var_args && args.size > signature.args.size
204
+ raise Sass::SyntaxError.new(
205
+ "#{args[signature.args.size].inspect} is not a keyword argument for `#{name}'")
206
+ elsif keywords.empty?
207
+ return args
208
+ end
209
+
210
+ args = args + signature.args[args.size..-1].map do |argname|
211
+ if keywords.has_key?(argname)
212
+ keywords.delete(argname)
213
+ else
214
+ raise Sass::SyntaxError.new("Function #{name} requires an argument named $#{argname}")
215
+ end
216
+ end
217
+
218
+ if keywords.size > 0
219
+ if signature.var_kwargs
220
+ args << keywords
221
+ else
222
+ argname = keywords.keys.sort.first
223
+ if signature.args.include?(argname)
224
+ raise Sass::SyntaxError.new("Function #{name} was passed argument $#{argname} both by position and by name")
225
+ else
226
+ raise Sass::SyntaxError.new("Function #{name} doesn't have an argument named $#{argname}")
227
+ end
228
+ end
229
+ end
230
+
231
+ args
232
+ end
233
+
234
+ def perform_sass_fn(function, args, keywords, splat)
235
+ Sass::Tree::Visitors::Perform.perform_arguments(function, args, keywords, splat) do |env|
236
+ val = catch :_sass_return do
237
+ function.tree.each {|c| Sass::Tree::Visitors::Perform.visit(c, env)}
238
+ raise Sass::SyntaxError.new("Function #{@name} finished without @return")
239
+ end
240
+ val
241
+ end
242
+ end
243
+ end
244
+ end
245
+ end