steep 0.45.0 → 0.46.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.github/workflows/ruby.yml +1 -0
- data/CHANGELOG.md +17 -2
- data/Gemfile.lock +2 -2
- data/lib/steep/cli.rb +7 -1
- data/lib/steep/diagnostic/lsp_formatter.rb +59 -6
- data/lib/steep/diagnostic/ruby.rb +51 -0
- data/lib/steep/drivers/check.rb +3 -0
- data/lib/steep/drivers/init.rb +10 -3
- data/lib/steep/drivers/utils/driver_helper.rb +15 -0
- data/lib/steep/drivers/validate.rb +1 -1
- data/lib/steep/drivers/watch.rb +3 -0
- data/lib/steep/project/dsl.rb +105 -33
- data/lib/steep/project/options.rb +12 -53
- data/lib/steep/project/target.rb +21 -8
- data/lib/steep/server/type_check_worker.rb +6 -9
- data/lib/steep/services/hover_content.rb +2 -2
- data/lib/steep/version.rb +1 -1
- data/sample/Steepfile +10 -3
- data/smoke/alias/Steepfile +2 -1
- data/smoke/and/Steepfile +2 -1
- data/smoke/array/Steepfile +2 -1
- data/smoke/block/Steepfile +2 -2
- data/smoke/case/Steepfile +2 -1
- data/smoke/class/Steepfile +2 -1
- data/smoke/const/Steepfile +2 -1
- data/smoke/diagnostics/Steepfile +2 -1
- data/smoke/diagnostics-rbs/Steepfile +1 -1
- data/smoke/diagnostics-rbs-duplicated/Steepfile +2 -1
- data/smoke/diagnostics-ruby-unsat/Steepfile +2 -1
- data/smoke/dstr/Steepfile +2 -1
- data/smoke/ensure/Steepfile +2 -1
- data/smoke/enumerator/Steepfile +2 -1
- data/smoke/extension/Steepfile +2 -1
- data/smoke/hash/Steepfile +2 -1
- data/smoke/hello/Steepfile +2 -1
- data/smoke/if/Steepfile +2 -1
- data/smoke/implements/Steepfile +2 -1
- data/smoke/initialize/Steepfile +2 -1
- data/smoke/integer/Steepfile +2 -1
- data/smoke/interface/Steepfile +2 -1
- data/smoke/kwbegin/Steepfile +2 -1
- data/smoke/lambda/Steepfile +2 -1
- data/smoke/literal/Steepfile +2 -1
- data/smoke/map/Steepfile +2 -1
- data/smoke/method/Steepfile +2 -1
- data/smoke/module/Steepfile +2 -1
- data/smoke/regexp/Steepfile +2 -1
- data/smoke/regression/Steepfile +2 -1
- data/smoke/rescue/Steepfile +2 -1
- data/smoke/self/Steepfile +2 -1
- data/smoke/skip/Steepfile +2 -1
- data/smoke/stdout/Steepfile +2 -1
- data/smoke/super/Steepfile +2 -1
- data/smoke/toplevel/Steepfile +2 -1
- data/smoke/tsort/Steepfile +4 -5
- data/smoke/type_case/Steepfile +2 -1
- data/smoke/unexpected/Steepfile +2 -1
- data/smoke/yield/Steepfile +2 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: e43c16938ef0238a9b3e44934a3e183ec663722b4c1161f9bd016dfcd2442b9b
|
4
|
+
data.tar.gz: 20168ebc69417b83c9eff010d44aac53ac43f47c572c8acc99d52d08ec11866d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 33c2bd116ea87f549ffb29fbc2382e7c000405a74280fcc4a1a8553ae52e6b7af3d5611a150c828d494fe50f37e120e58e45f286bd374bbd35958ee0c760c872
|
7
|
+
data.tar.gz: 0466f3f59d18bf0ba34ce522bc6a1cceed85c1f6ca4df66b6647a557bec165c64dd9d594f673833dc24a0b5a9d0eb04795bff37dc391e22cf560b566c6f08319
|
data/.github/workflows/ruby.yml
CHANGED
data/CHANGELOG.md
CHANGED
@@ -2,17 +2,32 @@
|
|
2
2
|
|
3
3
|
## master
|
4
4
|
|
5
|
+
## 0.46.0 (2021-08-30)
|
6
|
+
|
7
|
+
This release updates Steepfile DSL syntax, introducing `stdlib_path` and `configure_code_diagnostics` syntax (methods).
|
8
|
+
|
9
|
+
* `stdlib_path` allows configuring core/stdlib RBS file locations.
|
10
|
+
* `configure_code_diagnostics` allows configuring _severity_ of each type errors.
|
11
|
+
|
12
|
+
See the PRs for the explanation of these methods.
|
13
|
+
You can try `steep init` to generate updated `Steepfile` template.
|
14
|
+
|
15
|
+
* Flexible diagnostics configuration ([\#422](https://github.com/soutaro/steep/pull/422), [\#423](https://github.com/soutaro/steep/pull/423))
|
16
|
+
* Revise Steepfile _path_ DSL ([\#421](https://github.com/soutaro/steep/pull/421))
|
17
|
+
* Avoid to stop process by invalid jobs_count ([\#419](https://github.com/soutaro/steep/pull/419))
|
18
|
+
* Fix `Steep::Typing::UnknownNodeError` when hover method with numblock ([\#415](https://github.com/soutaro/steep/pull/415))
|
19
|
+
|
5
20
|
## 0.45.0 (2021-08-22)
|
6
21
|
|
7
22
|
* Fix error reporting on `RBS::MixinClassError` ([\#411](https://github.com/soutaro/steep/pull/411))
|
8
23
|
* Compact error reporting for method body type mismatch ([\#414](https://github.com/soutaro/steep/pull/414))
|
9
24
|
* Fix NoMethodError with csend/numblock ([\#412](https://github.com/soutaro/steep/pull/412))
|
10
|
-
* LSP completion for RBS files ([\#404](https://github.com/soutaro/steep/pull/404))
|
25
|
+
* LSP completion for RBS files ([\#404](https://github.com/soutaro/steep/pull/404))
|
11
26
|
* Allow break without value from bot methods ([\#398](https://github.com/soutaro/steep/pull/398))
|
12
27
|
* Type check on lvar assignments ([\#390](https://github.com/soutaro/steep/pull/390))
|
13
28
|
* Assign different error code to break without value ([\#387](https://github.com/soutaro/steep/pull/387))
|
14
29
|
* Support Ruby3 Keyword Arguments ([\#386](https://github.com/soutaro/steep/pull/386))
|
15
|
-
* LSP hover for RBS files ([\#385](https://github.com/soutaro/steep/pull/385), [\#397](https://github.com/soutaro/steep/pull/397))
|
30
|
+
* LSP hover for RBS files ([\#385](https://github.com/soutaro/steep/pull/385), [\#397](https://github.com/soutaro/steep/pull/397))
|
16
31
|
* Fix FileLoader to skip files not matching to the given pattern ([\#382](https://github.com/soutaro/steep/pull/382))
|
17
32
|
* Ruby3 support for numbered block parameters and end-less def ([\#381](https://github.com/soutaro/steep/pull/381))
|
18
33
|
|
data/Gemfile.lock
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
steep (0.
|
4
|
+
steep (0.46.0)
|
5
5
|
activesupport (>= 5.1)
|
6
6
|
language_server-protocol (>= 3.15, < 4.0)
|
7
7
|
listen (~> 3.0)
|
@@ -35,7 +35,7 @@ GEM
|
|
35
35
|
ffi (1.15.3)
|
36
36
|
i18n (1.8.10)
|
37
37
|
concurrent-ruby (~> 1.0)
|
38
|
-
language_server-protocol (3.16.0.
|
38
|
+
language_server-protocol (3.16.0.2)
|
39
39
|
listen (3.7.0)
|
40
40
|
rb-fsevent (~> 0.10, >= 0.10.3)
|
41
41
|
rb-inotify (~> 0.9, >= 0.9.10)
|
data/lib/steep/cli.rb
CHANGED
@@ -70,7 +70,7 @@ module Steep
|
|
70
70
|
default = physical_processor_count + modifier
|
71
71
|
command.jobs_count = default
|
72
72
|
opts.on("-j N", "--jobs=N", "Specify the number of type check workers (defaults: #{default})") do |count|
|
73
|
-
command.jobs_count = Integer(count)
|
73
|
+
command.jobs_count = Integer(count) if Integer(count) > 0
|
74
74
|
end
|
75
75
|
end
|
76
76
|
|
@@ -99,6 +99,9 @@ module Steep
|
|
99
99
|
opts.on("--save-expectations[=PATH]", "Save expectations with current type check result to PATH (or steep_expectations.yml)") do |path|
|
100
100
|
check.save_expectations_path = Pathname(path || "steep_expectations.yml")
|
101
101
|
end
|
102
|
+
opts.on("--severity-level=LEVEL", /^error|warning|information|hint$/, "Specify the minimum diagnostic severity to be recognized as an error (defaults: warning): error, warning, information, or hint") do |level|
|
103
|
+
check.severity_level = level.to_sym
|
104
|
+
end
|
102
105
|
handle_jobs_option check, opts
|
103
106
|
handle_logging_options opts
|
104
107
|
end.parse!(argv)
|
@@ -155,6 +158,9 @@ module Steep
|
|
155
158
|
Drivers::Watch.new(stdout: stdout, stderr: stderr).tap do |command|
|
156
159
|
OptionParser.new do |opts|
|
157
160
|
opts.banner = "Usage: steep watch [options] [dirs]"
|
161
|
+
opts.on("--severity-level=LEVEL", /^error|warning|information|hint$/, "Specify the minimum diagnostic severity to be recognized as an error (defaults: warning): error, warning, information, or hint") do |level|
|
162
|
+
command.severity_level = level.to_sym
|
163
|
+
end
|
158
164
|
handle_jobs_option command, opts
|
159
165
|
handle_logging_options opts
|
160
166
|
end.parse!(argv)
|
@@ -3,13 +3,66 @@ module Steep
|
|
3
3
|
class LSPFormatter
|
4
4
|
LSP = LanguageServer::Protocol
|
5
5
|
|
6
|
+
attr_reader :config
|
7
|
+
attr_reader :default_severity
|
8
|
+
|
9
|
+
ERROR = :error
|
10
|
+
WARNING = :warning
|
11
|
+
INFORMATION = :information
|
12
|
+
HINT = :hint
|
13
|
+
|
14
|
+
def initialize(config = {}, default_severity: ERROR)
|
15
|
+
@config = config
|
16
|
+
@default_severity = default_severity
|
17
|
+
|
18
|
+
config.each do |klass, severity|
|
19
|
+
validate_severity(klass, severity)
|
20
|
+
validate_class(klass)
|
21
|
+
end
|
22
|
+
validate_severity(:default, default_severity)
|
23
|
+
end
|
24
|
+
|
25
|
+
def validate_class(klass)
|
26
|
+
unless klass < Diagnostic::Ruby::Base
|
27
|
+
raise "Unexpected diagnostics class `#{klass}` given"
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
def validate_severity(klass, severity)
|
32
|
+
case severity
|
33
|
+
when ERROR, WARNING, INFORMATION, HINT, nil
|
34
|
+
# ok
|
35
|
+
else
|
36
|
+
raise "Unexpected severity `#{severity}` is specified for #{klass}"
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
6
40
|
def format(diagnostic)
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
41
|
+
severity = severity_for(diagnostic)
|
42
|
+
|
43
|
+
if severity
|
44
|
+
LSP::Interface::Diagnostic.new(
|
45
|
+
message: diagnostic.full_message,
|
46
|
+
code: diagnostic.diagnostic_code,
|
47
|
+
severity: severity,
|
48
|
+
range: diagnostic.location.as_lsp_range
|
49
|
+
).to_hash
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
def severity_for(diagnostic)
|
54
|
+
case config.fetch(diagnostic.class, default_severity)
|
55
|
+
when ERROR
|
56
|
+
LSP::Constant::DiagnosticSeverity::ERROR
|
57
|
+
when WARNING
|
58
|
+
LSP::Constant::DiagnosticSeverity::WARNING
|
59
|
+
when INFORMATION
|
60
|
+
LSP::Constant::DiagnosticSeverity::INFORMATION
|
61
|
+
when HINT
|
62
|
+
LSP::Constant::DiagnosticSeverity::HINT
|
63
|
+
when nil
|
64
|
+
nil
|
65
|
+
end
|
13
66
|
end
|
14
67
|
end
|
15
68
|
end
|
@@ -700,6 +700,57 @@ module Steep
|
|
700
700
|
"SyntaxError: #{message}"
|
701
701
|
end
|
702
702
|
end
|
703
|
+
|
704
|
+
ALL = ObjectSpace.each_object(Class).with_object([]) do |klass, array|
|
705
|
+
if klass < Base
|
706
|
+
array << klass
|
707
|
+
end
|
708
|
+
end
|
709
|
+
|
710
|
+
def self.all_error
|
711
|
+
@all_error ||= ALL.each.with_object({}) do |klass, hash|
|
712
|
+
hash[klass] = LSPFormatter::ERROR
|
713
|
+
end.freeze
|
714
|
+
end
|
715
|
+
|
716
|
+
def self.default
|
717
|
+
@default ||= all_error.merge(
|
718
|
+
{
|
719
|
+
ImplicitBreakValueMismatch => :warning,
|
720
|
+
FallbackAny => :information,
|
721
|
+
ElseOnExhaustiveCase => :warning,
|
722
|
+
UnknownConstantAssigned => :warning,
|
723
|
+
MethodDefinitionMissing => :information
|
724
|
+
}
|
725
|
+
).freeze
|
726
|
+
end
|
727
|
+
|
728
|
+
def self.strict
|
729
|
+
@strict ||= all_error.merge(
|
730
|
+
{
|
731
|
+
NoMethod => nil,
|
732
|
+
ImplicitBreakValueMismatch => nil,
|
733
|
+
FallbackAny => nil,
|
734
|
+
ElseOnExhaustiveCase => nil,
|
735
|
+
UnknownConstantAssigned => nil,
|
736
|
+
MethodDefinitionMissing => nil
|
737
|
+
}
|
738
|
+
).freeze
|
739
|
+
end
|
740
|
+
|
741
|
+
def self.lenient
|
742
|
+
@lenient ||= all_error.merge(
|
743
|
+
{
|
744
|
+
NoMethod => nil,
|
745
|
+
ImplicitBreakValueMismatch => nil,
|
746
|
+
FallbackAny => nil,
|
747
|
+
ElseOnExhaustiveCase => nil,
|
748
|
+
UnknownConstantAssigned => nil,
|
749
|
+
MethodDefinitionMissing => nil,
|
750
|
+
UnexpectedJump => nil
|
751
|
+
}
|
752
|
+
).freeze
|
753
|
+
end
|
703
754
|
end
|
704
755
|
end
|
705
756
|
end
|
data/lib/steep/drivers/check.rb
CHANGED
@@ -8,6 +8,7 @@ module Steep
|
|
8
8
|
attr_reader :command_line_patterns
|
9
9
|
attr_accessor :with_expectations_path
|
10
10
|
attr_accessor :save_expectations_path
|
11
|
+
attr_accessor :severity_level
|
11
12
|
|
12
13
|
include Utils::DriverHelper
|
13
14
|
include Utils::JobsCount
|
@@ -16,6 +17,7 @@ module Steep
|
|
16
17
|
@stdout = stdout
|
17
18
|
@stderr = stderr
|
18
19
|
@command_line_patterns = []
|
20
|
+
@severity_level = :warning
|
19
21
|
end
|
20
22
|
|
21
23
|
def run
|
@@ -70,6 +72,7 @@ module Steep
|
|
70
72
|
case
|
71
73
|
when response[:method] == "textDocument/publishDiagnostics"
|
72
74
|
ds = response[:params][:diagnostics]
|
75
|
+
ds.select! {|d| keep_diagnostic?(d) }
|
73
76
|
if ds.empty?
|
74
77
|
stdout.print "."
|
75
78
|
else
|
data/lib/steep/drivers/init.rb
CHANGED
@@ -8,6 +8,8 @@ module Steep
|
|
8
8
|
include Utils::DriverHelper
|
9
9
|
|
10
10
|
TEMPLATE = <<~EOF
|
11
|
+
# D = Steep::Diagnostic
|
12
|
+
#
|
11
13
|
# target :lib do
|
12
14
|
# signature "sig"
|
13
15
|
#
|
@@ -18,15 +20,20 @@ module Steep
|
|
18
20
|
#
|
19
21
|
# # library "pathname", "set" # Standard libraries
|
20
22
|
# # library "strong_json" # Gems
|
23
|
+
#
|
24
|
+
# # configure_code_diagnostics(D::Ruby.strict) # `strict` diagnostics setting
|
25
|
+
# # configure_code_diagnostics(D::Ruby.lenient) # `lenient` diagnostics setting
|
26
|
+
# # configure_code_diagnostics do |hash| # You can setup everything yourself
|
27
|
+
# # hash[D::Ruby::NoMethod] = :information
|
28
|
+
# # end
|
21
29
|
# end
|
22
30
|
|
23
|
-
# target :
|
31
|
+
# target :test do
|
24
32
|
# signature "sig", "sig-private"
|
25
33
|
#
|
26
|
-
# check "
|
34
|
+
# check "test"
|
27
35
|
#
|
28
36
|
# # library "pathname", "set" # Standard libraries
|
29
|
-
# # library "rspec"
|
30
37
|
# end
|
31
38
|
EOF
|
32
39
|
|
@@ -55,6 +55,21 @@ module Steep
|
|
55
55
|
end
|
56
56
|
end
|
57
57
|
end
|
58
|
+
|
59
|
+
def keep_diagnostic?(diagnostic)
|
60
|
+
severity = diagnostic[:severity]
|
61
|
+
|
62
|
+
case self.severity_level
|
63
|
+
when nil, :hint
|
64
|
+
true
|
65
|
+
when :error
|
66
|
+
severity <= LanguageServer::Protocol::Constant::DiagnosticSeverity::ERROR
|
67
|
+
when :warning
|
68
|
+
severity <= LanguageServer::Protocol::Constant::DiagnosticSeverity::WARNING
|
69
|
+
when :information
|
70
|
+
severity <= LanguageServer::Protocol::Constant::DiagnosticSeverity::INFORMATION
|
71
|
+
end
|
72
|
+
end
|
58
73
|
end
|
59
74
|
end
|
60
75
|
end
|
@@ -36,7 +36,7 @@ module Steep
|
|
36
36
|
|
37
37
|
any_error ||= !errors.empty?
|
38
38
|
|
39
|
-
formatter = Diagnostic::LSPFormatter.new
|
39
|
+
formatter = Diagnostic::LSPFormatter.new({})
|
40
40
|
diagnostics = errors.group_by {|e| e.location.buffer }.transform_values do |errors|
|
41
41
|
errors.map {|error| formatter.format(error) }
|
42
42
|
end
|
data/lib/steep/drivers/watch.rb
CHANGED
@@ -5,6 +5,7 @@ module Steep
|
|
5
5
|
attr_reader :stdout
|
6
6
|
attr_reader :stderr
|
7
7
|
attr_reader :queue
|
8
|
+
attr_accessor :severity_level
|
8
9
|
|
9
10
|
include Utils::DriverHelper
|
10
11
|
include Utils::JobsCount
|
@@ -16,6 +17,7 @@ module Steep
|
|
16
17
|
@stdout = stdout
|
17
18
|
@stderr = stderr
|
18
19
|
@queue = Thread::Queue.new
|
20
|
+
@severity_level = :warning
|
19
21
|
end
|
20
22
|
|
21
23
|
def watching?(changed_path, files:, dirs:)
|
@@ -126,6 +128,7 @@ module Steep
|
|
126
128
|
printer = DiagnosticPrinter.new(stdout: stdout, buffer: buffer)
|
127
129
|
|
128
130
|
diagnostics = response[:params][:diagnostics]
|
131
|
+
diagnostics.filter! {|d| keep_diagnostic?(d) }
|
129
132
|
|
130
133
|
unless diagnostics.empty?
|
131
134
|
diagnostics.each do |diagnostic|
|
data/lib/steep/project/dsl.rb
CHANGED
@@ -7,21 +7,21 @@ module Steep
|
|
7
7
|
attr_reader :libraries
|
8
8
|
attr_reader :signatures
|
9
9
|
attr_reader :ignored_sources
|
10
|
-
attr_reader :
|
11
|
-
attr_reader :
|
12
|
-
attr_reader :typing_option_hash
|
10
|
+
attr_reader :stdlib_root
|
11
|
+
attr_reader :core_root
|
13
12
|
attr_reader :repo_paths
|
13
|
+
attr_reader :code_diagnostics_config
|
14
14
|
|
15
|
-
def initialize(name, sources: [], libraries: [], signatures: [], ignored_sources: [], repo_paths: [])
|
15
|
+
def initialize(name, sources: [], libraries: [], signatures: [], ignored_sources: [], repo_paths: [], code_diagnostics_config: {})
|
16
16
|
@name = name
|
17
17
|
@sources = sources
|
18
18
|
@libraries = libraries
|
19
19
|
@signatures = signatures
|
20
20
|
@ignored_sources = ignored_sources
|
21
|
-
@
|
22
|
-
@
|
23
|
-
@typing_option_hash = {}
|
21
|
+
@core_root = nil
|
22
|
+
@stdlib_root = nil
|
24
23
|
@repo_paths = []
|
24
|
+
@code_diagnostics_config = code_diagnostics_config
|
25
25
|
end
|
26
26
|
|
27
27
|
def initialize_copy(other)
|
@@ -30,10 +30,10 @@ module Steep
|
|
30
30
|
@libraries = other.libraries.dup
|
31
31
|
@signatures = other.signatures.dup
|
32
32
|
@ignored_sources = other.ignored_sources.dup
|
33
|
-
@vendor_dir = other.vendor_dir
|
34
|
-
@strictness_level = other.strictness_level
|
35
|
-
@typing_option_hash = other.typing_option_hash
|
36
33
|
@repo_paths = other.repo_paths.dup
|
34
|
+
@core_root = other.core_root
|
35
|
+
@stdlib_root = other.stdlib_root
|
36
|
+
@code_diagnostics_config = other.code_diagnostics_config.dup
|
37
37
|
end
|
38
38
|
|
39
39
|
def check(*args)
|
@@ -48,9 +48,52 @@ module Steep
|
|
48
48
|
libraries.push(*args)
|
49
49
|
end
|
50
50
|
|
51
|
-
def typing_options(level =
|
52
|
-
|
53
|
-
|
51
|
+
def typing_options(level = nil, **hash)
|
52
|
+
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:"
|
53
|
+
|
54
|
+
messages = []
|
55
|
+
|
56
|
+
messages << "# D = Steep::Diagnostic # Define a constant to shorten namespace"
|
57
|
+
|
58
|
+
case level
|
59
|
+
when :strict
|
60
|
+
messages << "configure_code_diagnostics(D::Ruby.strict) # :strict"
|
61
|
+
when :default
|
62
|
+
messages << "configure_code_diagnostics(D::Ruby.default) # :default"
|
63
|
+
when :lenient
|
64
|
+
messages << "configure_code_diagnostics(D::Ruby.lenient) # :lenient"
|
65
|
+
end
|
66
|
+
|
67
|
+
messages.each do |msg|
|
68
|
+
Steep.logger.error " #{msg}"
|
69
|
+
end
|
70
|
+
|
71
|
+
config = []
|
72
|
+
|
73
|
+
if hash[:allow_missing_definitions]
|
74
|
+
config << "hash[D::Ruby::MethodDefinitionMissing] = nil # allow_missing_definitions"
|
75
|
+
end
|
76
|
+
|
77
|
+
if hash[:allow_fallback_any]
|
78
|
+
config << "hash[D::Ruby::FallbackAny] = nil # allow_fallback_any"
|
79
|
+
end
|
80
|
+
|
81
|
+
if hash[:allow_unknown_constant_assignment]
|
82
|
+
config << "hash[D::Ruby::UnknownConstantAssigned] = nil # allow_unknown_constant_assignment"
|
83
|
+
end
|
84
|
+
|
85
|
+
if hash[:allow_unknown_method_calls]
|
86
|
+
config << "hash[D::Ruby::NoMethod] = nil # allow_unknown_method_calls"
|
87
|
+
end
|
88
|
+
|
89
|
+
unless config.empty?
|
90
|
+
Steep.logger.error " configure_code_diagnostics do |hash|"
|
91
|
+
config.each do |c|
|
92
|
+
Steep.logger.error " #{c}"
|
93
|
+
end
|
94
|
+
Steep.logger.error " end"
|
95
|
+
end
|
96
|
+
|
54
97
|
end
|
55
98
|
|
56
99
|
def signature(*args)
|
@@ -68,20 +111,50 @@ module Steep
|
|
68
111
|
end
|
69
112
|
|
70
113
|
def no_builtin!(value = true)
|
71
|
-
Steep.logger.error "
|
114
|
+
Steep.logger.error "`#no_builtin!` in Steepfile is deprecated and ignored. Use `#stdlib_path` instead."
|
72
115
|
end
|
73
116
|
|
74
117
|
def vendor(dir = "vendor/sigs", stdlib: nil, gems: nil)
|
75
|
-
|
76
|
-
|
77
|
-
end
|
118
|
+
Steep.logger.error "`#vendor` in Steepfile is deprecated and ignored. Use `#stdlib_path` instead."
|
119
|
+
end
|
78
120
|
|
79
|
-
|
121
|
+
def stdlib_path(core_root:, stdlib_root:)
|
122
|
+
@core_root = core_root ? Pathname(core_root) : core_root
|
123
|
+
@stdlib_root = stdlib_root ? Pathname(stdlib_root) : stdlib_root
|
80
124
|
end
|
81
125
|
|
82
126
|
def repo_path(*paths)
|
83
127
|
@repo_paths.push(*paths.map {|s| Pathname(s) })
|
84
128
|
end
|
129
|
+
|
130
|
+
# Configure the code diagnostics printing setup.
|
131
|
+
#
|
132
|
+
# Yields a hash, and the update the hash in the block.
|
133
|
+
#
|
134
|
+
# ```rb
|
135
|
+
# D = Steep::Diagnostic
|
136
|
+
#
|
137
|
+
# configure_code_diagnostics do |hash|
|
138
|
+
# # Assign one of :error, :warning, :information, :hint or :nil to error classes.
|
139
|
+
# hash[D::Ruby::UnexpectedPositionalArgument] = :error
|
140
|
+
# end
|
141
|
+
# ```
|
142
|
+
#
|
143
|
+
# Passing a hash is also allowed.
|
144
|
+
#
|
145
|
+
# ```rb
|
146
|
+
# D = Steep::Diagnostic
|
147
|
+
#
|
148
|
+
# configure_code_diagnostics(D::Ruby.lenient)
|
149
|
+
# ```
|
150
|
+
#
|
151
|
+
def configure_code_diagnostics(hash = nil)
|
152
|
+
if hash
|
153
|
+
code_diagnostics_config.merge!(hash)
|
154
|
+
end
|
155
|
+
|
156
|
+
yield code_diagnostics_config if block_given?
|
157
|
+
end
|
85
158
|
end
|
86
159
|
|
87
160
|
attr_reader :project
|
@@ -107,7 +180,9 @@ module Steep
|
|
107
180
|
end
|
108
181
|
|
109
182
|
def self.parse(project, code, filename: "Steepfile")
|
110
|
-
|
183
|
+
Steep.logger.tagged filename do
|
184
|
+
self.new(project: project).instance_eval(code, filename)
|
185
|
+
end
|
111
186
|
end
|
112
187
|
|
113
188
|
def target(name, template: nil, &block)
|
@@ -115,10 +190,12 @@ module Steep
|
|
115
190
|
self.class.templates[template]&.dup&.update(name: name) or
|
116
191
|
raise "Unknown template: #{template}, available templates: #{@@templates.keys.join(", ")}"
|
117
192
|
else
|
118
|
-
TargetDSL.new(name)
|
193
|
+
TargetDSL.new(name, code_diagnostics_config: Diagnostic::Ruby.default.dup)
|
119
194
|
end
|
120
195
|
|
121
|
-
|
196
|
+
Steep.logger.tagged "target=#{name}" do
|
197
|
+
target.instance_eval(&block) if block_given?
|
198
|
+
end
|
122
199
|
|
123
200
|
source_pattern = Pattern.new(patterns: target.sources, ignores: target.ignored_sources, ext: ".rb")
|
124
201
|
signature_pattern = Pattern.new(patterns: target.signatures, ext: ".rbs")
|
@@ -129,18 +206,13 @@ module Steep
|
|
129
206
|
signature_pattern: signature_pattern,
|
130
207
|
options: Options.new.tap do |options|
|
131
208
|
options.libraries.push(*target.libraries)
|
132
|
-
options.
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
options.apply_lenient_typing_options!
|
140
|
-
end
|
141
|
-
|
142
|
-
options.merge!(target.typing_option_hash)
|
143
|
-
end
|
209
|
+
options.paths = Options::PathOptions.new(
|
210
|
+
core_root: target.core_root,
|
211
|
+
stdlib_root: target.stdlib_root,
|
212
|
+
repo_paths: target.repo_paths
|
213
|
+
)
|
214
|
+
end,
|
215
|
+
code_diagnostics_config: target.code_diagnostics_config
|
144
216
|
).tap do |target|
|
145
217
|
project.targets << target
|
146
218
|
end
|
@@ -1,63 +1,22 @@
|
|
1
1
|
module Steep
|
2
2
|
class Project
|
3
3
|
class Options
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
attr_accessor :vendor_path
|
9
|
-
attr_reader :libraries
|
10
|
-
attr_reader :repository_paths
|
11
|
-
|
12
|
-
def initialize
|
13
|
-
apply_default_typing_options!
|
14
|
-
self.vendor_path = nil
|
15
|
-
|
16
|
-
@libraries = []
|
17
|
-
@repository_paths = []
|
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
|
4
|
+
PathOptions = Struct.new(:core_root, :stdlib_root, :repo_paths, keyword_init: true) do
|
5
|
+
def customized_stdlib?
|
6
|
+
stdlib_root != nil
|
7
|
+
end
|
40
8
|
|
41
|
-
|
42
|
-
|
43
|
-
when error.is_a?(Diagnostic::Ruby::FallbackAny)
|
44
|
-
!allow_fallback_any
|
45
|
-
when error.is_a?(Diagnostic::Ruby::MethodDefinitionMissing)
|
46
|
-
!allow_missing_definitions
|
47
|
-
when error.is_a?(Diagnostic::Ruby::NoMethod)
|
48
|
-
!allow_unknown_method_calls
|
49
|
-
when error.is_a?(Diagnostic::Ruby::UnknownConstantAssigned)
|
50
|
-
!allow_unknown_constant_assignment
|
51
|
-
else
|
52
|
-
true
|
9
|
+
def customized_core?
|
10
|
+
core_root != nil
|
53
11
|
end
|
54
12
|
end
|
55
13
|
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
14
|
+
attr_reader :libraries
|
15
|
+
attr_accessor :paths
|
16
|
+
|
17
|
+
def initialize
|
18
|
+
@paths = PathOptions.new(repo_paths: [])
|
19
|
+
@libraries = []
|
61
20
|
end
|
62
21
|
end
|
63
22
|
end
|
data/lib/steep/project/target.rb
CHANGED
@@ -6,12 +6,14 @@ module Steep
|
|
6
6
|
|
7
7
|
attr_reader :source_pattern
|
8
8
|
attr_reader :signature_pattern
|
9
|
+
attr_reader :code_diagnostics_config
|
9
10
|
|
10
|
-
def initialize(name:, options:, source_pattern:, signature_pattern:)
|
11
|
+
def initialize(name:, options:, source_pattern:, signature_pattern:, code_diagnostics_config:)
|
11
12
|
@name = name
|
12
13
|
@options = options
|
13
14
|
@source_pattern = source_pattern
|
14
15
|
@signature_pattern = signature_pattern
|
16
|
+
@code_diagnostics_config = code_diagnostics_config
|
15
17
|
|
16
18
|
@source_files = {}
|
17
19
|
@signature_files = {}
|
@@ -30,16 +32,27 @@ module Steep
|
|
30
32
|
end
|
31
33
|
|
32
34
|
def self.construct_env_loader(options:, project:)
|
33
|
-
repo = RBS::Repository.new(no_stdlib: options.
|
34
|
-
|
35
|
+
repo = RBS::Repository.new(no_stdlib: options.paths.customized_stdlib?)
|
36
|
+
|
37
|
+
if options.paths.stdlib_root
|
38
|
+
repo.add(project.absolute_path(options.paths.stdlib_root))
|
39
|
+
end
|
40
|
+
|
41
|
+
options.paths.repo_paths.each do |path|
|
35
42
|
repo.add(project.absolute_path(path))
|
36
43
|
end
|
37
44
|
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
45
|
+
core_root_path =
|
46
|
+
if options.paths.customized_core?
|
47
|
+
if options.paths.core_root
|
48
|
+
project.absolute_path(options.paths.core_root)
|
49
|
+
end
|
50
|
+
else
|
51
|
+
RBS::EnvironmentLoader::DEFAULT_CORE_ROOT
|
52
|
+
end
|
53
|
+
|
54
|
+
loader = RBS::EnvironmentLoader.new(core_root: core_root_path, repository: repo)
|
55
|
+
|
43
56
|
options.libraries.each do |lib|
|
44
57
|
name, version = lib.split(/:/, 2)
|
45
58
|
loader.add(library: name, version: version)
|
@@ -144,7 +144,7 @@ module Steep
|
|
144
144
|
if job.guid == current_type_check_guid
|
145
145
|
Steep.logger.info { "Processing ValidateAppSignature for guid=#{job.guid}, path=#{job.path}" }
|
146
146
|
service.validate_signature(path: project.relative_path(job.path)) do |path, diagnostics|
|
147
|
-
formatter = Diagnostic::LSPFormatter.new()
|
147
|
+
formatter = Diagnostic::LSPFormatter.new({})
|
148
148
|
|
149
149
|
writer.write(
|
150
150
|
method: :"textDocument/publishDiagnostics",
|
@@ -162,13 +162,13 @@ module Steep
|
|
162
162
|
if job.guid == current_type_check_guid
|
163
163
|
Steep.logger.info { "Processing ValidateLibrarySignature for guid=#{job.guid}, path=#{job.path}" }
|
164
164
|
service.validate_signature(path: job.path) do |path, diagnostics|
|
165
|
-
formatter = Diagnostic::LSPFormatter.new()
|
165
|
+
formatter = Diagnostic::LSPFormatter.new({})
|
166
166
|
|
167
167
|
writer.write(
|
168
168
|
method: :"textDocument/publishDiagnostics",
|
169
169
|
params: LSP::Interface::PublishDiagnosticsParams.new(
|
170
170
|
uri: URI.parse(job.path.to_s).tap {|uri| uri.scheme = "file"},
|
171
|
-
diagnostics: diagnostics.map {|diagnostic| formatter.format(diagnostic) }.uniq
|
171
|
+
diagnostics: diagnostics.map {|diagnostic| formatter.format(diagnostic) }.uniq.compact
|
172
172
|
)
|
173
173
|
)
|
174
174
|
end
|
@@ -180,17 +180,14 @@ module Steep
|
|
180
180
|
if job.guid == current_type_check_guid
|
181
181
|
Steep.logger.info { "Processing TypeCheckCodeJob for guid=#{job.guid}, path=#{job.path}" }
|
182
182
|
service.typecheck_source(path: project.relative_path(job.path)) do |path, diagnostics|
|
183
|
-
|
184
|
-
|
185
|
-
end
|
186
|
-
|
187
|
-
formatter = Diagnostic::LSPFormatter.new()
|
183
|
+
target = project.target_for_source_path(path)
|
184
|
+
formatter = Diagnostic::LSPFormatter.new(target&.code_diagnostics_config || {})
|
188
185
|
|
189
186
|
writer.write(
|
190
187
|
method: :"textDocument/publishDiagnostics",
|
191
188
|
params: LSP::Interface::PublishDiagnosticsParams.new(
|
192
189
|
uri: URI.parse(job.path.to_s).tap {|uri| uri.scheme = "file"},
|
193
|
-
diagnostics: diagnostics.map {|diagnostic| formatter.format(diagnostic) }.uniq
|
190
|
+
diagnostics: diagnostics.map {|diagnostic| formatter.format(diagnostic) }.uniq.compact
|
194
191
|
)
|
195
192
|
)
|
196
193
|
end
|
data/lib/steep/version.rb
CHANGED
data/sample/Steepfile
CHANGED
@@ -1,6 +1,13 @@
|
|
1
|
-
|
2
|
-
|
1
|
+
D = Steep::Diagnostic
|
2
|
+
|
3
|
+
target :lib do
|
3
4
|
signature "sig"
|
4
5
|
|
5
|
-
|
6
|
+
check "lib" # Directory name
|
7
|
+
|
8
|
+
# configure_code_diagnostics(D::Ruby.strict) # `strict` diagnostics setting
|
9
|
+
# configure_code_diagnostics(D::Ruby.lenient) # `lenient` diagnostics setting
|
10
|
+
# configure_code_diagnostics do |hash| # You can setup everything yourself
|
11
|
+
# hash[D::Ruby::NoMethod] = :information
|
12
|
+
# end
|
6
13
|
end
|
data/smoke/alias/Steepfile
CHANGED
data/smoke/and/Steepfile
CHANGED
data/smoke/array/Steepfile
CHANGED
data/smoke/block/Steepfile
CHANGED
data/smoke/case/Steepfile
CHANGED
data/smoke/class/Steepfile
CHANGED
data/smoke/const/Steepfile
CHANGED
data/smoke/diagnostics/Steepfile
CHANGED
data/smoke/dstr/Steepfile
CHANGED
data/smoke/ensure/Steepfile
CHANGED
data/smoke/enumerator/Steepfile
CHANGED
data/smoke/extension/Steepfile
CHANGED
data/smoke/hash/Steepfile
CHANGED
data/smoke/hello/Steepfile
CHANGED
data/smoke/if/Steepfile
CHANGED
data/smoke/implements/Steepfile
CHANGED
data/smoke/initialize/Steepfile
CHANGED
data/smoke/integer/Steepfile
CHANGED
data/smoke/interface/Steepfile
CHANGED
data/smoke/kwbegin/Steepfile
CHANGED
data/smoke/lambda/Steepfile
CHANGED
data/smoke/literal/Steepfile
CHANGED
data/smoke/map/Steepfile
CHANGED
data/smoke/method/Steepfile
CHANGED
data/smoke/module/Steepfile
CHANGED
data/smoke/regexp/Steepfile
CHANGED
data/smoke/regression/Steepfile
CHANGED
data/smoke/rescue/Steepfile
CHANGED
data/smoke/self/Steepfile
CHANGED
data/smoke/skip/Steepfile
CHANGED
data/smoke/stdout/Steepfile
CHANGED
data/smoke/super/Steepfile
CHANGED
data/smoke/toplevel/Steepfile
CHANGED
data/smoke/tsort/Steepfile
CHANGED
data/smoke/type_case/Steepfile
CHANGED
data/smoke/unexpected/Steepfile
CHANGED
data/smoke/yield/Steepfile
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: steep
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.46.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Soutaro Matsumoto
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2021-08-
|
11
|
+
date: 2021-08-30 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: parser
|