steep 0.13.0 → 0.16.2

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.
Files changed (214) hide show
  1. checksums.yaml +4 -4
  2. data/.gitmodules +0 -3
  3. data/CHANGELOG.md +28 -0
  4. data/Rakefile +0 -13
  5. data/bin/setup +0 -2
  6. data/bin/smoke_runner.rb +0 -1
  7. data/exe/steep +0 -1
  8. data/lib/steep.rb +33 -1
  9. data/lib/steep/annotation_parser.rb +4 -4
  10. data/lib/steep/ast/buffer.rb +11 -7
  11. data/lib/steep/ast/builtin.rb +8 -0
  12. data/lib/steep/ast/types/factory.rb +124 -89
  13. data/lib/steep/cli.rb +16 -1
  14. data/lib/steep/drivers/annotations.rb +1 -1
  15. data/lib/steep/drivers/check.rb +20 -4
  16. data/lib/steep/drivers/init.rb +5 -5
  17. data/lib/steep/drivers/langserver.rb +13 -287
  18. data/lib/steep/drivers/utils/driver_helper.rb +1 -1
  19. data/lib/steep/drivers/vendor.rb +2 -2
  20. data/lib/steep/drivers/watch.rb +97 -85
  21. data/lib/steep/drivers/worker.rb +51 -0
  22. data/lib/steep/project.rb +9 -5
  23. data/lib/steep/project/completion_provider.rb +298 -0
  24. data/lib/steep/project/dsl.rb +14 -0
  25. data/lib/steep/project/file.rb +54 -47
  26. data/lib/steep/project/hover_content.rb +17 -8
  27. data/lib/steep/project/options.rb +25 -3
  28. data/lib/steep/project/target.rb +40 -24
  29. data/lib/steep/server/base_worker.rb +56 -0
  30. data/lib/steep/server/code_worker.rb +151 -0
  31. data/lib/steep/server/interaction_worker.rb +281 -0
  32. data/lib/steep/server/master.rb +196 -0
  33. data/lib/steep/server/signature_worker.rb +148 -0
  34. data/lib/steep/server/utils.rb +36 -0
  35. data/lib/steep/server/worker_process.rb +62 -0
  36. data/lib/steep/signature/errors.rb +1 -1
  37. data/lib/steep/signature/validator.rb +13 -13
  38. data/lib/steep/source.rb +1 -1
  39. data/lib/steep/type_construction.rb +1004 -727
  40. data/lib/steep/type_inference/constant_env.rb +3 -11
  41. data/lib/steep/type_inference/context.rb +8 -3
  42. data/lib/steep/type_inference/context_array.rb +111 -0
  43. data/lib/steep/type_inference/local_variable_type_env.rb +226 -0
  44. data/lib/steep/type_inference/logic.rb +130 -0
  45. data/lib/steep/type_inference/type_env.rb +5 -69
  46. data/lib/steep/typing.rb +91 -23
  47. data/lib/steep/version.rb +1 -1
  48. data/smoke/alias/Steepfile +1 -0
  49. data/smoke/alias/a.rb +1 -1
  50. data/smoke/and/Steepfile +1 -0
  51. data/smoke/array/Steepfile +1 -0
  52. data/smoke/array/b.rb +0 -2
  53. data/smoke/block/Steepfile +1 -0
  54. data/smoke/case/Steepfile +1 -0
  55. data/smoke/class/Steepfile +1 -0
  56. data/smoke/const/Steepfile +1 -0
  57. data/smoke/dstr/Steepfile +1 -0
  58. data/smoke/ensure/Steepfile +1 -0
  59. data/smoke/enumerator/Steepfile +1 -0
  60. data/smoke/extension/Steepfile +1 -0
  61. data/smoke/extension/c.rb +1 -0
  62. data/smoke/hash/Steepfile +1 -0
  63. data/smoke/hello/Steepfile +1 -0
  64. data/smoke/if/Steepfile +1 -0
  65. data/smoke/if/a.rb +1 -1
  66. data/smoke/implements/Steepfile +1 -0
  67. data/smoke/initialize/Steepfile +1 -0
  68. data/smoke/integer/Steepfile +1 -0
  69. data/smoke/interface/Steepfile +1 -0
  70. data/smoke/kwbegin/Steepfile +1 -0
  71. data/smoke/lambda/Steepfile +1 -0
  72. data/smoke/literal/Steepfile +1 -0
  73. data/smoke/map/Steepfile +1 -0
  74. data/smoke/method/Steepfile +1 -0
  75. data/smoke/module/Steepfile +1 -0
  76. data/smoke/regexp/Steepfile +1 -0
  77. data/smoke/regexp/b.rb +4 -4
  78. data/smoke/regression/Steepfile +1 -0
  79. data/smoke/rescue/Steepfile +1 -0
  80. data/smoke/rescue/a.rb +1 -1
  81. data/smoke/self/Steepfile +1 -0
  82. data/smoke/skip/Steepfile +1 -0
  83. data/smoke/stdout/Steepfile +1 -0
  84. data/smoke/super/Steepfile +1 -0
  85. data/smoke/type_case/Steepfile +1 -0
  86. data/smoke/yield/Steepfile +1 -0
  87. data/steep.gemspec +8 -8
  88. metadata +38 -138
  89. data/exe/rbs +0 -3
  90. data/exe/ruby-signature +0 -3
  91. data/vendor/ruby-signature/.github/workflows/ruby.yml +0 -27
  92. data/vendor/ruby-signature/.gitignore +0 -12
  93. data/vendor/ruby-signature/.rubocop.yml +0 -15
  94. data/vendor/ruby-signature/BSDL +0 -22
  95. data/vendor/ruby-signature/COPYING +0 -56
  96. data/vendor/ruby-signature/Gemfile +0 -6
  97. data/vendor/ruby-signature/README.md +0 -93
  98. data/vendor/ruby-signature/Rakefile +0 -66
  99. data/vendor/ruby-signature/bin/annotate-with-rdoc +0 -156
  100. data/vendor/ruby-signature/bin/console +0 -14
  101. data/vendor/ruby-signature/bin/query-rdoc +0 -103
  102. data/vendor/ruby-signature/bin/setup +0 -10
  103. data/vendor/ruby-signature/bin/sort +0 -88
  104. data/vendor/ruby-signature/bin/test_runner.rb +0 -17
  105. data/vendor/ruby-signature/docs/CONTRIBUTING.md +0 -97
  106. data/vendor/ruby-signature/docs/sigs.md +0 -148
  107. data/vendor/ruby-signature/docs/stdlib.md +0 -152
  108. data/vendor/ruby-signature/docs/syntax.md +0 -528
  109. data/vendor/ruby-signature/exe/rbs +0 -3
  110. data/vendor/ruby-signature/exe/ruby-signature +0 -7
  111. data/vendor/ruby-signature/lib/ruby/signature.rb +0 -64
  112. data/vendor/ruby-signature/lib/ruby/signature/ast/annotation.rb +0 -29
  113. data/vendor/ruby-signature/lib/ruby/signature/ast/comment.rb +0 -29
  114. data/vendor/ruby-signature/lib/ruby/signature/ast/declarations.rb +0 -391
  115. data/vendor/ruby-signature/lib/ruby/signature/ast/members.rb +0 -364
  116. data/vendor/ruby-signature/lib/ruby/signature/buffer.rb +0 -52
  117. data/vendor/ruby-signature/lib/ruby/signature/builtin_names.rb +0 -54
  118. data/vendor/ruby-signature/lib/ruby/signature/cli.rb +0 -534
  119. data/vendor/ruby-signature/lib/ruby/signature/constant.rb +0 -28
  120. data/vendor/ruby-signature/lib/ruby/signature/constant_table.rb +0 -152
  121. data/vendor/ruby-signature/lib/ruby/signature/definition.rb +0 -172
  122. data/vendor/ruby-signature/lib/ruby/signature/definition_builder.rb +0 -921
  123. data/vendor/ruby-signature/lib/ruby/signature/environment.rb +0 -283
  124. data/vendor/ruby-signature/lib/ruby/signature/environment_loader.rb +0 -138
  125. data/vendor/ruby-signature/lib/ruby/signature/environment_walker.rb +0 -126
  126. data/vendor/ruby-signature/lib/ruby/signature/errors.rb +0 -189
  127. data/vendor/ruby-signature/lib/ruby/signature/location.rb +0 -104
  128. data/vendor/ruby-signature/lib/ruby/signature/method_type.rb +0 -125
  129. data/vendor/ruby-signature/lib/ruby/signature/namespace.rb +0 -93
  130. data/vendor/ruby-signature/lib/ruby/signature/parser.y +0 -1343
  131. data/vendor/ruby-signature/lib/ruby/signature/prototype/rb.rb +0 -441
  132. data/vendor/ruby-signature/lib/ruby/signature/prototype/rbi.rb +0 -579
  133. data/vendor/ruby-signature/lib/ruby/signature/prototype/runtime.rb +0 -383
  134. data/vendor/ruby-signature/lib/ruby/signature/substitution.rb +0 -48
  135. data/vendor/ruby-signature/lib/ruby/signature/test.rb +0 -28
  136. data/vendor/ruby-signature/lib/ruby/signature/test/errors.rb +0 -63
  137. data/vendor/ruby-signature/lib/ruby/signature/test/hook.rb +0 -290
  138. data/vendor/ruby-signature/lib/ruby/signature/test/setup.rb +0 -58
  139. data/vendor/ruby-signature/lib/ruby/signature/test/spy.rb +0 -324
  140. data/vendor/ruby-signature/lib/ruby/signature/test/test_helper.rb +0 -185
  141. data/vendor/ruby-signature/lib/ruby/signature/test/type_check.rb +0 -256
  142. data/vendor/ruby-signature/lib/ruby/signature/type_name.rb +0 -72
  143. data/vendor/ruby-signature/lib/ruby/signature/types.rb +0 -932
  144. data/vendor/ruby-signature/lib/ruby/signature/variance_calculator.rb +0 -140
  145. data/vendor/ruby-signature/lib/ruby/signature/vendorer.rb +0 -49
  146. data/vendor/ruby-signature/lib/ruby/signature/version.rb +0 -5
  147. data/vendor/ruby-signature/lib/ruby/signature/writer.rb +0 -271
  148. data/vendor/ruby-signature/ruby-signature.gemspec +0 -45
  149. data/vendor/ruby-signature/stdlib/abbrev/abbrev.rbs +0 -3
  150. data/vendor/ruby-signature/stdlib/base64/base64.rbs +0 -15
  151. data/vendor/ruby-signature/stdlib/builtin/array.rbs +0 -1997
  152. data/vendor/ruby-signature/stdlib/builtin/basic_object.rbs +0 -280
  153. data/vendor/ruby-signature/stdlib/builtin/binding.rbs +0 -177
  154. data/vendor/ruby-signature/stdlib/builtin/builtin.rbs +0 -35
  155. data/vendor/ruby-signature/stdlib/builtin/class.rbs +0 -145
  156. data/vendor/ruby-signature/stdlib/builtin/comparable.rbs +0 -116
  157. data/vendor/ruby-signature/stdlib/builtin/complex.rbs +0 -400
  158. data/vendor/ruby-signature/stdlib/builtin/constants.rbs +0 -37
  159. data/vendor/ruby-signature/stdlib/builtin/data.rbs +0 -5
  160. data/vendor/ruby-signature/stdlib/builtin/deprecated.rbs +0 -2
  161. data/vendor/ruby-signature/stdlib/builtin/dir.rbs +0 -419
  162. data/vendor/ruby-signature/stdlib/builtin/encoding.rbs +0 -606
  163. data/vendor/ruby-signature/stdlib/builtin/enumerable.rbs +0 -404
  164. data/vendor/ruby-signature/stdlib/builtin/enumerator.rbs +0 -260
  165. data/vendor/ruby-signature/stdlib/builtin/errno.rbs +0 -781
  166. data/vendor/ruby-signature/stdlib/builtin/errors.rbs +0 -582
  167. data/vendor/ruby-signature/stdlib/builtin/exception.rbs +0 -193
  168. data/vendor/ruby-signature/stdlib/builtin/false_class.rbs +0 -40
  169. data/vendor/ruby-signature/stdlib/builtin/fiber.rbs +0 -68
  170. data/vendor/ruby-signature/stdlib/builtin/fiber_error.rbs +0 -12
  171. data/vendor/ruby-signature/stdlib/builtin/file.rbs +0 -476
  172. data/vendor/ruby-signature/stdlib/builtin/file_test.rbs +0 -59
  173. data/vendor/ruby-signature/stdlib/builtin/float.rbs +0 -696
  174. data/vendor/ruby-signature/stdlib/builtin/gc.rbs +0 -121
  175. data/vendor/ruby-signature/stdlib/builtin/hash.rbs +0 -1029
  176. data/vendor/ruby-signature/stdlib/builtin/integer.rbs +0 -710
  177. data/vendor/ruby-signature/stdlib/builtin/io.rbs +0 -683
  178. data/vendor/ruby-signature/stdlib/builtin/kernel.rbs +0 -574
  179. data/vendor/ruby-signature/stdlib/builtin/marshal.rbs +0 -135
  180. data/vendor/ruby-signature/stdlib/builtin/match_data.rbs +0 -141
  181. data/vendor/ruby-signature/stdlib/builtin/math.rbs +0 -66
  182. data/vendor/ruby-signature/stdlib/builtin/method.rbs +0 -182
  183. data/vendor/ruby-signature/stdlib/builtin/module.rbs +0 -248
  184. data/vendor/ruby-signature/stdlib/builtin/nil_class.rbs +0 -82
  185. data/vendor/ruby-signature/stdlib/builtin/numeric.rbs +0 -409
  186. data/vendor/ruby-signature/stdlib/builtin/object.rbs +0 -824
  187. data/vendor/ruby-signature/stdlib/builtin/proc.rbs +0 -426
  188. data/vendor/ruby-signature/stdlib/builtin/process.rbs +0 -354
  189. data/vendor/ruby-signature/stdlib/builtin/random.rbs +0 -93
  190. data/vendor/ruby-signature/stdlib/builtin/range.rbs +0 -226
  191. data/vendor/ruby-signature/stdlib/builtin/rational.rbs +0 -424
  192. data/vendor/ruby-signature/stdlib/builtin/rb_config.rbs +0 -10
  193. data/vendor/ruby-signature/stdlib/builtin/regexp.rbs +0 -131
  194. data/vendor/ruby-signature/stdlib/builtin/ruby_vm.rbs +0 -14
  195. data/vendor/ruby-signature/stdlib/builtin/signal.rbs +0 -55
  196. data/vendor/ruby-signature/stdlib/builtin/string.rbs +0 -770
  197. data/vendor/ruby-signature/stdlib/builtin/string_io.rbs +0 -13
  198. data/vendor/ruby-signature/stdlib/builtin/struct.rbs +0 -40
  199. data/vendor/ruby-signature/stdlib/builtin/symbol.rbs +0 -230
  200. data/vendor/ruby-signature/stdlib/builtin/thread.rbs +0 -1112
  201. data/vendor/ruby-signature/stdlib/builtin/thread_group.rbs +0 -23
  202. data/vendor/ruby-signature/stdlib/builtin/time.rbs +0 -739
  203. data/vendor/ruby-signature/stdlib/builtin/trace_point.rbs +0 -91
  204. data/vendor/ruby-signature/stdlib/builtin/true_class.rbs +0 -46
  205. data/vendor/ruby-signature/stdlib/builtin/unbound_method.rbs +0 -159
  206. data/vendor/ruby-signature/stdlib/builtin/warning.rbs +0 -17
  207. data/vendor/ruby-signature/stdlib/erb/erb.rbs +0 -18
  208. data/vendor/ruby-signature/stdlib/find/find.rbs +0 -44
  209. data/vendor/ruby-signature/stdlib/pathname/pathname.rbs +0 -21
  210. data/vendor/ruby-signature/stdlib/prime/integer-extension.rbs +0 -23
  211. data/vendor/ruby-signature/stdlib/prime/prime.rbs +0 -188
  212. data/vendor/ruby-signature/stdlib/securerandom/securerandom.rbs +0 -9
  213. data/vendor/ruby-signature/stdlib/set/set.rbs +0 -77
  214. data/vendor/ruby-signature/stdlib/tmpdir/tmpdir.rbs +0 -53
