Skip to content

Commit

Permalink
Merge pull request #284 from Shopify/at-forbid-t-enum
Browse files Browse the repository at this point in the history
Add `ForbidTEnum` cop
  • Loading branch information
Morriar authored Feb 20, 2025
2 parents 100bcf3 + d0e65c7 commit abe6884
Show file tree
Hide file tree
Showing 6 changed files with 133 additions and 0 deletions.
7 changes: 7 additions & 0 deletions config/default.yml
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,13 @@ Sorbet/ForbidSuperclassConstLiteral:
Exclude:
- db/migrate/*.rb

Sorbet/ForbidTEnum:
Description: 'Forbid usage of T::Enum.'
Enabled: false
VersionAdded: <<next>>
VersionChanged: <<next>>
Safe: false

Sorbet/ForbidTStruct:
Description: 'Forbid usage of T::Struct.'
Enabled: false
Expand Down
40 changes: 40 additions & 0 deletions lib/rubocop/cop/sorbet/forbid_t_enum.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
# frozen_string_literal: true

require "rubocop"

module RuboCop
module Cop
module Sorbet
# Disallow using `T::Enum`.
#
# @example
#
# # bad
# class MyEnum < T::Struct
# enums do
# A = new
# B = new
# end
# end
#
# # good
# class MyEnum
# A = "a'
# B = "b"
# C = "c"
# end
class ForbidTEnum < RuboCop::Cop::Base
MSG = "Using `T::Enum` is deprecated."

# @!method t_enum?(node)
def_node_matcher(:t_enum?, <<~PATTERN)
(const (const {nil? cbase} :T) :Enum)
PATTERN

def on_class(node)
add_offense(node) if t_enum?(node.parent_class)
end
end
end
end
end
1 change: 1 addition & 0 deletions lib/rubocop/cop/sorbet_cops.rb
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
require_relative "sorbet/forbid_untyped_struct_props"
require_relative "sorbet/implicit_conversion_method"
require_relative "sorbet/callback_conditionals_binding"
require_relative "sorbet/forbid_t_enum"
require_relative "sorbet/forbid_t_struct"
require_relative "sorbet/forbid_t_unsafe"
require_relative "sorbet/forbid_t_untyped"
Expand Down
1 change: 1 addition & 0 deletions manual/cops.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ In the following section you find all available cops:
* [Sorbet/ForbidIncludeConstLiteral](cops_sorbet.md#sorbetforbidincludeconstliteral)
* [Sorbet/ForbidRBIOutsideOfAllowedPaths](cops_sorbet.md#sorbetforbidrbioutsideofallowedpaths)
* [Sorbet/ForbidSuperclassConstLiteral](cops_sorbet.md#sorbetforbidsuperclassconstliteral)
* [Sorbet/ForbidTEnum](cops_sorbet.md#sorbetforbidtenum)
* [Sorbet/ForbidTStruct](cops_sorbet.md#sorbetforbidtstruct)
* [Sorbet/ForbidTUnsafe](cops_sorbet.md#sorbetforbidtunsafe)
* [Sorbet/ForbidTUntyped](cops_sorbet.md#sorbetforbidtuntyped)
Expand Down
27 changes: 27 additions & 0 deletions manual/cops_sorbet.md
Original file line number Diff line number Diff line change
Expand Up @@ -448,6 +448,33 @@ Name | Default value | Configurable values
--- | --- | ---
Exclude | `db/migrate/*.rb` | Array

## Sorbet/ForbidTEnum

Enabled by default | Safe | Supports autocorrection | VersionAdded | VersionChanged
--- | --- | --- | --- | ---
Disabled | No | No | <<next>> | <<next>>

Disallow using `T::Enum`.

### Examples

```ruby
# bad
class MyEnum < T::Struct
enums do
A = new
B = new
end
end

# good
class MyEnum
A = "a'
B = "b"
C = "c"
end
```
## Sorbet/ForbidTStruct
Enabled by default | Safe | Supports autocorrection | VersionAdded | VersionChanged
Expand Down
57 changes: 57 additions & 0 deletions spec/rubocop/cop/sorbet/forbid_t_enum_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
# frozen_string_literal: true

require "spec_helper"

RSpec.describe(RuboCop::Cop::Sorbet::ForbidTEnum, :config) do
describe("Offenses") do
it "adds offense when inheriting T::Enum on a multiline class" do
expect_offense(<<~RUBY)
class Foo < T::Enum
^^^^^^^^^^^^^^^^^^^ Using `T::Enum` is deprecated.
end
RUBY
end

it "adds offense when inheriting T::Enum on a singleline class" do
expect_offense(<<~RUBY)
class Foo < T::Enum; end
^^^^^^^^^^^^^^^^^^^^^^^^ Using `T::Enum` is deprecated.
RUBY
end

it "adds offense when inheriting ::T::Enum" do
expect_offense(<<~RUBY)
class Foo < ::T::Enum; end
^^^^^^^^^^^^^^^^^^^^^^^^^^ Using `T::Enum` is deprecated.
RUBY
end

it "adds offense for nested enums" do
expect_offense(<<~RUBY)
class Foo < T::Enum
^^^^^^^^^^^^^^^^^^^ Using `T::Enum` is deprecated.
class Bar < T::Enum
^^^^^^^^^^^^^^^^^^^ Using `T::Enum` is deprecated.
end
end
RUBY
end
end

describe("No offenses") do
it "does not add offense when not using T::Enum" do
expect_no_offenses(<<~RUBY)
class Foo
end
class Bar < Baz; end
class Baz
extend T::Enum
end
class T::Enum; end
RUBY
end
end
end

0 comments on commit abe6884

Please sign in to comment.