Module: MilkTea::LSP::Workspace::WorkspaceDependencyGraph

Included in:
MilkTea::LSP::Workspace
Defined in:
lib/milk_tea/lsp/workspace/dependency_graph.rb

Instance Method Summary collapse

Instance Method Details

#apply_watched_file_change(uri, change_type) ⇒ Object

Apply a workspace/didChangeWatchedFiles change to the indexed snapshot. Open documents are source-of-truth and are left untouched.



9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
# File 'lib/milk_tea/lsp/workspace/dependency_graph.rb', line 9

def apply_watched_file_change(uri, change_type)
  return [] if @document_state_mutex.synchronize { @open_documents.key?(uri) }

  if change_type.to_i == 3 # Deleted
    @document_state_mutex.synchronize do
      @indexed_documents.delete(uri)
    end
    invalidate_cache(uri)
    return refresh_import_dependent_caches(changed_uri: uri)
  end

  path = uri_to_path(uri)
  return [] unless path && File.file?(path)

  @document_state_mutex.synchronize do
    @indexed_documents[uri] = File.read(path)
  end
  invalidate_cache(uri)
  enqueue_definition_warmup(uri)
  affected_uris = refresh_import_dependent_caches(changed_uri: uri)
  if affected_uris.empty? && change_type.to_i == 1 # Created
    affected_uris = refresh_import_dependent_caches
    affected_uris.delete(uri)
  end
  affected_uris
rescue StandardError => e
  warn "LSP watched-file update error #{uri}: #{e.message}"
  []
end

#open_document_urisObject



46
47
48
49
50
# File 'lib/milk_tea/lsp/workspace/dependency_graph.rb', line 46

def open_document_uris
  @document_state_mutex.synchronize do
    @open_documents.keys.dup
  end
end

#refresh_open_document_dependency_caches(changed_uri) ⇒ Object



39
40
41
42
43
44
# File 'lib/milk_tea/lsp/workspace/dependency_graph.rb', line 39

def refresh_open_document_dependency_caches(changed_uri)
  path = uri_to_path(changed_uri)
  return [] unless path

  refresh_import_dependent_caches(changed_uri: changed_uri)
end

Returns open documents connected to seed_uri through the import dependency graph (imports and reverse dependents).



54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
# File 'lib/milk_tea/lsp/workspace/dependency_graph.rb', line 54

def related_open_document_uris(seed_uri)
  open_uris = @document_state_mutex.synchronize do
    @open_documents.keys.dup
  end
  return [] if open_uris.empty?

  @facts_cache_mutex.synchronize do
    open_uris.each do |uri|
      facts = @facts_cache[uri]
      update_dependency_index(uri, facts)
    end

    open_set = open_uris.to_set
    return [seed_uri] unless open_set.include?(seed_uri)

    module_to_uris = Hash.new { |hash, key| hash[key] = Set.new }
    open_uris.each do |uri|
      module_name = @dependency_module_name_by_uri[uri]
      module_to_uris[module_name] << uri if module_name
    end

    visited = Set.new
    queue = [seed_uri]

    until queue.empty?
      current = queue.shift
      next if visited.include?(current)

      visited << current

      current_module = @dependency_module_name_by_uri[current]
      if current_module
        @reverse_import_dependents[current_module].each do |dependent_uri|
          queue << dependent_uri if open_set.include?(dependent_uri) && !visited.include?(dependent_uri)
        end
      end

      imported_modules = @dependency_imports_by_uri[current] || Set.new
      imported_modules.each do |imported_module_name|
        module_to_uris[imported_module_name].each do |imported_uri|
          queue << imported_uri if open_set.include?(imported_uri) && !visited.include?(imported_uri)
        end
      end
    end

    visited.to_a
  end
end

#reverse_import_dependents_for(module_name) ⇒ Object



251
252
253
254
# File 'lib/milk_tea/lsp/workspace/dependency_graph.rb', line 251

def reverse_import_dependents_for(module_name)
  ensure_full_reverse_import_index
  @reverse_import_dependents[module_name]
end