@@ -9,6 +9,7 @@ module Steep
9
9
  attr_reader :ignored_sources
10
10
  attr_reader :no_builtin
11
11
  attr_reader :vendor_dir
12
+ attr_reader :strictness_level
12
13
 
13
14
  def initialize(name, sources: [], libraries: [], signatures: [], ignored_sources: [])
14
15
  @name = name
@@ -17,6 +18,7 @@ module Steep
17
18
  @signatures = signatures
18
19
  @ignored_sources = ignored_sources
19
20
  @vendor_dir = nil
21
+ @strictness_level = :default
20
22
  end
21
23
 
22
24
  def initialize_copy(other)
@@ -26,6 +28,7 @@ module Steep
26
28
  @signatures = other.signatures.dup
27
29
  @ignored_sources = other.ignored_sources.dup
28
30
  @vendor_dir = other.vendor_dir
31
+ @strictness_level = other.strictness_level
29
32
  end
30
33
 
31
34
  def check(*args)
@@ -40,6 +43,10 @@ module Steep
40
43
  libraries.push(*args)
41
44
  end
42
45
 
46
+ def typing_options(level)
47
+ @strictness_level = level
48
+ end
49
+
43
50
  def signature(*args)
44
51
  signatures.push(*args)
45
52
  end
@@ -114,6 +121,13 @@ module Steep
114
121
  options: Options.new.tap do |options|
