holistic-ruby 0.1.4 → 0.1.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/Gemfile.lock +1 -1
- data/README.md +5 -5
- data/exe/holistic-ruby +0 -1
- data/lib/holistic/application.rb +12 -4
- data/lib/holistic/database/migrations.rb +23 -0
- data/lib/holistic/database/node.rb +37 -0
- data/lib/holistic/database/relation.rb +21 -0
- data/lib/holistic/database.rb +57 -0
- data/lib/holistic/document/file/record.rb +10 -0
- data/lib/holistic/document/file/repository.rb +24 -0
- data/lib/holistic/document/file/store.rb +13 -0
- data/lib/holistic/document/location.rb +4 -6
- data/lib/holistic/document/unsaved/record.rb +12 -3
- data/lib/holistic/extensions/ruby/stdlib.rb +8 -8
- data/lib/holistic/language_server/requests/lifecycle/initialize.rb +5 -10
- data/lib/holistic/language_server/requests/text_document/completion.rb +16 -5
- data/lib/holistic/language_server/requests/text_document/did_close.rb +5 -9
- data/lib/holistic/language_server/requests/text_document/did_open.rb +1 -0
- data/lib/holistic/language_server/requests/text_document/did_save.rb +5 -9
- data/lib/holistic/language_server/requests/text_document/find_references.rb +7 -4
- data/lib/holistic/language_server/requests/text_document/go_to_definition.rb +3 -2
- data/lib/holistic/language_server/stdio/parser.rb +2 -2
- data/lib/holistic/language_server/stdio/start.rb +1 -1
- data/lib/holistic/ruby/autocompletion/suggest.rb +45 -25
- data/lib/holistic/ruby/parser/constant_resolution.rb +11 -11
- data/lib/holistic/ruby/parser/live_editing/process_file_changed.rb +23 -23
- data/lib/holistic/ruby/parser/program_visitor.rb +62 -29
- data/lib/holistic/ruby/parser.rb +51 -11
- data/lib/holistic/ruby/reference/delete.rb +18 -0
- data/lib/holistic/ruby/reference/find_referenced_scope.rb +2 -2
- data/lib/holistic/ruby/reference/record.rb +15 -8
- data/lib/holistic/ruby/reference/repository.rb +19 -41
- data/lib/holistic/ruby/reference/store.rb +29 -0
- data/lib/holistic/ruby/scope/delete.rb +29 -0
- data/lib/holistic/ruby/scope/lexical.rb +11 -0
- data/lib/holistic/ruby/scope/list_class_methods.rb +19 -0
- data/lib/holistic/ruby/scope/list_instance_methods.rb +19 -0
- data/lib/holistic/ruby/scope/list_references.rb +3 -3
- data/lib/holistic/ruby/scope/location.rb +9 -9
- data/lib/holistic/ruby/scope/outline.rb +10 -10
- data/lib/holistic/ruby/scope/record.rb +20 -50
- data/lib/holistic/ruby/scope/repository.rb +29 -26
- data/lib/holistic/ruby/scope/store.rb +45 -0
- data/lib/holistic/ruby/type_inference/clue/method_call.rb +1 -0
- data/lib/holistic/ruby/type_inference/clue/reference_to_superclass.rb +9 -0
- data/lib/holistic/ruby/type_inference/clue/scope_reference.rb +1 -0
- data/lib/holistic/ruby/type_inference/processing_queue.rb +28 -0
- data/lib/holistic/ruby/type_inference/resolver/class_method.rb +9 -0
- data/lib/holistic/ruby/type_inference/resolver/instance_method.rb +9 -0
- data/lib/holistic/ruby/type_inference/resolver/scope.rb +24 -0
- data/lib/holistic/ruby/type_inference/solve.rb +25 -69
- data/lib/holistic/ruby/type_inference/solve_pending_references.rb +3 -1
- data/lib/holistic/version.rb +1 -1
- metadata +21 -10
- data/lib/holistic/database/table.rb +0 -78
- data/lib/holistic/document/file.rb +0 -36
- data/lib/holistic/ruby/parser/table_of_contents.rb +0 -17
- data/lib/holistic/ruby/reference/register.rb +0 -15
- data/lib/holistic/ruby/reference/unregister.rb +0 -11
- data/lib/holistic/ruby/scope/register.rb +0 -31
- data/lib/holistic/ruby/scope/unregister.rb +0 -27
- data/lib/holistic/ruby/type_inference/conclusion.rb +0 -20
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: b5eda7bf8e9da75eb3716452dfc2ebafdbaf35af0a53aef452c64bd95cd00bd8
|
4
|
+
data.tar.gz: 5522698edac5824011fd5aeee3ba4c71eb5cfee51b956c3d5942e329c7644072
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 06caa82194be9d2d2d9832aefd9132ab3d3cc1838be8b2cff9cd64f3fbafa36a9f0f79c40384eb4439adfd224a559605a9e328ae7dfb722235870b535f0d155f
|
7
|
+
data.tar.gz: a542c510078f1f528b4621000ba87843d0544e23dea77123bcf627e79d17f8dcdcb987be4122bd0f39c7f96533fc57d1a26e489e0cc25b6f5e0e5dfc68c436d3
|
data/Gemfile.lock
CHANGED
data/README.md
CHANGED
@@ -5,7 +5,7 @@
|
|
5
5
|
## Installation for Sublime Text
|
6
6
|
|
7
7
|
1. Make sure you have the [LSP package installed](https://github.com/sublimelsp/LSP).
|
8
|
-
2. Install the gem `$ gem install holistic-ruby`
|
8
|
+
2. Install the gem with `$ gem install holistic-ruby`
|
9
9
|
3. Go to `Preferences > Package Settings > LSP > Settings` and add:
|
10
10
|
|
11
11
|
```json
|
@@ -25,10 +25,10 @@
|
|
25
25
|
|
26
26
|
* Go to definition.
|
27
27
|
* Find references.
|
28
|
-
* Autocompletion for namespaces
|
29
|
-
*
|
30
|
-
*
|
31
|
-
* Glossary.
|
28
|
+
* Autocompletion for namespaces and methods.
|
29
|
+
* (WIP) Outline dependencies.
|
30
|
+
* (WIP) Syntax highlighting boundaries based on packwerk.
|
31
|
+
* (WIP) Glossary.
|
32
32
|
|
33
33
|
## Why is it a toy language server?
|
34
34
|
|
data/exe/holistic-ruby
CHANGED
data/lib/holistic/application.rb
CHANGED
@@ -2,12 +2,12 @@
|
|
2
2
|
|
3
3
|
module Holistic
|
4
4
|
class Application
|
5
|
-
attr_reader :name, :root_directory, :
|
5
|
+
attr_reader :name, :root_directory, :database
|
6
6
|
|
7
7
|
def initialize(name:, root_directory:)
|
8
8
|
@name = name
|
9
9
|
@root_directory = root_directory
|
10
|
-
@
|
10
|
+
@database = Database.new.tap(&Database::Migrations::Run)
|
11
11
|
end
|
12
12
|
|
13
13
|
def extensions
|
@@ -15,11 +15,19 @@ module Holistic
|
|
15
15
|
end
|
16
16
|
|
17
17
|
def scopes
|
18
|
-
@scopes ||= Ruby::Scope::Repository.new
|
18
|
+
@scopes ||= Ruby::Scope::Repository.new(database:)
|
19
19
|
end
|
20
20
|
|
21
21
|
def references
|
22
|
-
@references ||= Ruby::Reference::Repository.new
|
22
|
+
@references ||= Ruby::Reference::Repository.new(database:)
|
23
|
+
end
|
24
|
+
|
25
|
+
def files
|
26
|
+
@files ||= Document::File::Repository.new(database:)
|
27
|
+
end
|
28
|
+
|
29
|
+
def type_inference_processing_queue
|
30
|
+
@type_inference_processing_queue ||= Ruby::TypeInference::ProcessingQueue.new
|
23
31
|
end
|
24
32
|
|
25
33
|
def unsaved_documents
|
@@ -0,0 +1,23 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Holistic::Database::Migrations
|
4
|
+
Run = ->(database) do
|
5
|
+
# scope lexical parent-children relation
|
6
|
+
database.define_relation(name: :lexical_children, inverse_of: :lexical_parent)
|
7
|
+
|
8
|
+
# scope inheritance and mixins
|
9
|
+
database.define_relation(name: :ancestors, inverse_of: :descendants)
|
10
|
+
|
11
|
+
# type inference conclusion
|
12
|
+
database.define_relation(name: :referenced_scope, inverse_of: :referenced_by)
|
13
|
+
|
14
|
+
# reference definition
|
15
|
+
database.define_relation(name: :located_in_scope, inverse_of: :contains_many_references)
|
16
|
+
|
17
|
+
# scope location in files
|
18
|
+
database.define_relation(name: :defines_scopes, inverse_of: :scope_defined_in_file)
|
19
|
+
|
20
|
+
# reference location in files
|
21
|
+
database.define_relation(name: :defines_references, inverse_of: :reference_defined_in_file)
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
class Holistic::Database::Node
|
4
|
+
attr_accessor :attributes, :relations, :__database__
|
5
|
+
|
6
|
+
def initialize(id, attributes)
|
7
|
+
@id = id
|
8
|
+
@attributes = attributes
|
9
|
+
@relations = ::Hash.new(&method(:build_relation_hash))
|
10
|
+
end
|
11
|
+
|
12
|
+
def attr(attribute_name)
|
13
|
+
@attributes[attribute_name]
|
14
|
+
end
|
15
|
+
|
16
|
+
def relation(relation_name)
|
17
|
+
@relations[relation_name]
|
18
|
+
end
|
19
|
+
|
20
|
+
def has_many(connection_name)
|
21
|
+
@relations[connection_name].to_a
|
22
|
+
end
|
23
|
+
|
24
|
+
def has_one(connection_name)
|
25
|
+
@relations[connection_name].first
|
26
|
+
end
|
27
|
+
|
28
|
+
private
|
29
|
+
|
30
|
+
def build_relation_hash(hash, name)
|
31
|
+
inverse_of = __database__.relations.dig(name, :inverse_of)
|
32
|
+
|
33
|
+
raise ::ArgumentError, "unknown relation: #{name}" if inverse_of.nil?
|
34
|
+
|
35
|
+
hash[name] = ::Holistic::Database::Relation.new(node: self, name:, inverse_of:)
|
36
|
+
end
|
37
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
class Holistic::Database::Relation < ::Set
|
4
|
+
def initialize(node:, name:, inverse_of:)
|
5
|
+
@node = node
|
6
|
+
@name = name
|
7
|
+
@inverse_of = inverse_of
|
8
|
+
|
9
|
+
super()
|
10
|
+
end
|
11
|
+
|
12
|
+
def add!(related_node)
|
13
|
+
@node.relations[@name].add(related_node)
|
14
|
+
related_node.relations[@inverse_of].add(@node)
|
15
|
+
end
|
16
|
+
|
17
|
+
def delete!(related_node)
|
18
|
+
@node.relations[@name].delete(related_node)
|
19
|
+
related_node.relations[@inverse_of].delete(@node)
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,57 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
class Holistic::Database
|
4
|
+
attr_reader :records, :relations
|
5
|
+
|
6
|
+
def initialize
|
7
|
+
@records = ::Hash.new
|
8
|
+
@relations = ::Hash.new
|
9
|
+
end
|
10
|
+
|
11
|
+
def define_relation(name:, inverse_of:)
|
12
|
+
raise ::ArgumentError if @relations.key?(name) || @relations.key?(inverse_of)
|
13
|
+
|
14
|
+
@relations[name] = { inverse_of: }
|
15
|
+
@relations[inverse_of] = { inverse_of: name }
|
16
|
+
end
|
17
|
+
|
18
|
+
def store(id, node_or_attrs)
|
19
|
+
if @records.key?(id)
|
20
|
+
return @records[id]&.tap do |node|
|
21
|
+
node.attributes =
|
22
|
+
case node_or_attrs
|
23
|
+
in ::Hash then node_or_attrs
|
24
|
+
in Node then node_or_attrs.attributes
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
node =
|
30
|
+
case node_or_attrs
|
31
|
+
in ::Hash then Node.new(id, node_or_attrs)
|
32
|
+
in Node then node_or_attrs
|
33
|
+
end
|
34
|
+
|
35
|
+
node.__database__ = self
|
36
|
+
|
37
|
+
@records[id] = node
|
38
|
+
end
|
39
|
+
|
40
|
+
def find(id)
|
41
|
+
@records[id]
|
42
|
+
end
|
43
|
+
|
44
|
+
def delete(id)
|
45
|
+
records.delete(id)
|
46
|
+
end
|
47
|
+
|
48
|
+
concerning :TestHelpers do
|
49
|
+
def all
|
50
|
+
records.values
|
51
|
+
end
|
52
|
+
|
53
|
+
def size
|
54
|
+
records.size
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module ::Holistic::Document::File
|
4
|
+
class Repository
|
5
|
+
attr_reader :database
|
6
|
+
|
7
|
+
def initialize(database:)
|
8
|
+
@database = database
|
9
|
+
end
|
10
|
+
|
11
|
+
# rename to `find_file`
|
12
|
+
def find(file_path)
|
13
|
+
@database.find(file_path)
|
14
|
+
end
|
15
|
+
|
16
|
+
concerning :TestHelpers do
|
17
|
+
def build_fake_location(file_path)
|
18
|
+
file = Store.call(database:, file_path:)
|
19
|
+
|
20
|
+
::Holistic::Document::Location.new(file, 0, 0, 0, 0)
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -2,20 +2,18 @@
|
|
2
2
|
|
3
3
|
module Holistic::Document
|
4
4
|
Location = ::Data.define(
|
5
|
-
:
|
5
|
+
:file,
|
6
6
|
:start_line,
|
7
7
|
:start_column,
|
8
8
|
:end_line,
|
9
9
|
:end_column
|
10
10
|
) do
|
11
|
-
def
|
12
|
-
|
11
|
+
def identifier
|
12
|
+
"#{file.path}[#{start_line},#{start_column},#{end_line},#{end_column}]"
|
13
13
|
end
|
14
14
|
|
15
|
-
def identifier = "#{file_path}[#{start_line},#{start_column},#{end_line},#{end_column}]"
|
16
|
-
|
17
15
|
def contains?(cursor)
|
18
|
-
same_file = cursor.file_path ==
|
16
|
+
same_file = cursor.file_path == file.path
|
19
17
|
contains_line = cursor.line >= start_line && cursor.line <= end_line
|
20
18
|
|
21
19
|
contains_column =
|
@@ -54,6 +54,14 @@ module Holistic::Document
|
|
54
54
|
line = 0
|
55
55
|
column = 0
|
56
56
|
|
57
|
+
# first edition to the document is special because we can't iterate over the content to find the insert position.
|
58
|
+
# there is nothing to iterate over.
|
59
|
+
if @content.empty? && change.insertion?
|
60
|
+
@content = change.text
|
61
|
+
|
62
|
+
return
|
63
|
+
end
|
64
|
+
|
57
65
|
@content.each_char.with_index do |char, index|
|
58
66
|
if change.insertion? && change.starts_on?(line, column)
|
59
67
|
content.insert(index, change.text)
|
@@ -74,10 +82,11 @@ module Holistic::Document
|
|
74
82
|
column += 1
|
75
83
|
end
|
76
84
|
end
|
77
|
-
end
|
78
85
|
|
79
|
-
|
80
|
-
|
86
|
+
# off-by-one error to insert at the of the document
|
87
|
+
if change.insertion? && change.starts_on?(line, column)
|
88
|
+
content.insert(@content.length, change.text)
|
89
|
+
end
|
81
90
|
end
|
82
91
|
end
|
83
92
|
end
|
@@ -10,7 +10,7 @@ module Holistic::Extensions::Ruby
|
|
10
10
|
if method_call_clue.method_name == "new" && referenced_scope.class?
|
11
11
|
initialize_method = "#{referenced_scope.fully_qualified_name}#initialize"
|
12
12
|
|
13
|
-
return application.scopes.
|
13
|
+
return application.scopes.find(initialize_method)
|
14
14
|
end
|
15
15
|
|
16
16
|
nil
|
@@ -19,12 +19,12 @@ module Holistic::Extensions::Ruby
|
|
19
19
|
RegisterClassConstructor = ->(application, params) do
|
20
20
|
class_scope, location = params[:class_scope], params[:location]
|
21
21
|
|
22
|
-
has_overridden_new_method = class_scope.
|
22
|
+
has_overridden_new_method = class_scope.lexical_children.find { _1.instance_method? && _1.name == "initialize" }
|
23
23
|
|
24
24
|
unless has_overridden_new_method
|
25
|
-
::Holistic::Ruby::Scope::
|
26
|
-
|
27
|
-
|
25
|
+
::Holistic::Ruby::Scope::Store.call(
|
26
|
+
database: application.database,
|
27
|
+
lexical_parent: class_scope,
|
28
28
|
kind: ::Holistic::Ruby::Scope::Kind::CLASS_METHOD,
|
29
29
|
name: "new",
|
30
30
|
location:
|
@@ -38,9 +38,9 @@ module Holistic::Extensions::Ruby
|
|
38
38
|
lambda_scope, location = params[:lambda_scope], params[:location]
|
39
39
|
|
40
40
|
LAMBDA_METHODS.each do |method_name|
|
41
|
-
::Holistic::Ruby::Scope::
|
42
|
-
|
43
|
-
|
41
|
+
::Holistic::Ruby::Scope::Store.call(
|
42
|
+
database: application.database,
|
43
|
+
lexical_parent: lambda_scope,
|
44
44
|
kind: ::Holistic::Ruby::Scope::Kind::CLASS_METHOD,
|
45
45
|
name: method_name,
|
46
46
|
location:
|
@@ -14,23 +14,18 @@ module Holistic::LanguageServer
|
|
14
14
|
|
15
15
|
parse_application_in_background(application)
|
16
16
|
|
17
|
-
|
17
|
+
respond_with_language_server_capabilities(request)
|
18
18
|
end
|
19
19
|
|
20
20
|
private
|
21
21
|
|
22
22
|
def create_application(request)
|
23
|
-
::Holistic.logger.info("===========")
|
24
|
-
::Holistic.logger.info(request.message.inspect)
|
25
|
-
|
26
23
|
root_directory = request.param("rootPath")
|
27
24
|
name = ::File.basename(root_directory)
|
28
25
|
|
29
|
-
Current.application = ::Holistic::Application.new(name:, root_directory:)
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
Current.application
|
26
|
+
Current.application = ::Holistic::Application.new(name:, root_directory:).tap do |application|
|
27
|
+
::Holistic::Extensions::Ruby::Stdlib.register(application)
|
28
|
+
end
|
34
29
|
end
|
35
30
|
|
36
31
|
def advance_lifecycle_state
|
@@ -45,7 +40,7 @@ module Holistic::LanguageServer
|
|
45
40
|
end
|
46
41
|
end
|
47
42
|
|
48
|
-
def
|
43
|
+
def respond_with_language_server_capabilities(request)
|
49
44
|
request.respond_with({
|
50
45
|
capabilities: {
|
51
46
|
# Defines how the host (editor) should sync document changes to the language server.
|
@@ -9,20 +9,31 @@ module Holistic::LanguageServer
|
|
9
9
|
|
10
10
|
document = request.application.unsaved_documents.find(cursor.file_path)
|
11
11
|
|
12
|
-
|
12
|
+
if document.nil?
|
13
|
+
::Holistic.logger.info("aborting completion because document was not found for #{cursor.file_path}")
|
14
|
+
|
15
|
+
return request.respond_with(nil)
|
16
|
+
end
|
13
17
|
|
14
18
|
if document.has_unsaved_changes?
|
15
19
|
::Holistic::Ruby::Parser::LiveEditing::ProcessFileChanged.call(
|
16
20
|
application: request.application,
|
17
|
-
|
21
|
+
file_path: document.path,
|
22
|
+
content: document.content
|
18
23
|
)
|
19
24
|
end
|
20
25
|
|
21
26
|
code = document.expand_code(cursor)
|
22
|
-
|
23
|
-
return request.respond_with(nil) if code.blank?
|
24
27
|
|
25
|
-
|
28
|
+
if code.blank?
|
29
|
+
::Holistic.logger.info("aborting completion because code under cursor was blank: #{cursor.inspect}")
|
30
|
+
|
31
|
+
return request.respond_with(nil)
|
32
|
+
end
|
33
|
+
|
34
|
+
scope = request.application.scopes.find_inner_most_scope_by_cursor(cursor) || request.application.scopes.root
|
35
|
+
|
36
|
+
::Holistic.logger.info("scope under cursor is: #{scope.fully_qualified_name}")
|
26
37
|
|
27
38
|
suggestions = ::Holistic::Ruby::Autocompletion::Suggest.call(code:, scope:)
|
28
39
|
|
@@ -13,19 +13,15 @@ module Holistic::LanguageServer
|
|
13
13
|
if unsaved_document.has_unsaved_changes?
|
14
14
|
unsaved_document.restore_original_content!
|
15
15
|
|
16
|
-
|
16
|
+
::Holistic::Ruby::Parser::LiveEditing::ProcessFileChanged.call(
|
17
|
+
application: request.application,
|
18
|
+
file_path: unsaved_document.path,
|
19
|
+
content: unsaved_document.content
|
20
|
+
)
|
17
21
|
end
|
18
22
|
end
|
19
23
|
|
20
24
|
request.respond_with(nil)
|
21
25
|
end
|
22
|
-
|
23
|
-
private
|
24
|
-
|
25
|
-
def process_in_background(application:, file:)
|
26
|
-
::Holistic::BackgroundProcess.run do
|
27
|
-
::Holistic::Ruby::Parser::LiveEditing::ProcessFileChanged.call(application:, file:)
|
28
|
-
end
|
29
|
-
end
|
30
26
|
end
|
31
27
|
end
|
@@ -9,6 +9,7 @@ module Holistic::LanguageServer
|
|
9
9
|
content = request.message.param("textDocument", "text")
|
10
10
|
|
11
11
|
request.application.unsaved_documents.add(path:, content:)
|
12
|
+
::Holistic::Document::File::Store.call(database: request.application.database, file_path: path)
|
12
13
|
|
13
14
|
request.respond_with(nil)
|
14
15
|
end
|
@@ -17,17 +17,13 @@ module Holistic::LanguageServer
|
|
17
17
|
|
18
18
|
unsaved_document.mark_as_saved!
|
19
19
|
|
20
|
-
|
20
|
+
::Holistic::Ruby::Parser::LiveEditing::ProcessFileChanged.call(
|
21
|
+
application: request.application,
|
22
|
+
file_path: unsaved_document.path,
|
23
|
+
content: unsaved_document.content
|
24
|
+
)
|
21
25
|
|
22
26
|
request.respond_with(nil)
|
23
27
|
end
|
24
|
-
|
25
|
-
private
|
26
|
-
|
27
|
-
def process_in_background(application:, file:)
|
28
|
-
::Holistic::BackgroundProcess.run do
|
29
|
-
::Holistic::Ruby::Parser::LiveEditing::ProcessFileChanged.call(application:, file:)
|
30
|
-
end
|
31
|
-
end
|
32
28
|
end
|
33
29
|
end
|
@@ -12,7 +12,8 @@ module Holistic::LanguageServer
|
|
12
12
|
if unsaved_document.has_unsaved_changes?
|
13
13
|
::Holistic::Ruby::Parser::LiveEditing::ProcessFileChanged.call(
|
14
14
|
application: request.application,
|
15
|
-
|
15
|
+
file_path: unsaved_document.path,
|
16
|
+
content: unsaved_document.content
|
16
17
|
)
|
17
18
|
end
|
18
19
|
end
|
@@ -37,11 +38,13 @@ module Holistic::LanguageServer
|
|
37
38
|
|
38
39
|
def respond_with_locations(request, references)
|
39
40
|
locations = references.map do |reference|
|
41
|
+
location = reference.location
|
42
|
+
|
40
43
|
{
|
41
|
-
"uri" => Format::FileUri.from_path(
|
44
|
+
"uri" => Format::FileUri.from_path(location.file.path),
|
42
45
|
"range" => {
|
43
|
-
"start" => { "line" =>
|
44
|
-
"end" => { "line" =>
|
46
|
+
"start" => { "line" => location.start_line, "character" => location.start_column },
|
47
|
+
"end" => { "line" => location.end_line, "character" => location.end_column }
|
45
48
|
}
|
46
49
|
}
|
47
50
|
end
|
@@ -12,7 +12,8 @@ module Holistic::LanguageServer
|
|
12
12
|
if unsaved_document.has_unsaved_changes?
|
13
13
|
::Holistic::Ruby::Parser::LiveEditing::ProcessFileChanged.call(
|
14
14
|
application: request.application,
|
15
|
-
|
15
|
+
file_path: unsaved_document.path,
|
16
|
+
content: unsaved_document.content
|
16
17
|
)
|
17
18
|
end
|
18
19
|
end
|
@@ -46,7 +47,7 @@ module Holistic::LanguageServer
|
|
46
47
|
"start" => { "line" => origin_location.start_line, "character" => origin_location.start_column },
|
47
48
|
"end" => { "line" => origin_location.end_line, "character" => origin_location.end_column }
|
48
49
|
},
|
49
|
-
"targetUri" => Format::FileUri.from_path(target_declaration_location.
|
50
|
+
"targetUri" => Format::FileUri.from_path(target_declaration_location.file.path),
|
50
51
|
"targetRange" => {
|
51
52
|
"start" => { "line" => target_declaration_location.start_line, "character" => target_declaration_location.start_column },
|
52
53
|
"end" => { "line" => target_declaration_location.end_line, "character" => target_declaration_location.end_column }
|
@@ -11,7 +11,7 @@ module Holistic::LanguageServer
|
|
11
11
|
|
12
12
|
def ingest(payload)
|
13
13
|
payload.each_char do |char|
|
14
|
-
if @in_header || !
|
14
|
+
if @in_header || !has_complete_message?
|
15
15
|
@buffer.concat(char)
|
16
16
|
else
|
17
17
|
@overflow_from_previous_ingestion.concat(char)
|
@@ -23,7 +23,7 @@ module Holistic::LanguageServer
|
|
23
23
|
end
|
24
24
|
end
|
25
25
|
|
26
|
-
def
|
26
|
+
def has_complete_message?
|
27
27
|
!@in_header && @content_length == @buffer.length
|
28
28
|
end
|
29
29
|
|