steep 1.4.0.dev.3 → 1.4.0.dev.4

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.
@@ -1911,10 +1911,12 @@ module Steep
1911
1911
  when_clause_constr = condition_constr
1912
1912
  body_envs = [] #: Array[TypeInference::TypeEnv]
1913
1913
 
1914
+ # @type var tests: Array[Parser::AST::Node]
1915
+ # @type var body: Parser::AST::Node?
1914
1916
  *tests, body = when_clause.children
1915
1917
 
1916
1918
  tests.each do |test|
1917
- test_type, condition_constr = condition_constr.synthesize(test, condition: true).to_ary
1919
+ test_type, condition_constr = condition_constr.synthesize(test, condition: true)
1918
1920
  truthy_env, falsy_env = interpreter.eval(env: condition_constr.context.type_env, node: test)
1919
1921
 
1920
1922
  condition_constr = condition_constr.update_type_env { falsy_env }
@@ -3181,46 +3183,65 @@ module Steep
3181
3183
  receiver_type = checker.factory.deep_expand_alias(recv_type)
3182
3184
  private = receiver.nil? || receiver.type == :self
3183
3185
 
3184
- type, constr = case receiver_type
3185
- when nil
3186
- raise
3187
-
3188
- when AST::Types::Any
3189
- constr = constr.synthesize_children(node, skips: [receiver])
3190
- constr.add_call(
3191
- TypeInference::MethodCall::Untyped.new(
3192
- node: node,
3193
- context: context.call_context,
3194
- method_name: method_name
3195
- )
3196
- )
3186
+ type, constr =
3187
+ case receiver_type
3188
+ when nil
3189
+ raise
3197
3190
 
3198
- else
3199
- if interface = calculate_interface(receiver_type, private: private)
3200
- constr.type_send_interface(
3201
- node,
3202
- interface: interface,
3203
- receiver: receiver,
3204
- receiver_type: receiver_type,
3205
- method_name: method_name,
3206
- arguments: arguments,
3207
- block_params: block_params,
3208
- block_body: block_body,
3209
- tapp: tapp
3210
- )
3211
- else
3212
- constr = constr.synthesize_children(node, skips: [receiver])
3213
- constr.add_call(
3214
- TypeInference::MethodCall::NoMethodError.new(
3215
- node: node,
3216
- context: context.call_context,
3217
- method_name: method_name,
3218
- receiver_type: receiver_type,
3219
- error: Diagnostic::Ruby::NoMethod.new(node: node, method: method_name, type: receiver_type)
3220
- )
3221
- )
3222
- end
3223
- end
3191
+ when AST::Types::Any
3192
+ case node.type
3193
+ when :block, :numblock
3194
+ # @type var node: Parser::AST::Node & Parser::AST::_BlockNode
3195
+ block_annotations = source.annotations(block: node, factory: checker.factory, context: nesting)
3196
+ block_params or raise
3197
+
3198
+ constr = constr.synthesize_children(node.children[0])
3199
+
3200
+ constr.type_block_without_hint(
3201
+ node: node,
3202
+ block_params: TypeInference::BlockParams.from_node(block_params, annotations: block_annotations),
3203
+ block_annotations: block_annotations,
3204
+ block_body: block_body
3205
+ ) do |error|
3206
+ constr.typing.errors << error
3207
+ end
3208
+ else
3209
+ constr = constr.synthesize_children(node, skips: [receiver])
3210
+ end
3211
+
3212
+ constr.add_call(
3213
+ TypeInference::MethodCall::Untyped.new(
3214
+ node: node,
3215
+ context: context.call_context,
3216
+ method_name: method_name
3217
+ )
3218
+ )
3219
+ else
3220
+ if interface = calculate_interface(receiver_type, private: private)
3221
+ constr.type_send_interface(
3222
+ node,
3223
+ interface: interface,
3224
+ receiver: receiver,
3225
+ receiver_type: receiver_type,
3226
+ method_name: method_name,
3227
+ arguments: arguments,
3228
+ block_params: block_params,
3229
+ block_body: block_body,
3230
+ tapp: tapp
3231
+ )
3232
+ else
3233
+ constr = constr.synthesize_children(node, skips: [receiver])
3234
+ constr.add_call(
3235
+ TypeInference::MethodCall::NoMethodError.new(
3236
+ node: node,
3237
+ context: context.call_context,
3238
+ method_name: method_name,
3239
+ receiver_type: receiver_type,
3240
+ error: Diagnostic::Ruby::NoMethod.new(node: node, method: method_name, type: receiver_type)
3241
+ )
3242
+ )
3243
+ end
3244
+ end
3224
3245
 