115
122
  options.libraries.push(*target.libraries)
116
123
 
124
+ case target.strictness_level
125
+ when :strict
126
+ options.apply_strict_typing_options!
127
+ when :lenient
128
+ options.apply_lenient_typing_options!
129
+ end
130
+
117
131
  case target.vendor_dir
118
132
  when Array
119
133
  options.vendored_stdlib_path = target.vendor_dir[0]
@@ -31,65 +31,72 @@ module Steep
31
31
  case status
32
32
  when TypeCheckStatus
33
33
  status.typing.errors
34
- # errors.reject do |error|
35
- # case
36
- # when error.is_a?(Errors::FallbackAny)
37
- # !options.fallback_any_is_error
38
- # when error.is_a?(Errors::MethodDefinitionMissing)
39
- # options.allow_missing_definitions
40
- # end
41
- # end
42
34
  else
43
35
  []
44
36
  end
45
37
  end
46
38
 
39
+ def self.parse(source_code, path:, factory:)
40
+ Source.parse(source_code, path: path.to_s, factory: factory, labeling: ASTUtils::Labeling.new)
41
+ end
42
+
43
+ def self.type_check(source, subtyping:)
44
+ annotations = source.annotations(block: source.node, factory: subtyping.factory, current_module: AST::Namespace.root)
45
+ const_env = TypeInference::ConstantEnv.new(factory: subtyping.factory, context: [AST::Namespace.root])
46
+ type_env = TypeInference::TypeEnv.build(annotations: annotations,
47
+ subtyping: subtyping,
48
+ const_env: const_env,
49
+ signatures: subtyping.factory.env)
50
+ lvar_env = TypeInference::LocalVariableTypeEnv.empty(
51
+ subtyping: subtyping,
52
+ self_type: AST::Builtin::Object.instance_type
53
+ ).annotate(annotations)
54
+
55
+ context = TypeInference::Context.new(
56
+ block_context: nil,
57
+ module_context: TypeInference::Context::ModuleContext.new(
58
+ instance_type: nil,
59
+ module_type: nil,
60
+ implement_name: nil,
61
+ current_namespace: AST::Namespace.root,
62
+ const_env: const_env,
63
+ class_name: nil
64
+ ),
65
+ method_context: nil,
66
+ break_context: nil,
67
+ self_type: AST::Builtin::Object.instance_type,
68
+ type_env: type_env,
69
+ lvar_env: lvar_env
70
+ )
71
+
72
+ typing = Typing.new(source: source, root_context: context)
73
+
74
+ construction = TypeConstruction.new(
75
+ checker: subtyping,
76
+ annotations: annotations,
77
+ source: source,
78
+ context: context,
79
+ typing: typing
80
+ )
81
+
82
+ construction.synthesize(source.node) if source.node
83
+
84
+ typing
85
+ end
86
+
47
87
  def type_check(subtyping, env_updated_at)
