Skip to content

Commit c41dfe8

Browse files
committed
[fixes rubocop#22] Introduce List, a frozen Array/Set
1 parent f496d2b commit c41dfe8

8 files changed

+71
-42
lines changed

lib/rubocop/ast.rb

+1
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
require 'parser'
44
require 'forwardable'
55

6+
require_relative 'ast/list'
67
require_relative 'ast/node_pattern'
78
require_relative 'ast/sexp'
89
require_relative 'ast/node'

lib/rubocop/ast/list.rb

+28
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
# frozen_string_literal: true
2+
3+
module RuboCop
4+
module AST
5+
# A frozen Array/Set
6+
#
7+
class List < ::Array
8+
extend Forwardable
9+
attr_reader :to_set
10+
11+
def initialize(*)
12+
super
13+
freeze
14+
end
15+
16+
def freeze
17+
@to_set = Set.new(self).freeze
18+
super
19+
end
20+
21+
def_delegators :@to_set, :include?, :===
22+
end
23+
end
24+
end
25+
26+
def List(list)
27+
RuboCop::AST::List.new(list)
28+
end

lib/rubocop/ast/node.rb

+26-26
Original file line numberDiff line numberDiff line change
@@ -23,37 +23,37 @@ class Node < Parser::AST::Node # rubocop:disable Metrics/ClassLength
2323
extend NodePattern::Macros
2424

2525
# <=> isn't included here, because it doesn't return a boolean.
26-
COMPARISON_OPERATORS = %i[== === != <= >= > <].freeze
26+
COMPARISON_OPERATORS = List %i[== === != <= >= > <]
2727

28-
TRUTHY_LITERALS = %i[str dstr xstr int float sym dsym array
28+
TRUTHY_LITERALS = List %i[str dstr xstr int float sym dsym array
2929
hash regexp true irange erange complex
30-
rational regopt].freeze
31-
FALSEY_LITERALS = %i[false nil].freeze
32-
LITERALS = (TRUTHY_LITERALS + FALSEY_LITERALS).freeze
33-
COMPOSITE_LITERALS = %i[dstr xstr dsym array hash irange
34-
erange regexp].freeze
35-
BASIC_LITERALS = (LITERALS - COMPOSITE_LITERALS).freeze
36-
MUTABLE_LITERALS = %i[str dstr xstr array hash
37-
regexp irange erange].freeze
38-
IMMUTABLE_LITERALS = (LITERALS - MUTABLE_LITERALS).freeze
39-
40-
EQUALS_ASSIGNMENTS = %i[lvasgn ivasgn cvasgn gvasgn
41-
casgn masgn].freeze
42-
SHORTHAND_ASSIGNMENTS = %i[op_asgn or_asgn and_asgn].freeze
43-
ASSIGNMENTS = (EQUALS_ASSIGNMENTS + SHORTHAND_ASSIGNMENTS).freeze
44-
45-
BASIC_CONDITIONALS = %i[if while until].freeze
46-
CONDITIONALS = [*BASIC_CONDITIONALS, :case].freeze
47-
VARIABLES = %i[ivar gvar cvar lvar].freeze
48-
REFERENCES = %i[nth_ref back_ref].freeze
49-
KEYWORDS = %i[alias and break case class def defs defined?
30+
rational regopt]
31+
FALSEY_LITERALS = List %i[false nil]
32+
LITERALS = List(TRUTHY_LITERALS + FALSEY_LITERALS)
33+
COMPOSITE_LITERALS = List %i[dstr xstr dsym array hash irange
34+
erange regexp]
35+
BASIC_LITERALS = List(LITERALS - COMPOSITE_LITERALS)
36+
MUTABLE_LITERALS = List %i[str dstr xstr array hash
37+
regexp irange erange]
38+
IMMUTABLE_LITERALS = List (LITERALS - MUTABLE_LITERALS)
39+
40+
EQUALS_ASSIGNMENTS = List %i[lvasgn ivasgn cvasgn gvasgn
41+
casgn masgn]
42+
SHORTHAND_ASSIGNMENTS = List %i[op_asgn or_asgn and_asgn]
43+
ASSIGNMENTS = List(EQUALS_ASSIGNMENTS + SHORTHAND_ASSIGNMENTS)
44+
45+
BASIC_CONDITIONALS = List %i[if while until]
46+
CONDITIONALS = List[*BASIC_CONDITIONALS, :case]
47+
VARIABLES = List %i[ivar gvar cvar lvar]
48+
REFERENCES = List %i[nth_ref back_ref]
49+
KEYWORDS = List %i[alias and break case class def defs defined?
5050
kwbegin do else ensure for if module next
5151
not or postexe redo rescue retry return self
5252
super zsuper then undef until when while
53-
yield].freeze
54-
OPERATOR_KEYWORDS = %i[and or].freeze
55-
SPECIAL_KEYWORDS = %w[__FILE__ __LINE__ __ENCODING__].freeze
56-
ARGUMENT_TYPES = %i[arg optarg restarg kwarg kwoptarg kwrestarg blockarg].freeze
53+
yield]
54+
OPERATOR_KEYWORDS = List %i[and or]
55+
SPECIAL_KEYWORDS = List %w[__FILE__ __LINE__ __ENCODING__]
56+
ARGUMENT_TYPES = List %i[arg optarg restarg kwarg kwoptarg kwrestarg blockarg]
5757

5858
# @see https://www.rubydoc.info/gems/ast/AST/Node:initialize
5959
def initialize(type, children = [], properties = {})

lib/rubocop/ast/node/block_node.rb

+1-1
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ module AST
1111
class BlockNode < Node
1212
include MethodIdentifierPredicates
1313

14-
VOID_CONTEXT_METHODS = %i[each tap].freeze
14+
VOID_CONTEXT_METHODS = List %i[each tap]
1515

1616
# The `send` node associated with this block.
1717
#

lib/rubocop/ast/node/mixin/collection_node.rb

+1-1
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ module CollectionNode
77
extend Forwardable
88

99
ARRAY_METHODS =
10-
(Array.instance_methods - Object.instance_methods - [:to_a]).freeze
10+
List(Array.instance_methods - Object.instance_methods - [:to_a])
1111

1212
def_delegators :to_a, *ARRAY_METHODS
1313
end

lib/rubocop/ast/node/mixin/method_dispatch_node.rb

+2-2
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,8 @@ module MethodDispatchNode
88
extend NodePattern::Macros
99
include MethodIdentifierPredicates
1010

11-
ARITHMETIC_OPERATORS = %i[+ - * / % **].freeze
12-
SPECIAL_MODIFIERS = %w[private protected].freeze
11+
ARITHMETIC_OPERATORS = List %i[+ - * / % **]
12+
SPECIAL_MODIFIERS = List %w[private protected]
1313

1414
# The receiving node of the method dispatch.
1515
#

lib/rubocop/ast/node/mixin/method_identifier_predicates.rb

+4-4
Original file line numberDiff line numberDiff line change
@@ -7,14 +7,14 @@ module AST
77
#
88
# @note this mixin expects `#method_name` and `#receiver` to be implemented
99
module MethodIdentifierPredicates
10-
ENUMERATOR_METHODS = %i[collect collect_concat detect downto each
10+
ENUMERATOR_METHODS = List %i[collect collect_concat detect downto each
1111
find find_all find_index inject loop map!
1212
map reduce reject reject! reverse_each select
13-
select! times upto].freeze
13+
select! times upto]
1414

1515
# http://phrogz.net/programmingruby/language.html#table_18.4
16-
OPERATOR_METHODS = %i[| ^ & <=> == === =~ > >= < <= << >> + - * /
17-
% ** ~ +@ -@ !@ ~@ [] []= ! != !~ `].freeze
16+
OPERATOR_METHODS = List %i[| ^ & <=> == === =~ > >= < <= << >> + - * /
17+
% ** ~ +@ -@ !@ ~@ [] []= ! != !~ `]
1818

1919
# Checks whether the method name matches the argument.
2020
#

lib/rubocop/ast/traversal.rb

+8-8
Original file line numberDiff line numberDiff line change
@@ -15,27 +15,27 @@ def walk(node)
1515
nil
1616
end
1717

18-
NO_CHILD_NODES = %i[true false nil int float complex
18+
NO_CHILD_NODES = List %i[true false nil int float complex
1919
rational str sym regopt self lvar
2020
ivar cvar gvar nth_ref back_ref cbase
2121
arg restarg blockarg shadowarg
2222
kwrestarg zsuper lambda redo retry
2323
forward_args forwarded_args
24-
match_var match_nil_pattern empty_else].freeze
25-
ONE_CHILD_NODE = %i[splat kwsplat block_pass not break next
24+
match_var match_nil_pattern empty_else]
25+
ONE_CHILD_NODE = List %i[splat kwsplat block_pass not break next
2626
preexe postexe match_current_line defined?
2727
arg_expr pin match_rest if_guard unless_guard
28-
match_with_trailing_comma].freeze
29-
MANY_CHILD_NODES = %i[dstr dsym xstr regexp array hash pair
28+
match_with_trailing_comma]
29+
MANY_CHILD_NODES = List %i[dstr dsym xstr regexp array hash pair
3030
mlhs masgn or_asgn and_asgn
3131
undef alias args super yield or and
3232
while_post until_post iflipflop eflipflop
3333
match_with_lvasgn begin kwbegin return
3434
in_match match_alt
3535
match_as array_pattern array_pattern_with_tail
36-
hash_pattern const_pattern].freeze
37-
SECOND_CHILD_ONLY = %i[lvasgn ivasgn cvasgn gvasgn optarg kwarg
38-
kwoptarg].freeze
36+
hash_pattern const_pattern]
37+
SECOND_CHILD_ONLY = List %i[lvasgn ivasgn cvasgn gvasgn optarg kwarg
38+
kwoptarg]
3939

4040
NO_CHILD_NODES.each do |type|
4141
module_eval("def on_#{type}(node); end", __FILE__, __LINE__)

0 commit comments

Comments
 (0)