Class: RubyLens::Index::LocationIndex

Inherits:
Object
  • Object
show all
Defined in:
lib/rubylens/index/location_index.rb

Overview

Answers the questions the collectors ask about a Rubydex location: which file it names, whether that file is in the workspace, whether it is test or core code, and which package owns it.

Rubydex hands out a fresh wrapper and a fresh URI string on every call and a codebase has far more definitions than files, so each answer is memoized by URI. That memoization is why the collectors can afford to ask per definition instead of hoisting the questions themselves.

Constant Summary collapse

TEST =

1 for a file under a test directory, 0 for any other workspace file.

1
CORE =
0
TEST_SEGMENTS =
%w[test tests spec specs feature features].freeze

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(manifest) ⇒ LocationIndex

The manifest is duck-typed: production passes a Manifest, tests pass stubs answering the same four questions.

: (untyped manifest) -> void



29
30
31
32
33
34
35
36
# File 'lib/rubylens/index/location_index.rb', line 29

def initialize(manifest)
  @manifest = manifest
  @path_by_uri = {}
  @workspace_by_uri = {}
  @scope_by_uri = {}
  @package_index_by_uri = {}
  @package_document_paths = Set.new
end

Instance Attribute Details

#package_document_pathsObject (readonly)

: Set



23
24
25
# File 'lib/rubylens/index/location_index.rb', line 23

def package_document_paths
  @package_document_paths
end

Instance Method Details

#package_index_for(location) ⇒ Object

Package attribution is deliberately limited to documents Rubydex actually indexed, so a path that merely sits inside a package root cannot claim it.

: (Rubydex::Location) -> Integer?



91
92
93
94
95
96
97
98
99
100
# File 'lib/rubylens/index/location_index.rb', line 91

def package_index_for(location)
  uri = location.uri
  @package_index_by_uri.fetch(uri) do
    path = path_for(uri)
    @package_index_by_uri[uri] =
      if path && @package_document_paths.include?(path)
        @manifest.package_index_for(path)
      end
  end
end

#path_for(uri) ⇒ Object

: (String) -> String?



57
58
59
60
61
# File 'lib/rubylens/index/location_index.rb', line 57

def path_for(uri)
  @path_by_uri.fetch(uri) do
    @path_by_uri[uri] = SourcePath.from_file_uri(uri)
  end
end

#resolve_documents(graph) ⇒ Object

One sweep over the indexed documents resolves each URI once, recording which of them belong to audited packages and returning the [document, path] pairs so callers need not re-enumerate or re-parse.

: (Rubydex::Graph) -> Array[[Rubydex::Document, String]]



43
44
45
46
47
48
49
50
51
52
53
54
# File 'lib/rubylens/index/location_index.rb', line 43

def resolve_documents(graph)
  audited = @manifest.packages.flat_map(&:files).to_set
  documents_with_paths = []
  graph.documents.each do |document|
    path = path_for(document.uri)
    next unless path

    documents_with_paths << [document, path]
    @package_document_paths << path if audited.include?(path)
  end
  documents_with_paths
end

#scope_for(uri) ⇒ Object

TEST, CORE, or nil when the URI has no workspace-relative path.

: (String) -> Integer?



77
78
79
80
81
82
83
84
85
# File 'lib/rubylens/index/location_index.rb', line 77

def scope_for(uri)
  @scope_by_uri.fetch(uri) do
    relative = @manifest.relative_workspace_path(path_for(uri))
    @scope_by_uri[uri] =
      if relative
        relative.split(File::SEPARATOR).any? { |segment| TEST_SEGMENTS.include?(segment) } ? TEST : CORE
      end
  end
end

#workspace?(location) ⇒ Boolean

: (Rubydex::Location) -> bool

Returns:

  • (Boolean)


64
65
66
67
68
69
70
71
72
# File 'lib/rubylens/index/location_index.rb', line 64

def workspace?(location)
  uri = location.uri
  @workspace_by_uri.fetch(uri) do
    path = path_for(uri)
    @workspace_by_uri[uri] = path ? @manifest.workspace_path?(path) : false
  end
rescue StandardError
  false
end