class SCSSLint::Linter::PrivateNamingConvention
Verifies that variables, functions, and mixins that follow the private naming convention are defined and used within the same file.
Constants
- DEFINED_BYS
- DEFINITIONS
- HUMAN_NODE_NAMES
Public Instance Methods
visit_mixin(node) { || ... }
click to toggle source
# File lib/scss_lint/linter/private_naming_convention.rb, line 45 def visit_mixin(node) check_privacy(node) yield # Continue into content block of this mixin's block end
visit_root(node) { || ... }
click to toggle source
# File lib/scss_lint/linter/private_naming_convention.rb, line 25 def visit_root(node) # Register all top-level function, mixin, and variable definitions. node.children.each_with_object([]) do |child_node| if DEFINITIONS.key?(child_node.class) register_node child_node else yield end end # After we have visited everything, we want to see if any private things # were defined but not used. after_visit_all end
visit_script_funcall(node) { || ... }
click to toggle source
# File lib/scss_lint/linter/private_naming_convention.rb, line 40 def visit_script_funcall(node) check_privacy(node) yield # Continue linting any arguments of this function call end
visit_script_variable(node)
click to toggle source
# File lib/scss_lint/linter/private_naming_convention.rb, line 50 def visit_script_variable(node) check_privacy(node) end
Private Instance Methods
after_visit_all()
click to toggle source
# File lib/scss_lint/linter/private_naming_convention.rb, line 132 def after_visit_all return unless @private_definitions @private_definitions.each do |_, nodes| nodes.each do |node_text, node_info| next if node_info[:times_used] > 0 node_type = humanize_node_class(node_info[:node]) add_lint( node_info[:node], "Private #{node_type} #{node_text} must be used in the same file it is defined" ) end end end
before?(node, before_location)
click to toggle source
# File lib/scss_lint/linter/private_naming_convention.rb, line 121 def before?(node, before_location) return true unless node.source_range location = location_from_range(node.source_range) return true if location.line < before_location.line if location.line == before_location.line && location.column < before_location.column return true end false end
check_privacy(node, node_text = node.name)
click to toggle source
# File lib/scss_lint/linter/private_naming_convention.rb, line 68 def check_privacy(node, node_text = node.name) return unless private?(node) defined_by_class = defined_by(node) # Look at top-level private definitions if @private_definitions && @private_definitions[defined_by_class] && @private_definitions[defined_by_class][node_text] @private_definitions[defined_by_class][node_text][:times_used] += 1 return end # We did not find a top-level private definition, so let's traverse up the # tree, looking for private definitions of this node that are scoped. looking_for = { node: node, defined_by: defined_by_class, location: location_from_range(node.source_range), } return if node_defined_earlier_in_branch?(node.node_parent, looking_for) node_type = humanize_node_class(node) add_lint( node, "Private #{node_type} #{node_text} must be defined in the same file it is used" ) end
defined_by(node)
click to toggle source
# File lib/scss_lint/linter/private_naming_convention.rb, line 151 def defined_by(node) DEFINED_BYS[node.class] end
humanize_node_class(node)
click to toggle source
# File lib/scss_lint/linter/private_naming_convention.rb, line 147 def humanize_node_class(node) HUMAN_NODE_NAMES[node.class] end
node_defined_earlier_in_branch?(node_to_look_in, looking_for)
click to toggle source
# File lib/scss_lint/linter/private_naming_convention.rb, line 97 def node_defined_earlier_in_branch?(node_to_look_in, looking_for) # Look at all of the children of this node and return true if we find a # defining node that matches in name and type. node_to_look_in.children.each_with_object([]) do |child_node| break unless before?(child_node, looking_for[:location]) next unless child_node.class == looking_for[:defined_by] next unless child_node.name == looking_for[:node].name return true # We found a match, so we are done end return false unless node_to_look_in.node_parent # We did not find a match yet, and haven't reached the top of the branch, # so recurse. if node_to_look_in.node_parent node_defined_earlier_in_branch?(node_to_look_in.node_parent, looking_for) end end
private?(node)
click to toggle source
# File lib/scss_lint/linter/private_naming_convention.rb, line 117 def private?(node) node.name.start_with?(config['prefix']) end
register_node(node, node_text = node.name)
click to toggle source
# File lib/scss_lint/linter/private_naming_convention.rb, line 56 def register_node(node, node_text = node.name) return unless private?(node) @private_definitions ||= {} @private_definitions[node.class] ||= {} @private_definitions[node.class][node_text] = { node: node, times_used: 0, } end