diff options
Diffstat (limited to 'rubocop/cop/gitlab/json.rb')
-rw-r--r-- | rubocop/cop/gitlab/json.rb | 33 |
1 files changed, 26 insertions, 7 deletions
diff --git a/rubocop/cop/gitlab/json.rb b/rubocop/cop/gitlab/json.rb index 56846e3c276..cf2ed0ba536 100644 --- a/rubocop/cop/gitlab/json.rb +++ b/rubocop/cop/gitlab/json.rb @@ -7,25 +7,44 @@ module RuboCop extend RuboCop::Cop::AutoCorrector MSG = <<~EOL - Avoid calling `JSON` directly. Instead, use the `Gitlab::Json` - wrapper. This allows us to alter the JSON parser being used. + Prefer `Gitlab::Json` over calling `JSON` directly. See https://docs.gitlab.com/ee/development/json.html EOL + AVAILABLE_METHODS = %i[parse parse! load decode dump generate encode pretty_generate].to_set.freeze + def_node_matcher :json_node?, <<~PATTERN - (send (const {nil? | (const nil? :ActiveSupport)} :JSON)...) + (send (const {nil? | (const nil? :ActiveSupport)} :JSON) $_ $...) PATTERN def on_send(node) - return unless json_node?(node) + method_name, arg_source = match_node(node) + return unless method_name add_offense(node) do |corrector| - _, method_name, *arg_nodes = *node - - replacement = "Gitlab::Json.#{method_name}(#{arg_nodes.map(&:source).join(', ')})" + replacement = "#{cbased(node)}Gitlab::Json.#{method_name}(#{arg_source})" corrector.replace(node.source_range, replacement) end end + + private + + def match_node(node) + method_name, arg_nodes = json_node?(node) + + # Only match if the method is implemented by Gitlab::Json + if method_name && AVAILABLE_METHODS.include?(method_name) + return [method_name, arg_nodes.map(&:source).join(", ")] + end + + nil + end + + def cbased(node) + return unless %r{/ee/}.match?(node.location.expression.source_buffer.name) + + "::" + end end end end |