steep-activesupport-4 1.9.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (164) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +13 -0
  3. data/.gitmodules +0 -0
  4. data/CHANGELOG.md +1032 -0
  5. data/LICENSE +21 -0
  6. data/README.md +260 -0
  7. data/Rakefile +227 -0
  8. data/Steepfile +68 -0
  9. data/bin/console +14 -0
  10. data/bin/generate-diagnostics-docs.rb +112 -0
  11. data/bin/mem_graph.rb +67 -0
  12. data/bin/mem_prof.rb +102 -0
  13. data/bin/output_rebaseline.rb +34 -0
  14. data/bin/output_test.rb +60 -0
  15. data/bin/rbs +20 -0
  16. data/bin/rbs-inline +19 -0
  17. data/bin/setup +9 -0
  18. data/bin/stackprof_test.rb +19 -0
  19. data/bin/steep +19 -0
  20. data/bin/steep-check.rb +251 -0
  21. data/bin/steep-prof +16 -0
  22. data/doc/narrowing.md +195 -0
  23. data/doc/shape.md +194 -0
  24. data/exe/steep +18 -0
  25. data/guides/README.md +5 -0
  26. data/guides/src/gem-rbs-collection/gem-rbs-collection.md +126 -0
  27. data/guides/src/getting-started/getting-started.md +163 -0
  28. data/guides/src/nil-optional/nil-optional.md +195 -0
  29. data/lib/steep/annotation_parser.rb +199 -0
  30. data/lib/steep/ast/annotation/collection.rb +172 -0
  31. data/lib/steep/ast/annotation.rb +137 -0
  32. data/lib/steep/ast/builtin.rb +104 -0
  33. data/lib/steep/ast/ignore.rb +148 -0
  34. data/lib/steep/ast/node/type_application.rb +88 -0
  35. data/lib/steep/ast/node/type_assertion.rb +81 -0
  36. data/lib/steep/ast/types/any.rb +35 -0
  37. data/lib/steep/ast/types/boolean.rb +45 -0
  38. data/lib/steep/ast/types/bot.rb +35 -0
  39. data/lib/steep/ast/types/class.rb +43 -0
  40. data/lib/steep/ast/types/factory.rb +557 -0
  41. data/lib/steep/ast/types/helper.rb +40 -0
  42. data/lib/steep/ast/types/instance.rb +42 -0
  43. data/lib/steep/ast/types/intersection.rb +93 -0
  44. data/lib/steep/ast/types/literal.rb +59 -0
  45. data/lib/steep/ast/types/logic.rb +84 -0
  46. data/lib/steep/ast/types/name.rb +128 -0
  47. data/lib/steep/ast/types/nil.rb +41 -0
  48. data/lib/steep/ast/types/proc.rb +117 -0
  49. data/lib/steep/ast/types/record.rb +79 -0
  50. data/lib/steep/ast/types/self.rb +43 -0
  51. data/lib/steep/ast/types/shared_instance.rb +11 -0
  52. data/lib/steep/ast/types/top.rb +35 -0
  53. data/lib/steep/ast/types/tuple.rb +60 -0
  54. data/lib/steep/ast/types/union.rb +97 -0
  55. data/lib/steep/ast/types/var.rb +65 -0
  56. data/lib/steep/ast/types/void.rb +35 -0
  57. data/lib/steep/cli.rb +401 -0
  58. data/lib/steep/diagnostic/deprecated/else_on_exhaustive_case.rb +20 -0
  59. data/lib/steep/diagnostic/deprecated/unknown_constant_assigned.rb +28 -0
  60. data/lib/steep/diagnostic/helper.rb +18 -0
  61. data/lib/steep/diagnostic/lsp_formatter.rb +78 -0
  62. data/lib/steep/diagnostic/result_printer2.rb +48 -0
  63. data/lib/steep/diagnostic/ruby.rb +1221 -0
  64. data/lib/steep/diagnostic/signature.rb +570 -0
  65. data/lib/steep/drivers/annotations.rb +52 -0
  66. data/lib/steep/drivers/check.rb +339 -0
  67. data/lib/steep/drivers/checkfile.rb +210 -0
  68. data/lib/steep/drivers/diagnostic_printer.rb +105 -0
  69. data/lib/steep/drivers/init.rb +66 -0
  70. data/lib/steep/drivers/langserver.rb +56 -0
  71. data/lib/steep/drivers/print_project.rb +113 -0
  72. data/lib/steep/drivers/stats.rb +203 -0
  73. data/lib/steep/drivers/utils/driver_helper.rb +143 -0
  74. data/lib/steep/drivers/utils/jobs_option.rb +26 -0
  75. data/lib/steep/drivers/vendor.rb +27 -0
  76. data/lib/steep/drivers/watch.rb +194 -0
  77. data/lib/steep/drivers/worker.rb +58 -0
  78. data/lib/steep/equatable.rb +23 -0
  79. data/lib/steep/expectations.rb +228 -0
  80. data/lib/steep/index/rbs_index.rb +350 -0
  81. data/lib/steep/index/signature_symbol_provider.rb +185 -0
  82. data/lib/steep/index/source_index.rb +167 -0
  83. data/lib/steep/interface/block.rb +103 -0
  84. data/lib/steep/interface/builder.rb +843 -0
  85. data/lib/steep/interface/function.rb +1090 -0
  86. data/lib/steep/interface/method_type.rb +330 -0
  87. data/lib/steep/interface/shape.rb +239 -0
  88. data/lib/steep/interface/substitution.rb +159 -0
  89. data/lib/steep/interface/type_param.rb +115 -0
  90. data/lib/steep/located_value.rb +20 -0
  91. data/lib/steep/method_name.rb +42 -0
  92. data/lib/steep/module_helper.rb +24 -0
  93. data/lib/steep/node_helper.rb +273 -0
  94. data/lib/steep/path_helper.rb +30 -0
  95. data/lib/steep/project/dsl.rb +268 -0
  96. data/lib/steep/project/group.rb +31 -0
  97. data/lib/steep/project/options.rb +63 -0
  98. data/lib/steep/project/pattern.rb +59 -0
  99. data/lib/steep/project/target.rb +92 -0
  100. data/lib/steep/project.rb +78 -0
  101. data/lib/steep/rake_task.rb +132 -0
  102. data/lib/steep/range_extension.rb +29 -0
  103. data/lib/steep/server/base_worker.rb +97 -0
  104. data/lib/steep/server/change_buffer.rb +73 -0
  105. data/lib/steep/server/custom_methods.rb +77 -0
  106. data/lib/steep/server/delay_queue.rb +45 -0
  107. data/lib/steep/server/interaction_worker.rb +492 -0
  108. data/lib/steep/server/lsp_formatter.rb +455 -0
  109. data/lib/steep/server/master.rb +912 -0
  110. data/lib/steep/server/target_group_files.rb +205 -0
  111. data/lib/steep/server/type_check_controller.rb +366 -0
  112. data/lib/steep/server/type_check_worker.rb +303 -0
  113. data/lib/steep/server/work_done_progress.rb +64 -0
  114. data/lib/steep/server/worker_process.rb +176 -0
  115. data/lib/steep/services/completion_provider.rb +802 -0
  116. data/lib/steep/services/content_change.rb +61 -0
  117. data/lib/steep/services/file_loader.rb +74 -0
  118. data/lib/steep/services/goto_service.rb +441 -0
  119. data/lib/steep/services/hover_provider/rbs.rb +88 -0
  120. data/lib/steep/services/hover_provider/ruby.rb +221 -0
  121. data/lib/steep/services/hover_provider/singleton_methods.rb +20 -0
  122. data/lib/steep/services/path_assignment.rb +46 -0
  123. data/lib/steep/services/signature_help_provider.rb +202 -0
  124. data/lib/steep/services/signature_service.rb +428 -0
  125. data/lib/steep/services/stats_calculator.rb +68 -0
  126. data/lib/steep/services/type_check_service.rb +394 -0
  127. data/lib/steep/services/type_name_completion.rb +236 -0
  128. data/lib/steep/signature/validator.rb +651 -0
  129. data/lib/steep/source/ignore_ranges.rb +69 -0
  130. data/lib/steep/source.rb +691 -0
  131. data/lib/steep/subtyping/cache.rb +30 -0
  132. data/lib/steep/subtyping/check.rb +1113 -0
  133. data/lib/steep/subtyping/constraints.rb +341 -0
  134. data/lib/steep/subtyping/relation.rb +101 -0
  135. data/lib/steep/subtyping/result.rb +324 -0
  136. data/lib/steep/subtyping/variable_variance.rb +89 -0
  137. data/lib/steep/test.rb +9 -0
  138. data/lib/steep/thread_waiter.rb +43 -0
  139. data/lib/steep/type_construction.rb +5183 -0
  140. data/lib/steep/type_inference/block_params.rb +416 -0
  141. data/lib/steep/type_inference/case_when.rb +303 -0
  142. data/lib/steep/type_inference/constant_env.rb +56 -0
  143. data/lib/steep/type_inference/context.rb +195 -0
  144. data/lib/steep/type_inference/logic_type_interpreter.rb +613 -0
  145. data/lib/steep/type_inference/method_call.rb +193 -0
  146. data/lib/steep/type_inference/method_params.rb +531 -0
  147. data/lib/steep/type_inference/multiple_assignment.rb +194 -0
  148. data/lib/steep/type_inference/send_args.rb +712 -0
  149. data/lib/steep/type_inference/type_env.rb +341 -0
  150. data/lib/steep/type_inference/type_env_builder.rb +138 -0
  151. data/lib/steep/typing.rb +321 -0
  152. data/lib/steep/version.rb +3 -0
  153. data/lib/steep.rb +369 -0
  154. data/manual/annotations.md +181 -0
  155. data/manual/ignore.md +20 -0
  156. data/manual/ruby-diagnostics.md +1879 -0
  157. data/sample/Steepfile +22 -0
  158. data/sample/lib/conference.rb +49 -0
  159. data/sample/lib/length.rb +35 -0
  160. data/sample/sig/conference.rbs +42 -0
  161. data/sample/sig/generics.rbs +15 -0
  162. data/sample/sig/length.rbs +34 -0
  163. data/steep-activesupport-4.gemspec +55 -0
  164. metadata +437 -0
