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.



117
118
119
120
121
# File 'lib/deprecool/finder.rb', line 117

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

Class Attribute Details

.registryObject (readonly)

All finder subclasses, in definition order.



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

def registry
  @registry
end

Instance Attribute Details

#file_pathObject (readonly)

Returns the value of attribute file_path.



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

def file_path
  @file_path
end

#sourceObject (readonly)

Returns the value of attribute source.



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

def source
  @source
end

Class Method Details

.affected_version_rangeObject



81
82
83
# File 'lib/deprecool/finder.rb', line 81

def affected_version_range
  [deprecated_in, removed_in]
end

.classnameObject

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



86
87
88
# File 'lib/deprecool/finder.rb', line 86

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



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

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

Prism


110
111
112
# File 'lib/deprecool/finder.rb', line 110

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



92
93
94
# File 'lib/deprecool/finder.rb', line 92

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

.inherited(subclass) ⇒ Object



42
43
44
45
# File 'lib/deprecool/finder.rb', line 42

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