Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 1 addition & 2 deletions lib/erb_lint/linters/allowed_script_type.rb
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,7 @@ class ConfigSchema < LinterConfig
self.config_schema = ConfigSchema

def run(processed_source)
parser = processed_source.parser
parser.nodes_with_type(:tag).each do |tag_node|
processed_source.tag_nodes.each do |tag_node|
tag = BetterHtml::Tree::Tag.from_node(tag_node)
next if tag.closing?
next unless tag.name == "script"
Expand Down
2 changes: 1 addition & 1 deletion lib/erb_lint/linters/closing_erb_tag_indent.rb
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ class ClosingErbTagIndent < Linter
END_SPACES = /([[:space:]]*)\z/m

def run(processed_source)
processed_source.ast.descendants(:erb).each do |erb_node|
processed_source.erb_nodes.each do |erb_node|
_, _, code_node, = *erb_node
code = code_node.children.first

Expand Down
2 changes: 1 addition & 1 deletion lib/erb_lint/linters/comment_syntax.rb
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ def run(processed_source)
file_content = processed_source.file_content
return if file_content.empty?

processed_source.ast.descendants(:erb).each do |erb_node|
processed_source.erb_nodes.each do |erb_node|
indicator_node, _, code_node, _ = *erb_node
next if code_node.nil?

Expand Down
2 changes: 1 addition & 1 deletion lib/erb_lint/linters/deprecated_classes.rb
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ def tags(processed_source)
end

def tag_nodes(processed_source)
processed_source.parser.nodes_with_type(:tag)
processed_source.tag_nodes
end

def generate_offenses(class_name, range)
Expand Down
3 changes: 1 addition & 2 deletions lib/erb_lint/linters/no_javascript_tag_helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,7 @@ class ConfigSchema < LinterConfig
self.config_schema = ConfigSchema

def run(processed_source)
parser = processed_source.parser
parser.ast.descendants(:erb).each do |erb_node|
processed_source.erb_nodes.each do |erb_node|
indicator_node, _, code_node, _ = *erb_node
indicator = indicator_node&.loc&.source
next if indicator == "#"
Expand Down
14 changes: 6 additions & 8 deletions lib/erb_lint/linters/require_input_autocomplete.rb
Original file line number Diff line number Diff line change
Expand Up @@ -42,16 +42,14 @@ class RequireInputAutocomplete < Linter
].freeze

def run(processed_source)
parser = processed_source.parser

find_html_input_tags(parser)
find_rails_helper_input_tags(parser)
find_html_input_tags(processed_source)
find_rails_helper_input_tags(processed_source)
end

private

def find_html_input_tags(parser)
parser.nodes_with_type(:tag).each do |tag_node|
def find_html_input_tags(processed_source)
processed_source.tag_nodes.each do |tag_node|
tag = BetterHtml::Tree::Tag.from_node(tag_node)

autocomplete_attribute = tag.attributes["autocomplete"]
Expand Down Expand Up @@ -82,8 +80,8 @@ def html_type_requires_autocomplete_attribute?(type_attribute)
type_present && HTML_INPUT_TYPES_REQUIRING_AUTOCOMPLETE.include?(type_attribute.value)
end

def find_rails_helper_input_tags(parser)
parser.ast.descendants(:erb).each do |erb_node|
def find_rails_helper_input_tags(processed_source)
processed_source.erb_nodes.each do |erb_node|
indicator_node, _, code_node, _ = *erb_node
source = code_node.loc.source
ruby_node = extract_ruby_node(source)
Expand Down
14 changes: 6 additions & 8 deletions lib/erb_lint/linters/require_script_nonce.rb
Original file line number Diff line number Diff line change
Expand Up @@ -11,16 +11,14 @@ class RequireScriptNonce < Linter
include LinterRegistry

def run(processed_source)
parser = processed_source.parser

find_html_script_tags(parser)
find_rails_helper_script_tags(parser)
find_html_script_tags(processed_source)
find_rails_helper_script_tags(processed_source)
end

private

def find_html_script_tags(parser)
parser.nodes_with_type(:tag).each do |tag_node|
def find_html_script_tags(processed_source)
processed_source.tag_nodes.each do |tag_node|
tag = BetterHtml::Tree::Tag.from_node(tag_node)
nonce_attribute = tag.attributes["nonce"]

Expand Down Expand Up @@ -52,8 +50,8 @@ def html_javascript_type_attribute?(tag)
type_attribute.value_node.to_a[1] != "application/javascript"
end

def find_rails_helper_script_tags(parser)
parser.ast.descendants(:erb).each do |erb_node|
def find_rails_helper_script_tags(processed_source)
processed_source.erb_nodes.each do |erb_node|
indicator_node, _, code_node, _ = *erb_node
source = code_node.loc.source
ruby_node = extract_ruby_node(source)
Expand Down
2 changes: 1 addition & 1 deletion lib/erb_lint/linters/right_trim.rb
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ class ConfigSchema < LinterConfig
self.config_schema = ConfigSchema

