Class: RuboCop::Cop::GraphQL::Overfetch
- Inherits:
-
RuboCop::Cop
- Object
- RuboCop::Cop
- RuboCop::Cop::GraphQL::Overfetch
- Includes:
- RangeHelp
- Defined in:
- lib/rubocop/cop/graphql/overfetch.rb
Overview
Public: Rubocop for catching overfetched fields in ERB templates.
Defined Under Namespace
Classes: OverfetchVisitor
Instance Method Summary collapse
Instance Method Details
#investigate(processed_source) ⇒ Object
19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 |
# File 'lib/rubocop/cop/graphql/overfetch.rb', line 19 def investigate(processed_source) erb = File.read(processed_source.buffer.name) query, = ::GraphQL::Client::ViewModule.extract_graphql_section(erb) return unless query # TODO: Use GraphQL client parser document = ::GraphQL.parse(query.gsub(/::/, "__")) visitor = OverfetchVisitor.new(document) do |line_num| # `source_range` is private to this object, # so yield back out to it to get this info: source_range(processed_source.buffer, line_num, 0) end visitor.visit send_methods(processed_source.ast).each do |node| method_names = method_names_for(*node) method_names.each do |method_name| visitor.aliases.fetch(method_name, []).each do |field_name| visitor.fields[field_name] += 1 end end end visitor.fields.each do |field, count| next if count > 0 add_offense(nil, location: visitor.ranges[field], message: "GraphQL field '#{field}' query but was not used in template.") end end |
#method_names_for(*node) ⇒ Object
84 85 86 87 88 89 90 91 92 93 94 |
# File 'lib/rubocop/cop/graphql/overfetch.rb', line 84 def method_names_for(*node) receiver, method_name, *_args = node method_names = [] method_names << method_name if method_name # add field accesses like `nodes.map(&:field)` method_names.concat(receiver.children) if receiver && receiver.sym_type? method_names.map!(&:to_s) end |