# frozen_string_literal: true module ThemeCheck class Analyzer def initialize(theme, checks = Check.all.map(&:new), auto_correct = false) @theme = theme @auto_correct = auto_correct @liquid_checks = Checks.new @json_checks = Checks.new @html_checks = Checks.new checks.each do |check| check.theme = @theme case check when LiquidCheck @liquid_checks << check when JsonCheck @json_checks << check when HtmlCheck @html_checks << check end end end def offenses @liquid_checks.flat_map(&:offenses) + @json_checks.flat_map(&:offenses) + @html_checks.flat_map(&:offenses) end def json_file_count @json_file_count ||= @theme.json.size end def liquid_file_count @liquid_file_count ||= @theme.liquid.size end def total_file_count json_file_count + liquid_file_count end def analyze_theme reset liquid_visitor = LiquidVisitor.new(@liquid_checks, @disabled_checks) html_visitor = HtmlVisitor.new(@html_checks) ThemeCheck.with_liquid_c_disabled do @theme.liquid.each_with_index do |liquid_file, i| yield(liquid_file.relative_path.to_s, i, total_file_count) if block_given? liquid_visitor.visit_liquid_file(liquid_file) html_visitor.visit_liquid_file(liquid_file) end end @theme.json.each_with_index do |json_file, i| yield(json_file.relative_path.to_s, liquid_file_count + i, total_file_count) if block_given? @json_checks.call(:on_file, json_file) end finish end def analyze_files(files) reset ThemeCheck.with_liquid_c_disabled do # Call all checks that run on the whole theme liquid_visitor = LiquidVisitor.new(@liquid_checks.whole_theme, @disabled_checks) html_visitor = HtmlVisitor.new(@html_checks.whole_theme) total = total_file_count + files.size @theme.liquid.each_with_index do |liquid_file, i| yield(liquid_file.relative_path.to_s, i, total) if block_given? liquid_visitor.visit_liquid_file(liquid_file) html_visitor.visit_liquid_file(liquid_file) end @theme.json.each_with_index do |json_file, i| yield(json_file.relative_path.to_s, liquid_file_count + i, total) if block_given? @json_checks.whole_theme.call(:on_file, json_file) end # Call checks that run on a single files, only on specified file liquid_visitor = LiquidVisitor.new(@liquid_checks.single_file, @disabled_checks) html_visitor = HtmlVisitor.new(@html_checks.single_file) files.each_with_index do |theme_file, i| yield(theme_file.relative_path.to_s, total_file_count + i, total) if block_given? if theme_file.liquid? liquid_visitor.visit_liquid_file(theme_file) html_visitor.visit_liquid_file(theme_file) elsif theme_file.json? @json_checks.single_file.call(:on_file, theme_file) end end end finish end def uncorrectable_offenses unless @auto_correct return offenses end offenses.select { |offense| !offense.correctable? } end def correct_offenses if @auto_correct offenses.each(&:correct) end end def write_corrections if @auto_correct @theme.liquid.each(&:write) @theme.json.each(&:write) end end private def reset @disabled_checks = DisabledChecks.new @liquid_checks.each do |check| check.offenses.clear end @html_checks.each do |check| check.offenses.clear end @json_checks.each do |check| check.offenses.clear end end def finish @liquid_checks.call(:on_end) @html_checks.call(:on_end) @json_checks.call(:on_end) @disabled_checks.remove_disabled_offenses(@liquid_checks) @disabled_checks.remove_disabled_offenses(@json_checks) @disabled_checks.remove_disabled_offenses(@html_checks) offenses end end end