<commit_before>require 'gherkin/tag_expression'
require 'gherkin/formatter/regexp_filter'
require 'gherkin/formatter/line_filter'

module Gherkin
  module Formatter
    class FilterFormatter
      def initialize(formatter, filters)
        @formatter = formatter
        @filter = detect_filter(filters)
        
        @header_events = []
        @feature_element_events = []
        @examples_events = []
      end

      def _feature(comments, tags, keyword, name, description, uri)
      end

      def _background(comments, keyword, name, description, line)
      end

      def _scenario(comments, tags, keyword, name, description, line)
      end

      def _scenario_outline(comments, tags, keyword, name, description, line)
      end

      def _examples(comments, tags, keyword, name, description, line, examples_table)
      end

      def _step(comments, keyword, name, line, multiline_arg, status, exception, arguments, stepdef_location)
      end

      def _eof
      end

    private

      def detect_filter(filters)
        raise "Inconsistent filters: #{filters.inspect}" if filters.map{|filter| filter.class}.uniq.length > 1
        case(filters[0])
        when Fixnum 
          LineFilter.new(filters)
        when Regexp 
          RegexpFilter.new(filters)
        when String 
          TagExpression.new(filters)
        end
      end

      def method_missing(*args)
        case(args[0])
        when :feature
          @header_events << args
          @feature_tags = args[2]
        when :background
          @header_events << args
        when :scenario, :scenario_outline
          replay!

          @feature_element_events.clear
          @feature_element_events << args
          
          case @filter
          when TagExpression
            @feature_element_tags = (@feature_tags + args[2]).uniq
            @feature_element_ok = @filter.eval(@feature_element_tags)
          when RegexpFilter
            @feature_element_name = args[4]
            @feature_element_ok = @filter.eval([@feature_element_name])
          when LineFilter
            @feature_element_start = args[6]
            @feature_element_end = args[6]
            @feature_element_ok = @filter.eval([feature_element_range])
          end
        when :examples
          replay!

          @examples_events.clear
          @examples_events << args

          case @filter
          when TagExpression
            examples_tags = (@feature_element_tags + args[2]).uniq
            @feature_element_ok = @filter.eval(examples_tags)
          when RegexpFilter
            examples_name = args[4]
            @feature_element_ok = @filter.eval([@feature_element_name, examples_name])
          when LineFilter
            examples_range = args[6]..args[7].last.line
            @feature_element_ok = @filter.eval([feature_element_range, examples_range])
          end
        when :step
          if @feature_element_events.any?
            @feature_element_events << args
            
            if LineFilter === @filter
              @feature_element_end = args[4]
              @feature_element_ok = @filter.eval([feature_element_range])
            end
          else
            @header_events << args
          end
        when :eof
          replay!
        else
          super
        end
      end<commit_msg>Don't use method_missing, to make it easier to port to Java.<commit_after>require 'gherkin/tag_expression'
require 'gherkin/formatter/regexp_filter'
require 'gherkin/formatter/line_filter'

module Gherkin
  module Formatter
    class FilterFormatter
      def initialize(formatter, filters)
        @formatter = formatter
        @filter = detect_filter(filters)
        
        @header_events = []
        @feature_element_events = []
        @examples_events = []
      end

      def feature(comments, tags, keyword, name, description, uri)
        @header_events << [:feature, comments, tags, keyword, name, description, uri]
        @feature_tags = tags
      end

      def background(comments, keyword, name, description, line)
        @header_events << [:background, comments, keyword, name, description, line]
      end

      def scenario(comments, tags, keyword, name, description, line)
        filter_scenario(:scenario, comments, tags, keyword, name, description, line)
      end

      def scenario_outline(comments, tags, keyword, name, description, line)
        filter_scenario(:scenario_outline, comments, tags, keyword, name, description, line)
      end

      def examples(comments, tags, keyword, name, description, line, examples_table)
        replay!

        @examples_events.clear
        @examples_events << [:examples, comments, tags, keyword, name, description, line, examples_table]

        case @filter
        when TagExpression
          examples_tags = (@feature_element_tags + tags).uniq
          @feature_element_ok = @filter.eval(examples_tags)
        when RegexpFilter
          examples_name = name
          @feature_element_ok = @filter.eval([@feature_element_name, examples_name])
        when LineFilter
          examples_range = line..examples_table.last.line
          @feature_element_ok = @filter.eval([feature_element_range, examples_range])
        end
      end

      def step(comments, keyword, name, line, multiline_arg, status, exception, arguments, stepdef_location)
        args = [:step, comments, keyword, name, line, multiline_arg, status, exception, arguments, stepdef_location]
        if @feature_element_events.any?
          @feature_element_events << args
          
          if LineFilter === @filter
            @feature_element_end = line
            @feature_element_ok = @filter.eval([feature_element_range])
          end
        else
          @header_events << args
        end
      end

      def eof
        replay!
        @formatter.eof
      end

    private

      def detect_filter(filters)
        raise "Inconsistent filters: #{filters.inspect}" if filters.map{|filter| filter.class}.uniq.length > 1
        case(filters[0])
        when Fixnum 
          LineFilter.new(filters)
        when Regexp 
          RegexpFilter.new(filters)
        when String 
          TagExpression.new(filters)
        end
      end

      def filter_scenario(method, comments, tags, keyword, name, description, line)
        replay!

        @feature_element_events.clear
        @feature_element_events << [method, comments, tags, keyword, name, description, line]
        
        case @filter
        when TagExpression
          @feature_element_tags = (@feature_tags + tags).uniq
          @feature_element_ok = @filter.eval(@feature_element_tags)
        when RegexpFilter
          @feature_element_name = name
          @feature_element_ok = @filter.eval([@feature_element_name])
        when LineFilter
          @feature_element_start = line
          @feature_element_end = line
          @feature_element_ok = @filter.eval([feature_element_range])
        end
      end
{'fraction_non_alphanumeric': 0.08241522392330805, 'fraction_numerical': 0.0021462297896694808, 'mean_word_length': 2.2956152758132955, 'pattern_counts': {'":': 0, '<': 27, '<?xml version=': 0, '>': 5, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6707438', 'n_tokens_mistral': 1924, 'n_tokens_neox': 1858, 'n_words': 446}