def run(processed_source)
processed_source.ast.descendants(:erb).each do |erb_node|
processed_source.erb_nodes.each do |erb_node|
_, _, _, trim_node = *erb_node
next if trim_node.nil? || trim_node.loc.source == @config.enforced_style

Expand Down
2 changes: 1 addition & 1 deletion lib/erb_lint/linters/rubocop.rb
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ def autocorrect(_processed_source, offense)
private

def descendant_nodes(processed_source)
processed_source.ast.descendants(:erb)
processed_source.erb_nodes
end

def inspect_content(processed_source, erb_node)
Expand Down
2 changes: 1 addition & 1 deletion lib/erb_lint/linters/self_closing_tag.rb
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ class ConfigSchema < LinterConfig
]

def run(processed_source)
processed_source.ast.descendants(:tag).each do |tag_node|
processed_source.tag_nodes.each do |tag_node|
tag = BetterHtml::Tree::Tag.from_node(tag_node)
next unless SELF_CLOSING_TAGS.include?(tag.name)

Expand Down
2 changes: 1 addition & 1 deletion lib/erb_lint/linters/space_around_erb_tag.rb
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ class SpaceAroundErbTag < Linter
END_SPACES = /([[:space:]]*)\z/m

def run(processed_source)
processed_source.ast.descendants(:erb).each do |erb_node|
processed_source.erb_nodes.each do |erb_node|
indicator_node, ltrim, code_node, rtrim = *erb_node
indicator = indicator_node&.loc&.source
next if indicator == "#" || indicator == "%"
Expand Down
2 changes: 1 addition & 1 deletion lib/erb_lint/linters/space_in_html_tag.rb
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ class SpaceInHtmlTag < Linter
include LinterRegistry

def run(processed_source)
processed_source.ast.descendants(:tag).each do |tag_node|
processed_source.tag_nodes.each do |tag_node|
start_solidus, name, attributes, end_solidus = *tag_node

next_loc = name&.loc&.begin_pos || attributes&.loc&.begin_pos ||
Expand Down
2 changes: 1 addition & 1 deletion lib/erb_lint/linters/strict_locals.rb
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ def run(processed_source)
file_content = processed_source.file_content
return if file_content.empty?

strict_locals_node = processed_source.ast.descendants(:erb).find do |erb_node|
strict_locals_node = processed_source.erb_nodes.find do |erb_node|
indicator_node, _, code_node, _ = *erb_node

indicator_node_str = indicator_node&.deconstruct&.last
Expand Down
9 changes: 9 additions & 0 deletions lib/erb_lint/processed_source.rb
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,15 @@ def ast
@parser.ast
end

# Memoized descendant lookups — many linters traverse the same node types
def erb_nodes
@erb_nodes ||= ast.descendants(:erb).to_a
end

def tag_nodes
@tag_nodes ||= parser.nodes_with_type(:tag).to_a
end

def source_buffer
@source_buffer ||= begin
buffer = Parser::Source::Buffer.new(filename)
Expand Down
49 changes: 49 additions & 0 deletions spec/erb_lint/processed_source_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
# frozen_string_literal: true

require "spec_helper"

describe ERBLint::ProcessedSource do
let(:file) { <<~FILE }
<div>
<script type="text/javascript">
var x = 1;
</script>
<input type="text" name="foo">
<%= helper_method %>
<% if condition %>
<span><%= value %></span>
<% end %>
</div>
FILE
let(:processed_source) { described_class.new("file.html.erb", file) }

describe "#erb_nodes" do
it "returns an array of erb nodes" do
expect(processed_source.erb_nodes).to(be_an(Array))
expect(processed_source.erb_nodes).not_to(be_empty)
end

it "returns the same object on subsequent calls" do
expect(processed_source.erb_nodes).to(equal(processed_source.erb_nodes))
end

it "matches ast.descendants(:erb)" do
expect(processed_source.erb_nodes).to(eq(processed_source.ast.descendants(:erb).to_a))
end
end

describe "#tag_nodes" do
it "returns an array of tag nodes" do
expect(processed_source.tag_nodes).to(be_an(Array))
expect(processed_source.tag_nodes).not_to(be_empty)
end

it "returns the same object on subsequent calls" do
expect(processed_source.tag_nodes).to(equal(processed_source.tag_nodes))
end

it "matches parser.nodes_with_type(:tag)" do
expect(processed_source.tag_nodes).to(eq(processed_source.parser.nodes_with_type(:tag).to_a))
end
end
end
Loading