steep 1.8.2 → 1.9.0.dev.1

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 (45) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +0 -12
  3. data/Steepfile +0 -14
  4. data/lib/steep/cli.rb +47 -5
  5. data/lib/steep/diagnostic/ruby.rb +1 -58
  6. data/lib/steep/drivers/annotations.rb +1 -1
  7. data/lib/steep/drivers/check.rb +107 -1
  8. data/lib/steep/drivers/checkfile.rb +10 -8
  9. data/lib/steep/drivers/print_project.rb +83 -40
  10. data/lib/steep/drivers/utils/driver_helper.rb +5 -3
  11. data/lib/steep/drivers/watch.rb +24 -2
  12. data/lib/steep/index/signature_symbol_provider.rb +8 -8
  13. data/lib/steep/interface/builder.rb +14 -1
  14. data/lib/steep/interface/function.rb +2 -2
  15. data/lib/steep/path_helper.rb +4 -2
  16. data/lib/steep/project/dsl.rb +176 -151
  17. data/lib/steep/project/group.rb +31 -0
  18. data/lib/steep/project/target.rb +32 -6
  19. data/lib/steep/project.rb +38 -10
  20. data/lib/steep/server/delay_queue.rb +0 -3
  21. data/lib/steep/server/interaction_worker.rb +2 -11
  22. data/lib/steep/server/master.rb +95 -281
  23. data/lib/steep/server/target_group_files.rb +205 -0
  24. data/lib/steep/server/type_check_controller.rb +322 -0
  25. data/lib/steep/server/type_check_worker.rb +60 -86
  26. data/lib/steep/services/file_loader.rb +23 -0
  27. data/lib/steep/services/goto_service.rb +40 -31
  28. data/lib/steep/services/hover_provider/singleton_methods.rb +4 -4
  29. data/lib/steep/services/path_assignment.rb +23 -4
  30. data/lib/steep/services/type_check_service.rb +76 -159
  31. data/lib/steep/signature/validator.rb +4 -4
  32. data/lib/steep/subtyping/check.rb +2 -2
  33. data/lib/steep/thread_waiter.rb +24 -16
  34. data/lib/steep/type_construction.rb +5 -5
  35. data/lib/steep/type_inference/block_params.rb +1 -2
  36. data/lib/steep/type_inference/context.rb +1 -1
  37. data/lib/steep/type_inference/type_env.rb +4 -4
  38. data/lib/steep/type_inference/type_env_builder.rb +1 -1
  39. data/lib/steep/version.rb +1 -1
  40. data/lib/steep.rb +6 -4
  41. data/sample/Steepfile +6 -0
  42. data/sample/lib/conference.rb +1 -5
  43. data/steep.gemspec +7 -1
  44. metadata +8 -6
  45. data/lib/steep/drivers/validate.rb +0 -65
@@ -11,7 +11,7 @@ module Steep
11
11
  attr_reader :assignment
12
12
 
13
13
  def initialize(project:, assignment:)
14
- @indexes = []
14
+ @indexes = {}
15
15
  @project = project
16
16
  @assignment = assignment
17
17
  end
@@ -39,20 +39,20 @@ module Steep
39
39
  end
40
40
  end
41
41
 
42
- def assigned?(path)
42
+ def assigned?(target, path)
43
43
  if path.relative?
44
44
  if project.targets.any? {|target| target.possible_signature_file?(path) }
45
45
  path = project.absolute_path(path)
46
46
  end
47
47
  end
48
48
 
49
- assignment =~ path
49
+ assignment =~ [target, path]
50
50
  end
51
51
 
52
52
  def query_symbol(query)
53
53
  symbols = [] #: Array[SymbolInformation]
54
54
 
55
- indexes.each do |index|
55
+ indexes.each do |target, index|
56
56
  index.each_entry do |entry|
57
57
  case entry
58
58
  when RBSIndex::TypeEntry
@@ -63,7 +63,7 @@ module Steep
63
63
 
64
64
  entry.declarations.each do |decl|
65
65
  location = decl.location or next
66
- next unless assigned?(Pathname(location.buffer.name))
66
+ next unless assigned?(target, Pathname(location.buffer.name))
67
67
 
68
68
  case decl
69
69
  when RBS::AST::Declarations::Class
@@ -111,7 +111,7 @@ module Steep
111
111
 
112
112
  entry.declarations.each do |decl|
113
113
  location = decl.location or next
114
- next unless assigned?(Pathname(location.buffer.name))
114
+ next unless assigned?(target, Pathname(location.buffer.name))
115
115
 