3225
3246
  Pair.new(type: type, constr: constr)
3226
3247
  end
@@ -1,6 +1,6 @@
1
1
  module Steep
2
2
  module TypeInference
3
- class MethodCall
3
+ module MethodCall
4
4
  class MethodDecl
5
5
  attr_reader :method_name
6
6
  attr_reader :method_def
@@ -569,7 +569,7 @@ module Steep
569
569
 
570
570
  def each
571
571
  if block_given?
572
- errors = []
572
+ errors = [] #: Array[PositionalArgs::error_arg | KeywordArgs::error_arg]
573
573
 
574
574
  last_positional_args = positional_arg
575
575
 
@@ -619,12 +619,12 @@ module Steep
619
619
  end
620
620
 
621
621
  if fag = forwarded_args_node
622
- params = Interface::Function::Params.new(
622
+ forward_params = Interface::Function::Params.new(
623
623
  positional_params: last_positional_args.positional_params,
624
624
  keyword_params: keyword_params
625
625
  )
626
626
 
627
- forwarded_args = ForwardedArgs.new(node: fag, params: params)
627
+ forwarded_args = ForwardedArgs.new(node: fag, params: forward_params)
628
628
  else
629
629
  keyword_args.tap do |args|
630
630
  while (a, args = args.next)
@@ -242,12 +242,14 @@ module Steep
242
242
 
243
243
  common_pure_nodes = envs
244
244
  .map {|env| Set.new(env.pure_method_calls.each_key) }
245
- .inject(Set.new(pure_method_calls.each_key)) {|s1, s2| s1.intersection(s2) }
245
+ .inject {|s1, s2| s1.intersection(s2) } || Set[]
246
246
 
247
247
  pure_call_updates = common_pure_nodes.each_with_object({}) do |node, hash|
248
248
  pairs = envs.map {|env| env.pure_method_calls[node] }
249
- refined_type = AST::Types::Union.build(types: pairs.map {|pair| pair[1] || pair[0].return_type })
250
- call, _ = (pure_method_calls[node] or raise)
249
+ refined_type = AST::Types::Union.build(types: pairs.map {|call, type| type || call.return_type })
250
+
251
+ # Any *pure_method_call* can be used because it's *pure*
252
+ (call, _ = envs[0].pure_method_calls[node]) or raise
251
253
 
252
254
  hash[node] = [call, refined_type]
253
255
  end
data/lib/steep/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Steep
2
- VERSION = "1.4.0.dev.3"
2
+ VERSION = "1.4.0.dev.4"
3
3
  end
data/lib/steep.rb CHANGED
@@ -107,6 +107,7 @@ require "steep/services/hover_provider/ruby"
107
107
  require "steep/services/hover_provider/rbs"
108
108
  require "steep/services/type_name_completion"
109
109
  require "steep/services/completion_provider"
110
+ require "steep/services/signature_help_provider"
110
111
  require "steep/services/stats_calculator"
111
112
  require "steep/services/file_loader"
112
113
  require "steep/services/goto_service"
data/sample/Steepfile CHANGED
@@ -5,6 +5,8 @@ target :lib do
5
5
 
6
6
  check "lib" # Directory name
7
7
 
8
+ library "rbs"
9
+
8
10
  # configure_code_diagnostics(D::Ruby.strict) # `strict` diagnostics setting
9
11
  # configure_code_diagnostics(D::Ruby.lenient) # `lenient` diagnostics setting
10
12
  # configure_code_diagnostics do |hash| # You can setup everything yourself
@@ -27,6 +27,271 @@ module LanguageServer
27
27
 
28
28
  HINT: String
29
29
  end
30
+
31
+ module CompletionItemKind
32
+ type t = Integer
33
+
34
+ TEXT: Integer
35
+ METHOD: Integer
36
+ FUNCTION: Integer
37
+ CONSTRUCTOR: Integer
38
+ FIELD: Integer
39
+ VARIABLE: Integer
40
+ CLASS: Integer
41
+ INTERFACE: Integer
42
+ MODULE: Integer
43
+ PROPERTY: Integer
44
+ UNIT: Integer
45
+ VALUE: Integer
46
+ ENUM: Integer
47
+ KEYWORD: Integer
48
+ SNIPPET: Integer
49
+ COLOR: Integer
50
+ FILE: Integer
51
+ REFERENCE: Integer
52
+ FOLDER: Integer
53
+ ENUMMEMBER: Integer
54
+ CONSTANT: Integer
55
+ STRUCT: Integer
56
+ EVENT: Integer
57
+ OPERATOR: Integer
58
+ TYPEPARAMETER: Integer
59
+ end
60
+
61
+ module CompletionItemTag
62
+ type t = Integer
63
+
64
+ Deprecated: Integer
65
+ end
66
+
67
+ module InsertTextFormat
68
+ type t = Integer
69
+
70
+ PLAIN_TEXT: Integer
71
+
72
+ SNIPPET: Integer
73
+ end
74
+
75
+ module InsertTextMode
76
+ type t = Integer
77
+
78
+ AS_IS: Integer
79
+
80
+ ADJUST_INDENTATION: Integer
81
+ end
82
+
83
+ module MarkupKind
84
+ type t = "plaintext" | "markdown"
85
+
86
+ PLAINTEXT: "plaintext"
87
+
88
+ MARKDOWN: "markdown"
89
+ end
90
+ end
91
+
92
+ module Interface
93
+ interface _Base
94
+ def attributes: () -> Hash[Symbol, untyped]
95
+
96
+ alias to_hash attributes
97
+
98
+ def to_json: () -> String
99
+ end
100
+
101
+ class Position
102
+ include _Base
103
+
104
+ # 0-origin line number
105
+ attr_reader line: Integer
106
+
107
+ # 0-origin character position (== cursor position)
108
+ attr_reader character: Integer
109
+
110
+ def initialize: (line: Integer, character: Integer) -> void
111
+ | (Hash[Symbol, untyped]) -> void
112
+ end
113
+
114
+ class Range
115
+ include _Base
116
+
117
+ attr_reader start: Position
118
+
119
+ attr_reader end: Position
120
+
121
+ def initialize: (start: Position, end: Position) -> void
122
+ | (Hash[Symbol, untyped]) -> void
123
+ end
124
+
125
+ class MarkupContent
126
+ include _Base
127
+
128
+ attr_reader kind: Constant::MarkupKind::t
129
+
130
+ attr_reader value: String
131
+
132
+ def initialize: (kind: Constant::MarkupKind::t, value: String) -> void
133
+ end
134
+
135
+ class TextEdit
136
+ include _Base
137
+
138
+ attr_reader range: Range
139
+
140
+ attr_reader new_text: String
141
+
142
+ def initialize: (range: Range, new_text: String) -> void
143
+ end
144
+
145
+ class InsertReplaceEdit
146
+ include _Base
147
+
148
+ attr_reader new_text: String
149
+
150
+ attr_reader insert: Range
151
+
152
+ attr_reader replace: Range
153
+
154
+ def initialize: (new_text: String, insert: Range, replace: Range) -> void
155
+ end
156
+
157
+ class Command
158
+ include _Base
159
+
160
+ attr_reader title: String
161
+
162
+ attr_reader command: String
163
+
164
+ attr_reader arguments: Array[untyped]?
165
+
166
+ def initialize: (title: String, command: String, ?arguments: Array[untyped]?) -> void
167
+ end
168
+
169
+ class Hover
170
+ include _Base
171
+
172
+ attr_reader contents: MarkupContent
173
+
174
+ attr_reader range: Range
175
+
176
+ def initialize: (contents: MarkupContent, range: Range) -> void
177
+ end
178
+
179
+ class CompletionList
180
+ include _Base
181
+
182
+ attr_reader is_incomplete: bool
183
+
184
+ attr_reader items: Array[CompletionItem]
185
+
186
+ def initialize: (items: Array[CompletionItem], is_incomplete: bool) -> void
187
+ end
188
+
189
+ class CompletionItem
190
+ include _Base
191
+
192
+ attr_reader label: String
193
+
194
+ attr_reader label_details: CompletionItemLabelDetails?
195
+
196
+ attr_reader kind: Constant::CompletionItemKind::t?
197
+
198
+ attr_reader tags: Array[Constant::CompletionItemTag::t]?
199
+
200
+ attr_reader detail: String?
201
+
202
+ attr_reader documentation: MarkupContent?
203
+
204
+ attr_reader preselect: bool?
205
+
206
+ attr_reader sort_text: String?
207
+
208
+ attr_reader filter_text: String?
209
+
210
+ attr_reader insert_text: String?
211
+
212
+ attr_reader insert_text_format: Constant::InsertTextFormat::t?
213
+
214
+ attr_reader insert_text_mode: Constant::InsertTextMode::t?
215
+
216
+ attr_reader text_edit: TextEdit | InsertReplaceEdit | nil
217
+
218
+ attr_reader text_edit_text: String?
219
+
220
+ attr_reader additional_text_edits: Array[TextEdit]?
221
+
222
+ attr_reader commit_characters: Array[String]?
223
+
224
+ attr_reader command: Command?
225
+
226
+ attr_reader data: untyped?
227
+
228
+ def initialize:(
229
+ label: String,
230
+ ?label_details: CompletionItemLabelDetails?,
231
+ ?kind: Constant::CompletionItemKind::t?,
232
+ ?tags: Array[Constant::CompletionItemTag::t]?,
233
+ ?detail: String?,
234
+ ?documentation: MarkupContent?,
235
+ ?preselect: bool?,
236
+ ?sort_text: String?,
237
+ ?filter_text: String?,
238
+ ?insert_text: String?,
239
+ ?insert_text_format: Constant::InsertTextFormat::t?,
240
+ ?insert_text_mode: Constant::InsertTextMode::t?,
241
+ ?text_edit: TextEdit | InsertReplaceEdit | nil,
242
+ ?text_edit_text: String?,
243
+ ?additional_text_edits: Array[TextEdit]?,
244
+ ?commit_characters: Array[String]?,
245
+ ?command: Command?,
246
+ ?data: untyped?
247
+ ) -> void
248
+ end
249
+
250
+ class CompletionItemLabelDetails
251
+ include _Base
252
+
253
+ attr_reader detail: String?
254
+
255
+ attr_reader description: String?
256
+
257
+ def initialize: (?detail: String?, ?description: String?) -> void
258
+ end
259
+
260
+ class SignatureInformation
261
+ include _Base
262
+
263
+ attr_reader label: String
264
+
265
+ attr_reader documentation: MarkupContent?
266
+
267
+ attr_reader parameters: Array[ParameterInformation]?
268
+
269
+ attr_reader active_parameter: Integer?
270
+
271
+ def initialize: (label: String, ?documentation: MarkupContent?, ?parameters: Array[ParameterInformation]?, ?active_parameter: Integer?) -> void
272
+ end
273
+
274
+ class ParameterInformation
275
+ include _Base
276
+
277
+ attr_reader label: String | [Integer, Integer]
278
+
279
+ attr_reader documentation: MarkupContent?
280
+
281
+ def initialize: (label: String | [Integer, Integer], ?documentation: MarkupContent) -> void
282
+ end
283
+
284
+ class SignatureHelp
285
+ include _Base
286
+
287
+ attr_reader signatures: Array[SignatureInformation]
288
+
289
+ attr_reader active_signature: Integer?
290
+
291
+ attr_reader active_parameter: Integer?
292
+
293
+ def initialize: (signatures: Array[SignatureInformation], ?active_signature: Integer?, ?active_parameter: Integer?) -> void
294
+ end
30
295
  end
31
296
  end
32
297
  end
data/sig/shims/parser.rbs CHANGED
@@ -43,4 +43,7 @@ module Parser
43
43
  def value: (untyped) -> untyped
44
44
  end
45
45
  end
46
+
47
+ class SyntaxError < StandardError
48
+ end
46
49
  end
@@ -6,6 +6,8 @@ module Steep
6
6
  attr_reader method_name: Symbol
7
7
 
8
8
  def initialize: (type_name: RBS::TypeName, method_name: Symbol) -> void
9
+
10
+ def relative: () -> InstanceMethodName
9
11
  end
10
12
 
11
13
  class SingletonMethodName
@@ -13,6 +15,8 @@ module Steep
13
15
  attr_reader method_name: Symbol
14
16
 
15
17
  def initialize: (type_name: RBS::TypeName, method_name: Symbol) -> void
18
+
19
+ def relative: () -> SingletonMethodName
16
20
  end
17
21
 
18
22
  class ::Object
@@ -20,7 +24,7 @@ module Steep
20
24
  #
21
25
  # * `ClassName#method_name` syntax returns an `InstanceMethodName` object
22
26
  # * `ClassName.method_name` syntax returns a `SingletonMethodName` object
23
- #
27
+ #
24
28
  def MethodName: (String string) -> (InstanceMethodName | SingletonMethodName)
25
29
  end
26
30
  end
@@ -36,7 +36,19 @@ module Steep
36
36
  def initialize: (id: String, path: Pathname, line: Integer, column: Integer, trigger: String) -> void
37
37
  end
38
38
 
39
- type job = ApplyChangeJob | HoverJob | CompletionJob
39
+ class SignatureHelpJob
40
+ attr_reader id: String
41
+
42
+ attr_reader path: Pathname
43
+
44
+ attr_reader line: Integer
45
+
46
+ attr_reader column: Integer
47
+
48
+ def initialize: (id: String, path: Pathname, line: Integer, column: Integer) -> void
49
+ end
50
+
51
+ type job = ApplyChangeJob | HoverJob | CompletionJob | SignatureHelpJob
40
52
 
41
53
  module LSP = LanguageServer::Protocol
42
54
 
@@ -50,21 +62,15 @@ module Steep
50
62
 
51
63
  def handle_request: (lsp_request) -> void
52
64
 
53
- def process_hover: (HoverJob job) -> untyped
54
-
55
- def process_completion: (CompletionJob job) -> untyped
56
-
57
- def format_completion_item_for_rbs: (Services::SignatureService, RBS::TypeName, CompletionJob job, String complete_text, Integer prefix_size) -> untyped
58
-
59
- def format_comment: (Comment? comment) -> untyped?
65
+ def process_hover: (HoverJob job) -> LanguageServer::Protocol::Interface::Hover?
60
66
 
61
- def format_comments: (Array[RBS::AST::Comment] comments) -> untyped?
67
+ def process_completion: (CompletionJob job) -> LanguageServer::Protocol::Interface::CompletionList?
62
68
 
63
- def format_completion_item: (CompletionProvider::item item) -> untyped
69
+ def process_signature_help: (SignatureHelpJob) -> LanguageServer::Protocol::Interface::SignatureHelp?
64
70
 
65
- def method_type_to_snippet: (RBS::MethodType method_type) -> ::String
71
+ def format_completion_item_for_rbs: (Services::SignatureService, RBS::TypeName, CompletionJob job, String complete_text, Integer prefix_size) -> LanguageServer::Protocol::Interface::CompletionItem
66
72
 
67
- def params_to_snippet: (RBS::Types::Function fun) -> String
73
+ def format_completion_item: (CompletionProvider::item item) -> LanguageServer::Protocol::Interface::CompletionItem
68
74
  end
69
75
  end
70
76
  end
@@ -1,38 +1,63 @@
1
+ use RBS::TypeName
2
+
1
3
  module Steep
2
4
  module Server
5
+ # LSPFormatter translates hover content and completion item to markdown string
6
+ #
7
+ # The class has four main methods:
8
+ #
9
+ # * `markup_content` translates a string to `MarkupContent` object
10
+ # * `format_hover_content` translates a hover content to Markdown string
11
+ # * `format_completion_docs` translates a completion item to a documentation
12
+ # * `format_rbs_competion_docs` generates docs for completion item of RBS
13
+ #
3
14
  module LSPFormatter
4
15
  include Services
5
16
 
6
- class CommentBuilder
7
- @array: Array[String]
17
+ module LSP = LanguageServer::Protocol
18
+
19
+ # Translate given String to MarkupContent
20
+ #
21
+ def self?.markup_content: (String?) -> LanguageServer::Protocol::Interface::MarkupContent?
22
+ | () { () -> String? } -> LanguageServer::Protocol::Interface::MarkupContent?
8
23
 
9
- def initialize: () -> void
24
+ # Translates a hover content to String
25
+ #
26
+ def self?.format_hover_content: (Services::HoverProvider::Ruby::content | Services::HoverProvider::RBS::content) -> String
10
27
 
11
- def self.build: () { (CommentBuilder) -> void } -> String
28
+ # Translates a completion item to String
29
+ def self?.format_completion_docs: (Services::CompletionProvider::item) -> String
12
30
 
13
- def to_s: () -> String
31
+ # Translates a completion item for RBS to String
32
+ def self?.format_rbs_completion_docs: (TypeName, summarizable_decl, Array[RBS::AST::Comment]) -> String
14
33
 
15
- def <<: (String? string) -> void
34
+ def self?.format_comment: (RBS::AST::Comment?, ?header: String?) -> String?
35
+ | (RBS::AST::Comment?, ?header: String?) { (String) -> void } -> void
16
36
 
17
- def push: () { (String) -> void } -> void
18
- end
37
+ def self?.format_comments: (Array[[String, RBS::AST::Comment?]]) -> String
19
38
 
20
- def self?.format_hover_content: (Services::HoverProvider::Ruby::content | Services::HoverProvider::RBS::content) -> untyped
39
+ def self?.local_variable: (Symbol, AST::Types::t) -> String
21
40
 
22
- def self?.to_list: [A < Object] (Enumerable[A] collection) ?{ (A) -> String } -> String
41
+ def self?.instance_variable: (Symbol, AST::Types::t) -> String
23
42
 
24
- def self?.name_and_args: (untyped name, untyped args) -> ::String
43
+ # Renders type application
44
+ def self?.name_and_args: (TypeName name, Array[RBS::Types::t] args) -> String
25
45
 
26
- def self?.name_and_params: (untyped name, untyped params) -> ::String
46
+ # Renders generic type definition
47
+ def self?.name_and_params: (TypeName name, Array[RBS::AST::TypeParam] params) -> String
27
48
 
28
- type summarizable_decl = ::RBS::AST::Declarations::Class
29
- | ::RBS::AST::Declarations::Module
30
- | ::RBS::AST::Declarations::Interface
31
- | ::RBS::AST::Declarations::TypeAlias
32
- | ::RBS::AST::Declarations::ClassAlias
33
- | ::RBS::AST::Declarations::ModuleAlias
49
+ type summarizable_decl = RBS::AST::Declarations::Class
50
+ | RBS::AST::Declarations::Module
51
+ | RBS::AST::Declarations::Interface
52
+ | RBS::AST::Declarations::TypeAlias
53
+ | RBS::AST::Declarations::ClassAlias
54
+ | RBS::AST::Declarations::ModuleAlias
55
+ | RBS::AST::Declarations::Global
56
+ | RBS::AST::Declarations::Constant
34
57
 
35
58
  def self?.declaration_summary: (summarizable_decl) -> String
59
+
60
+ def self?.format_method_item_doc: (Array[_ToS], Array[method_name], Hash[method_name, RBS::AST::Comment?], ?String footer) -> String
36
61
  end
37
62
  end
38
63
  end