steep 1.8.2 → 1.9.0.dev.1

Sign up to get free protection for your applications and to get access to all the features.
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