48
88
  # skip type check
49
89
  return false if status.is_a?(TypeCheckStatus) && env_updated_at <= status.timestamp
50
90
 
51
91
  parse(subtyping.factory) do |source|
52
- typing = Typing.new
53
-
54
- if source
55
- annotations = source.annotations(block: source.node, factory: subtyping.factory, current_module: AST::Namespace.root)
56
- const_env = TypeInference::ConstantEnv.new(factory: subtyping.factory, context: nil)
57
- type_env = TypeInference::TypeEnv.build(annotations: annotations,
58
- subtyping: subtyping,
59
- const_env: const_env,
60
- signatures: subtyping.factory.env)
61
-
62
- construction = TypeConstruction.new(
63
- checker: subtyping,
64
- annotations: annotations,
65
- source: source,
66
- context: TypeInference::Context.new(
67
- block_context: nil,
68
- module_context: TypeInference::Context::ModuleContext.new(
69
- instance_type: nil,
70
- module_type: nil,
71
- implement_name: nil,
72
- current_namespace: AST::Namespace.root,
73
- const_env: const_env,
74
- class_name: nil
75
- ),
76
- method_context: nil,
77
- break_context: nil,
78
- self_type: AST::Builtin::Object.instance_type,
79
- type_env: type_env
80
- ),
81
- typing: typing
82
- )
83
-
84
- construction.synthesize(source.node)
85
- end
86
-
92
+ typing = self.class.type_check(source, subtyping: subtyping)
87
93
  @status = TypeCheckStatus.new(
88
94
  typing: typing,
89
95
  source: source,
90
96
  timestamp: Time.now
91
97
  )
