Class: Deprecool::Finder

Inherits:
Object
  • Object
show all
Includes:
PrismHelpers
Defined in:
lib/deprecool/finder.rb

Overview

Base class for every deprecation finder.

A finder is responsible for detecting a single deprecation. Subclasses of Finder describe the deprecation with the class-level DSL and then implement one or more Prism visit hooks (e.g. on_call_node).

A Scanner then follows the AST a single time and dispatches each node to the finders that have a relevant method, which call add_offense when a match is found.

Example child class

class MyFinder < Deprecool::Finder
gem           :ruby
deprecated_in '4.0.0'
removed_in    '4.1.0'
title         'some_method will be removed'
summary       'some_method was causing a problem and will be removed soon'
suggestion    'remove some_method'
reference     'https://link_to_pr_or_relevant_info'
effort        :medium

def on_call_node(node)
  add_offense(node, confidence: :high) if node.name == :some_method
end
end

Defined Under Namespace

Classes: Offense

Class Attribute Summary collapse

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Methods included from PrismHelpers

#unwrap_arguments, #unwrap_array, #unwrap_children, #unwrap_class, #unwrap_parentheses

Constructor Details

#initialize(file_path, source, offenses) ⇒ Finder

Returns a new instance of Finder.



114
115
116
117
118
# File 'lib/deprecool/finder.rb', line 114

def initialize(file_path, source, offenses)
  @file_path = file_path
  @source    = source # the AST from Prism.parse
  @offenses  = offenses
end

Class Attribute Details

.registryObject (readonly)

All finder subclasses, in definition order.



38
39
40
# File 'lib/deprecool/finder.rb', line 38

def registry
  @registry
end

Instance Attribute Details

#file_pathObject (readonly)

Returns the value of attribute file_path.



112
113
114
# File 'lib/deprecool/finder.rb', line 112

def file_path
  @file_path
end

#sourceObject (readonly)

Returns the value of attribute source.



112
113
114
# File 'lib/deprecool/finder.rb', line 112

def source
  @source
end

Class Method Details

.affected_version_rangeObject



79
80
81
# File 'lib/deprecool/finder.rb', line 79

def affected_version_range
  [deprecated_in, removed_in]
end

.classnameObject

return just the class name without all the modules, for displaying



84
85
86
# File 'lib/deprecool/finder.rb', line 84

def classname
  name.split('::').last
end

.effort(value = (getter = true)) ⇒ Object

how much work is this to fix? low => Rails::v7_1_0::SerializerPositionalClassArgument just changes a method signature to have kwarg medium => Ruby::v4_0_0::ObjectSpaceId2ref to keep same functionality you need to remove the method and minor refactor to use WeakMap or something high => you're gonna need to make some changes to preserve the same functionality



69
70
71
72
73
74
75
76
77
# File 'lib/deprecool/finder.rb', line 69

def effort(value = (getter = true))
  return @effort if getter

  values = %i[low medium high]

  raise "Please use a standardized effort value, i.e #{values}" unless values.include?(value)

  @effort = value
end

.hook_methodsObject

This is what the Scanner class calls to see what methods are defined on the child classes,

child classes should define the methods with 'on' in place of 'visit' so that we can differentiate them from the default implementation provided by Prism::Visitor

(see https://docs.ruby-lang.org/en/master/Prism/Visitor.html for the full list of Prism compatible methods) some examples of prism compatible 'on_node' methods for a finder: Prism::VisitClassNode => on_class_node Prism::VisitDefNode => on_def_node Prism::VisitModuleNode => on_module_node



107
108
109
# File 'lib/deprecool/finder.rb', line 107

def hook_methods
  instance_methods(false).grep(/\Aon_\w+_node\z/)
end

.idObject

this is used internally to sort Finders so we might as well not sort the part thats repeated for every finder



90
91
92
# File 'lib/deprecool/finder.rb', line 90

def id
  name.delete_prefix('Deprecool::Finders::')
end

.inherited(subclass) ⇒ Object



40
41
42
43
# File 'lib/deprecool/finder.rb', line 40

def inherited(subclass)
  Finder.registry << subclass
  super
end