class GraphQL::Member

Constants

DEFAULT_CLEAN_UP_TRANSFORMS
DEFAULT_FIELD_TRANSFORMS
DEFAULT_TYPE_TRANSFORMS

Public Class Methods

new(member, skip: SkipOnNullKeyword, type_transforms: DEFAULT_TYPE_TRANSFORMS, field_transforms: DEFAULT_FIELD_TRANSFORMS, clean_up_transforms: DEFAULT_CLEAN_UP_TRANSFORMS) click to toggle source
# File lib/graphql/upgrader/member.rb, line 730
def initialize(member, skip: SkipOnNullKeyword, type_transforms: DEFAULT_TYPE_TRANSFORMS, field_transforms: DEFAULT_FIELD_TRANSFORMS, clean_up_transforms: DEFAULT_CLEAN_UP_TRANSFORMS)
  @member = member
  @skip = skip
  @type_transforms = type_transforms
  @field_transforms = field_transforms
  @clean_up_transforms = clean_up_transforms
end

Public Instance Methods

upgrade() click to toggle source
# File lib/graphql/upgrader/member.rb, line 772
def upgrade
  type_source = @member.dup
  should_skip = @skip.new.skip?(type_source)
  # return the unmodified code
  if should_skip
    return type_source
  end
  # Transforms on type defn code:
  type_source = apply_transforms(type_source, @type_transforms)
  # Transforms on each field:
  field_sources = find_fields(type_source)
  field_sources.each do |field_source|
    transformed_field_source = apply_transforms(field_source.dup, @field_transforms)
    # Replace the original source code with the transformed source code:
    type_source = type_source.gsub(field_source, transformed_field_source)
  end
  # Clean-up:
  type_source = apply_transforms(type_source, @clean_up_transforms)
  # Return the transformed source:
  type_source
end
upgradeable?() click to toggle source
# File lib/graphql/upgrader/member.rb, line 794
def upgradeable?
  return false if @member.include? '< GraphQL::Schema::'
  return false if @member =~ /< Types::Base#{GRAPHQL_TYPES}/

  true
end

Private Instance Methods

apply_transforms(source_code, transforms, idx: 0) click to toggle source
# File lib/graphql/upgrader/member.rb, line 803
def apply_transforms(source_code, transforms, idx: 0)
  next_transform = transforms[idx]
  case next_transform
  when nil
    # We got to the end of the list
    source_code
  when Class
    # Apply a class
    next_source_code = next_transform.new.apply(source_code)
    apply_transforms(next_source_code, transforms, idx: idx + 1)
  else
    # Apply an already-initialized object which responds to `apply`
    next_source_code = next_transform.apply(source_code)
    apply_transforms(next_source_code, transforms, idx: idx + 1)
  end
end
find_fields(type_source) click to toggle source

Parse the type, find calls to `field` and `connection` Return strings containing those calls

# File lib/graphql/upgrader/member.rb, line 822
def find_fields(type_source)
  type_ast = Parser::CurrentRuby.parse(type_source)
  finder = FieldFinder.new
  finder.process(type_ast)
  field_sources = []
  # For each of the locations we found, extract the text for that definition.
  # The text will be transformed independently,
  # then the transformed text will replace the original text.
  FieldFinder::DEFINITION_METHODS.each do |def_method|
    finder.locations[def_method].each do |name, (starting_idx, ending_idx)|
      field_source = type_source[starting_idx..ending_idx]
      field_sources << field_source
    end
  end
  # Here's a crazy thing: the transformation is pure,
  # so definitions like `argument :id, types.ID` can be transformed once
  # then replaced everywhere. So:
  # - make a unique array here
  # - use `gsub` after performing the transformation.
  field_sources.uniq!
  field_sources
rescue Parser::SyntaxError
  puts "Error Source:"
  puts type_source
  raise
end