92
98
  rescue => exn
99
+ Steep.log_error(exn)
93
100
  @status = TypeCheckErrorStatus.new(error: exn)
94
101
  end
95
102
 
@@ -100,7 +107,7 @@ module Steep
100
107
  if status.is_a?(TypeCheckStatus)
101
108
  yield status.source
102
109
  else
103
- yield Source.parse(content, path: path.to_s, factory: factory, labeling: ASTUtils::Labeling.new)
110
+ yield self.class.parse(content, path: path, factory: factory)
104
111
  end
105
112
  rescue AnnotationParser::SyntaxError => exn
106
113
  Steep.logger.warn { "Annotation syntax error on #{path}: #{exn.inspect}" }
@@ -133,10 +140,10 @@ module Steep
133
140
  end
134
141
 
135
142
  def load!
136
- buffer = Ruby::Signature::Buffer.new(name: path, content: content)
137
- decls = Ruby::Signature::Parser.parse_signature(buffer)
143
+ buffer = RBS::Buffer.new(name: path, content: content)
144
+ decls = RBS::Parser.parse_signature(buffer)
138
145
  @status = DeclarationsStatus.new(declarations: decls)
139
- rescue Ruby::Signature::Parser::SyntaxError, Ruby::Signature::Parser::SemanticsError => exn
146
+ rescue RBS::Parser::SyntaxError, RBS::Parser::SemanticsError => exn
140
147
  @status = ParseErrorStatus.new(error: exn)
