Class: A11y::Lint::CallNode

Inherits:
Object
  • Object
show all
Defined in:
lib/a11y/lint/call_node.rb

Overview

Wraps a Prism::CallNode with a rule-friendly query API.

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(prism_node) ⇒ CallNode

Returns a new instance of CallNode.



11
12
13
# File 'lib/a11y/lint/call_node.rb', line 11

def initialize(prism_node)
  @prism_node = prism_node
end

Instance Attribute Details

#prism_nodeObject (readonly)

Returns the value of attribute prism_node.



9
10
11
# File 'lib/a11y/lint/call_node.rb', line 9

def prism_node
  @prism_node
end

Instance Method Details

#block?Boolean

Returns:

  • (Boolean)


86
87
88
# File 'lib/a11y/lint/call_node.rb', line 86

def block?
  !@prism_node.block.nil?
end

#find(name) ⇒ Object

Finds a receiverless call by method name in this node’s subtree (including self). Returns a CallNode or nil.



92
93
94
95
# File 'lib/a11y/lint/call_node.rb', line 92

def find(name)
  found = search_for_call(@prism_node, name)
  found ? self.class.new(found) : nil
end

#first_positional_arg_empty_string?Boolean

Returns:

  • (Boolean)


81
82
83
84
# File 'lib/a11y/lint/call_node.rb', line 81

def first_positional_arg_empty_string?
  first = positional_args.first
  first.is_a?(Prism::StringNode) && first.unescaped.empty?
end

#keyword?(*keys) ⇒ Boolean

Checks for a keyword argument by name.

keyword?(:alt)                       => alt: or "alt" =>
keyword?(:aria, :label)              => aria: { label: ... }
keyword?(:"aria-label")              => "aria-label" =>
keyword?(:input_html, :aria, :label) => 3-level nested hash

Returns:

  • (Boolean)


24
25
26
27
28
# File 'lib/a11y/lint/call_node.rb', line 24

def keyword?(*keys)
  return false unless (kw_hash = find_keyword_hash)

  nested_keyword_in?(kw_hash, keys)
end

#keyword_non_empty?(key) ⇒ Boolean

True when the keyword is present AND its value is a non-empty string literal OR any non-string expression (dynamic — can’t be statically proven empty, so treat as providing content). False when the key is absent or the value is an empty string literal.

Returns:

  • (Boolean)


61
62
63
64
65
66
67
68
69
70
71
# File 'lib/a11y/lint/call_node.rb', line 61

def keyword_non_empty?(key)
  return false unless (kw_hash = find_keyword_hash)

  assoc = kw_hash.elements.find { |a| key_name(a) == key.to_s }
  return false unless assoc

  value = assoc.value
  return !value.unescaped.empty? if value.is_a?(Prism::StringNode)

  true
end

#keyword_symbol?(key, expected) ⇒ Boolean

True when ‘key:` is present and its value is the symbol literal `:expected` (e.g. `keyword_symbol?(:as, :select)` matches `as: :select`).

Returns:

  • (Boolean)


33
34
35
36
37
38
39
40
# File 'lib/a11y/lint/call_node.rb', line 33

def keyword_symbol?(key, expected)
  return false unless (kw_hash = find_keyword_hash)

  assoc = kw_hash.elements.find { |a| key_name(a) == key.to_s }
  return false unless assoc&.value.is_a?(Prism::SymbolNode)

  assoc.value.unescaped == expected.to_s
end

#label_hidden?Boolean

True when the ‘label:` keyword is present and its value is `false` or an empty string literal — i.e. the helper is being told to omit any visible label.

Returns:

  • (Boolean)


45
46
47
48
49
50
51
52
53
54
# File 'lib/a11y/lint/call_node.rb', line 45

def label_hidden?
  return false unless (kw_hash = find_keyword_hash)

  assoc = kw_hash.elements.find { |a| key_name(a) == "label" }
  return false unless assoc

  value = assoc.value
  value.is_a?(Prism::FalseNode) ||
    (value.is_a?(Prism::StringNode) && value.unescaped.empty?)
end

#method_nameObject



15
16
17
# File 'lib/a11y/lint/call_node.rb', line 15

def method_name
  @prism_node.name.to_s
end

#positional_argsObject



73
74
75
76
77
78
79
# File 'lib/a11y/lint/call_node.rb', line 73

def positional_args
  return [] unless @prism_node.arguments

  @prism_node.arguments.arguments.reject do |a|
    a.is_a?(Prism::KeywordHashNode)
  end
end