haml-edge 3.1.18 → 3.1.19
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.
- data/EDGE_GEM_VERSION +1 -1
- data/VERSION +1 -1
- data/lib/haml/exec.rb +2 -1
- data/lib/sass/environment.rb +14 -2
- data/lib/sass/error.rb +4 -1
- data/lib/sass/tree/mixin_node.rb +23 -3
- data/test/sass/engine_test.rb +57 -0
- metadata +2 -2
data/EDGE_GEM_VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
3.1.
|
1
|
+
3.1.19
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
3.1.
|
1
|
+
3.1.19
|
data/lib/haml/exec.rb
CHANGED
@@ -23,7 +23,8 @@ module Haml
|
|
23
23
|
rescue Exception => e
|
24
24
|
raise e if @options[:trace] || e.is_a?(SystemExit)
|
25
25
|
|
26
|
-
$stderr.
|
26
|
+
$stderr.print "#{e.class}: " unless e.class == RuntimeError
|
27
|
+
$stderr.puts "#{e.message}"
|
27
28
|
$stderr.puts " Use --trace for backtrace."
|
28
29
|
exit 1
|
29
30
|
end
|
data/lib/sass/environment.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
require 'set'
|
2
|
+
|
1
3
|
module Sass
|
2
4
|
# The lexical environment for SassScript.
|
3
5
|
# This keeps track of variable and mixin definitions.
|
@@ -24,6 +26,7 @@ module Sass
|
|
24
26
|
@mixins = {}
|
25
27
|
@parent = parent
|
26
28
|
@stack = [] unless parent
|
29
|
+
@mixins_in_use = Set.new unless parent
|
27
30
|
set_var("important", Script::String.new("!important")) unless @parent
|
28
31
|
end
|
29
32
|
|
@@ -56,6 +59,7 @@ module Sass
|
|
56
59
|
else
|
57
60
|
stack.push(frame_info)
|
58
61
|
end
|
62
|
+
mixins_in_use << stack.last[:mixin] if stack.last[:mixin] && !stack.last[:prepared]
|
59
63
|
end
|
60
64
|
|
61
65
|
# Like \{#push\_frame}, but next time a stack frame is pushed,
|
@@ -68,8 +72,9 @@ module Sass
|
|
68
72
|
|
69
73
|
# Pop a stack frame from the mixin/include stack.
|
70
74
|
def pop_frame
|
71
|
-
stack.pop if stack.last[:prepared]
|
72
|
-
stack.pop
|
75
|
+
stack.pop if stack.last && stack.last[:prepared]
|
76
|
+
popped = stack.pop
|
77
|
+
mixins_in_use.delete(popped[:mixin]) if popped && popped[:mixin]
|
73
78
|
end
|
74
79
|
|
75
80
|
# A list of stack frames in the mixin/include stack.
|
@@ -81,6 +86,13 @@ module Sass
|
|
81
86
|
@stack ||= @parent.stack
|
82
87
|
end
|
83
88
|
|
89
|
+
# A set of names of mixins currently present in the stack.
|
90
|
+
#
|
91
|
+
# @return [Set<String>] The mixin names.
|
92
|
+
def mixins_in_use
|
93
|
+
@mixins_in_use ||= @parent.mixins_in_use
|
94
|
+
end
|
95
|
+
|
84
96
|
class << self
|
85
97
|
private
|
86
98
|
|
data/lib/sass/error.rb
CHANGED
@@ -137,7 +137,10 @@ module Sass
|
|
137
137
|
# @see #sass_backtrace
|
138
138
|
# @return [String]
|
139
139
|
def sass_backtrace_str(default_filename = "an unknown file")
|
140
|
-
|
140
|
+
lines = self.message.split("\n")
|
141
|
+
msg = lines[0] + lines[1..-1].
|
142
|
+
map {|l| "\n" + (" " * "Syntax error: ".size) + l}.join
|
143
|
+
"Syntax error: #{msg}" +
|
141
144
|
Haml::Util.enum_with_index(sass_backtrace).map do |entry, i|
|
142
145
|
"\n #{i == 0 ? "on" : "from"} line #{entry[:line]}" +
|
143
146
|
" of #{entry[:filename] || default_filename}" +
|
data/lib/sass/tree/mixin_node.rb
CHANGED
@@ -66,6 +66,8 @@ module Sass::Tree
|
|
66
66
|
# @raise [Sass::SyntaxError] if an incorrect number of arguments was passed
|
67
67
|
# @see Sass::Tree
|
68
68
|
def perform!(environment)
|
69
|
+
handle_include_loop!(environment) if environment.mixins_in_use.include?(@name)
|
70
|
+
|
69
71
|
original_env = environment
|
70
72
|
original_env.push_frame(:filename => filename, :line => line)
|
71
73
|
original_env.prepare_frame(:mixin => @name)
|
@@ -93,11 +95,29 @@ END
|
|
93
95
|
|
94
96
|
self.children = mixin.tree.map {|c| c.perform(environment)}.flatten
|
95
97
|
rescue Sass::SyntaxError => e
|
96
|
-
|
97
|
-
|
98
|
+
if original_env # Don't add backtrace info if this is an @include loop
|
99
|
+
e.modify_backtrace(:mixin => @name, :line => @line)
|
100
|
+
e.add_backtrace(:line => @line)
|
101
|
+
end
|
98
102
|
raise e
|
99
103
|
ensure
|
100
|
-
original_env.pop_frame
|
104
|
+
original_env.pop_frame if original_env
|
105
|
+
end
|
106
|
+
|
107
|
+
private
|
108
|
+
|
109
|
+
def handle_include_loop!(environment)
|
110
|
+
msg = "An @include loop has been found:"
|
111
|
+
mixins = environment.stack.map {|s| s[:mixin]}.compact
|
112
|
+
if mixins.size == 2 && mixins[0] == mixins[1]
|
113
|
+
raise Sass::SyntaxError.new("#{msg} #{@name} includes itself")
|
114
|
+
end
|
115
|
+
|
116
|
+
mixins << @name
|
117
|
+
msg << "\n" << Haml::Util.enum_cons(mixins, 2).map do |m1, m2|
|
118
|
+
" #{m1} includes #{m2}"
|
119
|
+
end.join("\n")
|
120
|
+
raise Sass::SyntaxError.new(msg)
|
101
121
|
end
|
102
122
|
end
|
103
123
|
end
|
data/test/sass/engine_test.rb
CHANGED
@@ -342,6 +342,63 @@ SASS
|
|
342
342
|
assert_hash_has(err.sass_backtrace[4], :filename => nil, :mixin => nil, :line => 1)
|
343
343
|
end
|
344
344
|
|
345
|
+
def test_basic_mixin_loop_exception
|
346
|
+
render <<SASS
|
347
|
+
@mixin foo
|
348
|
+
@include foo
|
349
|
+
@include foo
|
350
|
+
SASS
|
351
|
+
assert(false, "Exception not raised")
|
352
|
+
rescue Sass::SyntaxError => err
|
353
|
+
assert_equal("An @include loop has been found: foo includes itself", err.message)
|
354
|
+
assert_hash_has(err.sass_backtrace[0], :mixin => "foo", :line => 2)
|
355
|
+
end
|
356
|
+
|
357
|
+
def test_double_mixin_loop_exception
|
358
|
+
render <<SASS
|
359
|
+
@mixin foo
|
360
|
+
@include bar
|
361
|
+
@mixin bar
|
362
|
+
@include foo
|
363
|
+
@include foo
|
364
|
+
SASS
|
365
|
+
assert(false, "Exception not raised")
|
366
|
+
rescue Sass::SyntaxError => err
|
367
|
+
assert_equal(<<MESSAGE.rstrip, err.message)
|
368
|
+
An @include loop has been found:
|
369
|
+
foo includes bar
|
370
|
+
bar includes foo
|
371
|
+
MESSAGE
|
372
|
+
assert_hash_has(err.sass_backtrace[0], :mixin => "bar", :line => 4)
|
373
|
+
assert_hash_has(err.sass_backtrace[1], :mixin => "foo", :line => 2)
|
374
|
+
end
|
375
|
+
|
376
|
+
def test_deep_mixin_loop_exception
|
377
|
+
render <<SASS
|
378
|
+
@mixin foo
|
379
|
+
@include bar
|
380
|
+
|
381
|
+
@mixin bar
|
382
|
+
@include baz
|
383
|
+
|
384
|
+
@mixin baz
|
385
|
+
@include foo
|
386
|
+
|
387
|
+
@include foo
|
388
|
+
SASS
|
389
|
+
assert(false, "Exception not raised")
|
390
|
+
rescue Sass::SyntaxError => err
|
391
|
+
assert_equal(<<MESSAGE.rstrip, err.message)
|
392
|
+
An @include loop has been found:
|
393
|
+
foo includes bar
|
394
|
+
bar includes baz
|
395
|
+
baz includes foo
|
396
|
+
MESSAGE
|
397
|
+
assert_hash_has(err.sass_backtrace[0], :mixin => "baz", :line => 8)
|
398
|
+
assert_hash_has(err.sass_backtrace[1], :mixin => "bar", :line => 5)
|
399
|
+
assert_hash_has(err.sass_backtrace[2], :mixin => "foo", :line => 2)
|
400
|
+
end
|
401
|
+
|
345
402
|
def test_exception_css_with_offset
|
346
403
|
opts = {:full_exception => true, :line => 362}
|
347
404
|
render(("a\n b: c\n" * 10) + "d\n e:\n" + ("f\n g: h\n" * 10), opts)
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: haml-edge
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 3.1.
|
4
|
+
version: 3.1.19
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Nathan Weizenbaum
|
@@ -11,7 +11,7 @@ autorequire:
|
|
11
11
|
bindir: bin
|
12
12
|
cert_chain: []
|
13
13
|
|
14
|
-
date: 2010-05-
|
14
|
+
date: 2010-05-23 00:00:00 -04:00
|
15
15
|
default_executable:
|
16
16
|
dependencies:
|
17
17
|
- !ruby/object:Gem::Dependency
|