141
148
  end
142
149
  end
@@ -33,21 +33,30 @@ module Steep
33
33
  end
34
34
 
35
35
  def content_for(path:, line:, column:)
36
- source_file = project.targets.map {|target| target.source_files[path] }.compact[0]
36
+ target = project.targets.find {|target| target.source_file?(path) }
37
+
38
+ if target
39
+ source_file = target.source_files[path]
40
+ target.type_check(target_sources: [source_file], validate_signatures: false)
37
41
 
38
- if source_file
39
42
  case (status = source_file.status)
40
43
  when SourceFile::TypeCheckStatus
41
44
  node, *parents = status.source.find_nodes(line: line, column: column)
42
45
 
43
46
  if node
44
47
  case node.type
45
- when :lvar, :lvasgn
48
+ when :lvar
46
49
  var_name = node.children[0]
47
- context = status.typing.context_of(node: node)
48
- var_type = context.type_env.get(lvar: var_name.name)
50
+ context = status.typing.context_at(line: line, column: column)
51
+ var_type = context.lvar_env[var_name.name] || AST::Types::Any.new(location: nil)
49
52
 
50
53
  VariableContent.new(node: node, name: var_name.name, type: var_type, location: node.location.name)
54
+ when :lvasgn
55
+ var_name, rhs = node.children
56
+ context = status.typing.context_at(line: line, column: column)
57
+ type = context.lvar_env[var_name.name] || status.typing.type_of(node: rhs)
58
+
59
+ VariableContent.new(node: node, name: var_name.name, type: type, location: node.location.name)
51
60
  when :send
52
61
  receiver, method_name, *_ = node.children
53
62
 
@@ -58,7 +67,7 @@ module Steep
58
67
  node
59
68
  end
60
69
 
61
- context = status.typing.context_of(node: result_node)
70
+ context = status.typing.context_at(line: line, column: column)
62
71
 
63
72
  receiver_type = if receiver
64
73
  status.typing.type_of(node: receiver)
