lib/ruby_indexer/lib/ruby_indexer/index.rb in ruby-lsp-0.11.2 vs lib/ruby_indexer/lib/ruby_indexer/index.rb in ruby-lsp-0.12.0

- old
+ new

@@ -93,11 +93,11 @@ # [#<Entry::Class name="Foo::Baz">], # ] # ``` sig { params(query: String, nesting: T::Array[String]).returns(T::Array[T::Array[Entry]]) } def prefix_search(query, nesting) - results = (nesting.length + 1).downto(0).flat_map do |i| + results = nesting.length.downto(0).flat_map do |i| prefix = T.must(nesting[0...i]).join("::") namespaced_query = prefix.empty? ? query : "#{prefix}::#{query}" @entries_tree.search(namespaced_query) end @@ -151,19 +151,37 @@ nil rescue UnresolvableAliasError nil end - sig { params(indexable_paths: T::Array[IndexablePath]).void } - def index_all(indexable_paths: RubyIndexer.configuration.indexables) - indexable_paths.each { |path| index_single(path) } + # Index all files for the given indexable paths, which defaults to what is configured. A block can be used to track + # and control indexing progress. That block is invoked with the current progress percentage and should return `true` + # to continue indexing or `false` to stop indexing. + sig do + params( + indexable_paths: T::Array[IndexablePath], + block: T.nilable(T.proc.params(progress: Integer).returns(T::Boolean)), + ).void end + def index_all(indexable_paths: RubyIndexer.configuration.indexables, &block) + # Calculate how many paths are worth 1% of progress + progress_step = (indexable_paths.length / 100.0).ceil + indexable_paths.each_with_index do |path, index| + if block && index % progress_step == 0 + progress = (index / progress_step) + 1 + break unless block.call(progress) + end + + index_single(path) + end + end + sig { params(indexable_path: IndexablePath, source: T.nilable(String)).void } def index_single(indexable_path, source = nil) content = source || File.read(indexable_path.full_path) - result = YARP.parse(content) + result = Prism.parse(content) visitor = IndexVisitor.new(self, result, indexable_path.full_path) result.value.accept(visitor) require_path = indexable_path.require_path @require_paths_tree.insert(require_path, indexable_path) if require_path @@ -231,109 +249,8 @@ original_entries << resolved_alias @entries_tree.insert(entry.name, original_entries) resolved_alias - end - - class Entry - extend T::Sig - - sig { returns(String) } - attr_reader :name - - sig { returns(String) } - attr_reader :file_path - - sig { returns(YARP::Location) } - attr_reader :location - - sig { returns(T::Array[String]) } - attr_reader :comments - - sig { returns(Symbol) } - attr_accessor :visibility - - sig { params(name: String, file_path: String, location: YARP::Location, comments: T::Array[String]).void } - def initialize(name, file_path, location, comments) - @name = name - @file_path = file_path - @location = location - @comments = comments - @visibility = T.let(:public, Symbol) - end - - sig { returns(String) } - def file_name - File.basename(@file_path) - end - - class Namespace < Entry - sig { returns(String) } - def short_name - T.must(@name.split("::").last) - end - end - - class Module < Namespace - end - - class Class < Namespace - end - - class Constant < Entry - end - - # An UnresolvedAlias points to a constant alias with a right hand side that has not yet been resolved. For - # example, if we find - # - # ```ruby - # CONST = Foo - # ``` - # Before we have discovered `Foo`, there's no way to eagerly resolve this alias to the correct target constant. - # All aliases are inserted as UnresolvedAlias in the index first and then we lazily resolve them to the correct - # target in [rdoc-ref:Index#resolve]. If the right hand side contains a constant that doesn't exist, then it's not - # possible to resolve the alias and it will remain an UnresolvedAlias until the right hand side constant exists - class UnresolvedAlias < Entry - extend T::Sig - - sig { returns(String) } - attr_reader :target - - sig { returns(T::Array[String]) } - attr_reader :nesting - - sig do - params( - target: String, - nesting: T::Array[String], - name: String, - file_path: String, - location: YARP::Location, - comments: T::Array[String], - ).void - end - def initialize(target, nesting, name, file_path, location, comments) # rubocop:disable Metrics/ParameterLists - super(name, file_path, location, comments) - - @target = target - @nesting = nesting - end - end - - # Alias represents a resolved alias, which points to an existing constant target - class Alias < Entry - extend T::Sig - - sig { returns(String) } - attr_reader :target - - sig { params(target: String, unresolved_alias: UnresolvedAlias).void } - def initialize(target, unresolved_alias) - super(unresolved_alias.name, unresolved_alias.file_path, unresolved_alias.location, unresolved_alias.comments) - - @target = target - end - end end end end