haml 2.2.0 → 2.2.1

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of haml might be problematic. Click here for more details.

data/VERSION CHANGED
@@ -1 +1 @@
1
- 2.2.0
1
+ 2.2.1
@@ -204,13 +204,13 @@ END
204
204
  when ELEMENT; render_tag(text)
205
205
  when COMMENT; render_comment(text[1..-1].strip)
206
206
  when SANITIZE
207
- return push_script(unescape_interpolation(text[3..-1].strip), :escape_html => true) if text[1..2] == "=="
207
+ return push_plain(text[3..-1].strip, :escape_html => true) if text[1..2] == "=="
208
208
  return push_script(text[2..-1].strip, :escape_html => true) if text[1] == SCRIPT
209
- return push_script(unescape_interpolation(text[1..-1].strip), :escape_html => true) if text[1] == ?\s
209
+ return push_flat_script(text[2..-1].strip, :escape_html => true) if text[1] == FLAT_SCRIPT
210
+ return push_plain(text[1..-1].strip, :escape_html => true) if text[1] == ?\s
210
211
  push_plain text
211
212
  when SCRIPT
212
- return push_script(unescape_interpolation(text[2..-1].strip)) if text[1] == SCRIPT
213
- return push_script(text[1..-1], :escape_html => true) if options[:escape_html]
213
+ return push_plain(text[2..-1].strip) if text[1] == SCRIPT
214
214
  push_script(text[1..-1])
215
215
  when FLAT_SCRIPT; push_flat_script(text[1..-1])
216
216
  when SILENT_SCRIPT
@@ -237,9 +237,10 @@ END
237
237
  when FILTER; start_filtered(text[1..-1].downcase)
238
238
  when DOCTYPE
239
239
  return render_doctype(text) if text[0...3] == '!!!'
240
- return push_script(unescape_interpolation(text[3..-1].strip)) if text[1..2] == "=="
241
- return push_script(text[2..-1].strip) if text[1] == SCRIPT
242
- return push_script(unescape_interpolation(text[1..-1].strip)) if text[1] == ?\s
240
+ return push_plain(text[3..-1].strip, :escape_html => false) if text[1..2] == "=="
241
+ return push_script(text[2..-1].strip, :escape_html => false) if text[1] == SCRIPT
242
+ return push_flat_script(text[2..-1].strip, :escape_html => false) if text[1] == FLAT_SCRIPT
243
+ return push_plain(text[1..-1].strip, :escape_html => false) if text[1] == ?\s
243
244
  push_plain text
244
245
  when ESCAPE; push_plain text[1..-1]
245
246
  else push_plain text
@@ -306,13 +307,13 @@ END
306
307
 
307
308
  # Renders a block of text as plain text.
308
309
  # Also checks for an illegally opened block.
309
- def push_plain(text)
310
+ def push_plain(text, options = {})
310
311
  if block_opened?
311
312
  raise SyntaxError.new("Illegal nesting: nesting within plain text is illegal.", @next_line.index)
312
313
  end
313
314
 
314
315
  if contains_interpolation?(text)
315
- push_script unescape_interpolation(text)
316
+ push_script unescape_interpolation(text), :escape_html => options[:escape_html]
316
317
  else
317
318
  push_text text
318
319
  end
@@ -333,6 +334,7 @@ END
333
334
  def push_script(text, opts = {})
334
335
  raise SyntaxError.new("There's no Ruby code for = to evaluate.") if text.empty?
335
336
  return if options[:suppress_eval]
337
+ opts[:escape_html] = options[:escape_html] if opts[:escape_html].nil?
336
338
 
337
339
  args = %w[preserve_script in_tag preserve_tag escape_html nuke_inner_whitespace]
338
340
  args.map! {|name| opts[name.to_sym]}
@@ -363,11 +365,11 @@ END
363
365
 
364
366
  # Causes <tt>text</tt> to be evaluated, and Haml::Helpers#find_and_flatten
365
367
  # to be run on it afterwards.
366
- def push_flat_script(text)
368
+ def push_flat_script(text, options = {})
367
369
  flush_merged_text
368
370
 
369
371
  raise SyntaxError.new("There's no Ruby code for ~ to evaluate.") if text.empty?
370
- push_script(text, :preserve_script => true)
372
+ push_script(text, options.merge(:preserve_script => true))
371
373
  end