@@ -98,10 +107,10 @@ module Steep
98
107
  location: result_node.location.expression
99
108
  )
100
109
  when :def, :defs
101
- context = status.typing.context_of(node: node)
110
+ context = status.typing.context_at(line: line, column: column)
102
111
  method_context = context.method_context
103
112
 
104
- if method_context
113
+ if method_context && method_context.method
105
114
  DefinitionContent.new(
106
115
  node: node,
107
116
  method_name: method_context.name,
@@ -1,20 +1,42 @@
1
1
  module Steep
2
2
  class Project
3
3
  class Options
4
- attr_accessor :fallback_any_is_error
4
+ attr_accessor :allow_fallback_any
5
5
  attr_accessor :allow_missing_definitions
6
+ attr_accessor :allow_unknown_constant_assignment
7
+ attr_accessor :allow_unknown_method_calls
6
8
  attr_accessor :vendored_stdlib_path
7
9
  attr_accessor :vendored_gems_path
8
10
  attr_reader :libraries
9
11
 
10
12
  def initialize
11
- self.fallback_any_is_error = false
12
- self.allow_missing_definitions = true
13
+ apply_default_typing_options!
13
14
  self.vendored_gems_path = nil
14
15
  self.vendored_stdlib_path = nil
15
16
 
16
17
  @libraries = []
17
18
  end
19
+
20
+ def apply_default_typing_options!
21
+ self.allow_fallback_any = true
22
+ self.allow_missing_definitions = true
23
+ self.allow_unknown_constant_assignment = false
24
+ self.allow_unknown_method_calls = false
25
+ end
26
+
27
+ def apply_strict_typing_options!
28
+ self.allow_fallback_any = false
29
+ self.allow_missing_definitions = false
30
+ self.allow_unknown_constant_assignment = false
31
+ self.allow_unknown_method_calls = false
32
+ end
33
+
34
+ def apply_lenient_typing_options!
35
+ self.allow_fallback_any = true
36
+ self.allow_missing_definitions = true
37
+ self.allow_unknown_constant_assignment = true
38
+ self.allow_unknown_method_calls = true
39
+ end
18
40
  end
19
41
  end
20
42
  end
@@ -67,32 +67,38 @@ module Steep
67
67
  end
68
68
 
69
69
  def possible_source_file?(path)
70
- self.class.test_pattern(source_patterns, path) &&
71
- !self.class.test_pattern(ignore_patterns, path)
70
+ self.class.test_pattern(source_patterns, path, ext: ".rb") &&
71
+ !self.class.test_pattern(ignore_patterns, path, ext: ".rb")
72
72
  end
73
73
 
74
74
  def possible_signature_file?(path)
75
- self.class.test_pattern(signature_patterns, path)
75
+ self.class.test_pattern(signature_patterns, path, ext: ".rbs")
76
76
  end
77
77
 
78
- def self.test_pattern(patterns, path)
78
+ def self.test_pattern(patterns, path, ext:)
79
79
  patterns.any? do |pattern|
80
80
  p = pattern.end_with?(File::Separator) ? pattern : pattern + File::Separator
81
- path.to_s.start_with?(p) || File.fnmatch(pattern, path.to_s)
81
+ (path.to_s.start_with?(p) && path.extname == ext) || File.fnmatch(pattern, path.to_s)
82
82
  end
83
83
  end
84
84
 
85
- def type_check
86
- load_signatures do |env, check, timestamp|
87
- run_type_check(env, check, timestamp)
85
+ def type_check(target_sources: source_files.values, validate_signatures: true)
86
+ Steep.logger.tagged "target#type_check(target_sources: [#{target_sources.map(&:path).join(", ")}], validate_signatures: #{validate_signatures})" do
87
+ Steep.measure "load signature and type check" do
88
+ load_signatures(validate: validate_signatures) do |env, check, timestamp|
89
+ Steep.measure "type checking #{target_sources.size} files" do
90
+ run_type_check(env, check, timestamp, target_sources: target_sources)
91
+ end
92
+ end
93
+ end
88
94
  end
89
95
  end
90
96
 
91
97
  def environment
92
- @environment ||= Ruby::Signature::Environment.new().tap do |env|
93
- stdlib_root = options.vendored_stdlib_path || Ruby::Signature::EnvironmentLoader::STDLIB_ROOT
98
+ @environment ||= RBS::Environment.new().tap do |env|
99
+ stdlib_root = options.vendored_stdlib_path || RBS::EnvironmentLoader::STDLIB_ROOT
94
100
  gem_vendor_path = options.vendored_gems_path
95
- loader = Ruby::Signature::EnvironmentLoader.new(stdlib_root: stdlib_root, gem_vendor_path: gem_vendor_path)
101
+ loader = RBS::EnvironmentLoader.new(stdlib_root: stdlib_root, gem_vendor_path: gem_vendor_path)
96
102
  options.libraries.each do |lib|
97
103
  loader.add(library: lib)
98
104
  end
@@ -100,7 +106,7 @@ module Steep
100
106
  end
101
107
  end
102
108
 
103
- def load_signatures
109
+ def load_signatures(validate:)
104
110
  timestamp = case status
105
111
  when TypeCheckStatus
106
112
  status.timestamp
@@ -129,20 +135,24 @@ module Steep
129
135
  end
130
136
  end
131
137
 
132
- definition_builder = Ruby::Signature::DefinitionBuilder.new(env: env)
138
+ definition_builder = RBS::DefinitionBuilder.new(env: env)
133
139
  factory = AST::Types::Factory.new(builder: definition_builder)
134
140
  check = Subtyping::Check.new(factory: factory)
135
141
 
136
- validator = Signature::Validator.new(checker: check)
137
- validator.validate()
138
-
139
- if validator.no_error?
140
- yield env, check, Time.now
142
+ if validate
143
+ validator = Signature::Validator.new(checker: check)
144
+ validator.validate()
145
+
146
+ if validator.no_error?
147
+ yield env, check, Time.now
148
+ else
149
+ @status = SignatureValidationErrorStatus.new(
150
+ errors: validator.each_error.to_a,
151
+ timestamp: Time.now
152
+ )
153
+ end
141
154
  else
142
- @status = SignatureValidationErrorStatus.new(
143
- errors: validator.each_error.to_a,
144
- timestamp: Time.now
145
- )
155
+ yield env, check, Time.now
146
156
  end
147
157
  end
148
158
 
@@ -160,10 +170,10 @@ module Steep
160
170
  end
161
171
  end
162
172
 
163
- def run_type_check(env, check, timestamp)
173
+ def run_type_check(env, check, timestamp, target_sources: source_files.values)
164
174
  type_check_sources = []
165
175
 
166
- source_files.each_value do |file|
176
+ target_sources.each do |file|
167
177
  if file.type_check(check, timestamp)
168
178
  type_check_sources << file
169
179
  end
@@ -177,6 +187,12 @@ module Steep
177
187
  )
