Class: Solargraph::Library
- Inherits:
-
Object
- Object
- Solargraph::Library
- Defined in:
- lib/solargraph/library.rb
Overview
A Library handles coordination between a Workspace and an ApiMap.
Class Method Summary collapse
-
.load(directory = '') ⇒ Solargraph::Library
Create a library from a directory.
Instance Method Summary collapse
-
#catalog ⇒ void
Update the ApiMap from the library’s workspace and open files.
-
#checkout(filename) ⇒ Source
Check a file out of the library.
-
#close(filename) ⇒ void
Close a file in the library.
-
#completions_at(filename, line, column) ⇒ SourceMap::Completion
Get completion suggestions at the specified file and location.
-
#contain?(filename) ⇒ Boolean
True if the specified file is included in the workspace (but not necessarily open).
-
#create(filename, text) ⇒ Boolean
Create a source to be added to the workspace.
-
#create_from_disk(filename) ⇒ Boolean
Create a file source from a file on disk.
-
#definitions_at(filename, line, column) ⇒ Array<Solargraph::Pin::Base>
Get definition suggestions for the expression at the specified file and location.
-
#delete(filename) ⇒ void
Delete a file from the library.
-
#diagnose(filename) ⇒ Array<Hash>
Get diagnostics about a file.
- #document(query) ⇒ Array<YARD::CodeObject::Base>
-
#document_symbols(filename) ⇒ Array<Solargraph::Pin::Base>
Get an array of document symbols.
-
#get_path_pins(path) ⇒ Array<Solargraph::Pin::Base>
Get an array of pins that match a path.
-
#initialize(workspace = Solargraph::Workspace.new) ⇒ Library
constructor
A new instance of Library.
-
#locate_pin(location) ⇒ Solargraph::Pin::Base
Get the pin at the specified location or nil if the pin does not exist.
-
#open(filename, text, version) ⇒ void
Open a file in the library.
-
#open?(filename) ⇒ Boolean
True if the specified file is currently open.
- #path_pins(path) ⇒ Array<Solargraph::Pin::Base>
-
#query_symbols(query) ⇒ Array<Pin::Base>
Get an array of all symbols in the workspace that match the query.
-
#read_text(filename) ⇒ String
Get the current text of a file in the library.
- #references_from(filename, line, column, strip: false) ⇒ Array<Solargraph::Range>
- #search(query) ⇒ Array<String>
-
#signatures_at(filename, line, column) ⇒ Array<Solargraph::Pin::Base>
Get signature suggestions for the method at the specified file and location.
-
#synchronized? ⇒ Boolean
True if the ApiMap is up to date with the library’s workspace and open files.
-
#update(updater) ⇒ void
Update a source in the library from the provided updater.
Constructor Details
#initialize(workspace = Solargraph::Workspace.new) ⇒ Library
Returns a new instance of Library.
6 7 8 9 10 11 |
# File 'lib/solargraph/library.rb', line 6 def initialize workspace = Solargraph::Workspace.new @mutex = Mutex.new @workspace = workspace api_map.catalog bundle @synchronized = true end |
Class Method Details
.load(directory = '') ⇒ Solargraph::Library
Create a library from a directory.
321 322 323 |
# File 'lib/solargraph/library.rb', line 321 def self.load directory = '' Solargraph::Library.new(Solargraph::Workspace.new(directory)) end |
Instance Method Details
#catalog ⇒ void
This method returns an undefined value.
Update the ApiMap from the library’s workspace and open files.
312 313 314 315 |
# File 'lib/solargraph/library.rb', line 312 def catalog api_map.catalog bundle @synchronized = true end |
#checkout(filename) ⇒ Source
Check a file out of the library. If the file is not part of the workspace, the ApiMap will virtualize it for mapping purposes. If filename is nil, any source currently checked out of the library will be removed from the ApiMap. Only one file can be checked out (virtualized) at a time.
216 217 218 |
# File 'lib/solargraph/library.rb', line 216 def checkout filename read filename end |
#close(filename) ⇒ void
This method returns an undefined value.
Close a file in the library. Closing a file will make it unavailable for checkout although it may still exist in the workspace.
109 110 111 112 113 114 |
# File 'lib/solargraph/library.rb', line 109 def close filename mutex.synchronize do open_file_hash.delete filename catalog end end |
#completions_at(filename, line, column) ⇒ SourceMap::Completion
Take a Location instead of filename/line/column
Get completion suggestions at the specified file and location.
123 124 125 126 127 |
# File 'lib/solargraph/library.rb', line 123 def completions_at filename, line, column position = Position.new(line, column) cursor = Source::Cursor.new(checkout(filename), position) api_map.clip(cursor).complete end |
#contain?(filename) ⇒ Boolean
True if the specified file is included in the workspace (but not necessarily open).
50 51 52 |
# File 'lib/solargraph/library.rb', line 50 def contain? filename workspace.has_file?(filename) end |
#create(filename, text) ⇒ Boolean
Create a source to be added to the workspace. The file is ignored if the workspace is not configured to include the file.
60 61 62 63 64 65 66 67 68 69 70 |
# File 'lib/solargraph/library.rb', line 60 def create filename, text result = false mutex.synchronize do next unless workspace.would_merge?(filename) source = Solargraph::Source.load_string(text, filename) workspace.merge(source) catalog #unless api_map.try_merge!(source) result = true end result end |
#create_from_disk(filename) ⇒ Boolean
Create a file source from a file on disk. The file is ignored if the workspace is not configured to include the file.
77 78 79 80 81 82 83 84 85 86 87 88 |
# File 'lib/solargraph/library.rb', line 77 def create_from_disk filename result = false mutex.synchronize do next if File.directory?(filename) or !File.exist?(filename) next unless workspace.would_merge?(filename) source = Solargraph::Source.load_string(File.read(filename), filename) workspace.merge(source) catalog #unless api_map.try_merge!(source) result = true end result end |
#definitions_at(filename, line, column) ⇒ Array<Solargraph::Pin::Base>
Take filename/position instead of filename/line/column
Get definition suggestions for the expression at the specified file and location.
137 138 139 140 141 |
# File 'lib/solargraph/library.rb', line 137 def definitions_at filename, line, column position = Position.new(line, column) cursor = Source::Cursor.new(checkout(filename), position) api_map.clip(cursor).define end |
#delete(filename) ⇒ void
This method returns an undefined value.
Delete a file from the library. Deleting a file will make it unavailable for checkout and optionally remove it from the workspace unless the workspace configuration determines that it should still exist.
96 97 98 99 100 101 102 |
# File 'lib/solargraph/library.rb', line 96 def delete filename mutex.synchronize do open_file_hash.delete filename workspace.remove filename catalog end end |
#diagnose(filename) ⇒ Array<Hash>
Get diagnostics about a file.
294 295 296 297 298 299 300 301 302 303 304 305 306 307 |
# File 'lib/solargraph/library.rb', line 294 def diagnose filename # @todo Only open files get diagnosed. Determine whether anything or # everything in the workspace should get diagnosed, or if there should # be an option to do so. return [] unless open?(filename) result = [] source = read(filename) workspace.config.reporters.each do |name| reporter = Diagnostics.reporter(name) raise DiagnosticsError, "Diagnostics reporter #{name} does not exist" if reporter.nil? result.concat reporter.new.diagnose(source, api_map) end result end |
#document(query) ⇒ Array<YARD::CodeObject::Base>
222 223 224 |
# File 'lib/solargraph/library.rb', line 222 def document query api_map.document query end |
#document_symbols(filename) ⇒ Array<Solargraph::Pin::Base>
Get an array of document symbols.
Document symbols are composed of namespace, method, and constant pins. The results of this query are appropriate for building the response to a textDocument/documentSymbol message in the language server protocol.
248 249 250 251 |
# File 'lib/solargraph/library.rb', line 248 def document_symbols filename return [] unless open_file_hash.has_key?(filename) api_map.document_symbols(filename) end |
#get_path_pins(path) ⇒ Array<Solargraph::Pin::Base>
Get an array of pins that match a path.
202 203 204 |
# File 'lib/solargraph/library.rb', line 202 def get_path_pins path api_map.get_path_suggestions(path) end |
#locate_pin(location) ⇒ Solargraph::Pin::Base
Get the pin at the specified location or nil if the pin does not exist.
194 195 196 |
# File 'lib/solargraph/library.rb', line 194 def locate_pin location api_map.locate_pin location end |
#open(filename, text, version) ⇒ void
This method returns an undefined value.
Open a file in the library. Opening a file will make it available for checkout and merge it into the workspace if applicable.
28 29 30 31 32 33 34 35 |
# File 'lib/solargraph/library.rb', line 28 def open filename, text, version mutex.synchronize do source = Solargraph::Source.load_string(text, filename, version) workspace.merge source open_file_hash[filename] = source catalog #unless api_map.try_merge!(source) end end |
#open?(filename) ⇒ Boolean
True if the specified file is currently open.
41 42 43 |
# File 'lib/solargraph/library.rb', line 41 def open? filename open_file_hash.has_key? filename end |
#path_pins(path) ⇒ Array<Solargraph::Pin::Base>
255 256 257 |
# File 'lib/solargraph/library.rb', line 255 def path_pins path api_map.get_path_suggestions(path) end |
#query_symbols(query) ⇒ Array<Pin::Base>
Get an array of all symbols in the workspace that match the query.
236 237 238 |
# File 'lib/solargraph/library.rb', line 236 def query_symbols query api_map.query_symbols query end |
#read_text(filename) ⇒ String
Get the current text of a file in the library.
285 286 287 288 |
# File 'lib/solargraph/library.rb', line 285 def read_text filename source = read(filename) source.code end |
#references_from(filename, line, column, strip: false) ⇒ Array<Solargraph::Range>
Take a Location instead of filename/line/column
163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 |
# File 'lib/solargraph/library.rb', line 163 def references_from filename, line, column, strip: false cursor = api_map.cursor_at(filename, Position.new(line, column)) clip = api_map.clip(cursor) pins = clip.define return [] if pins.empty? result = [] pins.uniq.each do |pin| (workspace.sources + open_file_hash.values).uniq.each do |source| found = source.references(pin.name) found.select! do |loc| referenced = definitions_at(loc.filename, loc.range.ending.line, loc.range.ending.character) referenced.any?{|r| r == pin} end # HACK for language clients that exclude special characters from the start of variable names if strip && match = cursor.word.match(/^[^a-z0-9_]+/) found.map! do |loc| Solargraph::Location.new(loc.filename, Solargraph::Range.from_to(loc.range.start.line, loc.range.start.column + match[0].length, loc.range.ending.line, loc.range.ending.column)) end end result.concat(found.sort{ |a, b| a.range.start.line <=> b.range.start.line }) end end result end |
#search(query) ⇒ Array<String>
228 229 230 |
# File 'lib/solargraph/library.rb', line 228 def search query api_map.search query end |
#signatures_at(filename, line, column) ⇒ Array<Solargraph::Pin::Base>
Take filename/position instead of filename/line/column
Get signature suggestions for the method at the specified file and location.
151 152 153 154 155 |
# File 'lib/solargraph/library.rb', line 151 def signatures_at filename, line, column position = Position.new(line, column) cursor = Source::Cursor.new(checkout(filename), position) api_map.clip(cursor).signify end |
#synchronized? ⇒ Boolean
True if the ApiMap is up to date with the library’s workspace and open files.
17 18 19 |
# File 'lib/solargraph/library.rb', line 17 def synchronized? @synchronized end |
#update(updater) ⇒ void
This method will not update the library’s ApiMap. See Library#ynchronized? and Library#catalog for more information.
This method returns an undefined value.
Update a source in the library from the provided updater.
268 269 270 271 272 273 274 275 276 277 278 279 |
# File 'lib/solargraph/library.rb', line 268 def update updater mutex.synchronize do if workspace.has_file?(updater.filename) workspace.synchronize!(updater) open_file_hash[updater.filename] = workspace.source(updater.filename) if open?(updater.filename) else raise FileNotFoundError, "Unable to update #{updater.filename}" unless open?(updater.filename) open_file_hash[updater.filename] = open_file_hash[updater.filename].synchronize(updater) end @synchronized = false end end |