refined-steep-server 0.1.0

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.
@@ -0,0 +1,150 @@
1
+ # rbs_inline: enabled
2
+ # frozen_string_literal: true
3
+
4
+ module Refined
5
+ module Steep
6
+ module Server
7
+ Interface = LanguageServer::Protocol::Interface
8
+ Constant = LanguageServer::Protocol::Constant
9
+ Transport = LanguageServer::Protocol::Transport
10
+
11
+ class Message
12
+ attr_reader :method #: String
13
+ attr_reader :params #: untyped
14
+
15
+ # @rbs method: String
16
+ # @rbs params: untyped
17
+ # @rbs return: void
18
+ def initialize(method:, params:)
19
+ @method = method
20
+ @params = params
21
+ end
22
+
23
+ # @rbs return: Hash[Symbol, untyped]
24
+ def to_hash
25
+ raise NotImplementedError
26
+ end
27
+ end
28
+
29
+ class Notification < Message
30
+ class << self
31
+ # @rbs message: String
32
+ # @rbs type: Integer
33
+ # @rbs return: Notification
34
+ def window_show_message(message, type: Constant::MessageType::INFO)
35
+ new(
36
+ method: "window/showMessage",
37
+ params: Interface::ShowMessageParams.new(type: type, message: message),
38
+ )
39
+ end
40
+
41
+ # @rbs message: String
42
+ # @rbs type: Integer
43
+ # @rbs return: Notification
44
+ def window_log_message(message, type: Constant::MessageType::LOG)
45
+ new(
46
+ method: "window/logMessage",
47
+ params: Interface::LogMessageParams.new(type: type, message: message),
48
+ )
49
+ end
50
+
51
+ # @rbs uri: String
52
+ # @rbs diagnostics: Array[untyped]
53
+ # @rbs version: Integer?
54
+ # @rbs return: Notification
55
+ def publish_diagnostics(uri, diagnostics, version: nil)
56
+ new(
57
+ method: "textDocument/publishDiagnostics",
58
+ params: Interface::PublishDiagnosticsParams.new(uri: uri, diagnostics: diagnostics, version: version),
59
+ )
60
+ end
61
+ end
62
+
63
+ # @rbs return: Hash[Symbol, untyped]
64
+ def to_hash
65
+ hash = { method: @method } #: Hash[Symbol, untyped]
66
+
67
+ if @params
68
+ hash[:params] = @params.to_hash
69
+ end
70
+
71
+ hash
72
+ end
73
+ end
74
+
75
+ class Request < Message
76
+ # @rbs @id: Integer | String
77
+
78
+ # @rbs id: Integer | String
79
+ # @rbs method: String
80
+ # @rbs params: untyped
81
+ # @rbs return: void
82
+ def initialize(id:, method:, params:)
83
+ @id = id
84
+ super(method: method, params: params)
85
+ end
86
+
87
+ # @rbs return: Hash[Symbol, untyped]
88
+ def to_hash
89
+ hash = { id: @id, method: @method } #: Hash[Symbol, untyped]
90
+
91
+ if @params
92
+ hash[:params] = @params.to_hash
93
+ end
94
+
95
+ hash
96
+ end
97
+ end
98
+
99
+ class ErrorResponse
100
+ # @rbs @id: Integer
101
+ # @rbs @data: Hash[Symbol, untyped]?
102
+
103
+ attr_reader :message #: String
104
+ attr_reader :code #: Integer
105
+
106
+ # @rbs id: Integer
107
+ # @rbs code: Integer
108
+ # @rbs message: String
109
+ # @rbs data: Hash[Symbol, untyped]?
110
+ # @rbs return: void
111
+ def initialize(id:, code:, message:, data: nil)
112
+ @id = id
113
+ @code = code
114
+ @message = message
115
+ @data = data
116
+ end
117
+
118
+ # @rbs return: Hash[Symbol, untyped]
119
+ def to_hash
120
+ {
121
+ id: @id,
122
+ error: {
123
+ code: @code,
124
+ message: @message,
125
+ data: @data,
126
+ },
127
+ }
128
+ end
129
+ end
130
+
131
+ class Result
132
+ attr_reader :response #: untyped
133
+ attr_reader :id #: Integer
134
+
135
+ # @rbs id: Integer
136
+ # @rbs response: untyped
137
+ # @rbs return: void
138
+ def initialize(id:, response:)
139
+ @id = id
140
+ @response = response
141
+ end
142
+
143
+ # @rbs return: Hash[Symbol, untyped]
144
+ def to_hash
145
+ { id: @id, result: @response }
146
+ end
147
+ end
148
+ end
149
+ end
150
+ end
@@ -0,0 +1,80 @@
1
+ # rbs_inline: enabled
2
+ # frozen_string_literal: true
3
+
4
+ module Refined
5
+ module Steep
6
+ module Server
7
+ class SteepState
8
+ # @rbs @buffered_changes: Hash[Pathname, Array[::Steep::Services::ContentChange]]
9
+
10
+ attr_reader :project #: ::Steep::Project
11
+ attr_reader :type_check_service #: ::Steep::Services::TypeCheckService
12
+ attr_reader :assignment #: ::Steep::Services::PathAssignment
13
+ attr_reader :mutex #: Mutex
14
+
15
+ # @rbs steepfile_path: Pathname
16
+ # @rbs return: void
17
+ def initialize(steepfile_path:)
18
+ @mutex = Mutex.new
19
+ @project = load_project(steepfile_path)
20
+ @type_check_service = ::Steep::Services::TypeCheckService.new(project: @project)
21
+ @assignment = ::Steep::Services::PathAssignment.all
22
+ @buffered_changes = {}
23
+ end
24
+
25
+ # @rbs path: Pathname
26
+ # @rbs changes: Array[::Steep::Services::ContentChange]
27
+ # @rbs return: void
28
+ def push_changes(path, changes)
29
+ @mutex.synchronize do
30
+ existing = @buffered_changes[path]
31
+ unless existing
32
+ existing = [] #: Array[::Steep::Services::ContentChange]
33
+ @buffered_changes[path] = existing
34
+ end
35
+ existing.concat(changes)
36
+ end
37
+ end
38
+
39
+ # @rbs return: Hash[Pathname, Array[::Steep::Services::ContentChange]]
40
+ def flush_changes
41
+ @mutex.synchronize do
42
+ copy = @buffered_changes.dup
43
+ @buffered_changes.clear
44
+ copy
45
+ end
46
+ end
47
+
48
+ # @rbs return: void
49
+ def apply_changes
50
+ changes = flush_changes
51
+ type_check_service.update(changes: changes) unless changes.empty?
52
+ end
53
+
54
+ # @rbs path: Pathname
55
+ # @rbs return: ::Steep::Project::Target?
56
+ def target_for_path(path)
57
+ project.target_for_source_path(path) ||
58
+ project.target_for_signature_path(path)
59
+ end
60
+
61
+ # @rbs target_name: Symbol
62
+ # @rbs return: ::Steep::Services::SignatureService?
63
+ def signature_service_for(target_name)
64
+ type_check_service.signature_services[target_name]
65
+ end
66
+
67
+ private
68
+
69
+ # @rbs steepfile_path: Pathname
70
+ # @rbs return: ::Steep::Project
71
+ def load_project(steepfile_path)
72
+ path = steepfile_path.expand_path
73
+ ::Steep::Project.new(steepfile_path: path).tap do |project|
74
+ ::Steep::Project::DSL.parse(project, path.read, filename: path.to_s)
75
+ end
76
+ end
77
+ end
78
+ end
79
+ end
80
+ end
@@ -0,0 +1,113 @@
1
+ # rbs_inline: enabled
2
+ # frozen_string_literal: true
3
+
4
+ module Refined
5
+ module Steep
6
+ module Server
7
+ class Store
8
+ class DocumentEntry
9
+ attr_reader :uri #: String
10
+ attr_reader :content #: String
11
+ attr_reader :version #: Integer
12
+
13
+ # @rbs uri: String
14
+ # @rbs content: String
15
+ # @rbs version: Integer
16
+ # @rbs return: void
17
+ def initialize(uri:, content:, version:)
18
+ @uri = uri
19
+ @content = content
20
+ @version = version
21
+ end
22
+ end
23
+
24
+ # @rbs @steep_state: SteepState
25
+ # @rbs @documents: Hash[String, DocumentEntry]
26
+
27
+ # @rbs steep_state: SteepState
28
+ # @rbs return: void
29
+ def initialize(steep_state)
30
+ @steep_state = steep_state
31
+ @documents = {}
32
+ end
33
+
34
+ # @rbs uri: String
35
+ # @rbs text: String
36
+ # @rbs version: Integer
37
+ # @rbs return: void
38
+ def open(uri:, text:, version:)
39
+ @documents[uri] = DocumentEntry.new(uri: uri, content: text, version: version)
40
+
41
+ path = uri_to_relative_path(uri)
42
+ return unless path
43
+
44
+ @steep_state.push_changes(path, [
45
+ ::Steep::Services::ContentChange.new(text: text),
46
+ ])
47
+ end
48
+
49
+ # @rbs uri: String
50
+ # @rbs content_changes: Array[Hash[Symbol, untyped]]
51
+ # @rbs version: Integer
52
+ # @rbs return: void
53
+ def change(uri:, content_changes:, version:)
54
+ entry = @documents[uri]
55
+ return unless entry
56
+
57
+ changes = content_changes.map do |change|
58
+ range = change[:range]
59
+ ::Steep::Services::ContentChange.new(
60
+ range: range && [
61
+ ::Steep::Services::ContentChange::Position.new(
62
+ line: range[:start][:line] + 1,
63
+ column: range[:start][:character],
64
+ ),
65
+ ::Steep::Services::ContentChange::Position.new(
66
+ line: range[:end][:line] + 1,
67
+ column: range[:end][:character],
68
+ ),
69
+ ],
70
+ text: change[:text],
71
+ )
72
+ end
73
+
74
+ # Update the stored content with the last full text
75
+ last_change = content_changes.last
76
+ if last_change && !last_change[:range]
77
+ @documents[uri] = DocumentEntry.new(uri: uri, content: last_change[:text], version: version)
78
+ else
79
+ @documents[uri] = DocumentEntry.new(uri: uri, content: entry.content, version: version)
80
+ end
81
+
82
+ path = uri_to_relative_path(uri)
83
+ return unless path
84
+
85
+ @steep_state.push_changes(path, changes)
86
+ end
87
+
88
+ # @rbs uri: String
89
+ # @rbs return: void
90
+ def close(uri:)
91
+ @documents.delete(uri)
92
+ end
93
+
94
+ # @rbs uri: String
95
+ # @rbs return: DocumentEntry?
96
+ def get(uri)
97
+ @documents[uri]
98
+ end
99
+
100
+ private
101
+
102
+ # @rbs uri: String
103
+ # @rbs return: Pathname?
104
+ def uri_to_relative_path(uri)
105
+ path = ::Steep::PathHelper.to_pathname(uri)
106
+ return unless path
107
+
108
+ @steep_state.project.relative_path(path)
109
+ end
110
+ end
111
+ end
112
+ end
113
+ end
@@ -0,0 +1,9 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Refined
4
+ module Steep
5
+ module Server
6
+ VERSION = "0.1.0"
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,22 @@
1
+ # rbs_inline: enabled
2
+ # frozen_string_literal: true
3
+
4
+ require "language_server-protocol"
5
+ require "steep"
6
+ require "json"
7
+
8
+ require_relative "server/version"
9
+ require_relative "server/message"
10
+ require_relative "server/io"
11
+ require_relative "server/base_server"
12
+ require_relative "server/steep_state"
13
+ require_relative "server/store"
14
+ require_relative "server/lsp_server"
15
+
16
+ module Refined
17
+ module Steep
18
+ module Server
19
+ class Error < StandardError; end
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,19 @@
1
+ # Download sources
2
+ sources:
3
+ - type: git
4
+ name: ruby/gem_rbs_collection
5
+ remote: https://github.com/ruby/gem_rbs_collection.git
6
+ revision: main
7
+ repo_dir: gems
8
+
9
+ # You can specify local directories as sources also.
10
+ # - type: local
11
+ # path: path/to/your/local/repository
12
+
13
+ # A directory to install the downloaded RBSs
14
+ path: .gem_rbs_collection
15
+
16
+ # gems:
17
+ # # If you want to avoid installing rbs files for gems, you can specify them here.
18
+ # - name: GEM_NAME
19
+ # ignore: true