Class: A11y::Lint::PhlexRunner::PhlexCall

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

Overview

Wraps a ‘Prism::CallNode` with the predicates and block accessors PhlexRunner uses to classify and traverse Phlex view code: tag vs helper, block form (`do…end`, `&block`, none), first positional arg, class values.

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(call_node) ⇒ PhlexCall

Returns a new instance of PhlexCall.



21
22
23
# File 'lib/a11y/lint/phlex_runner/phlex_call.rb', line 21

def initialize(call_node)
  @call_node = call_node
end

Instance Attribute Details

#call_nodeObject (readonly)

Returns the value of attribute call_node.



25
26
27
# File 'lib/a11y/lint/phlex_runner/phlex_call.rb', line 25

def call_node
  @call_node
end

Class Method Details

.wrap(node) ⇒ Object

Phlex tag/helper calls are always receiverless; a call like ‘helpers.image_tag(…)` has a receiver and is skipped.



15
16
17
18
19
# File 'lib/a11y/lint/phlex_runner/phlex_call.rb', line 15

def self.wrap(node)
  return unless node.is_a?(Prism::CallNode) && node.receiver.nil?

  new(node)
end

Instance Method Details

#arg_has_text?Boolean

Phlex’s tag API emits the first positional argument as text content (‘a(“Click me”, href: “/x”)` is equivalent to `a(href: “/x”) { “Click me” }`).

Returns:

  • (Boolean)


71
72
73
74
75
76
# File 'lib/a11y/lint/phlex_runner/phlex_call.rb', line 71

def arg_has_text?
  arg = first_positional_arg
  return false if arg.nil?

  BlockTextScanner.text_emitting?(arg)
end

#blockObject



43
44
45
# File 'lib/a11y/lint/phlex_runner/phlex_call.rb', line 43

def block
  call_node.block
end

#block_childrenObject



60
61
62
# File 'lib/a11y/lint/phlex_runner/phlex_call.rb', line 60

def block_children
  block_node ? block_node.child_nodes.compact : []
end

#block_has_text?(children = []) ⇒ Boolean

Returns:

  • (Boolean)


64
65
66
# File 'lib/a11y/lint/phlex_runner/phlex_call.rb', line 64

def block_has_text?(children = [])
  BlockTextScanner.scan(block_node, children: children)
end

#block_nodeObject

The block as a Prism::BlockNode, or nil for ‘&block` forwards and calls without a block.



49
50
51
# File 'lib/a11y/lint/phlex_runner/phlex_call.rb', line 49

def block_node
  block.is_a?(Prism::BlockNode) ? block : nil
end

#class_valuesObject



87
88
89
# File 'lib/a11y/lint/phlex_runner/phlex_call.rb', line 87

def class_values
  PhlexNode.kwarg_class_values(call_node)
end

#first_positional_argObject



78
79
80
81
82
83
84
85
# File 'lib/a11y/lint/phlex_runner/phlex_call.rb', line 78

def first_positional_arg
  return nil unless call_node.arguments

  call_node.arguments.arguments.find do |arg|
    !arg.is_a?(Prism::KeywordHashNode) &&
      !arg.is_a?(Prism::BlockArgumentNode)
  end
end

#forwarded_block?Boolean

‘tag(&block)` defers content to the caller; we can’t see what they emit, so trust the wrapper rather than report a false positive.

Returns:

  • (Boolean)


56
57
58
# File 'lib/a11y/lint/phlex_runner/phlex_call.rb', line 56

def forwarded_block?
  block.is_a?(Prism::BlockArgumentNode)
end

#helper?Boolean

Returns:

  • (Boolean)


39
40
41
# File 'lib/a11y/lint/phlex_runner/phlex_call.rb', line 39

def helper?
  !tag?
end

#lineObject



31
32
33
# File 'lib/a11y/lint/phlex_runner/phlex_call.rb', line 31

def line
  call_node.location.start_line
end

#nameObject



27
28
29
# File 'lib/a11y/lint/phlex_runner/phlex_call.rb', line 27

def name
  call_node.name.to_s
end

#tag?Boolean

Returns:

  • (Boolean)


35
36
37
# File 'lib/a11y/lint/phlex_runner/phlex_call.rb', line 35

def tag?
  PhlexNode.html_tag?(name)
end