372
374
 
373
375
  def start_haml_comment
@@ -615,7 +617,7 @@ END
615
617
  return name, [:dynamic, var]
616
618
  end
617
619
 
618
- re = /((?:\\.|\#[^{]|[^#{quote}\\#])*)(#{quote}|#\{)/
620
+ re = /((?:\\.|\#[^{]|[^#{quote}\\#])*#?)(#{quote}|#\{)/
619
621
  content = []
620
622
  loop do
621
623
  return false unless scanner.scan(re)
@@ -651,8 +653,9 @@ END
651
653
  parse = true
652
654
  value = unescape_interpolation(value[1..-1].strip) if value[0] == ?=
653
655
  when '&', '!'
654
- if value[0] == ?=
656
+ if value[0] == ?= || value[0] == ?~
655
657
  parse = true
658
+ preserve_script = (value[0] == ?~)
656
659
  value =
657
660
  if value[1] == ?=
658
661
  unescape_interpolation(value[2..-1].strip)
@@ -12,7 +12,7 @@ require 'sass/tree/if_node'
12
12
  require 'sass/tree/while_node'
13
13
  require 'sass/tree/for_node'
14
14
  require 'sass/tree/debug_node'
15
- require 'sass/tree/file_node'
15
+ require 'sass/tree/import_node'
16
16
  require 'sass/environment'
17
17
  require 'sass/script'
18
18
  require 'sass/error'
@@ -227,21 +227,23 @@ END
227
227
 
228
228
  def build_tree(parent, line, root = false)
229
229
  @line = line.index
230
- node = parse_line(parent, line, root)
230
+ node_or_nodes = parse_line(parent, line, root)
231
231
 
232
- # Node is a symbol if it's non-outputting, like a variable assignment,
233
- # or an array if it's a group of nodes to add
234
- return node unless node.is_a? Tree::Node
232
+ Array(node_or_nodes).each do |node|
233
+ # Node is a symbol if it's non-outputting, like a variable assignment
234
+ next unless node.is_a? Tree::Node
235
235
 
236
- node.line = line.index
237
- node.filename = line.filename
236
+ node.line = line.index
237
+ node.filename = line.filename
238
238
 
239
- if node.is_a?(Tree::CommentNode)
240
- node.lines = line.children
241
- else
242
- append_children(node, line.children, false)
239
+ if node.is_a?(Tree::CommentNode)
240
+ node.lines = line.children
241
+ else
242
+ append_children(node, line.children, false)
243
+ end
243
244
  end
244
- return node
245
+
246
+ node_or_nodes
245
247
  end
246
248
 
247
249
  def append_children(parent, children, root)
@@ -279,7 +281,7 @@ END
279
281
  case child
280
282
  when Tree::MixinDefNode
281
283
  raise SyntaxError.new("Mixins may only be defined at the root of a document.", line.index)
282
- when Tree::DirectiveNode, Tree::FileNode
284
+ when Tree::ImportNode
283
285
  raise SyntaxError.new("Import directives may only be used at the root of a document.", line.index)
284
286
  end
285
287
  end
@@ -365,7 +367,7 @@ END
365
367
  # it's a CSS @import rule and we don't want to touch it.
366
368
  if directive == "import" && value !~ /^(url\(|")/
367
369
  raise SyntaxError.new("Illegal nesting: Nothing may be nested beneath import directives.", @line + 1) unless line.children.empty?
368
- import(value)
370
+ value.split(/,\s*/).map {|f| Tree::ImportNode.new(f)}
369
371
  elsif directive == "for"
370
372
  parse_for(line, root, value)
371
373
  elsif directive == "else"
@@ -470,27 +472,5 @@ END
470
472
  offset = options[:offset] || 0
471
473
  Script.parse(script, line, offset, @options[:filename])
472
474
  end
473
-
474
- def import_paths
475
- paths = (@options[:load_paths] || []).dup
476
- paths.unshift(File.dirname(@options[:filename])) if @options[:filename]
477
- paths
478
- end
479
-
480
- def import(files)
481
- files.split(/,\s*/).map do |filename|
482
- engine = nil
483
-
484
- begin
485
- filename = Sass::Files.find_file_to_import(filename, import_paths)
486
- rescue Exception => e
487
- raise SyntaxError.new(e.message, @line)
488
- end
489
-
490
- next Tree::DirectiveNode.new("@import url(#{filename})") if filename =~ /\.css$/
491
-
492
- Tree::FileNode.new(filename)
493
- end.flatten
494
- end
495
475
  end
496
476
  end
@@ -65,10 +65,11 @@ module Sass
65
65
  # Used for error reporting
66
66
  # @param offset [Fixnum] The number of characters in on which the SassScript appears.
67
67
  # Used for error reporting
68
- def initialize(str, line, offset)
68
+ def initialize(str, line, offset, filename)
69
69
  @scanner = str.is_a?(StringScanner) ? str : StringScanner.new(str)
70
70
  @line = line
71
71
  @offset = offset
72
+ @filename = filename
72
73
  @prev = nil
73
74
  end
74
75
 
@@ -158,7 +159,18 @@ module Sass
158
159
  end
159
160
 
160
161
  def op
162
+ prev_chr = @scanner.string[@scanner.pos - 1].chr
161
163
  return unless op = @scanner.scan(REGULAR_EXPRESSIONS[:op])
164
+ if @prev && op == '-' && prev_chr !~ /\s/ &&
165
+ [:bool, :ident, :const].include?(@prev.type)
166
+ warn(<<END)
167
+ DEPRECATION WARNING:
168
+ On line #{@line}, character #{last_match_position}#{" of '#{@filename}'" if @filename}
169
+ - will be allowed as part of variable names in version 2.4.
170
+ Please add whitespace to separate it from the previous token.
171
+ END
172
+ end
173
+
162
174
  [OPERATORS[op]]
163
175
  end
164
176
 
@@ -14,7 +14,7 @@ module Sass
14
14
  # Used for error reporting
15
15
  def initialize(str, line, offset, filename = nil)
16
16
  @filename = filename
17
- @lexer = Lexer.new(str, line, offset)
17
+ @lexer = Lexer.new(str, line, offset, filename)
18
18
  end
19
19
 
20
20
  # Parses a SassScript expression within an interpolated segment (`#{}`).
@@ -49,13 +49,14 @@ module Sass::Tree
49
49
  # @see #invisible?
50
50
  def to_s(tabs = 0, _ = nil)
51
51
  return if invisible?
52
+ spaces = ' ' * (tabs - 1)
52
53
 
53
54
  content = (value.split("\n") + lines.map {|l| l.text})
55
+ return spaces + "/* */" if content.empty?
54
56
  content.map! {|l| (l.empty? ? "" : " ") + l}
55
57
  content.first.gsub!(/^ /, '')
56
58
  content.last.gsub!(%r{ ?\*/ *$}, '')
57
59
 
58
- spaces = ' ' * (tabs - 1)
59
60
  spaces + "/* " + content.join(style == :compact ? '' : "\n#{spaces} *") + " */"
60
61
  end
61
62
 
@@ -5,10 +5,7 @@ module Sass::Tree
5
5
  # only CSS directives like `@media` and `@font-face` become {DirectiveNode}s.
6
6
  #
7
7
  # `@import` is a bit of a weird case;
8
- # if it's importing a Sass file,
9
- # it becomes a {FileNode},
10
- # but if it's importing a plain CSS file,
11
- # it becomes a {DirectiveNode}.
8
+ # it becomes an {ImportNode}.
12
9
  #
13
10
  # @see Sass::Tree
14
11
  class DirectiveNode < Node
@@ -3,10 +3,10 @@ module Sass
3
3
  # A static node that wraps the {Sass::Tree} for an `@import`ed file.
4
4
  # It doesn't have a functional purpose other than to add the `@import`ed file
5
5
  # to the backtrace if an error occurs.
6
- class FileNode < Node
7
- # @param filename [String] The name of the imported file
8
- def initialize(filename)
9
- @filename = filename
6
+ class ImportNode < Node
7
+ # @param imported_filename [String] The name of the imported file
8
+ def initialize(imported_filename)
9
+ @imported_filename = imported_filename
10
10
  super()
11
11
  end
12
12
 
@@ -30,12 +30,36 @@ module Sass
30
30
  # @param environment [Sass::Environment] The lexical environment containing
31
31
  # variable and mixin values
32
32
  def perform!(environment)
33
- self.children = Sass::Files.tree_for(filename, @options).children
33
+ return unless full_filename = import
34
+ self.children = Sass::Files.tree_for(full_filename, @options).children
34
35
  self.children = perform_children(environment)
35
36
  rescue Sass::SyntaxError => e
36
37
  e.add_backtrace_entry(@filename)
37
38
  raise e
38
39
  end
40
+
41
+ private
42
+
43
+ def import_paths
44
+ paths = (@options[:load_paths] || []).dup
45
+ paths.unshift(File.dirname(@options[:filename])) if @options[:filename]
46
+ paths
47
+ end
48
+
49
+ def import
50
+ begin
51
+ full_filename = Sass::Files.find_file_to_import(@imported_filename, import_paths)
52
+ rescue Exception => e
53
+ raise SyntaxError.new(e.message, self.line)
54
+ end
55
+
56
+ if full_filename =~ /\.css$/
57
+ @to_s = "@import url(#{full_filename});"
58
+ return false
59
+ end
60
+
61
+ return full_filename
62
+ end
39
63
  end
40
64
  end
41
65
  end
@@ -359,6 +359,72 @@ HTML
359
359
  HAML
360
360
  end
361
361
 
362
+ def test_escape_html
363
+ html = <<HTML
364
+ &amp;
365
+ &
366
+ &amp;
367
+ HTML
368
+
369
+ assert_equal(html, render(<<HAML, :escape_html => true))
370
+ &= "&"
371
+ != "&"
372
+ = "&"
373
+ HAML
374
+
375
+ assert_equal(html, render(<<HAML, :escape_html => true))
376
+ &~ "&"
377
+ !~ "&"
378
+ ~ "&"
379
+ HAML
380
+
381
+ assert_equal(html, render(<<HAML, :escape_html => true))
382
+ & \#{"&"}
383
+ ! \#{"&"}
384
+ \#{"&"}
385
+ HAML
386
+
387
+ assert_equal(html, render(<<HAML, :escape_html => true))
388
+ &== \#{"&"}
389
+ !== \#{"&"}
390
+ == \#{"&"}
391
+ HAML
392
+
393
+ tag_html = <<HTML
394
+ <p>&amp;</p>
395
+ <p>&</p>
396
+ <p>&amp;</p>
397
+ HTML
398
+
399
+ assert_equal(tag_html, render(<<HAML, :escape_html => true))
400
+ %p&= "&"
401
+ %p!= "&"
402
+ %p= "&"
403
+ HAML
404
+
405
+ assert_equal(tag_html, render(<<HAML, :escape_html => true))
406
+ %p&~ "&"
407
+ %p!~ "&"
408
+ %p~ "&"
409
+ HAML
410
+
411
+ assert_equal(tag_html, render(<<HAML, :escape_html => true))
412
+ %p& \#{"&"}
413
+ %p! \#{"&"}
414
+ %p \#{"&"}
415
+ HAML
416
+
417
+ assert_equal(tag_html, render(<<HAML, :escape_html => true))
418
+ %p&== \#{"&"}
419
+ %p!== \#{"&"}
420
+ %p== \#{"&"}
421
+ HAML
422
+ end
423
+
424
+ def test_new_attrs_with_hash
425
+ assert_equal("<a href='#'></a>\n", render('%a(href="#")'))
426
+ end
427
+
362
428
  # HTML escaping tests
363
429
 
364
430
  def test_ampersand_equals_should_escape
@@ -126,8 +126,8 @@ class SassEngineTest < Test::Unit::TestCase
126
126
  render("p\n\ta: b\n\tq\n\t\tc: d\n"))
127
127
  end
128
128
 
129
- def test_exceptions
130
- EXCEPTION_MAP.each do |key, value|
129
+ EXCEPTION_MAP.each do |key, value|
130
+ define_method("test_exception (#{key.inspect})") do
131
131
  line = 10
132
132
  begin
133
133
  Sass::Engine.new(key, :filename => __FILE__, :line => line).render
@@ -790,6 +790,20 @@ CSS
790
790
  SASS
791
791
  end
792
792
 
793
+ def test_empty_comment
794
+ assert_equal(<<CSS, render(<<SASS))
795
+ /* */
796
+ a {
797
+ /* */
798
+ b: c; }
799
+ CSS
800
+ /*
801
+ a
802
+ /*
803
+ b: c
804
+ SASS
805
+ end
806
+
793
807
  private
794
808
 
795
809
  def render(sass, options = {})
@@ -34,7 +34,7 @@ class SassPluginTest < Test::Unit::TestCase
34
34
  end
35
35
 
36
36
  def test_update_needed_when_modified
37
- sleep(1)
37
+ sleep 1
38
38
  FileUtils.touch(template_loc('basic'))
39
39
  assert Sass::Plugin.stylesheet_needs_update?('basic', template_loc, tempfile_loc)
40
40
  Sass::Plugin.update_stylesheets
@@ -42,7 +42,7 @@ class SassPluginTest < Test::Unit::TestCase
42
42
  end
43
43
 
44
44
  def test_update_needed_when_dependency_modified
45
- sleep(1)
45
+ sleep 1
46
46
  FileUtils.touch(template_loc('basic'))
47
47
  assert Sass::Plugin.stylesheet_needs_update?('import', template_loc, tempfile_loc)
48
48
  Sass::Plugin.update_stylesheets
@@ -89,15 +89,6 @@ class SassPluginTest < Test::Unit::TestCase
89
89
  assert_renders_correctly('more1_with_line_comments', 'more1', :prefix => 'more_')
90
90
  end
91
91
 
92
- def test_rails_update
93
- File.delete(tempfile_loc('basic'))
94
- assert Sass::Plugin.stylesheet_needs_update?('basic', template_loc, tempfile_loc)
95
-
96
- ActionController::Base.new.process
97
-
98
- assert !Sass::Plugin.stylesheet_needs_update?('basic', template_loc, tempfile_loc)
99
- end
100
-
101
92
  def test_merb_update
102
93
  begin
103
94
  require 'merb'
@@ -131,6 +122,21 @@ class SassPluginTest < Test::Unit::TestCase
131
122
  assert !File.exists?(tempfile_loc('_partial'))
132
123
  end
133
124
 
125
+ ## Regression
126
+
127
+ def test_cached_dependencies_update
128
+ FileUtils.mv(template_loc("basic"), template_loc("basic", "more_"))
129
+ set_plugin_opts :load_paths => [result_loc, template_loc(nil, "more_")]
130
+
131
+ sleep 1
132
+ FileUtils.touch(template_loc("basic", "more_"))
133
+ assert Sass::Plugin.stylesheet_needs_update?("import", template_loc, tempfile_loc)
134
+ Sass::Plugin.update_stylesheets
135
+ assert_renders_correctly("import")
136
+ ensure
137
+ FileUtils.mv(template_loc("basic", "more_"), template_loc("basic"))
138
+ end
139
+
134
140
  private
135
141
 
136
142
  def assert_renders_correctly(*arguments)
@@ -191,6 +197,11 @@ class SassPluginTest < Test::Unit::TestCase
191
197
  :always_update => true,
192
198
  }.merge(overrides)
193
199
  end
200
+
201
+ def wait_a_tick
202
+ time = Time.now
203
+ loop {break if Time.now.sec != time.sec}
204
+ end
194
205
  end
195
206
 
196
207
  module Sass::Plugin
@@ -207,8 +218,3 @@ class Sass::Engine
207
218
  old_render
208
219
  end
209
220
  end
210
-
211
- class ActionController::Base
212
- undef :sass_old_process
213
- def sass_old_process(*args); end
214
- end
@@ -61,22 +61,22 @@ foo \#{"\\\#{" + "baz"} bang
61
61
  SASS
62
62
  end
63
63
 
64
- def test_warning_reporting
64
+ def test_implicit_string_warning
65
65
  assert_warning(<<WARN) {eval("foo")}
66
66
  DEPRECATION WARNING:
67
- On line 1, character 1 of 'test_warning_reporting_inline.sass'
67
+ On line 1, character 1 of 'test_implicit_string_warning_inline.sass'
68
68
  Implicit strings have been deprecated and will be removed in version 2.4.
69
69
  'foo' was not quoted. Please add double quotes (e.g. "foo").
70
70
  WARN
71
71
  assert_warning(<<WARN) {eval("1 + foo")}
72
72
  DEPRECATION WARNING:
73
- On line 1, character 5 of 'test_warning_reporting_inline.sass'
73
+ On line 1, character 5 of 'test_implicit_string_warning_inline.sass'
74
74
  Implicit strings have been deprecated and will be removed in version 2.4.
75
75
  'foo' was not quoted. Please add double quotes (e.g. "foo").
76
76
  WARN
77
77
  assert_warning(<<WARN) {render("@if 1 + foo")}
78
78
  DEPRECATION WARNING:
79
- On line 1, character 9 of 'test_warning_reporting_inline.sass'
79
+ On line 1, character 9 of 'test_implicit_string_warning_inline.sass'
80
80
  Implicit strings have been deprecated and will be removed in version 2.4.
81
81
  'foo' was not quoted. Please add double quotes (e.g. "foo").
82
82
  WARN
@@ -84,7 +84,7 @@ WARN
84
84
  # Regression
85
85
  assert_warning(<<WARN) {render("@if if")}
86
86
  DEPRECATION WARNING:
87
- On line 1, character 5 of 'test_warning_reporting_inline.sass'
87
+ On line 1, character 5 of 'test_implicit_string_warning_inline.sass'
88
88
  Implicit strings have been deprecated and will be removed in version 2.4.
89
89
  'if' was not quoted. Please add double quotes (e.g. "if").
90
90
  WARN
@@ -102,6 +102,24 @@ WARN
102
102
  assert_equal "public_instance_methods()", resolve("public_instance_methods()")
103
103
  end
104
104
 
105
+ def test_hyphen_warning
106
+ a = Sass::Script::String.new("a")
107
+ b = Sass::Script::String.new("b")
108
+ assert_warning(<<WARN) {eval("!a-!b", {}, env("a" => a, "b" => b))}
109
+ DEPRECATION WARNING:
110
+ On line 1, character 3 of 'test_hyphen_warning_inline.sass'
111
+ - will be allowed as part of variable names in version 2.4.
112
+ Please add whitespace to separate it from the previous token.
113
+ WARN
114
+
115
+ assert_warning(<<WARN) {eval("true-false")}
116
+ DEPRECATION WARNING:
117
+ On line 1, character 5 of 'test_hyphen_warning_inline.sass'
118
+ - will be allowed as part of variable names in version 2.4.
119
+ Please add whitespace to separate it from the previous token.
120
+ WARN
121
+ end
122
+
105
123
  def test_ruby_equality
106
124
  assert_equal eval('"foo"'), eval('"foo"')
107
125
  assert_equal eval('1'), eval('1.0')
@@ -3,7 +3,7 @@
3
3
  =premixin
4
4
  pre-mixin: here
5
5
 
6
- @import importee, basic, basic.css, ../results/complex.css, partial
6
+ @import importee.sass, basic.sass, basic.css, ../results/complex.css, partial.sass
7
7
 
8
8
  nonimported
9
9
  :myconst = !preconst
@@ -7,6 +7,8 @@ $:.unshift lib_dir unless $:.include?(lib_dir)
7
7
  require 'haml'
8
8
  require 'sass'
9
9
 
10
+ Sass::RAILS_LOADED = true
11
+
10
12
  # required because of Sass::Plugin
11
13
  unless defined? RAILS_ROOT
12
14
  RAILS_ROOT = '.'
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: haml
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.2.0
4
+ version: 2.2.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Nathan Weizenbaum
@@ -10,7 +10,7 @@ autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
12
 
13
- date: 2009-07-06 00:00:00 -07:00
13
+ date: 2009-07-12 00:00:00 -04:00
14
14
  default_executable:
15
15
  dependencies:
16
16
  - !ruby/object:Gem::Dependency
@@ -75,12 +75,12 @@ files:
75
75
  - lib/sass/tree/node.rb
76
76
  - lib/sass/tree/for_node.rb
77
77
  - lib/sass/tree/debug_node.rb
78
+ - lib/sass/tree/import_node.rb
78
79
  - lib/sass/tree/while_node.rb
79
80
  - lib/sass/tree/mixin_def_node.rb
80
81
  - lib/sass/tree/if_node.rb
81
82
  - lib/sass/tree/mixin_node.rb
82
83
  - lib/sass/tree/directive_node.rb
83
- - lib/sass/tree/file_node.rb
84
84
  - lib/sass/tree/rule_node.rb
85
85
  - lib/sass/tree/prop_node.rb
86
86
  - lib/sass/tree/variable_node.rb