steep 1.5.0.pre.6 → 1.5.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: d00242c259b7c8d2a4a0f7022874ac5bb5f08491ab3edade6165ff1a9fbe89a7
4
- data.tar.gz: e02d896359c4eb88c730601320bb9137342c19b9ad1956d4ac417ffa5926d74a
3
+ metadata.gz: d7775c9db83acf70b19f27b4983923ee40e8d1a39043c981726573b0c06eb1c8
4
+ data.tar.gz: 1d9f2753a19a577cce778f6ec1ee924534523812764c0350c21280d82a0e1c69
5
5
  SHA512:
6
- metadata.gz: 5be83d84d984d215342c030e9ea590c419a1e12963361266f4bc57e2b2ceec110a3f08313754b2f46a274fc8b0d2acca497c71f2eff24c3fd4505cb1ff2ac5a7
7
- data.tar.gz: 7a30b064aa7ec6e27e3811e93b1ddf7ff4824cdeb5dfe70075f34311f7e22016bf4f3a2b107307a5247c54532451a25155fc2ba277842fec85f71aa23fdaced1
6
+ metadata.gz: 6bd6340dfecc114df47a959d25a4201a87ccccbc0b1e59238962de51c28218b01aa25499ae8a760e678481192131dfdd3c99b6c89412ce4b6e0b3fad2bf34ca5
7
+ data.tar.gz: 87437181a053c65f297192eb9e339c0b58ad074d4c6716eef2a1019116d3ed06d0525eebcc49855ae99a8393bffac82640d77f608479b98f67e158b42c54d327
data/CHANGELOG.md CHANGED
@@ -2,6 +2,36 @@
2
2
 
3
3
  ## master
4
4
 
