forked from rubocop/rubocop-ast
/
method_identifier_predicates.rb
114 lines (99 loc) · 3.71 KB
/
method_identifier_predicates.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
# frozen_string_literal: true
module RuboCop
module AST
# Common predicates for nodes that reference method identifiers:
# `send`, `csend`, `def`, `defs`, `super`, `zsuper`
#
# @note this mixin expects `#method_name` and `#receiver` to be implemented
module MethodIdentifierPredicates
ENUMERATOR_METHODS = %i[collect collect_concat detect downto each
find find_all find_index inject loop map!
map reduce reject reject! reverse_each select
select! times upto].to_set.freeze
# http://phrogz.net/programmingruby/language.html#table_18.4
OPERATOR_METHODS = %i[| ^ & <=> == === =~ > >= < <= << >> + - * /
% ** ~ +@ -@ !@ ~@ [] []= ! != !~ `].to_set.freeze
# Checks whether the method name matches the argument.
#
# @param [Symbol, String] name the method name to check for
# @return [Boolean] whether the method name matches the argument
def method?(name)
method_name == name.to_sym
end
# Checks whether the method is an operator method.
#
# @return [Boolean] whether the method is an operator
def operator_method?
OPERATOR_METHODS.include?(method_name)
end
# Checks whether the method is a comparison method.
#
# @return [Boolean] whether the method is a comparison
def comparison_method?
Node::COMPARISON_OPERATORS.include?(method_name)
end
# Checks whether the method is an assignment method.
#
# @return [Boolean] whether the method is an assignment
def assignment_method?
!comparison_method? && method_name.to_s.end_with?('=')
end
# Checks whether the method is an enumerator method.
#
# @return [Boolean] whether the method is an enumerator
def enumerator_method?
ENUMERATOR_METHODS.include?(method_name) ||
method_name.to_s.start_with?('each_')
end
# Checks whether the method is a predicate method.
#
# @return [Boolean] whether the method is a predicate method
def predicate_method?
method_name.to_s.end_with?('?')
end
# Checks whether the method is a bang method.
#
# @return [Boolean] whether the method is a bang method
def bang_method?
method_name.to_s.end_with?('!')
end
# Checks whether the method is a camel case method,
# e.g. `Integer()`.
#
# @return [Boolean] whether the method is a camel case method
def camel_case_method?
method_name.to_s =~ /\A[A-Z]/
end
# Checks whether the *explicit* receiver of this node is `self`.
#
# @return [Boolean] whether the receiver of this node is `self`
def self_receiver?
receiver&.self_type?
end
# Checks whether the *explicit* receiver of node is a `const` node.
#
# @return [Boolean] whether the receiver of this node is a `const` node
def const_receiver?
receiver&.const_type?
end
# Checks whether this is a negation method, i.e. `!` or keyword `not`.
#
# @return [Boolean] whether this method is a negation method
def negation_method?
receiver && method_name == :!
end
# Checks whether this is a prefix not method, e.g. `not foo`.
#
# @return [Boolean] whether this method is a prefix not
def prefix_not?
negation_method? && loc.selector.is?('not')
end
# Checks whether this is a prefix bang method, e.g. `!foo`.
#
# @return [Boolean] whether this method is a prefix bang
def prefix_bang?
negation_method? && loc.selector.is?('!')
end
end
end
end