| 
									
										
										
										
											2024-08-12 10:30:59 +01:00
										 |  |  | # typed: true # rubocop:todo Sorbet/StrictSigil | 
					
						
							| 
									
										
										
										
											2024-01-26 13:52:46 -08:00
										 |  |  | # frozen_string_literal: true | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | module RuboCop | 
					
						
							|  |  |  |   module Cop | 
					
						
							|  |  |  |     module Homebrew | 
					
						
							|  |  |  |       # Enforces the use of `collection.exclude?(obj)` | 
					
						
							|  |  |  |       # over `!collection.include?(obj)`. | 
					
						
							|  |  |  |       # | 
					
						
							| 
									
										
										
										
											2024-04-26 20:55:51 +02:00
										 |  |  |       # NOTE: This cop is unsafe because false positives will occur for | 
					
						
							|  |  |  |       #       receiver objects that do not have an `#exclude?` method (e.g. `IPAddr`). | 
					
						
							| 
									
										
										
										
											2024-01-26 13:52:46 -08:00
										 |  |  |       # | 
					
						
							| 
									
										
										
										
											2024-04-26 20:55:51 +02:00
										 |  |  |       # ### Example | 
					
						
							| 
									
										
										
										
											2024-01-26 13:52:46 -08:00
										 |  |  |       # | 
					
						
							| 
									
										
										
										
											2024-04-26 20:55:51 +02:00
										 |  |  |       # ```ruby | 
					
						
							|  |  |  |       # # bad | 
					
						
							|  |  |  |       # !array.include?(2) | 
					
						
							|  |  |  |       # !hash.include?(:key) | 
					
						
							| 
									
										
										
										
											2024-01-26 13:52:46 -08:00
										 |  |  |       # | 
					
						
							| 
									
										
										
										
											2024-04-26 20:55:51 +02:00
										 |  |  |       # # good | 
					
						
							|  |  |  |       # array.exclude?(2) | 
					
						
							|  |  |  |       # hash.exclude?(:key) | 
					
						
							|  |  |  |       # ``` | 
					
						
							| 
									
										
										
										
											2024-01-26 13:52:46 -08:00
										 |  |  |       class NegateInclude < Base | 
					
						
							|  |  |  |         extend AutoCorrector | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         MSG = "Use `.exclude?` and remove the negation part." | 
					
						
							| 
									
										
										
										
											2024-04-26 20:55:51 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-01-26 13:52:46 -08:00
										 |  |  |         RESTRICT_ON_SEND = [:!].freeze | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         def_node_matcher :negate_include_call?, <<~PATTERN | 
					
						
							|  |  |  |           (send (send $!nil? :include? $_) :!) | 
					
						
							|  |  |  |         PATTERN | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         def on_send(node) | 
					
						
							|  |  |  |           return unless (receiver, obj = negate_include_call?(node)) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |           add_offense(node) do |corrector| | 
					
						
							|  |  |  |             corrector.replace(node, "#{receiver.source}.exclude?(#{obj.source})") | 
					
						
							|  |  |  |           end | 
					
						
							|  |  |  |         end | 
					
						
							|  |  |  |       end | 
					
						
							|  |  |  |     end | 
					
						
							|  |  |  |   end | 
					
						
							|  |  |  | end |