rubocop-migration 0.2.0 → 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +5 -5
- data/.rubocop.yml +58 -0
- data/CODE_OF_CONDUCT.md +84 -0
- data/Gemfile +11 -1
- data/Gemfile.lock +89 -0
- data/LICENSE.txt +21 -0
- data/README.md +42 -18
- data/Rakefile +9 -3
- data/config/default.yml +151 -0
- data/data/reserved_words_mysql.txt +750 -0
- data/lib/rubocop/cop/migration/add_check_constraint.rb +111 -0
- data/lib/rubocop/cop/migration/add_column_with_default_value.rb +229 -0
- data/lib/rubocop/cop/migration/add_foreign_key.rb +166 -0
- data/lib/rubocop/cop/migration/add_index_columns_count.rb +114 -0
- data/lib/rubocop/cop/migration/add_index_concurrently.rb +164 -0
- data/lib/rubocop/cop/migration/add_index_duplicate.rb +183 -0
- data/lib/rubocop/cop/migration/batch_in_batches.rb +95 -0
- data/lib/rubocop/cop/migration/batch_in_transaction.rb +83 -0
- data/lib/rubocop/cop/migration/batch_with_throttling.rb +108 -0
- data/lib/rubocop/cop/migration/change_column.rb +113 -0
- data/lib/rubocop/cop/migration/change_column_null.rb +208 -0
- data/lib/rubocop/cop/migration/create_table_force.rb +89 -0
- data/lib/rubocop/cop/migration/jsonb.rb +131 -0
- data/lib/rubocop/cop/migration/remove_column.rb +246 -0
- data/lib/rubocop/cop/migration/rename_column.rb +81 -0
- data/lib/rubocop/cop/migration/rename_table.rb +79 -0
- data/lib/rubocop/cop/migration/reserved_word_mysql.rb +232 -0
- data/lib/rubocop/migration/config_loader.rb +51 -0
- data/lib/rubocop/migration/cop_concerns/batch_processing.rb +34 -0
- data/lib/rubocop/migration/cop_concerns/column_type_method.rb +28 -0
- data/lib/rubocop/migration/cop_concerns/disable_ddl_transaction.rb +51 -0
- data/lib/rubocop/migration/cop_concerns.rb +11 -0
- data/lib/rubocop/migration/rubocop_extension.rb +15 -0
- data/lib/rubocop/migration/version.rb +4 -2
- data/lib/rubocop/migration.rb +23 -0
- data/rubocop-migration.gemspec +25 -31
- metadata +49 -137
- data/.gitignore +0 -15
- data/bin/console +0 -14
- data/bin/setup +0 -8
- data/circle.yml +0 -6
- data/lib/rubocop/cop/migration/unsafe_migration.rb +0 -69
- data/lib/rubocop/migration/strong_migrations_checker.rb +0 -47
- data/lib/rubocop-migration.rb +0 -16
- data/vendor/.gitkeep +0 -0
@@ -0,0 +1,113 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RuboCop
|
4
|
+
module Cop
|
5
|
+
module Migration
|
6
|
+
# Avoid changing column type that is in use.
|
7
|
+
#
|
8
|
+
# Changing the type of a column causes the entire table to be rewritten.
|
9
|
+
# During this time, reads and writes are blocked in Postgres, and writes are blocked in MySQL and MariaDB.
|
10
|
+
#
|
11
|
+
# Some changes don’t require a table rewrite and are safe in PostgreSQL:
|
12
|
+
#
|
13
|
+
# Type | Safe Changes
|
14
|
+
# --- | ---
|
15
|
+
# `cidr` | Changing to `inet`
|
16
|
+
# `citext` | Changing to `text` if not indexed, changing to `string` with no `:limit` if not indexed
|
17
|
+
# `datetime` | Increasing or removing `:precision`, changing to `timestamptz` when session time zone is UTC in Postgres 12+
|
18
|
+
# `decimal` | Increasing `:precision` at same `:scale`, removing `:precision` and `:scale`
|
19
|
+
# `interval` | Increasing or removing `:precision`
|
20
|
+
# `numeric` | Increasing `:precision` at same `:scale`, removing `:precision` and `:scale`
|
21
|
+
# `string` | Increasing or removing `:limit`, changing to `text`, changing `citext` if not indexed
|
22
|
+
# `text` | Changing to `string` with no `:limit`, changing to `citext` if not indexed
|
23
|
+
# `time` | Increasing or removing `:precision`
|
24
|
+
# `timestamptz` | Increasing or removing `:limit`, changing to `datetime` when session time zone is UTC in Postgres 12+
|
25
|
+
#
|
26
|
+
# And some in MySQL and MariaDB:
|
27
|
+
#
|
28
|
+
# Type | Safe Changes
|
29
|
+
# --- | ---
|
30
|
+
# `string` | Increasing `:limit` from under 255 up to 255, increasing `:limit` from over 255 to the max
|
31
|
+
#
|
32
|
+
# A safer approach is to:
|
33
|
+
#
|
34
|
+
# 1. Create a new column
|
35
|
+
# 2. Write to both columns
|
36
|
+
# 3. Backfill data from the old column to the new column
|
37
|
+
# 4. Move reads from the old column to the new column
|
38
|
+
# 5. Stop writing to the old column
|
39
|
+
# 6. Drop the old column
|
40
|
+
#
|
41
|
+
# @safety
|
42
|
+
# Only meaningful if the table is in use and the type change is really unsafe as described above.
|
43
|
+
#
|
44
|
+
# @example
|
45
|
+
# # bad
|
46
|
+
# class ChangeUsersSomeColumnType < ActiveRecord::Migration[7.0]
|
47
|
+
# def change
|
48
|
+
# change_column :users, :some_column, :new_type
|
49
|
+
# end
|
50
|
+
# end
|
51
|
+
#
|
52
|
+
# # good
|
53
|
+
# class AddUsersAnotherColumn < ActiveRecord::Migration[7.0]
|
54
|
+
# def change
|
55
|
+
# add_column :users, :another_column, :new_type
|
56
|
+
# end
|
57
|
+
# end
|
58
|
+
#
|
59
|
+
# class RemoveUsersSomeColumn < ActiveRecord::Migration[7.0]
|
60
|
+
# def change
|
61
|
+
# remove_column :users, :some_column
|
62
|
+
# end
|
63
|
+
# end
|
64
|
+
class ChangeColumn < RuboCop::Cop::Base
|
65
|
+
MSG = 'Avoid changing column type that is in use.'
|
66
|
+
|
67
|
+
RESTRICT_ON_SEND = %i[
|
68
|
+
change
|
69
|
+
change_column
|
70
|
+
].freeze
|
71
|
+
|
72
|
+
# @param node [RuboCop::AST::SendNode]
|
73
|
+
# @return [void]
|
74
|
+
def on_send(node)
|
75
|
+
return unless bad?(node)
|
76
|
+
|
77
|
+
add_offense(node)
|
78
|
+
end
|
79
|
+
|
80
|
+
private
|
81
|
+
|
82
|
+
# @!method change?(node)
|
83
|
+
# @param node [RuboCop::AST::SendNode]
|
84
|
+
# @return [Boolean]
|
85
|
+
def_node_matcher :change?, <<~PATTERN
|
86
|
+
(send
|
87
|
+
lvar
|
88
|
+
:change
|
89
|
+
...
|
90
|
+
)
|
91
|
+
PATTERN
|
92
|
+
|
93
|
+
# @!method change_column?(node)
|
94
|
+
# @param node [RuboCop::AST::SendNode]
|
95
|
+
# @return [Boolean]
|
96
|
+
def_node_matcher :change_column?, <<~PATTERN
|
97
|
+
(send
|
98
|
+
nil?
|
99
|
+
:change_column
|
100
|
+
...
|
101
|
+
)
|
102
|
+
PATTERN
|
103
|
+
|
104
|
+
# @param node [RuboCop::AST::SendNode]
|
105
|
+
# @return [Boolean]
|
106
|
+
def bad?(node)
|
107
|
+
change?(node) ||
|
108
|
+
change_column?(node)
|
109
|
+
end
|
110
|
+
end
|
111
|
+
end
|
112
|
+
end
|
113
|
+
end
|
@@ -0,0 +1,208 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RuboCop
|
4
|
+
module Cop
|
5
|
+
module Migration
|
6
|
+
# Avoid simply setting `NOT NULL` constraint on an existing column in PostgreSQL.
|
7
|
+
#
|
8
|
+
# It blocks reads and writes while every row is checked.
|
9
|
+
# In PostgreSQL 12+, you can safely set `NOT NULL` constraint if corresponding check constraint exists.
|
10
|
+
#
|
11
|
+
# @safety
|
12
|
+
# Only meaningful in PostgreSQL 12+.
|
13
|
+
#
|
14
|
+
# @example
|
15
|
+
# # bad
|
16
|
+
# class SetNotNullColumnConstraintToUsersName < ActiveRecord::Migration[7.0]
|
17
|
+
# def change
|
18
|
+
# change_column_null :users, :name, false
|
19
|
+
# end
|
20
|
+
# end
|
21
|
+
#
|
22
|
+
# # good
|
23
|
+
# class SetNotNullCheckConstraintToUsersName < ActiveRecord::Migration[7.0]
|
24
|
+
# def change
|
25
|
+
# add_check_constraint :users, 'name IS NOT NULL', name: 'users_name_is_not_null', validate: false
|
26
|
+
# end
|
27
|
+
# end
|
28
|
+
#
|
29
|
+
# class ReplaceNotNullConstraintOnUsersName < ActiveRecord::Migration[7.0]
|
30
|
+
# def change
|
31
|
+
# validate_constraint :users, name: 'users_name_is_not_null'
|
32
|
+
# change_column_null :users, :name, false
|
33
|
+
# remove_check_constraint :users, name: 'users_name_is_not_null'
|
34
|
+
# end
|
35
|
+
# end
|
36
|
+
class ChangeColumnNull < RuboCop::Cop::Base
|
37
|
+
extend AutoCorrector
|
38
|
+
|
39
|
+
MSG = 'Avoid simply setting `NOT NULL` constraint on an existing column in PostgreSQL.'
|
40
|
+
|
41
|
+
RESTRICT_ON_SEND = %i[
|
42
|
+
change_column_null
|
43
|
+
change_null
|
44
|
+
].freeze
|
45
|
+
|
46
|
+
# @param node [RuboCop::AST::SendNode]
|
47
|
+
# @return [void]
|
48
|
+
def on_send(node)
|
49
|
+
return if called_with_validate_constraint?(node)
|
50
|
+
|
51
|
+
add_offense(node) do |corrector|
|
52
|
+
autocorrect(corrector, node)
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
private
|
57
|
+
|
58
|
+
# @!method validate_constraint?(node)
|
59
|
+
# @param node [RuboCop::AST::SendNode]
|
60
|
+
# @return [Boolean]
|
61
|
+
def_node_matcher :validate_constraint?, <<~PATTERN
|
62
|
+
(send nil? :validate_constraint ...)
|
63
|
+
PATTERN
|
64
|
+
|
65
|
+
# @param corrector [RuboCop::Cop::Corrector]
|
66
|
+
# @param node [RuboCop::AST::SendNode]
|
67
|
+
# @return [void]
|
68
|
+
def autocorrect(
|
69
|
+
corrector,
|
70
|
+
node
|
71
|
+
)
|
72
|
+
case node.method_name
|
73
|
+
when :change_column_null
|
74
|
+
autocorrect_change_column_null(corrector, node)
|
75
|
+
when :change_null
|
76
|
+
autocorrect_change_null(corrector, node)
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
# @param corrector [RuboCop::Cop::Corrector]
|
81
|
+
# @param node [RuboCop::AST::SendNode]
|
82
|
+
# @return [void]
|
83
|
+
def autocorrect_change_column_null(
|
84
|
+
corrector,
|
85
|
+
node
|
86
|
+
)
|
87
|
+
corrector.replace(
|
88
|
+
node,
|
89
|
+
format_add_check_constraint(
|
90
|
+
column_name: find_column_name_from_change_column_null(node),
|
91
|
+
table_name: find_table_name_from_change_column_null(node)
|
92
|
+
)
|
93
|
+
)
|
94
|
+
end
|
95
|
+
|
96
|
+
# @param corrector [RuboCop::Cop::Corrector]
|
97
|
+
# @param node [RuboCop::AST::SendNode]
|
98
|
+
# @return [void]
|
99
|
+
def autocorrect_change_null(
|
100
|
+
corrector,
|
101
|
+
node
|
102
|
+
)
|
103
|
+
corrector.replace(
|
104
|
+
node.location.selector.with(
|
105
|
+
end_pos: node.location.expression.end_pos
|
106
|
+
),
|
107
|
+
format_check_constraint(
|
108
|
+
column_name: find_column_name_from_change_null(node),
|
109
|
+
table_name: find_table_name_from_change_null(node)
|
110
|
+
)
|
111
|
+
)
|
112
|
+
end
|
113
|
+
|
114
|
+
# @param node [RuboCop::AST::SendNode]
|
115
|
+
# @return [Boolean]
|
116
|
+
def called_with_validate_constraint?(node)
|
117
|
+
case node.method_name
|
118
|
+
when :change_column_null
|
119
|
+
node
|
120
|
+
when :change_null
|
121
|
+
find_ancestor_change_table(node)
|
122
|
+
end.left_siblings.any? do |sibling|
|
123
|
+
validate_constraint?(sibling)
|
124
|
+
end
|
125
|
+
end
|
126
|
+
|
127
|
+
# @param node [RuboCop::AST::SendNode]
|
128
|
+
# @return [RuboCop::AST::BlockNode]
|
129
|
+
def find_ancestor_change_table(node)
|
130
|
+
node.each_ancestor(:block).find do |ancestor|
|
131
|
+
ancestor.method?(:change_table)
|
132
|
+
end
|
133
|
+
end
|
134
|
+
|
135
|
+
# @param node [RuboCop::AST::SendNode]
|
136
|
+
# @return [String]
|
137
|
+
def find_column_name_from_change_column_null(node)
|
138
|
+
node.arguments[1].value.to_s
|
139
|
+
end
|
140
|
+
|
141
|
+
# @param node [RuboCop::AST::SendNode]
|
142
|
+
# @return [String]
|
143
|
+
def find_column_name_from_change_null(node)
|
144
|
+
node.arguments[0].value.to_s
|
145
|
+
end
|
146
|
+
|
147
|
+
# @parm node [RuboCop::AST::SendNode]
|
148
|
+
# @return [String]
|
149
|
+
def find_table_name_from_change_column_null(node)
|
150
|
+
node.arguments[0].value.to_s
|
151
|
+
end
|
152
|
+
|
153
|
+
# @param node [RuboCop::AST::SendNode]
|
154
|
+
# @return [String]
|
155
|
+
def find_table_name_from_change_null(node)
|
156
|
+
find_ancestor_change_table(node).send_node.arguments[0].value.to_s
|
157
|
+
end
|
158
|
+
|
159
|
+
# @param column_name [String]
|
160
|
+
# @param table_name [String]
|
161
|
+
# @return [String]
|
162
|
+
def format_add_check_constraint(
|
163
|
+
column_name:,
|
164
|
+
table_name:
|
165
|
+
)
|
166
|
+
format(
|
167
|
+
'add_check_constraint :%<table_name>s, %<arguments>s',
|
168
|
+
arguments: format_check_constraint_arguments(
|
169
|
+
column_name: column_name,
|
170
|
+
table_name: table_name
|
171
|
+
),
|
172
|
+
table_name: table_name
|
173
|
+
)
|
174
|
+
end
|
175
|
+
|
176
|
+
# @param column_name [String]
|
177
|
+
# @param table_name [String]
|
178
|
+
# @return [String]
|
179
|
+
def format_check_constraint(
|
180
|
+
column_name:,
|
181
|
+
table_name:
|
182
|
+
)
|
183
|
+
format(
|
184
|
+
'check_constraint %<arguments>s',
|
185
|
+
arguments: format_check_constraint_arguments(
|
186
|
+
column_name: column_name,
|
187
|
+
table_name: table_name
|
188
|
+
)
|
189
|
+
)
|
190
|
+
end
|
191
|
+
|
192
|
+
# @param coumn_name [String]
|
193
|
+
# @param table_name [String]
|
194
|
+
# @return [String]
|
195
|
+
def format_check_constraint_arguments(
|
196
|
+
column_name:,
|
197
|
+
table_name:
|
198
|
+
)
|
199
|
+
format(
|
200
|
+
"'%<column_name>s IS NOT NULL', name: '%<constraint_name>s', validate: false",
|
201
|
+
column_name: column_name,
|
202
|
+
constraint_name: "#{table_name}_#{column_name}_is_not_null"
|
203
|
+
)
|
204
|
+
end
|
205
|
+
end
|
206
|
+
end
|
207
|
+
end
|
208
|
+
end
|
@@ -0,0 +1,89 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RuboCop
|
4
|
+
module Cop
|
5
|
+
module Migration
|
6
|
+
# Create tables without `force: true` option.
|
7
|
+
#
|
8
|
+
# The `force: true` option can drop an existing table.
|
9
|
+
# If you indend to drop an existing table, explicitly call `drop_table` first.
|
10
|
+
#
|
11
|
+
# @example
|
12
|
+
# # bad
|
13
|
+
# class CreateUsers < ActiveRecord::Migration[7.0]
|
14
|
+
# def change
|
15
|
+
# create_table :users, force: true
|
16
|
+
# end
|
17
|
+
# end
|
18
|
+
#
|
19
|
+
# # good
|
20
|
+
# class CreateUsers < ActiveRecord::Migration[7.0]
|
21
|
+
# def change
|
22
|
+
# create_table :users
|
23
|
+
# end
|
24
|
+
# end
|
25
|
+
class CreateTableForce < RuboCop::Cop::Base
|
26
|
+
extend AutoCorrector
|
27
|
+
|
28
|
+
include RangeHelp
|
29
|
+
|
30
|
+
MSG = 'Create tables without `force: true` option.'
|
31
|
+
|
32
|
+
RESTRICT_ON_SEND = %i[
|
33
|
+
create_table
|
34
|
+
].freeze
|
35
|
+
|
36
|
+
# @param node [RuboCop::AST::SendNode]
|
37
|
+
# @return [void]
|
38
|
+
def on_send(node)
|
39
|
+
option_node = option_force_true_from_create_table(node)
|
40
|
+
return unless option_node
|
41
|
+
|
42
|
+
add_offense(option_node) do |corrector|
|
43
|
+
autocorrect(corrector, option_node)
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
private
|
48
|
+
|
49
|
+
# @!method option_force_true_from_create_table(node)
|
50
|
+
# @param node [RuboCop::AST::SendNode]
|
51
|
+
# @return [RuboCop::AST::PairNode, nil]
|
52
|
+
def_node_matcher :option_force_true_from_create_table, <<~PATTERN
|
53
|
+
(send
|
54
|
+
nil?
|
55
|
+
:create_table
|
56
|
+
_
|
57
|
+
(hash
|
58
|
+
<
|
59
|
+
$(pair
|
60
|
+
(sym :force)
|
61
|
+
true
|
62
|
+
)
|
63
|
+
...
|
64
|
+
>
|
65
|
+
)
|
66
|
+
)
|
67
|
+
PATTERN
|
68
|
+
|
69
|
+
# @param corrector [RuboCop::Cop::Corrector]
|
70
|
+
# @param node [RuboCop::AST::PairNode]
|
71
|
+
# @return [void]
|
72
|
+
def autocorrect(
|
73
|
+
corrector,
|
74
|
+
node
|
75
|
+
)
|
76
|
+
corrector.remove(
|
77
|
+
range_with_surrounding_comma(
|
78
|
+
range_with_surrounding_space(
|
79
|
+
node.location.expression,
|
80
|
+
side: :left
|
81
|
+
),
|
82
|
+
:left
|
83
|
+
)
|
84
|
+
)
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|
89
|
+
end
|
@@ -0,0 +1,131 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RuboCop
|
4
|
+
module Cop
|
5
|
+
module Migration
|
6
|
+
# Prefer `jsonb` to `json`.
|
7
|
+
#
|
8
|
+
# In PostgreSQL, there is no equality operator for the json column type,
|
9
|
+
# which can cause errors for existing `SELECT DISTINCT` queries in your application.
|
10
|
+
#
|
11
|
+
# @safety
|
12
|
+
# Only meaningful in PostgreSQL.
|
13
|
+
#
|
14
|
+
# @example
|
15
|
+
# # bad
|
16
|
+
# add_column :users, :properties, :json
|
17
|
+
#
|
18
|
+
# # good
|
19
|
+
# add_column :users, :properties, :jsonb
|
20
|
+
class Jsonb < RuboCop::Cop::Base
|
21
|
+
extend AutoCorrector
|
22
|
+
|
23
|
+
MSG = 'Prefer `jsonb` to `json`.'
|
24
|
+
|
25
|
+
RESTRICT_ON_SEND = %i[
|
26
|
+
add_column
|
27
|
+
change
|
28
|
+
change_column
|
29
|
+
json
|
30
|
+
].freeze
|
31
|
+
|
32
|
+
# @param node [RuboCop::AST::SendNode]
|
33
|
+
# @return [void]
|
34
|
+
def on_send(node)
|
35
|
+
json_range = json_range_from_target_send_node(node)
|
36
|
+
return unless json_range
|
37
|
+
|
38
|
+
add_offense(json_range) do |corrector|
|
39
|
+
corrector.replace(json_range, 'jsonb')
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
private
|
44
|
+
|
45
|
+
# @!method json_type_node_from_add_column(node)
|
46
|
+
# @param node [RuboCop::AST::SendNode]
|
47
|
+
# @return [RuboCop::AST::SymNode, nil]
|
48
|
+
def_node_matcher :json_type_node_from_add_column, <<~PATTERN
|
49
|
+
(send
|
50
|
+
nil?
|
51
|
+
_
|
52
|
+
_
|
53
|
+
_
|
54
|
+
$(sym :json)
|
55
|
+
)
|
56
|
+
PATTERN
|
57
|
+
alias json_type_node_from_change_column json_type_node_from_add_column
|
58
|
+
|
59
|
+
# @!method json_type_node_from_change(node)
|
60
|
+
# @param node [RuboCop::AST::SendNode]
|
61
|
+
# @return [RuboCop::AST::SymNode, nil]
|
62
|
+
def_node_matcher :json_type_node_from_change, <<~PATTERN
|
63
|
+
(send
|
64
|
+
lvar
|
65
|
+
_
|
66
|
+
_
|
67
|
+
$(sym :json)
|
68
|
+
)
|
69
|
+
PATTERN
|
70
|
+
|
71
|
+
# @!method json_type_node_from_json(node)
|
72
|
+
# @param node [RuboCop::AST::SendNode]
|
73
|
+
# @return [RuboCop::AST::SendNode, nil]
|
74
|
+
def_node_matcher :json_type_node_from_json, <<~PATTERN
|
75
|
+
$(send
|
76
|
+
lvar
|
77
|
+
_
|
78
|
+
...
|
79
|
+
)
|
80
|
+
PATTERN
|
81
|
+
|
82
|
+
# @param corrector [RuboCop::Cop::Corrector]
|
83
|
+
# @param node [RuboCop::AST::SendNode, RuboCop::AST::SymNode]
|
84
|
+
# @return [void]
|
85
|
+
def autocorrect(
|
86
|
+
corrector,
|
87
|
+
node
|
88
|
+
)
|
89
|
+
corrector.replace(node, 'jsonb')
|
90
|
+
end
|
91
|
+
|
92
|
+
# @param node [RuboCop::AST::SendNode]
|
93
|
+
# @return [RuboCop::AST::SymNode, nil]
|
94
|
+
def json_node_from_target_send_node(node)
|
95
|
+
case node.method_name
|
96
|
+
when :add_column
|
97
|
+
json_type_node_from_add_column(node)
|
98
|
+
when :change
|
99
|
+
json_type_node_from_change(node)
|
100
|
+
when :change_column
|
101
|
+
json_type_node_from_change_column(node)
|
102
|
+
when :json
|
103
|
+
json_type_node_from_json(node)
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|
107
|
+
# @param node [RuboCop::AST::SendNode, RuboCop::AST::SymNode]
|
108
|
+
# @return [Parser::Source::Range]
|
109
|
+
def json_range_from_json_node(node)
|
110
|
+
case node.type
|
111
|
+
when :send
|
112
|
+
node.location.selector
|
113
|
+
when :sym
|
114
|
+
node.location.expression.with(
|
115
|
+
begin_pos: node.location.expression.begin_pos + 1
|
116
|
+
)
|
117
|
+
end
|
118
|
+
end
|
119
|
+
|
120
|
+
# @param node [RuboCop::AST::SendNode]
|
121
|
+
# @return [Parser::Source::Range]
|
122
|
+
def json_range_from_target_send_node(node)
|
123
|
+
json_node = json_node_from_target_send_node(node)
|
124
|
+
return unless json_node
|
125
|
+
|
126
|
+
json_range_from_json_node(json_node)
|
127
|
+
end
|
128
|
+
end
|
129
|
+
end
|
130
|
+
end
|
131
|
+
end
|