123456789_123456789_123456789_123456789_123456789_

Class: RBS::Diff

Relationships & Source Files
Inherits: Object
Defined in: lib/rbs/diff.rb

Class Method Summary

Instance Method Summary

Constructor Details

.new(type_name:, library_options:, after_path: [], before_path: [], detail: false) ⇒ Diff

[ GitHub ]

  
# File 'lib/rbs/diff.rb', line 5

def initialize(type_name:, library_options:, after_path: [], before_path: [], detail: false)
  @type_name = type_name
  @library_options = library_options
  @after_path = after_path
  @before_path = before_path
  @detail = detail
end

Instance Method Details

#build_builder(env) (private)

[ GitHub ]

  
# File 'lib/rbs/diff.rb', line 96

def build_builder(env)
  DefinitionBuilder.new(env: env.resolve_type_names)
end

#build_env(path) (private)

[ GitHub ]

  
# File 'lib/rbs/diff.rb', line 77

def build_env(path)
  loader = @library_options.loader()
  path&.each do |dir|
    dir_pathname = Pathname(dir)
    loader.add(path: dir_pathname)

    manifest_pathname = dir_pathname / 'manifest.yaml'
    if manifest_pathname.exist?
      manifest = YAML.safe_load(manifest_pathname.read)
      if manifest['dependencies']
        manifest['dependencies'].each do |dependency|
          loader.add(library: dependency['name'], version: nil)
        end
      end
    end
  end
  Environment.from_loader(loader)
end

#build_methods(path) (private)

[ GitHub ]

  
# File 'lib/rbs/diff.rb', line 49

def build_methods(path)
  env = build_env(path)
  builder = build_builder(env)

  instance_methods = begin
    builder.build_instance(@type_name).methods
  rescue => e
    RBS.logger.warn("#{path}: (#{e.class}) #{e.message}")
    {} #: Hash[Symbol, Definition::Method]
  end
  singleton_methods = begin
    builder.build_singleton(@type_name).methods
  rescue => e
    RBS.logger.warn("#{path}: (#{e.class}) #{e.message}")
    {} #: Hash[Symbol, Definition::Method]
  end

  constant_children = begin
    constant_resolver = RBS::Resolver::ConstantResolver.new(builder: builder)
    constant_resolver.children(@type_name)
  rescue => e
    RBS.logger.warn("#{path}: (#{e.class}) #{e.message}")
    {} #: Hash[Symbol, Constant]
  end

  [ instance_methods, singleton_methods, constant_children ]
end

#constant_to_s(constant) (private)

[ GitHub ]

  
# File 'lib/rbs/diff.rb', line 116

def constant_to_s(constant)
  if constant
    detail_to_s = @detail ? "[#{constant.name.namespace.to_type_name.to_s}] " : ""
    "#{detail_to_s}#{constant.name.name}: #{constant.type}"
  else
    +"-"
  end
end

#definition_method_to_s(key, kind, definition_method) (private)

[ GitHub ]

  
# File 'lib/rbs/diff.rb', line 100

def definition_method_to_s(key, kind, definition_method)
  if definition_method
    prefix = kind == :instance ? "" : "self."

    detail_to_s = @detail ? "[#{definition_method.defined_in} #{definition_method.accessibility}] " : ""
    if definition_method.alias_of
      first_def = definition_method.alias_of.defs.first #: Definition::Method::TypeDef
      "#{detail_to_s}alias #{prefix}#{key} #{prefix}#{first_def.member.name}"
    else
      "#{detail_to_s}def #{prefix}#{key}: #{definition_method.method_types.join(" | ")}"
    end
  else
    +"-"
  end
end

#each_diff(&block)

[ GitHub ]

  
# File 'lib/rbs/diff.rb', line 13

def each_diff(&block)
  return to_enum(:each_diff) unless block

  before_instance_methods, before_singleton_methods, before_constant_children = build_methods(@before_path)
  after_instance_methods, after_singleton_methods, after_constant_children = build_methods(@after_path)

  each_diff_methods(:instance, before_instance_methods, after_instance_methods, &block)
  each_diff_methods(:singleton, before_singleton_methods, after_singleton_methods, &block)

  each_diff_constants(before_constant_children, after_constant_children, &block)
end

#each_diff_constants(before_constant_children, after_constant_children) (private)

[ GitHub ]

  
# File 'lib/rbs/diff.rb', line 38

def each_diff_constants(before_constant_children, after_constant_children)
  all_keys = before_constant_children.keys.to_set + after_constant_children.keys.to_set
  all_keys.each do |key|
    before = constant_to_s(before_constant_children[key]) or next
    after = constant_to_s(after_constant_children[key]) or next
    next if before == after

    yield before, after
  end
end

#each_diff_methods(kind, before_methods, after_methods) (private)

[ GitHub ]

  
# File 'lib/rbs/diff.rb', line 27

def each_diff_methods(kind, before_methods, after_methods)
  all_keys = before_methods.keys.to_set + after_methods.keys.to_set
  all_keys.each do |key|
    before = definition_method_to_s(key, kind, before_methods[key]) or next
    after = definition_method_to_s(key, kind, after_methods[key]) or next
    next if before == after

    yield before, after
  end
end