178
188
  end
179
189
 
190
+ def no_error?
191
+ source_files.all? do |_, file|
192
+ file.status.is_a?(Project::SourceFile::TypeCheckStatus)
193
+ end
194
+ end
195
+
180
196
  def errors
181
197
  case status
182
198
  when TypeCheckStatus
@@ -0,0 +1,56 @@
1
+ module Steep
2
+ module Server
3
+ class BaseWorker
4
+ LSP = LanguageServer::Protocol
5
+
6
+ include Utils
7
+
8
+ attr_reader :project
9
+ attr_reader :reader, :writer
10
+
11
+ def initialize(project:, reader:, writer:)
12
+ @project = project
13
+ @reader = reader
14
+ @writer = writer
15
+ end
16
+
17
+ def handle_request(request)
18
+ # process request
19
+ end
20
+
21
+ def handle_job(job)
22
+ # process async job
23
+ end
24
+
25
+ def run
26
+ tags = Steep.logger.formatter.current_tags.dup
27
+ thread = Thread.new do
28
+ Steep.logger.formatter.push_tags(*tags)
29
+ Steep.logger.tagged "background" do
30
+ while job = queue.pop
31
+ handle_job(job)
32
+ end
33
+ end
34
+ end
35
+
36
+ Steep.logger.tagged "frontend" do
37
+ begin
38
+ reader.read do |request|
39
+ case request[:method]
40
+ when "shutdown"
41
+ # nop
42
+ when "exit"
43
+ break
44
+ else
45
+ handle_request(request)
46
+ end
47
+ end
48
+ ensure
49
+ queue << nil
50
+ thread.join
51
+ end
52
+ end
53
+ end
54
+ end
55
+ end
56
+ end