<commit_before>module Wool
  module SexpAnalysis
    # This class models a scope in Ruby. It has a constant table,
    # a self pointer, and a parent pointer to the enclosing scope.
    # It also has a local variable table.
    class Scope
      class ScopeLookupFailure < StandardError
        attr_reader :scope, :query
        def initialize(scope, query)
          @scope, @query = scope, query
          super("Scope #{@scope.inspect} does not contain #{query.inspect}")
        end
      end

      attr_accessor :constants, :self_ptr, :parent, :locals
      def initialize(parent, self_ptr, constants={}, locals={})
        @parent, @self_ptr, @constants, @locals = parent, self_ptr, constants, locals
      end
      
      def path
        self_ptr.class_used.path
      end

      def lookup_or_create_module(new_mod_name)
        begin
          lookup(new_mod_name).scope
        rescue Scope::ScopeLookupFailure => err
          new_mod_full_path = self == GlobalScope ? '' : path
          new_mod_full_path += "::" unless new_mod_full_path.empty?
          new_mod_full_path += new_mod_name
          # gotta swizzle in the new scope because the module we create is creating
          # the new scope!
          new_scope = Scope.new(self, nil)
          new_mod = WoolModule.new(new_mod_full_path, new_scope)
          new_scope
        end
      end

      def lookup(str)
        if str =~ /^[A-Z]/ && constants[str]
        then constants[str]
        elsif locals[str[0,1]]
        else raise ScopeLookupFailure.new(self, str)
        end
      end

      def lookup_path(path)
        parts = path.split('::')
        parts.inject(self) { |scope, part| scope.lookup(part).scope }
      end
    end
  end
end<commit_msg>Made 'self' be tracked in the @locals hash for scopes.<commit_after>module Wool
  module SexpAnalysis
    # This class models a scope in Ruby. It has a constant table,
    # a self pointer, and a parent pointer to the enclosing scope.
    # It also has a local variable table.
    class Scope
      class ScopeLookupFailure < StandardError
        attr_reader :scope, :query
        def initialize(scope, query)
          @scope, @query = scope, query
          super("Scope #{@scope.inspect} does not contain #{query.inspect}")
        end
      end

      attr_accessor :constants, :self_ptr, :parent, :locals
      def initialize(parent, self_ptr, constants={}, locals={})
        @parent, @self_ptr, @constants, @locals = parent, self_ptr, constants, locals
        @locals['self'] = self_ptr
      end
      
      def self_ptr=(other)
        @self_ptr = other
        @locals['self'] = other
      end
      
      def path
        self_ptr.class_used.path
      end

      def lookup_or_create_module(new_mod_name)
        begin
          lookup(new_mod_name).scope
        rescue Scope::ScopeLookupFailure => err
          new_mod_full_path = self == GlobalScope ? '' : path
          new_mod_full_path += "::" unless new_mod_full_path.empty?
          new_mod_full_path += new_mod_name
          # gotta swizzle in the new scope because the module we create is creating
          # the new scope!
          new_scope = Scope.new(self, nil)
          new_mod = WoolModule.new(new_mod_full_path, new_scope)
          new_scope
        end
      end

      def lookup(str)
        if str =~ /^[A-Z]/ && constants[str]
        then constants[str]
        elsif locals[str[0,1]]
        else raise ScopeLookupFailure.new(self, str)
        end
      end

      def lookup_path(path)
        parts = path.split('::')
        parts.inject(self) { |scope, part| scope.lookup(part).scope }
      end
    end
  end
end
{'fraction_non_alphanumeric': 0.08939311098961181, 'fraction_numerical': 0.0010934937124111536, 'mean_word_length': 2.22663139329806, 'pattern_counts': {'":': 2, '<': 5, '<?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': '6058529', 'n_tokens_mistral': 1093, 'n_tokens_neox': 1082, 'n_words': 317}