Repository navigation
Add RedundantTLet cop - #362
Conversation
Morriar
left a comment
There was a problem hiding this comment.
This is looking good, let's add a few tests to encode current behaviour with more complex type expressions then we can merge it 👍
| @a = T.let(a, T::Array[Integer]) | ||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ #{MSG} | ||
| end | ||
| RUBY |
There was a problem hiding this comment.
Let's add a few example with more complicated type syntax:
sig { params(a: Foo[Bar], b: T.any(A, B), c: T.proc.void).void }
def initialize(proc)
@a = T.let(a, Foo[Foo]) # error
@b = T.let(b, T.any(B, A)) # it's equivalent, should it be ok or error?
@c = T.let(c, T.proc.returns(Integer)) # ok
end
There was a problem hiding this comment.
Added a few more examples:)
@ b = T.let(b, T.any(B, A)) # it's equivalent, should it be ok or error?
Right now the cop is checking for syntactical equivalence, not semantical, so T.any(A, B) and T.any(B, A) (or T.proc.params(x: A, y: B) and T.proc.params(y: B, x: A)) are treated as different and left alone
I think it would be possible to manually check for parity in these cases but the solutions I looked at felt a bit fragile. I would lean towards not warning/autocorrecting. What do you think?
2848a5b to
b0648aa
Compare
Similar to `Sorbet/RedundantTLet` (Shopify#362), which removes redundant `T.let` in `initialize` methods where instance variable types can be inferred from the signature, this cop targets a different case: constant assignments with simple literals. When a constant is assigned a simple literal (String, Integer, Float, Symbol, Regexp, Complex, Rational) wrapped in `T.let` with the matching class as the type, the `T.let` is redundant because Sorbet can infer the type of simple literals automatically. For example: # bad — Sorbet already knows this is Integer MAX_RETRIES = T.let(3, Integer) # good MAX_RETRIES = 3 The cop only fires on constant assignments (`casgn`) with simple literals. It correctly ignores collections, nilable types, instance variables, local variables, and cases where the type doesn't match the literal. Includes autocorrection support.
Similar to `Sorbet/RedundantTLet` (Shopify#362), which removes redundant `T.let` in `initialize` methods where instance variable types can be inferred from the signature, this cop targets a different case: constant assignments with simple literals. When a constant is assigned a simple literal (String, Integer, Float, Symbol, Regexp, Complex, Rational) wrapped in `T.let` with the matching class as the type, the `T.let` is redundant because Sorbet can infer the type of simple literals automatically. For example: # bad — Sorbet already knows this is Integer MAX_RETRIES = T.let(3, Integer) # good MAX_RETRIES = 3 The cop only fires on constant assignments (`casgn`) with simple literals. It correctly ignores collections, nilable types, instance variables, local variables, and cases where the type doesn't match the literal. Includes autocorrection support.
Similar to `Sorbet/RedundantTLet` (Shopify#362), which removes redundant `T.let` in `initialize` methods where instance variable types can be inferred from the signature, this cop targets a different case: constant assignments with simple literals. When a constant is assigned a simple literal (String, Integer, Float, Symbol, Regexp) wrapped in `T.let` with the matching class as the type, the `T.let` is redundant because Sorbet can infer the type automatically. For example: # bad — Sorbet already knows this is Integer MAX_RETRIES = T.let(3, Integer) # good MAX_RETRIES = 3 The cop only fires on constant assignments (`casgn`) with simple literals. It correctly ignores collections, nilable types, instance variables, local variables, and cases where the type doesn't match the literal. Includes autocorrection support.
Similar to `Sorbet/RedundantTLet` (Shopify#362), which removes redundant `T.let` in `initialize` methods where instance variable types can be inferred from the signature, this cop targets a different case: constant assignments with simple literals. When a constant is assigned a simple literal (Float, Integer, Regexp, String, Symbol) wrapped in `T.let` with the matching class as the type, the `T.let` is redundant because Sorbet can infer the type automatically. For example: # bad — Sorbet already knows this is Integer MAX_RETRIES = T.let(3, Integer) # good MAX_RETRIES = 3 The cop only fires on constant assignments (`casgn`) with simple literals. It correctly ignores collections, nilable types, instance variables, local variables, and cases where the type doesn't match the literal. Includes autocorrection support.
Similar to `Sorbet/RedundantTLet` (Shopify#362), which removes redundant `T.let` in `initialize` methods where instance variable types can be inferred from the signature, this cop targets a different case: constant assignments with simple literals. When a constant is assigned a simple literal (Float, Integer, Regexp, String, Symbol) wrapped in `T.let` with the matching class as the type, the `T.let` is redundant because Sorbet can infer the type automatically. For example: # bad — Sorbet already knows this is Integer MAX_RETRIES = T.let(3, Integer) # good MAX_RETRIES = 3 The cop only fires on constant assignments (`casgn`) with simple literals. It correctly ignores collections, nilable types, instance variables, local variables, and cases where the type doesn't match the literal. Includes autocorrection support.
Similar to `Sorbet/RedundantTLet` (Shopify#362), which removes redundant `T.let` in `initialize` methods where instance variable types can be inferred from the signature, this cop targets a different case: constant assignments with simple literals. When a constant is assigned a simple literal (Float, Integer, Regexp, String, Symbol) wrapped in `T.let` with the matching class as the type, the `T.let` is redundant because Sorbet can infer the type automatically. For example: # bad — Sorbet already knows this is Integer MAX_RETRIES = T.let(3, Integer) # good MAX_RETRIES = 3 The cop only fires on constant assignments (`casgn`) with simple literals. It correctly ignores collections, nilable types, instance variables, local variables, and cases where the type doesn't match the literal. Includes autocorrection support.
Similar to `Sorbet/RedundantTLet` (Shopify#362), which removes redundant `T.let` in `initialize` methods where instance variable types can be inferred from the signature, this cop targets a different case: constant assignments with simple literals. When a constant is assigned a simple literal (Float, Integer, Regexp, String, Symbol) wrapped in `T.let` with the matching class as the type, the `T.let` is redundant because Sorbet can infer the type automatically. For example: # bad — Sorbet already knows this is Integer MAX_RETRIES = T.let(3, Integer) # good MAX_RETRIES = 3 The cop only fires on constant assignments (`casgn`) with simple literals. It correctly ignores collections, nilable types, instance variables, local variables, and cases where the type doesn't match the literal. Includes autocorrection support.
Similar to `Sorbet/RedundantTLet` (#362), which removes redundant `T.let` in `initialize` methods where instance variable types can be inferred from the signature, this cop targets a different case: constant assignments with simple literals. When a constant is assigned a simple literal (Float, Integer, Regexp, String, Symbol) wrapped in `T.let` with the matching class as the type, the `T.let` is redundant because Sorbet can infer the type automatically. For example: # bad — Sorbet already knows this is Integer MAX_RETRIES = T.let(3, Integer) # good MAX_RETRIES = 3 The cop only fires on constant assignments (`casgn`) with simple literals. It correctly ignores collections, nilable types, instance variables, local variables, and cases where the type doesn't match the literal. Includes autocorrection support.
Sorbet can infer the type of
initializemethod instance variables when they are assigned to parameters already typed by signatures. In cases where aT.letassertion is:initializemethodsigparamswe can DRY up code by removing it
sig { params(foo: String) } def initialize(foo:) - @foo = T.let(foo, String) + @foo = foo endThe cop will display
Sorbet/RedundantTLet: Unnecessary T.let. The instance variable type is inferred from the signatureand optionally autocorrectDemo
tlet-demo.mov