Class: Ibex::LSP::DocumentStore

Inherits:
Object
  • Object
show all
Includes:
DocumentStoreDiagnostics, DocumentStoreValidation
Defined in:
lib/ibex/lsp/document_store.rb

Overview

Owns open buffers, parsed snapshots, include closures, and reverse dependencies.

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods included from DocumentStoreValidation

#valid_replacements?

Constructor Details

#initialize(workspace, loader) ⇒ DocumentStore

Returns a new instance of DocumentStore.



29
30
31
32
33
34
35
36
37
38
39
40
# File 'lib/ibex/lsp/document_store.rb', line 29

def initialize(workspace, loader)
  @workspace = workspace
  @loader = loader
  @analyzer = WorkspaceAnalyzer.new(workspace, loader)
  @snapshots = {} #: Hash[String, snapshot]
  @roots = {} #: Hash[String, bool]
  @closures = {} #: Hash[String, Array[String]]
  @reverse_dependencies = {} #: Hash[String, Array[String]]
  @resolutions = {} #: Hash[String, Frontend::Resolution]
  @document_diagnostics = {} #: Hash[String, Array[WorkspaceAnalyzer::lsp_diagnostic]]
  @root_diagnostics = {} #: Hash[String, Hash[String, Array[WorkspaceAnalyzer::lsp_diagnostic]]]
end

Instance Attribute Details

#loaderObject (readonly)

@rbs! type snapshot = { uri: String, path: String, version: Integer?, source: String, open: bool, document: Frontend::SourceDocument? } type publication = { uri: String, ?version: Integer, diagnostics: Array }



25
26
27
# File 'lib/ibex/lsp/document_store.rb', line 25

def loader
  @loader
end

#workspaceObject (readonly)

: Workspace



26
27
28
# File 'lib/ibex/lsp/document_store.rb', line 26

def workspace
  @workspace
end

Instance Method Details

#change(uri, version, source) ⇒ Object



55
56
57
58
59
60
61
62
63
64
65
66
67
# File 'lib/ibex/lsp/document_store.rb', line 55

def change(uri, version, source)
  path = workspace.path(uri)
  current = open_snapshot(path, uri)
  validate_version(version)
  unless current.fetch(:version) && version > current.fetch(:version)
    raise ProtocolError.new("document version must increase monotonically", code: -32_602)
  end

  validate_source(source)
  loader.set_overlay(path, source)
  @snapshots[path] = snapshot(uri, path, version, source, true, nil)
  refresh(path)
end

#close(uri) ⇒ Object

Clear the open version first, then replace it with a disk snapshot if one exists.



84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
# File 'lib/ibex/lsp/document_store.rb', line 84

def close(uri)
  path = workspace.path(uri)
  open_snapshot(path, uri)
  clear = { uri: uri, diagnostics: [] } #: publication
  old_files = files_for(path)
  was_root = @roots[path]
  disk_path = disk_path_for_close(path, uri)
  disk_source = loader.disk_source(disk_path) if disk_path && loader.disk_file?(disk_path)
  loader.delete_overlay(path)
  if disk_source
    @snapshots[path] = snapshot(uri, path, nil, disk_source, false, nil)
    if was_root
      analyzed = @analyzer.analyze(path)
      update_snapshot(path, analyzed)
      remove_root_state(path)
      [clear] + publish_paths((old_files + [path]).uniq)
    else
      [clear] + refresh(path)
    end
  else
    remove_path(path)
    [clear] + refresh_dependents(path)
  end
end

#files_for(path) ⇒ Object



124
125
126
127
128
# File 'lib/ibex/lsp/document_store.rb', line 124

def files_for(path)
  roots = affected_roots(path)
  files = roots.flat_map { |root| @closures.fetch(root, [root]) }
  (files + [path]).uniq
end

#open(uri, version, source) ⇒ Object

Raises:



43
44
45
46
47
48
49
50
51
52
# File 'lib/ibex/lsp/document_store.rb', line 43

def open(uri, version, source)
  path = workspace.path(uri)
  raise ProtocolError.new("document is already open: #{uri}", code: -32_602) if @snapshots.dig(path, :open)

  validate_version(version)
  validate_source(source)
  loader.set_overlay(path, source)
  @snapshots[path] = snapshot(uri, path, version, source, true, nil)
  refresh(path)
end

#resolutions_for(path) ⇒ Object



131
132
133
# File 'lib/ibex/lsp/document_store.rb', line 131

def resolutions_for(path)
  affected_roots(path).filter_map { |root| @resolutions[root] }
end

#roots_for(path) ⇒ Object



136
137
138
# File 'lib/ibex/lsp/document_store.rb', line 136

def roots_for(path)
  affected_roots(path)
end

#save(uri, source: nil) ⇒ Object



70
71
72
73
74
75
76
77
78
79
80
# File 'lib/ibex/lsp/document_store.rb', line 70

def save(uri, source: nil)
  path = workspace.path(uri)
  current = open_snapshot(path, uri)
  if source
    validate_source(source)
    loader.set_overlay(path, source)
    current = snapshot(uri, path, current.fetch(:version), source, true, nil)
    @snapshots[path] = current
  end
  refresh(path)
end

#snapshot_for(path) ⇒ Object



110
111
112
# File 'lib/ibex/lsp/document_store.rb', line 110

def snapshot_for(path)
  @snapshots[path]
end

#uri_for(path) ⇒ Object

Preserve the URI spelling used to open a document; closed files use their canonical URI.



116
117
118
119
120
121
# File 'lib/ibex/lsp/document_store.rb', line 116

def uri_for(path)
  entry = @snapshots[path]
  return entry.fetch(:uri) if entry&.fetch(:open)

  workspace.uri(path)
end