5
+ ## 1.5.1 (2023-07-20)
6
+
7
+ ### Type checker core
8
+
9
+ * Support unreachable branch detection with `elsif` ([#879](https://github.com/soutaro/steep/pull/879))
10
+ * Give an optional type hint to lhs of `||` ([#874](https://github.com/soutaro/steep/pull/874))
11
+
12
+ ### Miscellaneous
13
+
14
+ * Update steep ([#878](https://github.com/soutaro/steep/pull/878))
15
+ * Update inline type comments ([#875](https://github.com/soutaro/steep/pull/875))
16
+
17
+ ## 1.5.0 (2023-07-13)
18
+
19
+ ### Type checker core
20
+
21
+ * Fix for the case `untyped` is the proc type hint ([#868](https://github.com/soutaro/steep/pull/868))
22
+ * Type case with type variable ([#869](https://github.com/soutaro/steep/pull/869))
23
+ * Filx `nil?` unreachability detection ([#867](https://github.com/soutaro/steep/pull/867))
24
+
25
+ ### Commandline tool
26
+
27
+ * Update `#configure_code_diagnostics` type ([#873](https://github.com/soutaro/steep/pull/873))
28
+ * Update diagnostics templates ([#871](https://github.com/soutaro/steep/pull/871))
29
+ * Removed "set" from "libray" in init.rb and README ([#870](https://github.com/soutaro/steep/pull/870))
30
+
31
+ ### Language server
32
+
33
+ * Use RBS::Buffer method to calculate position ([#872](https://github.com/soutaro/steep/pull/872))
34
+
5
35
  ## 1.5.0.pre.6 (2023-07-11)
6
36
 
7
37
  ### Type checker core
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- steep (1.5.0.pre.6)
4
+ steep (1.5.1)
5
5
  activesupport (>= 5.1)
6
6
  concurrent-ruby (>= 1.1.10)
7
7
  csv (>= 3.0.9)
@@ -53,7 +53,7 @@ GEM
53
53
  rb-fsevent (0.11.2)
54
54
  rb-inotify (0.10.1)
55
55
  ffi (~> 1.0)
56
- rbs (3.1.0)
56
+ rbs (3.1.1)
57
57
  ruby-lsp (0.5.1)
58
58
  language_server-protocol (~> 3.17.0)
59
59
  sorbet-runtime
data/Gemfile.steep.lock CHANGED
@@ -1,17 +1,17 @@
1
1
  GEM
2
2
  remote: https://rubygems.org/
3
3
  specs:
4
- activesupport (7.0.5)
4
+ activesupport (7.0.6)
5
5
  concurrent-ruby (~> 1.0, >= 1.0.2)
6
6
  i18n (>= 1.6, < 2)
7
7
  minitest (>= 5.1)
8
8
  tzinfo (~> 2.0)
9
9
  ast (2.4.2)
10
10
  concurrent-ruby (1.2.2)
11
- csv (3.2.6)
11
+ csv (3.2.7)
12
12
  ffi (1.15.5)
13
13
  fileutils (1.7.1)
14
- i18n (1.13.0)
14
+ i18n (1.14.1)
15
15
  concurrent-ruby (~> 1.0)
16
16
  json (2.6.3)
17
17
  language_server-protocol (3.17.0.3)
@@ -19,18 +19,20 @@ GEM
19
19
  rb-fsevent (~> 0.10, >= 0.10.3)
20
20
  rb-inotify (~> 0.9, >= 0.9.10)
21
21
  logger (1.5.3)
22
- minitest (5.18.0)
23
- parser (3.2.2.1)
22
+ minitest (5.18.1)
23
+ parser (3.2.2.3)
24
24
  ast (~> 2.4.1)
25
+ racc
26
+ racc (1.7.1)
25
27
  rainbow (3.1.1)
26
28
  rb-fsevent (0.11.2)
27
29
  rb-inotify (0.10.1)
28
30
  ffi (~> 1.0)
29
- rbs (3.1.0)
31
+ rbs (3.1.1)
30
32
  securerandom (0.2.2)
31
- steep (1.4.0)
33
+ steep (1.5.0)
32
34
  activesupport (>= 5.1)
33
- concurrent-ruby (>= 1.2.2)
35
+ concurrent-ruby (>= 1.1.10)
34
36
  csv (>= 3.0.9)
35
37
  fileutils (>= 1.1.0)
36
38
  json (>= 2.1.0)
@@ -39,7 +41,7 @@ GEM
39
41
  logger (>= 1.3.0)
40
42
  parser (>= 3.1)
41
43
  rainbow (>= 2.2.2, < 4.0)
42
- rbs (>= 2.8.0)
44
+ rbs (>= 3.1.0)
43
45
  securerandom (>= 0.1)
44
46
  strscan (>= 1.0.0)
45
47
  terminal-table (>= 2, < 4)
data/README.md CHANGED
@@ -30,7 +30,7 @@ target :app do
30
30
  check "lib"
31
31
  signature "sig"
32
32
 
33
- library "set", "pathname"
33
+ library "pathname"
34
34
  end
35
35
  ```
36
36
 
data/Steepfile CHANGED
@@ -3,13 +3,12 @@ D = Steep::Diagnostic
3
3
  target :app do
4
4
  check "lib"
5
5
  ignore "lib/steep/shims"
6
-
6
+
7
7
  signature "sig"
8
8
 
9
9
  collection_config "rbs_collection.steep.yaml"
10
10
 
11
- configure_code_diagnostics do |hash| # You can setup everything yourself
12
- hash[D::Ruby::MethodDefinitionMissing] = :hint
11
+ configure_code_diagnostics(D::Ruby.strict) do |hash|
13
12
  end
14
13
 
15
14
  FileUtils.mkpath("tmp")
@@ -110,20 +110,20 @@ module Steep
110
110
  end
111
111
 
112
112
  def lvar_types
113
- var_type_annotations.each_key.with_object({}) do |name, hash|
114
- hash[name] = var_type(lvar: name)
113
+ var_type_annotations.each_key.with_object({}) do |name, hash| #$ Hash[Symbol, Types::t]
114
+ hash[name] = var_type(lvar: name) || raise
115
115
  end
116
116
  end
117
117
 
118
118
  def ivar_types
119
- ivar_type_annotations.each_key.with_object({}) do |name, hash|
120
- hash[name] = var_type(ivar: name)
119
+ ivar_type_annotations.each_key.with_object({}) do |name, hash| #$ Hash[Symbol, Types::t]
120
+ hash[name] = var_type(ivar: name) || raise
121
121
  end
122
122
  end
123
123
 
124
124
  def const_types
125
- const_type_annotations.each_key.with_object({}) do |name, hash|
126
- hash[name] = var_type(const: name)
125
+ const_type_annotations.each_key.with_object({}) do |name, hash| #$ Hash[RBS::TypeName, Types::t]
126
+ hash[name] = var_type(const: name) || raise
127
127
  end
128
128
  end
129
129
 
@@ -841,7 +841,6 @@ module Steep
841
841
  end
842
842
 
843
843
  class UnexpectedError < Base
844
- attr_reader :message
845
844
  attr_reader :error
846
845
 
847
846
  def initialize(node:, error:)
@@ -850,7 +849,28 @@ module Steep
850
849
  end
851
850
 
852
851
  def header_line
853
- "UnexpectedError: #{error.message}"
852
+ "UnexpectedError: #{error.message}(#{error.class})"
853
+ end
854
+
855
+ def detail_lines
856
+ if trace = error.backtrace
857
+ io = StringIO.new
858
+
859
+ total = trace.size
860
+ if total > 30
861
+ trace = trace.take(15)
862
+ end
863
+
864
+ trace.each.with_index do |line, index|
865
+ io.puts "#{index+1}. #{line}"
866
+ end
867
+
868
+ if trace.size != total
869
+ io.puts " (#{total - trace.size} more backtrace)"
870
+ end
871
+
872
+ io.string
873
+ end
854
874
  end
855
875
  end
856
876
 
@@ -992,20 +1012,57 @@ module Steep
992
1012
  def self.default
993
1013
  @default ||= _ = all_error.merge(
994
1014
  {
995
- ImplicitBreakValueMismatch => :warning,
996
- FallbackAny => :information,
997
- UnreachableValueBranch => :warning,
998
- UnreachableBranch => :information,
1015
+ ArgumentTypeMismatch => :error,
1016
+ BlockBodyTypeMismatch => :hint,
1017
+ BlockTypeMismatch => :hint,
1018
+ BreakTypeMismatch => :hint,
1019
+ DifferentMethodParameterKind => :hint,
1020
+ FallbackAny => :hint,
1021
+ FalseAssertion => :hint,
1022
+ ImplicitBreakValueMismatch => :hint,
1023
+ IncompatibleAnnotation => :hint,
1024
+ IncompatibleArgumentForwarding => :warning,
1025
+ IncompatibleAssignment => :hint,
1026
+ IncompatibleMethodTypeAnnotation => :hint,
1027
+ IncompatibleTypeCase => :hint,
1028
+ InsufficientKeywordArguments => :error,
1029
+ InsufficientPositionalArguments => :error,
1030
+ InsufficientTypeArgument => :hint,
1031
+ MethodArityMismatch => :error,
1032
+ MethodBodyTypeMismatch => :error,
1033
+ MethodDefinitionMissing => nil,
1034
+ MethodParameterMismatch => :error,
1035
+ MethodReturnTypeAnnotationMismatch => :hint,
1036
+ MultipleAssignmentConversionError => :hint,
1037
+ NoMethod => :error,
1038
+ ProcHintIgnored => :hint,
1039
+ ProcTypeExpected => :hint,
1040
+ RBSError => :information,
1041
+ RequiredBlockMissing => :error,
1042
+ ReturnTypeMismatch => :error,
1043
+ SetterBodyTypeMismatch => :information,
1044
+ SetterReturnTypeMismatch => :information,
1045
+ SyntaxError => :hint,
1046
+ TypeArgumentMismatchError => :hint,
1047
+ UnexpectedBlockGiven => :warning,
1048
+ UnexpectedDynamicMethod => :hint,
1049
+ UnexpectedError => :hint,
1050
+ UnexpectedJump => :hint,
1051
+ UnexpectedJumpValue => :hint,
1052
+ UnexpectedKeywordArgument => :error,
1053
+ UnexpectedPositionalArgument => :error,
1054
+ UnexpectedSplat => :hint,
1055
+ UnexpectedSuper => :information,
1056
+ UnexpectedTypeArgument => :hint,
1057
+ UnexpectedYield => :warning,
999
1058
  UnknownConstant => :warning,
1000
- MethodDefinitionMissing => :information,
1001
- FalseAssertion => :information,
1002
- UnexpectedTypeArgument => :information,
1003
- InsufficientTypeArgument => :information,
1004
- UnexpectedTypeArgument => :information,
1005
- UnsupportedSyntax => nil,
1006
- ProcHintIgnored => :information,
1007
- SetterBodyTypeMismatch => nil,
1008
- SetterReturnTypeMismatch => nil
1059
+ UnknownGlobalVariable => :warning,
1060
+ UnknownInstanceVariable => :information,
1061
+ UnreachableBranch => :hint,
1062
+ UnreachableValueBranch => :hint,
1063
+ UnresolvedOverloading => :error,
1064
+ UnsatisfiableConstraint => :hint,
1065
+ UnsupportedSyntax => :hint,
1009
1066
  }
1010
1067
  ).freeze
1011
1068
  end
@@ -1013,17 +1070,57 @@ module Steep
1013
1070
  def self.strict
1014
1071
  @strict ||= _ = all_error.merge(
1015
1072
  {
1016
- NoMethod => nil,
1017
- ImplicitBreakValueMismatch => nil,
1018
- FallbackAny => nil,
1019
- UnreachableValueBranch => nil,
1020
- UnreachableBranch => nil,
1021
- UnknownConstant => nil,
1022
- MethodDefinitionMissing => nil,
1023
- UnsupportedSyntax => nil,
1024
- ProcHintIgnored => :warning,
1073
+ ArgumentTypeMismatch => :error,
1074
+ BlockBodyTypeMismatch => :error,
1075
+ BlockTypeMismatch => :error,
1076
+ BreakTypeMismatch => :error,
1077
+ DifferentMethodParameterKind => :error,
1078
+ FallbackAny => :warning,
1079
+ FalseAssertion => :error,
1080
+ ImplicitBreakValueMismatch => :information,
1081
+ IncompatibleAnnotation => :error,
1082
+ IncompatibleArgumentForwarding => :error,
1083
+ IncompatibleAssignment => :error,
1084
+ IncompatibleMethodTypeAnnotation => :error,
1085
+ IncompatibleTypeCase => :error,
1086
+ InsufficientKeywordArguments => :error,
1087
+ InsufficientPositionalArguments => :error,
1088
+ InsufficientTypeArgument => :error,
1089
+ MethodArityMismatch => :error,
1090
+ MethodBodyTypeMismatch => :error,
1091
+ MethodDefinitionMissing => :hint,
1092
+ MethodParameterMismatch => :error,
1093
+ MethodReturnTypeAnnotationMismatch => :error,
1094
+ MultipleAssignmentConversionError => :error,
1095
+ NoMethod => :error,
1096
+ ProcHintIgnored => :information,
1097
+ ProcTypeExpected => :error,
1098
+ RBSError => :error,
1099
+ RequiredBlockMissing => :error,
1100
+ ReturnTypeMismatch => :error,
1025
1101
  SetterBodyTypeMismatch => :error,
1026
- SetterReturnTypeMismatch => :error
1102
+ SetterReturnTypeMismatch => :error,
1103
+ SyntaxError => :hint,
1104
+ TypeArgumentMismatchError => :error,
1105
+ UnexpectedBlockGiven => :error,
1106
+ UnexpectedDynamicMethod => :information,
1107
+ UnexpectedError => :information,
1108
+ UnexpectedJump => :error,
1109
+ UnexpectedJumpValue => :error,
1110
+ UnexpectedKeywordArgument => :error,
1111
+ UnexpectedPositionalArgument => :error,
1112
+ UnexpectedSplat => :warning,
1113
+ UnexpectedSuper => :error,
1114
+ UnexpectedTypeArgument => :error,
1115
+ UnexpectedYield => :error,
1116
+ UnknownConstant => :error,
1117
+ UnknownGlobalVariable => :error,
1118
+ UnknownInstanceVariable => :error,
1119
+ UnreachableBranch => :information,
1120
+ UnreachableValueBranch => :warning,
1121
+ UnresolvedOverloading => :error,
1122
+ UnsatisfiableConstraint => :error,
1123
+ UnsupportedSyntax => :information,
1027
1124
  }
1028
1125
  ).freeze
1029
1126
  end
@@ -1031,19 +1128,57 @@ module Steep
1031
1128
  def self.lenient
1032
1129
  @lenient ||= _ = all_error.merge(
1033
1130
  {
1034
- NoMethod => nil,
1035
- ImplicitBreakValueMismatch => nil,
1131
+ ArgumentTypeMismatch => :information,
1132
+ BlockBodyTypeMismatch => :hint,
1133
+ BlockTypeMismatch => :hint,
1134
+ BreakTypeMismatch => :hint,
1135
+ DifferentMethodParameterKind => nil,
1036
1136
  FallbackAny => nil,
1037
- UnreachableValueBranch => nil,
1038
- UnreachableBranch => nil,
1039
- UnknownConstant => nil,
1137
+ FalseAssertion => nil,
1138
+ ImplicitBreakValueMismatch => nil,
1139
+ IncompatibleAnnotation => nil,
1140
+ IncompatibleArgumentForwarding => :information,
1141
+ IncompatibleAssignment => :hint,
1142
+ IncompatibleMethodTypeAnnotation => nil,
1143
+ IncompatibleTypeCase => nil,
1144
+ InsufficientKeywordArguments => :information,
1145
+ InsufficientPositionalArguments => :information,
1146
+ InsufficientTypeArgument => nil,
1147
+ MethodArityMismatch => :information,
1148
+ MethodBodyTypeMismatch => :warning,
1040
1149
  MethodDefinitionMissing => nil,
1041
- UnexpectedJump => nil,
1042
- FalseAssertion => :hint,
1043
- UnsupportedSyntax => nil,
1044
- ProcHintIgnored => :hint,
1150
+ MethodParameterMismatch => :warning,
1151
+ MethodReturnTypeAnnotationMismatch => nil,
1152
+ MultipleAssignmentConversionError => nil,
1153
+ NoMethod => :information,
1154
+ ProcHintIgnored => nil,
1155
+ ProcTypeExpected => nil,
1156
+ RBSError => :information,
1157
+ RequiredBlockMissing => :hint,
1158
+ ReturnTypeMismatch => :warning,
1045
1159
  SetterBodyTypeMismatch => nil,
1046
- SetterReturnTypeMismatch => nil
1160
+ SetterReturnTypeMismatch => nil,
1161
+ SyntaxError => :hint,
1162
+ TypeArgumentMismatchError => nil,
1163
+ UnexpectedBlockGiven => :hint,
1164
+ UnexpectedDynamicMethod => nil,
1165
+ UnexpectedError => :hint,
1166
+ UnexpectedJump => nil,
1167
+ UnexpectedJumpValue => nil,
1168
+ UnexpectedKeywordArgument => :information,
1169
+ UnexpectedPositionalArgument => :information,
1170
+ UnexpectedSplat => nil,
1171
+ UnexpectedSuper => nil,
1172
+ UnexpectedTypeArgument => nil,
1173
+ UnexpectedYield => :information,
1174
+ UnknownConstant => :hint,
1175
+ UnknownGlobalVariable => :hint,
1176
+ UnknownInstanceVariable => :hint,
1177
+ UnreachableBranch => :hint,
1178
+ UnreachableValueBranch => :hint,
1179
+ UnresolvedOverloading => :information,
1180
+ UnsatisfiableConstraint => :hint,
1181
+ UnsupportedSyntax => :hint,
1047
1182
  }
1048
1183
  ).freeze
1049
1184
  end
@@ -168,8 +168,7 @@ module Steep
168
168
 
169
169
  Steep.logger.info { "Starting type checking: #{request_guid}" }
170
170
 
171
- diagnostic_notifications = []
172
- error_messages = []
171
+ error_messages = [] #: Array[String]
173
172
  client_reader.read do |response|
174
173
  case
175
174
  when response[:method] == "textDocument/publishDiagnostics"
@@ -18,9 +18,10 @@ module Steep
18
18
  # check "app/models/**/*.rb" # Glob
19
19
  # # ignore "lib/templates/*.rb"
20
20
  #
21
- # # library "pathname", "set" # Standard libraries
21
+ # # library "pathname" # Standard libraries
22
22
  # # library "strong_json" # Gems
23
23
  #
24
+ # # configure_code_diagnostics(D::Ruby.default) # `default` diagnostics setting (applies by default)
24
25
  # # configure_code_diagnostics(D::Ruby.strict) # `strict` diagnostics setting
25
26
  # # configure_code_diagnostics(D::Ruby.lenient) # `lenient` diagnostics setting
26
27
  # # configure_code_diagnostics(D::Ruby.silent) # `silent` diagnostics setting
@@ -34,7 +35,7 @@ module Steep
34
35
  #
35
36
  # check "test"
36
37
  #
37
- # # library "pathname", "set" # Standard libraries
38
+ # # library "pathname" # Standard libraries
38
39
  # end
39
40
  EOF
40
41
 
@@ -54,7 +54,7 @@ module Steep
54
54
  end
55
55
 
56
56
  def print(stats_result)
57
- rows = []
57
+ rows = [] #: Array[Array[untyped]]
58
58
  stats_result.sort_by {|row| row[:path] }.each do |row|
59
59
  if row[:type] == "success"
60
60
  rows << [
@@ -471,8 +471,8 @@ module Steep
471
471
 
472
472
  # For overloading
473
473
  def +(other)
474
- requireds = {}
475
- optionals = {}
474
+ requireds = {} #: Hash[Symbol, AST::Types::t]
475
+ optionals = {} #: Hash[Symbol, AST::Types::t]
476
476
 
477
477
  all_keys = Set[] + self.requireds.keys + self.optionals.keys + other.requireds.keys + other.optionals.keys
478
478
  all_keys.each do |key|
@@ -535,8 +535,8 @@ module Steep
535
535
 
536
536
  # For union
537
537
  def |(other)
538
- requireds = {}
539
- optionals = {}
538
+ requireds = {} #: Hash[Symbol, AST::Types::t]
539
+ optionals = {} #: Hash[Symbol, AST::Types::t]
540
540
 
541
541
  all_keys = Set[] + self.requireds.keys + self.optionals.keys + other.requireds.keys + other.optionals.keys
542
542
  all_keys.each do |key|
@@ -600,8 +600,8 @@ module Steep
600
600
 
601
601
  # For intersection
602
602
  def &(other)
603
- requireds = {}
604
- optionals = {}
603
+ requireds = {} #: Hash[Symbol, AST::Types::t]
604
+ optionals = {} #: Hash[Symbol, AST::Types::t]
605
605
 
606
606
  all_keys = Set[] + self.requireds.keys + self.optionals.keys + other.requireds.keys + other.optionals.keys
607
607
  all_keys.each do |key|
@@ -665,7 +665,7 @@ module Steep
665
665
  end
666
666
 
667
667
  def required
668
- array = []
668
+ array = [] #: Array[AST::Types::t]
669
669
 
670
670
  positional_params&.each do |param|
671
671
  case param
@@ -680,7 +680,7 @@ module Steep
680
680
  end
681
681
 
682
682
  def optional
683
- array = []
683
+ array = [] #: Array[AST::Types::t]
684
684
 
685
685
  positional_params&.each do |param|
686
686
  case param
@@ -66,7 +66,7 @@ module Steep
66
66
  def typing_options(level = nil, **hash)
67
67
  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:"
68
68
 
69
- messages = []
69
+ messages = [] #: Array[String]
70
70
 
71
71
  messages << "# D = Steep::Diagnostic # Define a constant to shorten namespace"
72
72
 
@@ -83,7 +83,7 @@ module Steep
83
83
  Steep.logger.error " #{msg}"
84
84
  end
85
85
 
86
- config = []
86
+ config = [] #: Array[String]
87
87
 
88
88
  if hash[:allow_missing_definitions]
89
89
  config << "hash[D::Ruby::MethodDefinitionMissing] = nil # allow_missing_definitions"
@@ -143,27 +143,6 @@ module Steep
143
143
  @repo_paths.push(*paths.map {|s| Pathname(s) })
144
144
  end
145
145
 
146
- # Configure the code diagnostics printing setup.
147
- #
148
- # Yields a hash, and the update the hash in the block.
149
- #
150
- # ```rb
151
- # D = Steep::Diagnostic
152
- #
153
- # configure_code_diagnostics do |hash|
154
- # # Assign one of :error, :warning, :information, :hint or :nil to error classes.
155
- # hash[D::Ruby::UnexpectedPositionalArgument] = :error
156
- # end
157
- # ```
158
- #
159
- # Passing a hash is also allowed.
160
- #
161
- # ```rb
162
- # D = Steep::Diagnostic
163
- #
164
- # configure_code_diagnostics(D::Ruby.lenient)
165
- # ```
166
- #
167
146
  def configure_code_diagnostics(hash = nil)
168
147
  if hash
169
148
  code_diagnostics_config.merge!(hash)
@@ -122,7 +122,7 @@ module Steep
122
122
  items = begin
123
123
  provider.run(line: job.line, column: job.column)
124
124
  rescue Parser::SyntaxError
125
- []
125
+ [] #: Array[Services::CompletionProvider::item]
126
126
  end
127
127
 
128
128
  completion_items = items.map do |item|
@@ -157,7 +157,7 @@ module Steep
157
157
  locator = RBS::Locator.new(buffer: buffer, dirs: dirs, decls: decls)
158
158
 
159
159
  _hd, tail = locator.find2(line: job.line, column: job.column)
160
- tail ||= []
160
+ tail ||= [] #: Array[RBS::Locator::component]
161
161
 
162
162
  tail.reverse_each do |t|
163
163
  case t
data/lib/steep/source.rb CHANGED
@@ -330,13 +330,12 @@ module Steep
330
330
  def find_heredoc_nodes(line, column, position)
331
331
  each_heredoc_node() do |nodes, location|
332
332
  node = nodes[0]
333
+ loc = location.heredoc_body #: Parser::Source::Range
333
334
 
334
- range = location.heredoc_body&.yield_self do |r|
335
- r.begin_pos..r.end_pos
336
- end
337
-
338
- if range && (range === position)
339
- return nodes
335
+ if range = loc.to_range
336
+ if range.begin <= position && position <= range.end
337
+ return nodes
338
+ end
340
339
  end
341
340
  end
342
341
 
@@ -344,12 +343,10 @@ module Steep
344
343
  end
345
344
 
346
345
  def find_nodes_loc(node, position, parents)
347
- range = node.location.expression&.yield_self do |r|
348
- r.begin_pos..r.end_pos
349
- end
346
+ range = node.location.expression&.to_range
350
347
 
351
348
  if range
352
- if range === position
349
+ if range.begin <= position && position <= range.end
353
350
  parents.unshift node
354
351
 
355
352
  Source.each_child_node(node) do |child|
@@ -366,9 +363,7 @@ module Steep
366
363
  def find_nodes(line:, column:)
367
364
  return [] unless node
368
365
 
369
- position = (line-1).times.sum do |i|
370
- node.location.expression.source_buffer.source_line(i+1).size + 1
371
- end + column
366
+ position = buffer.loc_to_pos([line, column])
372
367
 
373
368
  if heredoc_nodes = find_heredoc_nodes(line, column, position)
374
369
  Source.each_child_node(heredoc_nodes[0]) do |child|
@@ -430,7 +430,7 @@ module Steep
430
430
  when AST::Types::Name::Singleton
431
431
  singleton_super_types(relation.sub_type.name)
432
432
  else
433
- []
433
+ [] #: Array[super_type]
434
434
  end
435
435
 
436
436
  unless possible_sub_types.empty?
@@ -743,7 +743,7 @@ module Steep
743
743
  args.each {|arg| constraints.unknown!(arg.name) }
744
744
 
745
745
  upper_bounds = {}
746
- relations = []
746
+ relations = [] #: Array[Relation]
747
747
 
748
748
  args.zip(sub_type.type_params, super_type.type_params).each do |arg, sub_param, sup_param|
749
749
  sub_ub = sub_param.upper_bound
@@ -249,8 +249,8 @@ module Steep
249
249
  class_type = context.class_type
250
250
  end
251
251
 
252
- vars = []
253
- types = []
252
+ vars = [] #: Array[Symbol]
253
+ types = [] #: Array[AST::Types::t]
254
254
 
255
255
  dictionary.each_key do |var|
256
256
  if variables.include?(var)
@@ -1778,7 +1778,10 @@ module Steep
1778
1778
  yield_self do
1779
1779
  left_node, right_node = node.children
1780
1780
 
1781
- left_type, constr, left_context = synthesize(left_node, hint: hint, condition: true).to_ary
1781
+ if hint
1782
+ left_hint = union_type_unify(hint, AST::Builtin.nil_type, AST::Builtin.false_type)
1783
+ end
1784
+ left_type, constr, left_context = synthesize(left_node, hint: left_hint, condition: true).to_ary
1782
1785
 
1783
1786
  interpreter = TypeInference::LogicTypeInterpreter.new(subtyping: checker, typing: typing, config: builder_config)
1784
1787
  left_truthy, left_falsy = interpreter.eval(env: left_context.type_env, node: left_node)
@@ -1888,7 +1891,7 @@ module Steep
1888
1891
  if loc.respond_to?(:keyword)
1889
1892
  condition_loc = loc #: NodeHelper::condition_loc
1890
1893
  case condition_loc.keyword.source
1891
- when "if"
1894
+ when "if", "elsif"
1892
1895
  location = condition_loc.begin || condition_loc.keyword
1893
1896
  when "unless"
1894
1897
  # `else` token always exists
@@ -1913,8 +1916,9 @@ module Steep
1913
1916
 
1914
1917
  if loc.respond_to?(:keyword)
1915
1918
  condition_loc = loc #: NodeHelper::condition_loc
1919
+
1916
1920
  case condition_loc.keyword.source
1917
- when "if"
1921
+ when "if", "elsif"
1918
1922
  # `else` token always exists
1919
1923
  location = condition_loc.else || raise
1920
1924
  when "unless"
@@ -3103,27 +3107,29 @@ module Steep
3103
3107
 
3104
3108
  type_hint = deep_expand_alias(type_hint) || type_hint
3105
3109
 
3106
- procs = flatten_union(type_hint).select do |type|
3107
- check_relation(sub_type: type, super_type: AST::Builtin::Proc.instance_type).success? &&
3108
- !type.is_a?(AST::Types::Any)
3109
- end
3110
+ unless type_hint.is_a?(AST::Types::Any)
3111
+ procs = flatten_union(type_hint).select do |type|
3112
+ check_relation(sub_type: type, super_type: AST::Builtin::Proc.instance_type).success? &&
3113
+ !type.is_a?(AST::Types::Any)
3114
+ end
3110
3115
 
3111
- proc_instances, proc_types = procs.partition {|type| AST::Builtin::Proc.instance_type?(type) }
3116
+ proc_instances, proc_types = procs.partition {|type| AST::Builtin::Proc.instance_type?(type) }
3112
3117
 
3113
- case
3114
- when !proc_instances.empty? && proc_types.empty?
3115
- # `::Proc` is given as a hint
3116
- when proc_types.size == 1
3117
- # Proc type is given as a hint
3118
- hint_proc = proc_types[0] #: AST::Types::Proc
3119
- params_hint = hint_proc.type.params
3120
- return_hint = hint_proc.type.return_type
3121
- block_hint = hint_proc.block
3122
- self_hint = hint_proc.self_type
3123
- else
3124
- typing.add_error(
3125
- Diagnostic::Ruby::ProcHintIgnored.new(hint_type: original_hint, node: node)
3126
- )
3118
+ case
3119
+ when !proc_instances.empty? && proc_types.empty?
3120
+ # `::Proc` is given as a hint
3121
+ when proc_types.size == 1
3122
+ # Proc type is given as a hint
3123
+ hint_proc = proc_types[0] #: AST::Types::Proc
3124
+ params_hint = hint_proc.type.params
3125
+ return_hint = hint_proc.type.return_type
3126
+ block_hint = hint_proc.block
3127
+ self_hint = hint_proc.self_type
3128
+ else
3129
+ typing.add_error(
3130
+ Diagnostic::Ruby::ProcHintIgnored.new(hint_type: original_hint, node: node)
3131
+ )
3132
+ end
3127
3133
  end
3128
3134
  end
3129
3135
 
@@ -280,20 +280,22 @@ module Steep
280
280
  when AST::Types::Logic::ReceiverIsNil
281
281
  if receiver && arguments.size.zero?
282
282
  receiver_type = typing.type_of(node: receiver)
283
- truthy_receiver, falsy_receiver = factory.partition_union(receiver_type)
283
+ unwrap = factory.unwrap_optional(receiver_type)
284
+ truthy_receiver = AST::Builtin.nil_type
285
+ falsy_receiver = unwrap || receiver_type
284
286
 
285
287
  truthy_env, falsy_env = refine_node_type(
286
288
  env: env,
287
289
  node: receiver,
288
- truthy_type: falsy_receiver || BOT,
289
- falsy_type: truthy_receiver || BOT
290
+ truthy_type: truthy_receiver,
291
+ falsy_type: falsy_receiver
290
292
  )
291
293
 
292
294
  truthy_result = Result.new(type: TRUE, env: truthy_env, unreachable: false)
293
- truthy_result.unreachable! unless truthy_receiver
295
+ truthy_result.unreachable! if unwrap == receiver_type
294
296
 
295
297
  falsy_result = Result.new(type: FALSE, env: falsy_env, unreachable: false)
296
- falsy_result.unreachable! unless falsy_receiver
298
+ falsy_result.unreachable! unless unwrap
297
299
 
298
300
  [truthy_result, falsy_result]
299
301
  end
@@ -500,7 +502,7 @@ module Steep
500
502
  type_case_select0(ty, klass)
501
503
  end
502
504
 
503
- when AST::Types::Any, AST::Types::Top
505
+ when AST::Types::Any, AST::Types::Top, AST::Types::Var
504
506
  [
505
507
  [instance_type],
506
508
  [type]
@@ -9,7 +9,7 @@ module Steep
9
9
  attr_reader :pure_method_calls
10
10
 
11
11
  def to_s
12
- array = []
12
+ array = [] #: Array[String]
13
13
 
14
14
  local_variable_types.each do |name, entry|
15
15
  if enforced_type = entry[1]
@@ -108,7 +108,7 @@ module Steep
108
108
  end
109
109
 
110
110
  def assign_local_variables(assignments)
111
- local_variable_types = {}
111
+ local_variable_types = {} #: Hash[Symbol, local_variable_entry]
112
112
  invalidated_nodes = Set[]
113
113
 
114
114
  assignments.each do |name, new_type|
@@ -135,7 +135,7 @@ module Steep
135
135
  end
136
136
 
137
137
  def refine_types(local_variable_types: {}, pure_call_types: {})
138
- local_variable_updates = {}
138
+ local_variable_updates = {} #: Hash[Symbol, local_variable_entry]
139
139
 
140
140
  local_variable_types.each do |name, type|
141
141
  local_variable_name!(name)
data/lib/steep/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Steep
2
- VERSION = "1.5.0.pre.6"
2
+ VERSION = "1.5.1"
3
3
  end
@@ -32,3 +32,8 @@ class HogeHoge
32
32
  bar(self, ...).to_s
33
33
  end
34
34
  end
35
+
36
+
37
+
38
+ conference = nil #: Conference?
39
+
@@ -2,7 +2,7 @@ module Steep
2
2
  module AST
3
3
  module Annotation
4
4
  class Collection
5
- attr_reader annotations: untyped
5
+ attr_reader annotations: Array[Annotation::t]
6
6
 
7
7
  attr_reader factory: Types::Factory
8
8
 
@@ -14,31 +14,34 @@ module Steep
14
14
 
15
15
  attr_reader ivar_type_annotations: Hash[Symbol, IvarType]
16
16
 
17
- attr_reader method_type_annotations: untyped
17
+ attr_reader method_type_annotations: Hash[Symbol, MethodType?]
18
18
 
19
- attr_reader block_type_annotation: untyped
19
+ attr_reader block_type_annotation: BlockType?
20
20
 
21
- attr_reader return_type_annotation: untyped
21
+ attr_reader return_type_annotation: ReturnType?
22
22
 
23
- attr_reader self_type_annotation: untyped
23
+ attr_reader self_type_annotation: SelfType?
24
24
 
25
- attr_reader instance_type_annotation: untyped
25
+ attr_reader instance_type_annotation: InstanceType?
26
26
 
27
- attr_reader module_type_annotation: untyped
27
+ attr_reader module_type_annotation: ModuleType?
28
28
 
29
29
  attr_reader implement_module_annotation: Implements?
30
30
 
31
- attr_reader dynamic_annotations: untyped
31
+ attr_reader dynamic_annotations: Array[Dynamic]
32
32
 
33
- attr_reader break_type_annotation: untyped
33
+ attr_reader break_type_annotation: BreakType?
34
34
 
35
- def initialize: (annotations: untyped, factory: untyped, context: untyped) -> void
35
+ def initialize: (annotations: Array[Annotation::t], factory: Types::Factory, context: RBS::Resolver::context) -> void
36
36
 
37
- def absolute_type: (untyped `type`) -> (untyped | nil)
37
+ def absolute_type: (Types::t) -> Types::t
38
+ | (Types::t?) -> Types::t?
38
39
 
39
- def var_type: (?lvar: untyped?, ?ivar: untyped?, ?const: untyped?) -> untyped
40
+ def var_type: (lvar: Symbol) -> Types::t?
41
+ | (ivar: Symbol) -> Types::t?
42
+ | (const: RBS::TypeName) -> Types::t?
40
43
 
41
- def method_type: (untyped name) -> (untyped | nil)
44
+ def method_type: (Symbol name) -> Interface::MethodType?
42
45
 
43
46
  %a{pure} def block_type: () -> Types::t?
44
47
 
@@ -52,23 +55,23 @@ module Steep
52
55
 
53
56
  %a{pure} def break_type: () -> Types::t?
54
57
 
55
- def lvar_types: () -> untyped
58
+ def lvar_types: () -> Hash[Symbol, Types::t]
56
59
 
57
- def ivar_types: () -> untyped
60
+ def ivar_types: () -> Hash[Symbol, Types::t]
58
61
 
59
- def const_types: () -> untyped
62
+ def const_types: () -> Hash[RBS::TypeName, Types::t]
60
63
 
61
- def instance_dynamics: () -> untyped
64
+ def instance_dynamics: () -> Array[Symbol]
62
65
 
63
- def module_dynamics: () -> untyped
66
+ def module_dynamics: () -> Array[Symbol]
64
67
 
65
- def merge_block_annotations: (untyped annotations) -> untyped
68
+ def merge_block_annotations: (Collection annotations) -> Collection
66
69
 
67
- def any?: () { () -> untyped } -> untyped
70
+ def any?: () { (Annotation::t) -> boolish } -> bool
68
71
 
69
- def size: () -> untyped
72
+ def size: () -> Integer
70
73
 
71
- def include?: (untyped obj) -> untyped
74
+ def include?: (Annotation::t obj) -> bool
72
75
  end
73
76
  end
74
77
  end
@@ -77,13 +77,12 @@ module Steep
77
77
  # Returns a type that doesn't have `nil` in the union component
78
78
  #
79
79
  # * Returns `nil` if given type is `nil`
80
- # * **Doesn't expand type alias automatically**
80
+ # * Expand (unfold) the type aliases automatically
81
81
  #
82
82
  # ```ruby
83
83
  # unwrap_optional(`String?`) # => `String`
84
84
  # unwrap_optional(`String | Integer | false | nil`) # => `String | Integer | false`
85
85
  # unwrap_optional(`nil`) # => nil
86
- # unwrap_optional(`boolish`) # => `boolish`
87
86
  # ```
88
87
  #
89
88
  def unwrap_optional: (Types::t) -> Types::t?
@@ -546,11 +546,9 @@ module Steep
546
546
  end
547
547
 
548
548
  class UnexpectedError < Base
549
- attr_reader message: untyped
550
-
551
- attr_reader error: untyped
549
+ attr_reader error: Exception
552
550
 
553
- def initialize: (node: untyped, error: untyped) -> void
551
+ def initialize: (node: Parser::AST::Node, error: Exception) -> void
554
552
 
555
553
  def header_line: () -> ::String
556
554
  end
@@ -623,7 +621,7 @@ module Steep
623
621
  end
624
622
 
625
623
  # RBS embedded in the Ruby code has validation error
626
- #
624
+ #
627
625
  class RBSError < Base
628
626
  attr_reader error: Signature::Base
629
627
 
@@ -662,21 +660,35 @@ module Steep
662
660
 
663
661
  ALL: Array[singleton(Base)]
664
662
 
665
- type template = Hash[singleton(Base), LSPFormatter::severity]
663
+ type template = Hash[singleton(Base), LSPFormatter::severity?]
666
664
 
667
665
  self.@all_error: template?
666
+ self.@default: template?
667
+ self.@strict: template?
668
+ self.@lenient: template?
669
+ self.@silent: template?
670
+
671
+ # This template reports everything as an error
672
+ #
668
673
  def self.all_error: () -> template
669
674
 
670
- self.@default: template?
675
+ # This template detects inconsistencies between RBS and Ruby code APIs
676
+ #
671
677
  def self.default: () -> template
672
678
 
673
- self.@strict: template?
679
+ # This template helps you keeping your codebase (almost) type-safe
680
+ #
681
+ # You can start with this template to review the problems reported on the project,
682
+ # and you can ignore some kind of errors.
683
+ #
674
684
  def self.strict: () -> template
675
685
 
676
- self.@lenient: template?
686
+ # This template detects inconsistent definition in Ruby code with respect to your RBS definition
687
+ #
677
688
  def self.lenient: () -> template
678
689
 
679
- self.@silent: template?
690
+ # This template reports nothing
691
+ #
680
692
  def self.silent: () -> template
681
693
  end
682
694
  end
@@ -1,3 +1,5 @@
1
+ use Steep::Diagnostic::Ruby::template
2
+
1
3
  module Steep
2
4
  class Project
3
5
  class DSL
@@ -71,10 +73,13 @@ module Steep
71
73
  # D = Steep::Diagnostic
72
74
  #
73
75
  # configure_code_diagnostics(D::Ruby.lenient)
76
+ # configure_code_diagnostics(D::Ruby.strict) do |config|
77
+ # config[D::Ruby::NoMethod] = nil
78
+ # end
74
79
  # ```
75
80
  #
76
- def configure_code_diagnostics: (Hash[untyped, untyped] hash) -> void
77
- | () { (Hash[untyped, untyped]) -> void } -> void
81
+ def configure_code_diagnostics: (template hash) ?{ (template) -> void }-> void
82
+ | () { (template) -> void }-> void
78
83
 
79
84
  def collection_config: (Pathname path) -> void
80
85
 
@@ -1,16 +1,4 @@
1
1
  ---
2
- - file: unexpected.rb
3
- diagnostics:
4
- - range:
5
- start:
6
- line: 1
7
- character: 0
8
- end:
9
- line: 1
10
- character: 14
11
- severity: ERROR
12
- message: 'UnexpectedError: unexpected.rbs:2:17...2:24: Could not find String1'
13
- code: Ruby::UnexpectedError
14
2
  - file: unexpected.rbs
15
3
  diagnostics:
16
4
  - range:
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: 1.5.0.pre.6
4
+ version: 1.5.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Soutaro Matsumoto
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2023-07-11 00:00:00.000000000 Z
11
+ date: 2023-07-20 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: parser
@@ -266,7 +266,6 @@ files:
266
266
  - lib/steep/ast/builtin.rb
267
267
  - lib/steep/ast/node/type_application.rb
268
268
  - lib/steep/ast/node/type_assertion.rb
269
- - lib/steep/ast/type_params.rb
270
269
  - lib/steep/ast/types/any.rb
271
270
  - lib/steep/ast/types/boolean.rb
272
271
  - lib/steep/ast/types/bot.rb
@@ -401,7 +400,6 @@ files:
401
400
  - sig/steep/ast/builtin.rbs
402
401
  - sig/steep/ast/node/type_application.rbs
403
402
  - sig/steep/ast/node/type_assertion.rbs
404
- - sig/steep/ast/type_params.rbs
405
403
  - sig/steep/ast/types.rbs
406
404
  - sig/steep/ast/types/any.rbs
407
405
  - sig/steep/ast/types/boolean.rbs
@@ -757,7 +755,6 @@ files:
757
755
  - smoke/type_case/test_expectations.yml
758
756
  - smoke/unexpected/Steepfile
759
757
  - smoke/unexpected/test_expectations.yml
760
- - smoke/unexpected/unexpected.rb
761
758
  - smoke/unexpected/unexpected.rbs
762
759
  - smoke/yield/Steepfile
763
760
  - smoke/yield/a.rb
@@ -782,9 +779,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
782
779
  version: 2.7.0
783
780
  required_rubygems_version: !ruby/object:Gem::Requirement
784
781
  requirements:
785
- - - ">"
782
+ - - ">="
786
783
  - !ruby/object:Gem::Version
787
- version: 1.3.1
784
+ version: '0'
788
785
  requirements: []
789
786
  rubygems_version: 3.4.10
790
787
  signing_key:
@@ -1,13 +0,0 @@
1
- module Steep
2
- module AST
3
- class TypeParams
4
- attr_reader :location
5
- attr_reader :variables
6
-
7
- def initialize(location: nil, variables:)
8
- @location = location
9
- @variables = variables
10
- end
11
- end
12
- end
13
- end
@@ -1,11 +0,0 @@
1
- # module Steep
2
- # module AST
3
- # class TypeParams
4
- # attr_reader location: untyped
5
-
6
- # attr_reader variables: untyped
7
-
8
- # def initialize: (variables: untyped, ?location: untyped?) -> void
9
- # end
10
- # end
11
- # end
@@ -1 +0,0 @@
1
- Unexpected.new.foo().bar