@@ -0,0 +1,321 @@
1
+ module Steep
2
+ class Typing
3
+ class UnknownNodeError < StandardError
4
+ attr_reader :op
5
+ attr_reader :node
6
+
7
+ def initialize(op, node:)
8
+ @op = op
9
+ @node = node
10
+ super "Unknown node for #{op}: #{node.inspect}"
11
+ end
12
+ end
13
+
14
+ class CursorContext
15
+ attr_reader :index
16
+
17
+ attr_reader :data
18
+
19
+ def initialize(index)
20
+ @index = index
21
+ end
22
+
23
+ def set(range, context = nil)
24
+ if range.is_a?(CursorContext)
25
+ range, context = range.data
26
+ range or return
27
+ context or return
28
+ end
29
+
30
+ context or raise
31
+ return unless index
32
+
33
+ if current_range = self.range
34
+ if range.begin <= index && index <= range.end
35
+ if current_range.begin <= range.begin && range.end <= current_range.end
36
+ @data = [range, context]
37
+ end
38
+ end
39
+ else
40
+ @data = [range, context]
41
+ end
42
+ end
43
+
44
+ def set_node_context(node, context)
45
+ begin_pos = node.loc.expression.begin_pos
46
+ end_pos = node.loc.expression.end_pos
47
+
48
+ set(begin_pos..end_pos, context)
49
+ end
50
+
51
+ def set_body_context(node, context)
52
+ case node.type
53
+ when :class
54
+ name_node, super_node, _ = node.children
55
+ begin_pos = if super_node
56
+ super_node.loc.expression.end_pos
57
+ else
58
+ name_node.loc.expression.end_pos
59
+ end
60
+ end_pos = node.loc.end.begin_pos # steep:ignore NoMethod
61
+
62
+ set(begin_pos..end_pos, context)
63
+
64
+ when :module
65
+ name_node = node.children[0]
66
+ begin_pos = name_node.loc.expression.end_pos
67
+ end_pos = node.loc.end.begin_pos # steep:ignore NoMethod
68
+ set(begin_pos..end_pos, context)
69
+
70
+ when :sclass
71
+ name_node = node.children[0]
72
+ begin_pos = name_node.loc.expression.end_pos
73
+ end_pos = node.loc.end.begin_pos # steep:ignore NoMethod
74
+ set(begin_pos..end_pos, context)
75
+
76
+ when :def, :defs
77
+ if node.children.last
78
+ args_node =
79
+ case node.type
80
+ when :def
81
+ node.children[1]
82
+ when :defs
83
+ node.children[2]
84
+ end
85
+
86
+ body_begin_pos =
87
+ case
88
+ when node.loc.assignment # steep:ignore NoMethod
89
+ # endless def
90
+ node.loc.assignment.end_pos # steep:ignore NoMethod
91
+ when args_node.loc.expression
92
+ # with args
93
+ args_node.loc.expression.end_pos
94
+ else
95
+ # without args
96
+ node.loc.name.end_pos # steep:ignore NoMethod
97
+ end
98
+
99
+ body_end_pos =
100
+ if node.loc.end # steep:ignore NoMethod
101
+ node.loc.end.begin_pos # steep:ignore NoMethod
102
+ else
103
+ node.loc.expression.end_pos
104
+ end
105
+
106
+ set(body_begin_pos..body_end_pos, context)
107
+ end
108
+
109
+ when :block, :numblock
110
+ range = block_range(node)
111
+ set(range, context)
112
+
113
+ when :for
114
+ _, collection, _ = node.children
115
+
116
+ begin_pos = collection.loc.expression.end_pos
117
+ end_pos = node.loc.end.begin_pos # steep:ignore NoMethod
118
+
119
+ set(begin_pos..end_pos, context)
120
+ else
121
+ raise "Unexpected node for insert_context: #{node.type}"
122
+ end
123
+ end
124
+
125
+ def block_range(node)
126
+ case node.type
127
+ when :block
128
+ send_node, args_node, _ = node.children
129
+ begin_pos = if send_node.type != :lambda && args_node.loc.expression
130
+ args_node.loc.expression.end_pos
131
+ else
132
+ node.loc.begin.end_pos # steep:ignore NoMethod
133
+ end
134
+ end_pos = node.loc.end.begin_pos # steep:ignore NoMethod
135
+ when :numblock
136
+ send_node, _ = node.children
137
+ begin_pos = node.loc.begin.end_pos # steep:ignore NoMethod
138
+ end_pos = node.loc.end.begin_pos # steep:ignore NoMethod
139
+ end
140
+
141
+ begin_pos..end_pos
142
+ end
143
+
144
+ def range
145
+ range, _ = data
146
+ range
147
+ end
148
+
149
+ def context
150
+ _, context = data
151
+ context
152
+ end
153
+ end
154
+
155
+ attr_reader :source
156
+ attr_reader :errors
157
+ attr_reader :typing
158
+ attr_reader :parent
159
+ attr_reader :parent_last_update
160
+ attr_reader :last_update
161
+ attr_reader :should_update
162
+ attr_reader :contexts
163
+ attr_reader :root_context
164
+ attr_reader :method_calls
165
+ attr_reader :source_index
166
+ attr_reader :cursor_context
167
+
168
+ def initialize(source:, root_context:, parent: nil, parent_last_update: parent&.last_update, source_index: nil, cursor:)
169
+ @source = source
170
+
171
+ @parent = parent
172
+ @parent_last_update = parent_last_update
173
+ @last_update = parent&.last_update || 0
174
+ @should_update = false
175
+
176
+ @errors = []
177
+ (@typing = {}).compare_by_identity
178
+ @root_context = root_context
179
+ (@method_calls = {}).compare_by_identity
180
+
181
+ @cursor_context = CursorContext.new(cursor)
182
+ if root_context
183
+ cursor_context.set(0..source.buffer.content&.size || 0, root_context)
184
+ end
185
+
186
+ @source_index = source_index || Index::SourceIndex.new(source: source)
187
+ end
188
+
189
+ def add_error(error)
190
+ errors << error
191
+ end
192
+
193
+ def add_typing(node, type, _context)
194
+ typing[node] = type
195
+ @last_update += 1
196
+
197
+ type
198
+ end
199
+
200
+ def add_call(node, call)
201
+ method_calls[node] = call
202
+
203
+ call
204
+ end
205
+
206
+ def has_type?(node)
207
+ typing.key?(node)
208
+ end
209
+
210
+ def type_of(node:)
211
+ raise "`nil` given to `Typing#type_of(node:)`" unless node
212
+
213
+ type = typing[node]
214
+
215
+ if type
216
+ type
217
+ else
218
+ if parent
219
+ parent.type_of(node: node)
220
+ else
221
+ raise UnknownNodeError.new(:type, node: node)
222
+ end
223
+ end
224
+ end
225
+
226
+ def call_of(node:)
227
+ call = method_calls[node]
228
+
229
+ if call
230
+ call
231
+ else
232
+ if parent
233
+ parent.call_of(node: node)
234
+ else
235
+ raise UnknownNodeError.new(:call, node: node)
236
+ end
237
+ end
238
+ end
239
+
240
+ def block_range(node)
241
+ case node.type
242
+ when :block
243
+ send_node, args_node, _ = node.children
244
+ begin_pos = if send_node.type != :lambda && args_node.loc.expression
245
+ args_node.loc.expression.end_pos
246
+ else
247
+ node.loc.begin.end_pos # steep:ignore NoMethod
248
+ end
249
+ end_pos = node.loc.end.begin_pos # steep:ignore NoMethod
250
+ when :numblock
251
+ send_node, _ = node.children
252
+ begin_pos = node.loc.begin.end_pos # steep:ignore NoMethod
253
+ end_pos = node.loc.end.begin_pos # steep:ignore NoMethod
254
+ end
255
+
256
+ begin_pos..end_pos
257
+ end
258
+
259
+ def dump(io)
260
+ # steep:ignore:start
261
+ io.puts "Typing: "
262
+ nodes.each_value do |node|
263
+ io.puts " #{Typing.summary(node)} => #{type_of(node: node).inspect}"
264
+ end
265
+
266
+ io.puts "Errors: "
267
+ errors.each do |error|
268
+ io.puts " #{Typing.summary(error.node)} => #{error.inspect}"
269
+ end
270
+ # steep:ignore:end
271
+ end
272
+
273
+ def self.summary(node)
274
+ src = node.loc.expression.source.split(/\n/).first
275
+ line = node.loc.first_line
276
+ col = node.loc.column
277
+
278
+ "#{line}:#{col}:#{src}"
279
+ end
280
+
281
+ def new_child()
282
+ child = self.class.new(
283
+ source: source,
284
+ parent: self,
285
+ root_context: root_context,
286
+ source_index: source_index.new_child,
287
+ cursor: cursor_context.index
288
+ )
289
+ @should_update = true
290
+
291
+ if block_given?
292
+ yield child
293
+ else
294
+ child
295
+ end
296
+ end
297
+
298
+ def each_typing(&block)
299
+ typing.each(&block)
300
+ end
301
+
302
+ def save!
303
+ raise "Unexpected save!" unless parent
304
+ raise "Parent modified since #new_child: parent.last_update=#{parent.last_update}, parent_last_update=#{parent_last_update}" unless parent.last_update == parent_last_update
305
+
306
+ each_typing do |node, type|
307
+ parent.add_typing(node, type, nil)
308
+ end
309
+
310
+ parent.method_calls.merge!(method_calls)
311
+
312
+ errors.each do |error|
313
+ parent.add_error error
314
+ end
315
+
316
+ parent.cursor_context.set(cursor_context)
317
+
318
+ parent.source_index.merge!(source_index)
319
+ end
320
+ end
321
+ end
@@ -0,0 +1,3 @@
1
+ module Steep
2
+ VERSION = "1.9.3"
3
+ end
data/lib/steep.rb ADDED
@@ -0,0 +1,369 @@
1
+ require "steep/version"
2
+
3
+ require "pathname"
4
+ require "parser/ruby33"
5
+ require "active_support"
6
+ require "active_support/core_ext/object/try"
7
+ require "active_support/core_ext/string/inflections"
8
+ require "logger"
9
+ require "rainbow"
10
+ require "listen"
11
+ require 'language_server-protocol'
12
+ require "etc"
13
+ require "open3"
14
+ require "stringio"
15
+ require 'uri'
16
+ require "yaml"
17
+ require "securerandom"
18
+ require "base64"
19
+ require "time"
20
+
21
+ require "concurrent/utility/processor_counter"
22
+ require "terminal-table"
23
+
24
+ require "rbs"
25
+
26
+ require "steep/path_helper"
27
+ require "steep/located_value"
28
+ require "steep/thread_waiter"
29
+ require "steep/equatable"
30
+ require "steep/method_name"
31
+ require "steep/node_helper"
32
+ require "steep/ast/types/shared_instance"
33
+ require "steep/ast/types/helper"
34
+ require "steep/ast/types/any"
35
+ require "steep/ast/types/instance"
36
+ require "steep/ast/types/class"
37
+ require "steep/ast/types/union"
38
+ require "steep/ast/types/var"
39
+ require "steep/ast/types/name"
40
+ require "steep/ast/types/self"
41
+ require "steep/ast/types/intersection"
42
+ require "steep/ast/types/void"
43
+ require "steep/ast/types/bot"
44
+ require "steep/ast/types/top"
45
+ require "steep/ast/types/nil"
46
+ require "steep/ast/types/literal"
47
+ require "steep/ast/types/boolean"
48
+ require "steep/ast/types/tuple"
49
+ require "steep/ast/types/proc"
50
+ require "steep/ast/types/record"
51
+ require "steep/ast/types/logic"
52
+ require "steep/ast/annotation"
53
+ require "steep/ast/annotation/collection"
54
+ require "steep/ast/node/type_assertion"
55
+ require "steep/ast/node/type_application"
56
+ require "steep/ast/builtin"
57
+ require "steep/ast/types/factory"
58
+ require "steep/ast/ignore"
59
+
60
+ require "steep/range_extension"
61
+
62
+ require "steep/interface/type_param"
63
+ require "steep/interface/function"
64
+ require "steep/interface/block"
65
+ require "steep/interface/method_type"
66
+ require "steep/interface/substitution"
67
+ require "steep/interface/shape"
68
+ require "steep/interface/builder"
69
+
70
+ require "steep/subtyping/result"
71
+ require "steep/subtyping/check"
72
+ require "steep/subtyping/cache"
73
+ require "steep/subtyping/relation"
74
+ require "steep/subtyping/constraints"
75
+ require "steep/subtyping/variable_variance"
76
+
77
+ require "steep/diagnostic/helper"
78
+ require "steep/diagnostic/result_printer2"
79
+ require "steep/diagnostic/ruby"
80
+ require "steep/diagnostic/signature"
81
+ require "steep/diagnostic/lsp_formatter"
82
+ require "steep/signature/validator"
83
+ require "steep/module_helper"
84
+ require "steep/source"
85
+ require "steep/source/ignore_ranges"
86
+ require "steep/annotation_parser"
87
+ require "steep/typing"
88
+ require "steep/type_construction"
89
+ require "steep/type_inference/context"
90
+ require "steep/type_inference/send_args"
91
+ require "steep/type_inference/block_params"
92
+ require "steep/type_inference/method_params"
93
+ require "steep/type_inference/constant_env"
94
+ require "steep/type_inference/type_env"
95
+ require "steep/type_inference/type_env_builder"
96
+ require "steep/type_inference/logic_type_interpreter"
97
+ require "steep/type_inference/multiple_assignment"
98
+ require "steep/type_inference/method_call"
99
+ require "steep/type_inference/case_when"
100
+
101
+ require "steep/index/rbs_index"
102
+ require "steep/index/signature_symbol_provider"
103
+ require "steep/index/source_index"
104
+
105
+ require "steep/services/content_change"
106
+ require "steep/services/path_assignment"
107
+ require "steep/services/signature_service"
108
+ require "steep/services/type_check_service"
109
+ require "steep/services/hover_provider/singleton_methods"
110
+ require "steep/services/hover_provider/ruby"
111
+ require "steep/services/hover_provider/rbs"
112
+ require "steep/services/type_name_completion"
113
+ require "steep/services/completion_provider"
114
+ require "steep/services/signature_help_provider"
115
+ require "steep/services/stats_calculator"
116
+ require "steep/services/file_loader"
117
+ require "steep/services/goto_service"
118
+
119
+ require "steep/server/custom_methods"
120
+ require "steep/server/work_done_progress"
121
+ require "steep/server/delay_queue"
122
+ require "steep/server/lsp_formatter"
123
+ require "steep/server/change_buffer"
124
+ require "steep/server/base_worker"
125
+ require "steep/server/worker_process"
126
+ require "steep/server/interaction_worker"
127
+ require "steep/server/type_check_worker"
128
+ require "steep/server/target_group_files"
129
+ require "steep/server/type_check_controller"
130
+ require "steep/server/master"
131
+
132
+ require "steep/project"
133
+ require "steep/project/pattern"
134
+ require "steep/project/options"
135
+ require "steep/project/target"
136
+ require "steep/project/group"
137
+ require "steep/project/dsl"
138
+
139
+ require "steep/expectations"
140
+ require "steep/drivers/utils/driver_helper"
141
+ require "steep/drivers/utils/jobs_option"
142
+ require "steep/drivers/check"
143
+ require "steep/drivers/checkfile"
144
+ require "steep/drivers/stats"
145
+ require "steep/drivers/annotations"
146
+ require "steep/drivers/watch"
147
+ require "steep/drivers/langserver"
148
+ require "steep/drivers/print_project"
149
+ require "steep/drivers/init"
150
+ require "steep/drivers/vendor"
151
+ require "steep/drivers/worker"
152
+ require "steep/drivers/diagnostic_printer"
153
+
154
+ if ENV["NO_COLOR"]
155
+ Rainbow.enabled = false
156
+ end
157
+
158
+ $stderr = STDERR
159
+
160
+ module Steep
161
+ def self.logger
162
+ @logger || raise
163
+ end
164
+
165
+ def self.ui_logger
166
+ @ui_logger || raise
167
+ end
168
+
169
+ def self.new_logger(output, prev_level)
170
+ logger = Logger.new(output)
171
+ logger.formatter = proc do |severity, datetime, progname, msg|
172
+ # @type var severity: String
173
+ # @type var datetime: Time
174
+ # @type var progname: untyped
175
+ # @type var msg: untyped
176
+ # @type block: String
177
+ "#{datetime.strftime('%Y-%m-%d %H:%M:%S.%L')}: #{severity}: #{msg}\n"
178
+ end
179
+ ActiveSupport::TaggedLogging.new(logger).tap do |logger|
180
+ logger.push_tags "Steep #{VERSION}"
181
+ logger.level = prev_level || Logger::ERROR
182
+ end
183
+ end
184
+
185
+ def self.log_output
186
+ @log_output
187
+ end
188
+
189
+ def self.log_output=(output)
190
+ @log_output = output
191
+
192
+ prev_level = @logger&.level
193
+ @logger = new_logger(output, prev_level)
194
+
195
+ prev_level = @ui_logger&.level
196
+ @ui_logger = new_logger(output, prev_level)
197
+
198
+ output
199
+ end
200
+
201
+ @logger = nil
202
+ @ui_logger = nil
203
+ self.log_output = STDERR
204
+
205
+ def self.measure(message, level: :warn, threshold: 0.0)
206
+ start = Time.now
207
+ begin
208
+ yield
209
+ ensure
210
+ time = Time.now - start
211
+ if level.is_a?(Symbol)
212
+ level = Logger.const_get(level.to_s.upcase)
213
+ end
214
+ if time > threshold
215
+ self.logger.log(level) { "#{message} took #{time} seconds" }
216
+ end
217
+ end
218
+ end
219
+
220
+ def self.log_error(exn, message: "Unexpected error: #{exn.inspect}")
221
+ Steep.logger.fatal message
222
+ if backtrace = exn.backtrace
223
+ backtrace.each do |loc|
224
+ Steep.logger.error " #{loc}"
225
+ end
226
+ end
227
+ end
228
+
229
+ class Sampler
230
+ def initialize()
231
+ @samples = []
232
+ end
233
+
234
+ def sample(message)
235
+ start = Time.now
236
+ begin
237
+ yield
238
+ ensure
239
+ time = Time.now - start
240
+ @samples << [message, time]
241
+ end
242
+ end
243
+
244
+ def count
245
+ @samples.count
246
+ end
247
+
248
+ def total
249
+ @samples.sum(&:last)
250
+ end
251
+
252
+ def slowests(num)
253
+ @samples.sort_by(&:last).reverse.take(num)
254
+ end
255
+
256
+ def average
257
+ if count > 0
258
+ total/count
259
+ else
260
+ 0.to_f
261
+ end
262
+ end
263
+
264
+ def percentile(p)
265
+ c = [count * p / 100.to_r, 1].max or raise
266
+ slowests(c.to_i).last&.last || 0.to_f
267
+ end
268
+ end
269
+
270
+ def self.measure2(message, level: :warn)
271
+ sampler = Sampler.new
272
+ result = yield(sampler)
273
+
274
+ if level.is_a?(Symbol)
275
+ level = Logger.const_get(level.to_s.upcase)
276
+ end
277
+ logger.log(level) { "#{sampler.total}secs for \"#{message}\"" }
278
+ logger.log(level) { " Average: #{sampler.average}secs"}
279
+ logger.log(level) { " Median: #{sampler.percentile(50)}secs"}
280
+ logger.log(level) { " Samples: #{sampler.count}"}
281
+ logger.log(level) { " 99 percentile: #{sampler.percentile(99)}secs"}
282
+ logger.log(level) { " 90 percentile: #{sampler.percentile(90)}secs"}
283
+ logger.log(level) { " 10 Slowests:"}
284
+ sampler.slowests(10).each do |message, time|
285
+ logger.log(level) { " #{message} (#{time}secs)"}
286
+ end
287
+
288
+ result
289
+ end
290
+ end
291
+
292
+ klasses = [
293
+ # Steep::Interface::MethodType
294
+ ] #: Array[Class]
295
+
296
+ klasses.each do |klass|
297
+ klass.instance_eval do
298
+ def self.new(*_a, **_b, &_c)
299
+ super
300
+ end
301
+ end
302
+ end
303
+
304
+ module GCCounter
305
+ module_function
306
+
307
+ def count_objects(title, regexp = /^Steep/, skip: false)
308
+ if ENV["COUNT_GC_OBJECTS"] && !skip
309
+ unless GC.disable
310
+ GC.start(immediate_sweep: true, immediate_mark: true, full_mark: true)
311
+
312
+ begin
313
+ yield
314
+ ensure
315
+ Steep.logger.fatal "===== #{title} ==============================="
316
+
317
+ klasses = [] #: Array[Class]
318
+
319
+ ObjectSpace.each_object(Class) do |klass|
320
+ if (klass.name || "") =~ regexp
321
+ klasses << klass
322
+ end
323
+ end
324
+
325
+ before = {} #: Hash[Class, Integer]
326
+
327
+ klasses.each do |klass|
328
+ count = ObjectSpace.each_object(klass).count
329
+ before[klass] = count
330
+ end
331
+
332
+ GC.start(immediate_sweep: true, immediate_mark: true, full_mark: true)
333
+
334
+ gceds = [] #: Array[[Class, Integer]]
335
+
336
+ klasses.each do |klass|
337
+ count = ObjectSpace.each_object(klass).count
338
+ gced = (before[klass] || 0) - count
339
+
340
+ gceds << [klass, gced] if gced > 0
341
+ end
342
+
343
+ gceds.sort_by! {|_, count| -count }
344
+ gceds.each do |klass, count|
345
+ Steep.logger.fatal { "#{klass.name} => #{count}"}
346
+ end
347
+
348
+ GC.enable
349
+ end
350
+ else
351
+ yield
352
+ end
353
+ else
354
+ yield
355
+ end
356
+ end
357
+ end
358
+
359
+
360
+
361
+
362
+ # klasses = [Set]
363
+ # klasses.each do |klass|
364
+ # # steep:ignore:start
365
+ # def klass.new(...)
366
+ # super
367
+ # end
368
+ # # steep:ignore:end
369
+ # end