116
116
  case decl
117
117
  when RBS::AST::Members::MethodDefinition
@@ -151,7 +151,7 @@ module Steep
151
151
 
152
152
  entry.declarations.each do |decl|
153
153
  next unless decl.location
154
- next unless assigned?(Pathname(decl.location.buffer.name))
154
+ next unless assigned?(target, Pathname(decl.location.buffer.name))
155
155
 
156
156
  symbols << SymbolInformation.new(
157
157
  name: entry.const_name.name.to_s,
@@ -165,7 +165,7 @@ module Steep
165
165
 
166
166
  entry.declarations.each do |decl|
167
167
  next unless decl.location
168
- next unless assigned?(Pathname(decl.location.buffer.name))
168
+ next unless assigned?(target, Pathname(decl.location.buffer.name))
169
169
 
170
170
  symbols << SymbolInformation.new(
171
171
  name: decl.name.to_s,
@@ -282,6 +282,7 @@ module Steep
282
282
  method_type = factory.method_type(type_def.type)
283
283
  method_type = replace_primitive_method(method_name, type_def, method_type)
284
284
  method_type = replace_kernel_class(method_name, type_def, method_type) { AST::Builtin::Class.instance_type }
285
+ method_type = add_implicitly_returns_nil(type_def.annotations, method_type)
285
286
  Shape::MethodOverload.new(method_type, [type_def])
286
287
  end
287
288
 
@@ -315,6 +316,7 @@ module Steep
315
316
  if type_name.class?
316
317
  method_type = replace_kernel_class(method_name, type_def, method_type) { AST::Types::Name::Singleton.new(name: type_name) }
317
318
  end
319
+ method_type = add_implicitly_returns_nil(type_def.annotations, method_type)
318
320
  Shape::MethodOverload.new(method_type, [type_def])
319
321
  end
320
322
 
@@ -586,7 +588,7 @@ module Steep
586
588
 
587
589
  def record_shape(record)
588
590
  all_key_type = AST::Types::Union.build(
589
- types: record.elements.each_key.map {|value| AST::Types::Literal.new(value: value) }
591
+ types: record.elements.each_key.map {|value| AST::Types::Literal.new(value: value).back_type }
590
592
  )
591
593
  all_value_type = AST::Types::Union.build(types: record.elements.values)
592
594
  hash_type = AST::Builtin::Hash.instance_type(all_key_type, all_value_type)
@@ -822,6 +824,17 @@ module Steep
822
824
 
823
825
  method_type
824
826
  end
827
+
828
+ def add_implicitly_returns_nil(annotations, method_type)
829
+ if annotations.find { _1.string == "implicitly-returns-nil" }
830
+ return_type = method_type.type.return_type
831
+ method_type = method_type.with(
832
+ type: method_type.type.with(return_type: AST::Types::Union.build(types: [return_type, AST::Builtin.nil_type]))
833
+ )
834
+ else
835
+ method_type
836
+ end
837
+ end
825
838
  end
826
839
  end
827
840
  end
@@ -926,10 +926,10 @@ module Steep
926
926
  def to_s
927
927
  required = self.required.map {|ty| ty.to_s }
928
928
  optional = self.optional.map {|ty| "?#{ty}" }
929
- rest = self.rest ? ["*#{self.rest}"] : []
929
+ rest = self.rest ? ["*#{self.rest}"] : [] #: Array[String]
930
930
  required_keywords = keyword_params.requireds.map {|name, type| "#{name}: #{type}" }
931
931
  optional_keywords = keyword_params.optionals.map {|name, type| "?#{name}: #{type}"}
932
- rest_keywords = keyword_params.rest ? ["**#{keyword_params.rest}"] : []
932
+ rest_keywords = keyword_params.rest ? ["**#{keyword_params.rest}"] : [] #: Array[String]
933
933
  "(#{(required + optional + rest + required_keywords + optional_keywords + rest_keywords).join(", ")})"
934
934
  end
935
935
 
@@ -2,12 +2,14 @@ module Steep
2
2
  module PathHelper
3
3
  module_function
4
4
 
5
+ URIParser = URI::RFC2396_Parser.new()
6
+
5
7
  def to_pathname(uri, dosish: Gem.win_platform?)
6
8
  uri = URI.parse(uri)
7
9
  if uri.scheme == "file"
8
10
  path = uri.path or raise
9
11
  path.sub!(%r{^/([a-zA-Z])(:|%3A)//?}i, '\1:/') if dosish
10
- path = URI::DEFAULT_PARSER.unescape(path)
12
+ path = URIParser.unescape(path)
11
13
  Pathname(path)
12
14
  end
13
15
  end
@@ -21,7 +23,7 @@ module Steep
21
23
  if dosish
22
24
  str_path.insert(0, "/") if str_path[0] != "/"
23
25
  end
24
- str_path = URI::DEFAULT_PARSER.escape(str_path)
26
+ str_path = URIParser.escape(str_path)
25
27
  URI::File.build(path: str_path)
26
28
  end
27
29
  end
@@ -1,137 +1,154 @@
1
1
  module Steep
2
2
  class Project
3
3
  class DSL
4
- class TargetDSL
5
- attr_reader :name
6
- attr_reader :sources
7
- attr_reader :libraries
8
- attr_reader :signatures
9
- attr_reader :ignored_sources
4
+ module LibraryOptions
10
5
  attr_reader :stdlib_root
11
6
  attr_reader :core_root
12
- attr_reader :repo_paths
13
- attr_reader :code_diagnostics_config
14
- attr_reader :project
15
7
  attr_reader :collection_config_path
16
8
 
17
- def initialize(name, sources: [], libraries: [], signatures: [], ignored_sources: [], repo_paths: [], code_diagnostics_config: {}, project: nil, collection_config_path: nil)
18
- @name = name
19
- @sources = sources
20
- @libraries = libraries
21
- @signatures = signatures
22
- @ignored_sources = ignored_sources
23
- @core_root = nil
24
- @stdlib_root = nil
25
- @repo_paths = []
26
- @code_diagnostics_config = code_diagnostics_config
27
- @project = project
28
- @collection_config_path = collection_config_path
9
+ def stdlib_path(core_root:, stdlib_root:)
10
+ @core_root = Pathname(core_root)
11
+ @stdlib_root = Pathname(stdlib_root)
29
12
  end
30
13
 
31
- def initialize_copy(other)
32
- @name = other.name
33
- @sources = other.sources.dup
34
- @libraries = other.libraries.dup
35
- @signatures = other.signatures.dup
36
- @ignored_sources = other.ignored_sources.dup
37
- @repo_paths = other.repo_paths.dup
38
- @core_root = other.core_root
39
- @stdlib_root = other.stdlib_root
40
- @code_diagnostics_config = other.code_diagnostics_config.dup
41
- @project = other.project
42
- @collection_config_path = other.collection_config_path
14
+ def repo_path(*paths)
15
+ @library_configured = true
16
+ repo_paths.push(*paths.map {|s| Pathname(s) })
43
17
  end
44
18
 
45
- def check(*args)
46
- sources.push(*args)
19
+ def collection_config(path)
20
+ @library_configured = true
21
+ @collection_config_path = project.absolute_path(path)
47
22
  end
48
23
 
49
- def ignore(*args)
50
- ignored_sources.push(*args)
24
+ def disable_collection
25
+ @library_configured = true
26
+ @collection_config_path = false
51
27
  end
52
28
 
53
29
  def library(*args)
30
+ @library_configured = true
54
31
  libraries.push(*args)
55
32
  end
56
33
 
57
- def typing_options(level = nil, **hash)
58
- Steep.logger.error "#typing_options is deprecated and has no effect as of version 0.46.0. Update your Steepfile as follows for (almost) equivalent setting:"
34
+ def repo_paths
35
+ @repo_paths ||= []
36
+ end
59
37
 
60
- messages = [] #: Array[String]
38
+ def libraries
39
+ @libraries ||= []
40
+ end
61
41
 
62
- messages << "# D = Steep::Diagnostic # Define a constant to shorten namespace"
42
+ def library_configured?
43
+ @library_configured
44
+ end
63
45
 
64
- case level
65
- when :strict
66
- messages << "configure_code_diagnostics(D::Ruby.strict) # :strict"
67
- when :default
68
- messages << "configure_code_diagnostics(D::Ruby.default) # :default"
69
- when :lenient
70
- messages << "configure_code_diagnostics(D::Ruby.lenient) # :lenient"
71
- end
46
+ def to_library_options
47
+ config_path =
48
+ case collection_config_path
49
+ when Pathname
50
+ collection_config_path
51
+ when nil
52
+ default = project.absolute_path(RBS::Collection::Config::PATH)
53
+ if default.file?
54
+ default
55
+ end
56
+ when false
57
+ nil
58
+ end
72
59
 
73
- messages.each do |msg|
74
- Steep.logger.error " #{msg}"
60
+ Options.new.tap do |options|
61
+ options.libraries.push(*libraries)
62
+ options.paths = Options::PathOptions.new(
63
+ core_root: core_root,
64
+ stdlib_root: stdlib_root,
65
+ repo_paths: repo_paths
66
+ )
67
+ options.collection_config_path = config_path
75
68
  end
69
+ end
70
+ end
76
71
 
77
- config = [] #: Array[String]
72
+ module WithPattern
73
+ def check(*args)
74
+ sources.concat(args)
75
+ end
78
76
 
79
- if hash[:allow_missing_definitions]
80
- config << "hash[D::Ruby::MethodDefinitionMissing] = nil # allow_missing_definitions"
81
- end
77
+ def ignore(*args)
78
+ ignored_sources.concat(args)
79
+ end
82
80
 
83
- if hash[:allow_fallback_any]
84
- config << "hash[D::Ruby::FallbackAny] = nil # allow_fallback_any"
85
- end
81
+ def signature(*args)
82
+ signatures.concat(args)
83
+ end
86
84
 
87
- if hash[:allow_unknown_constant_assignment]
88
- config << "hash[D::Ruby::UnknownConstantAssigned] = nil # allow_unknown_constant_assignment"
89
- end
85
+ def ignore_signature(*args)
86
+ ignored_signatures.concat(args)
87
+ end
90
88
 
91
- if hash[:allow_unknown_method_calls]
92
- config << "hash[D::Ruby::NoMethod] = nil # allow_unknown_method_calls"
93
- end
89
+ def sources
90
+ @sources ||= []
91
+ end
94
92
 
95
- unless config.empty?
96
- Steep.logger.error " configure_code_diagnostics do |hash|"
97
- config.each do |c|
98
- Steep.logger.error " #{c}"
99
- end
100
- Steep.logger.error " end"
101
- end
93
+ def ignored_sources
94
+ @ignored_sources ||= []
95
+ end
102
96
 
97
+ def signatures
98
+ @signatures ||= []
103
99
  end
104
100
 
105
- def signature(*args)
106
- signatures.push(*args)
101
+ def ignored_signatures
102
+ @ignored_signatures ||= []
107
103
  end
108
104
 
109
- def update(name: self.name, sources: self.sources, libraries: self.libraries, ignored_sources: self.ignored_sources, signatures: self.signatures, project: self.project)
110
- self.class.new(
111
- name,
112
- sources: sources,
113
- libraries: libraries,
114
- signatures: signatures,
115
- ignored_sources: ignored_sources,
116
- project: project,
117
- )
105
+ def source_pattern
106
+ Pattern.new(patterns: sources, ignores: ignored_sources, ext: ".rb")
118
107
  end
119
108
 
120
- def no_builtin!(value = true)
121
- Steep.logger.error "`#no_builtin!` in Steepfile is deprecated and ignored. Use `#stdlib_path` instead."
109
+ def signature_pattern
110
+ Pattern.new(patterns: signatures, ignores: ignored_signatures, ext: ".rbs")
122
111
  end
112
+ end
113
+
114
+ class TargetDSL
115
+ include LibraryOptions
116
+ include WithPattern
117
+
118
+ attr_reader :name
119
+ attr_reader :project
120
+ attr_reader :unreferenced
121
+ attr_reader :groups
123
122
 
124
- def vendor(dir = "vendor/sigs", stdlib: nil, gems: nil)
125
- Steep.logger.error "`#vendor` in Steepfile is deprecated and ignored. Use `#stdlib_path` instead."
123
+ def initialize(name, project:)
124
+ @name = name
125
+ @core_root = nil
126
+ @stdlib_root = nil
127
+ @project = project
128
+ @collection_config_path = collection_config_path
129
+ @unreferenced = false
130
+ @groups = []
126
131
  end
127
132
 
128
- def stdlib_path(core_root:, stdlib_root:)
129
- @core_root = Pathname(core_root)
130
- @stdlib_root = Pathname(stdlib_root)
133
+ def initialize_copy(other)
134
+ @name = other.name
135
+ @libraries = other.libraries.dup
136
+ @sources = other.sources.dup
137
+ @signatures = other.signatures.dup
138
+ @ignored_sources = other.ignored_sources.dup
139
+ @ignored_signatures = other.ignored_signatures.dup
140
+ @repo_paths = other.repo_paths.dup
141
+ @core_root = other.core_root
142
+ @stdlib_root = other.stdlib_root
143
+ @code_diagnostics_config = other.code_diagnostics_config.dup
144
+ @project = other.project
145
+ @collection_config_path = other.collection_config_path
146
+ @unreferenced = other.unreferenced
147
+ @groups = other.groups.dup
131
148
  end
132
149
 
133
- def repo_path(*paths)
134
- @repo_paths.push(*paths.map {|s| Pathname(s) })
150
+ def unreferenced!(value = true)
151
+ @unreferenced = value
135
152
  end
136
153
 
137
154
  def configure_code_diagnostics(hash = nil)
@@ -142,91 +159,99 @@ module Steep
142
159
  yield code_diagnostics_config if block_given?
143
160
  end
144
161
 
145
- def project!
146
- project or raise "TargetDSL doesn't have project (#{name})"
162
+ def code_diagnostics_config
163
+ @code_diagnostics_config ||= Diagnostic::Ruby.default.dup
147
164
  end
148
165
 
149
- def collection_config(path)
150
- @collection_config_path = project!.absolute_path(path)
151
- end
166
+ def group(name, &block)
167
+ group = GroupDSL.new(name, self)
152
168
 
153
- def disable_collection
154
- @collection_config_path = false
169
+ Steep.logger.tagged "group=#{name}" do
170
+ group.instance_exec(&block) if block
171
+ end
172
+
173
+ groups << group
155
174
  end
156
175
  end
157
176
 
158
- attr_reader :project
177
+ class GroupDSL
178
+ include WithPattern
179
+
180
+ attr_reader :name
181
+
182
+ attr_reader :target
183
+
184
+ attr_reader :code_diagnostics_config
159
185
 
160
- @@templates = {
161
- gemfile: TargetDSL.new(:gemfile).tap do |target|
162
- target.check "Gemfile"
163
- target.library "gemfile"
186
+ def initialize(name, target)
187
+ @name = name
188
+ @target = target
164
189
  end
165
- }
166
190
 
167
- def self.templates
168
- @@templates
191
+ def configure_code_diagnostics(config = nil)
192
+ if block_given?
193
+ if code_diagnostics_config
194
+ if config
195
+ code_diagnostics_config.merge!(config)
196
+ end
197
+ else
198
+ @code_diagnostics_config = (config || target.code_diagnostics_config).dup
199
+ end
200
+
201
+ yield (code_diagnostics_config || raise)
202
+ else
203
+ @code_diagnostics_config = config&.dup
204
+ end
205
+ end
169
206
  end
170
207
 
208
+ include LibraryOptions
209
+
210
+ attr_reader :project
211
+
171
212
  def initialize(project:)
172
213
  @project = project
173
214
  end
174
215
 
175
- def self.register_template(name, target)
176
- templates[name] = target
177
- end
178
-
179
216
  def self.parse(project, code, filename: "Steepfile")
180
217
  Steep.logger.tagged filename do
181
- self.new(project: project).instance_eval(code, filename)
218
+ dsl = self.new(project: project)
219
+ dsl.instance_eval(code, filename)
220
+ project.global_options = dsl.to_library_options
182
221
  end
183
222
  end
184
223
 
185
- def target(name, template: nil, &block)
186
- target = if template
187
- self.class.templates[template]&.dup&.update(name: name, project: project) or
188
- raise "Unknown template: #{template}, available templates: #{@@templates.keys.join(", ")}"
189
- else
190
- TargetDSL.new(name, code_diagnostics_config: Diagnostic::Ruby.default.dup, project: project)
191
- end
192
-
193
- Steep.logger.tagged "target=#{name}" do
194
- target.instance_eval(&block) if block
224
+ def self.eval(project, &block)
225
+ Steep.logger.tagged "DSL.eval" do
226
+ dsl = self.new(project: project)
227
+ dsl.instance_exec(&block)
228
+ project.global_options = dsl.to_library_options
195
229
  end
230
+ end
196
231
 
197
- source_pattern = Pattern.new(patterns: target.sources, ignores: target.ignored_sources, ext: ".rb")
198
- signature_pattern = Pattern.new(patterns: target.signatures, ext: ".rbs")
232
+ def target(name, &block)
233
+ dsl = TargetDSL.new(name, project: project)
199
234
 
200
- config_path =
201
- case target.collection_config_path
202
- when Pathname
203
- target.collection_config_path
204
- when nil
205
- default = project.absolute_path(RBS::Collection::Config::PATH)
206
- if default.file?
207
- default
208
- end
209
- when false
210
- nil
211
- end
235
+ Steep.logger.tagged "target=#{name}" do
236
+ dsl.instance_eval(&block) if block
237
+ end
212
238
 
213
- Project::Target.new(
214
- name: target.name,
215
- source_pattern: source_pattern,
216
- signature_pattern: signature_pattern,
217
- options: Options.new.tap do |options|
218
- options.libraries.push(*target.libraries)
219
- options.paths = Options::PathOptions.new(
220
- core_root: target.core_root,
221
- stdlib_root: target.stdlib_root,
222
- repo_paths: target.repo_paths
223
- )
224
- options.collection_config_path = config_path
225
- end,
226
- code_diagnostics_config: target.code_diagnostics_config
227
- ).tap do |target|
228
- project.targets << target
239
+ target = Project::Target.new(
240
+ name: dsl.name,
241
+ source_pattern: dsl.source_pattern,
242
+ signature_pattern: dsl.signature_pattern,
243
+ options: dsl.library_configured? ? dsl.to_library_options : nil,
244
+ code_diagnostics_config: dsl.code_diagnostics_config,
245
+ project: project,
246
+ unreferenced: dsl.unreferenced
247
+ )
248
+
249
+ dsl.groups.each do
250
+ group = Group.new(target, _1.name, _1.source_pattern, _1.signature_pattern, _1.code_diagnostics_config || target.code_diagnostics_config)
251
+ target.groups << group
229
252
  end
253
+
254
+ project.targets << target
230
255
  end
231
256
  end
232
257
  end
@@ -0,0 +1,31 @@
1
+ module Steep
2
+ class Project
3
+ class Group
4
+ attr_reader :name
5
+ attr_reader :source_pattern
6
+ attr_reader :signature_pattern
7
+ attr_reader :target
8
+ attr_reader :code_diagnostics_config
9
+
10
+ def initialize(target, name, source_pattern, signature_pattern, code_diagnostics_config)
11
+ @target = target
12
+ @name = name
13
+ @source_pattern = source_pattern
14
+ @signature_pattern = signature_pattern
15
+ @code_diagnostics_config = code_diagnostics_config
16
+ end
17
+
18
+ def project
19
+ target.project
20
+ end
21
+
22
+ def possible_source_file?(path)
23
+ source_pattern =~ path
24
+ end
25
+
26
+ def possible_signature_file?(path)
27
+ signature_pattern =~ path
28
+ end
29
+ end
30
+ end
31
+ end
@@ -2,29 +2,55 @@ module Steep
2
2
  class Project
3
3
  class Target
4
4
  attr_reader :name
5
- attr_reader :options
5
+ attr_reader :target_options
6
6
 
7
7
  attr_reader :source_pattern
8
8
  attr_reader :signature_pattern
9
9
  attr_reader :code_diagnostics_config
10
+ attr_reader :project
11
+ attr_reader :unreferenced
12
+ attr_reader :groups
10
13
 
11
- def initialize(name:, options:, source_pattern:, signature_pattern:, code_diagnostics_config:)
14
+ def initialize(name:, options:, source_pattern:, signature_pattern:, code_diagnostics_config:, project:, unreferenced:)
12
15
  @name = name
13
- @options = options
16
+ @target_options = options
14
17
  @source_pattern = source_pattern
15
18
  @signature_pattern = signature_pattern
16
19
  @code_diagnostics_config = code_diagnostics_config
20
+ @project = project
21
+ @unreferenced = unreferenced
22
+ @groups = []
23
+ end
24
+
25
+ def options
26
+ target_options || project.global_options
17
27
  end
18
28
 
19
29
  def possible_source_file?(path)
20
- source_pattern =~ path
30
+ if target = groups.find { _1.possible_source_file?(path) }
31
+ return target
32
+ end
33
+
34
+ if source_pattern =~ path
35
+ return self
36
+ end
37
+
38
+ nil
21
39
  end
22
40
 
23
41
  def possible_signature_file?(path)
24
- signature_pattern =~ path
42
+ if target = groups.find { _1.possible_signature_file?(path) }
43
+ return target
44
+ end
45
+
46
+ if signature_pattern =~ path
47
+ return self
48
+ end
49
+
50
+ nil
25
51
  end
26
52
 
27
- def new_env_loader(project:)
53
+ def new_env_loader()
28
54
  Target.construct_env_loader(options: options, project: project)
29
55
  end
30
56