class Sass::Environment
so that they can be made available to {Sass::Script::Functions}.
Environment also keeps track of the {Engine} options
but new variables are defined locally.
so it has access to variables defined in enclosing scopes,
The new environment refers to the environment in the upper scope,
This allows variables to be lexically scoped.
A new environment is created for each level of Sass nesting.
This keeps track of variable and mixin definitions.
The lexical environment for SassScript.
def inherited_hash(name)
Note: when updating this,
def inherited_hash(name) class_eval <<RUBY, __FILE__, __LINE__ + 1 def #{name}(name) _#{name}(name.gsub('_', '-')) end def _#{name}(name) @#{name}s[name] || @parent && @parent._#{name}(name) end protected :_#{name} def set_#{name}(name, value) name = name.gsub('_', '-') @#{name}s[name] = value unless try_set_#{name}(name, value) end def try_set_#{name}(name, value) if @#{name}s.include?(name) @#{name}s[name] = value true elsif @parent @parent.try_set_#{name}(name, value) else false end end protected :try_set_#{name} def set_local_#{name}(name, value) @#{name}s[name.gsub('_', '-')] = value end end
def initialize(parent = nil)
-
parent
(Environment
) -- See \{#parent}
def initialize(parent = nil) @vars = {} @mixins = {} @parent = parent @stack = [] unless parent @mixins_in_use = Set.new unless parent set_var("important", Script::String.new("!important")) unless @parent end
def mixins_in_use
-
(Set
- The mixin names.)
def mixins_in_use @mixins_in_use ||= @parent.mixins_in_use end
def options
-
({Symbol => Object})
-
def options @options || (parent && parent.options) || {} end
def pop_frame
def pop_frame stack.pop if stack.last && stack.last[:prepared] popped = stack.pop mixins_in_use.delete(popped[:mixin]) if popped && popped[:mixin] end
def prepare_frame(frame_info)
-
frame_info
({Symbol => Object}
) -- Same as for \{#push\_frame}.
def prepare_frame(frame_info) push_frame(frame_info.merge(:prepared => true)) end
def push_frame(frame_info)
-
frame_info
({Symbol => Object}
) --
def push_frame(frame_info) if stack.last && stack.last[:prepared] stack.last.delete(:prepared) stack.last.merge!(frame_info) else stack.push(frame_info) end mixins_in_use << stack.last[:mixin] if stack.last[:mixin] && !stack.last[:prepared] end
def stack
-
(Array<{Symbol => Object}>)
- The stack frames,
def stack @stack ||= @parent.stack end