/usr/lib/ruby/vendor_ruby/sass/tree/node.rb is in ruby-sass 3.4.6-2.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 | module Sass
# A namespace for nodes in the Sass parse tree.
#
# The Sass parse tree has three states: dynamic, static Sass, and static CSS.
#
# When it's first parsed, a Sass document is in the dynamic state.
# It has nodes for mixin definitions and `@for` loops and so forth,
# in addition to nodes for CSS rules and properties.
# Nodes that only appear in this state are called **dynamic nodes**.
#
# {Tree::Visitors::Perform} creates a static Sass tree, which is
# different. It still has nodes for CSS rules and properties but it
# doesn't have any dynamic-generation-related nodes. The nodes in
# this state are in a similar structure to the Sass document: rules
# and properties are nested beneath one another, although the
# {Tree::RuleNode} selectors are already in their final state. Nodes
# that can be in this state or in the dynamic state are called
# **static nodes**; nodes that can only be in this state are called
# **solely static nodes**.
#
# {Tree::Visitors::Cssize} is then used to create a static CSS tree.
# This is like a static Sass tree,
# but the structure exactly mirrors that of the generated CSS.
# Rules and properties can't be nested beneath one another in this state.
#
# Finally, {Tree::Visitors::ToCss} can be called on a static CSS tree
# to get the actual CSS code as a string.
module Tree
# The abstract superclass of all parse-tree nodes.
class Node
include Enumerable
def self.inherited(base)
node_name = base.name.gsub(/.*::(.*?)Node$/, '\\1').downcase
base.instance_eval <<-METHODS
# @return [Symbol] The name that is used for this node when visiting.
def node_name
:#{node_name}
end
# @return [Symbol] The method that is used on the visitor to visit nodes of this type.
def visit_method
:visit_#{node_name}
end
# @return [Symbol] The method name that determines if the parent is invalid.
def invalid_child_method_name
:"invalid_#{node_name}_child?"
end
# @return [Symbol] The method name that determines if the node is an invalid parent.
def invalid_parent_method_name
:"invalid_#{node_name}_parent?"
end
METHODS
end
# The child nodes of this node.
#
# @return [Array<Tree::Node>]
attr_reader :children
# Whether or not this node has child nodes.
# This may be true even when \{#children} is empty,
# in which case this node has an empty block (e.g. `{}`).
#
# @return [Boolean]
attr_accessor :has_children
# The line of the document on which this node appeared.
#
# @return [Fixnum]
attr_accessor :line
# The source range in the document on which this node appeared.
#
# @return [Sass::Source::Range]
attr_accessor :source_range
# The name of the document on which this node appeared.
#
# @return [String]
attr_writer :filename
# The options hash for the node.
# See {file:SASS_REFERENCE.md#sass_options the Sass options documentation}.
#
# @return [{Symbol => Object}]
attr_reader :options
def initialize
@children = []
end
# Sets the options hash for the node and all its children.
#
# @param options [{Symbol => Object}] The options
# @see #options
def options=(options)
Sass::Tree::Visitors::SetOptions.visit(self, options)
end
# @private
def children=(children)
self.has_children ||= !children.empty?
@children = children
end
# The name of the document on which this node appeared.
#
# @return [String]
def filename
@filename || (@options && @options[:filename])
end
# Appends a child to the node.
#
# @param child [Tree::Node, Array<Tree::Node>] The child node or nodes
# @raise [Sass::SyntaxError] if `child` is invalid
def <<(child)
return if child.nil?
if child.is_a?(Array)
child.each {|c| self << c}
else
self.has_children = true
@children << child
end
end
# Compares this node and another object (only other {Tree::Node}s will be equal).
# This does a structural comparison;
# if the contents of the nodes and all the child nodes are equivalent,
# then the nodes are as well.
#
# Only static nodes need to override this.
#
# @param other [Object] The object to compare with
# @return [Boolean] Whether or not this node and the other object
# are the same
# @see Sass::Tree
def ==(other)
self.class == other.class && other.children == children
end
# True if \{#to\_s} will return `nil`;
# that is, if the node shouldn't be rendered.
# Should only be called in a static tree.
#
# @return [Boolean]
def invisible?; false; end
# The output style. See {file:SASS_REFERENCE.md#sass_options the Sass options documentation}.
#
# @return [Symbol]
def style
@options[:style]
end
# Computes the CSS corresponding to this static CSS tree.
#
# @return [String] The resulting CSS
# @see Sass::Tree
def css
Sass::Tree::Visitors::ToCss.new.visit(self)
end
# Computes the CSS corresponding to this static CSS tree, along with
# the respective source map.
#
# @return [(String, Sass::Source::Map)] The resulting CSS and the source map
# @see Sass::Tree
def css_with_sourcemap
visitor = Sass::Tree::Visitors::ToCss.new(:build_source_mapping)
result = visitor.visit(self)
return result, visitor.source_mapping
end
# Returns a representation of the node for debugging purposes.
#
# @return [String]
def inspect
return self.class.to_s unless has_children
"(#{self.class} #{children.map {|c| c.inspect}.join(' ')})"
end
# Iterates through each node in the tree rooted at this node
# in a pre-order walk.
#
# @yield node
# @yieldparam node [Node] a node in the tree
def each
yield self
children.each {|c| c.each {|n| yield n}}
end
# Converts a node to Sass code that will generate it.
#
# @param options [{Symbol => Object}] An options hash (see {Sass::CSS#initialize})
# @return [String] The Sass code corresponding to the node
def to_sass(options = {})
Sass::Tree::Visitors::Convert.visit(self, options, :sass)
end
# Converts a node to SCSS code that will generate it.
#
# @param options [{Symbol => Object}] An options hash (see {Sass::CSS#initialize})
# @return [String] The Sass code corresponding to the node
def to_scss(options = {})
Sass::Tree::Visitors::Convert.visit(self, options, :scss)
end
# Return a deep clone of this node.
# The child nodes are cloned, but options are not.
#
# @return [Node]
def deep_copy
Sass::Tree::Visitors::DeepCopy.visit(self)
end
# Whether or not this node bubbles up through RuleNodes.
#
# @return [Boolean]
def bubbles?
false
end
protected
# @see Sass::Shared.balance
# @raise [Sass::SyntaxError] if the brackets aren't balanced
def balance(*args)
res = Sass::Shared.balance(*args)
return res if res
raise Sass::SyntaxError.new("Unbalanced brackets.", :line => line)
end
end
end
end
|