rubocop-ast 1.1.1 → 1.49.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +5 -5
- data/lib/rubocop/ast/builder.rb +104 -64
- data/lib/rubocop/ast/builder_prism.rb +11 -0
- data/lib/rubocop/ast/ext/range.rb +3 -3
- data/lib/rubocop/ast/node/and_asgn_node.rb +17 -0
- data/lib/rubocop/ast/node/arg_node.rb +34 -0
- data/lib/rubocop/ast/node/args_node.rb +10 -0
- data/lib/rubocop/ast/node/array_node.rb +10 -6
- data/lib/rubocop/ast/node/asgn_node.rb +26 -0
- data/lib/rubocop/ast/node/block_node.rb +50 -4
- data/lib/rubocop/ast/node/case_match_node.rb +17 -3
- data/lib/rubocop/ast/node/case_node.rb +1 -1
- data/lib/rubocop/ast/node/casgn_node.rb +23 -0
- data/lib/rubocop/ast/node/class_node.rb +2 -2
- data/lib/rubocop/ast/node/complex_node.rb +13 -0
- data/lib/rubocop/ast/node/const_node.rb +1 -56
- data/lib/rubocop/ast/node/csend_node.rb +14 -0
- data/lib/rubocop/ast/node/def_node.rb +1 -1
- data/lib/rubocop/ast/node/dstr_node.rb +16 -0
- data/lib/rubocop/ast/node/ensure_node.rb +36 -0
- data/lib/rubocop/ast/node/for_node.rb +1 -1
- data/lib/rubocop/ast/node/hash_node.rb +3 -3
- data/lib/rubocop/ast/node/if_node.rb +12 -5
- data/lib/rubocop/ast/node/in_pattern_node.rb +38 -0
- data/lib/rubocop/ast/node/keyword_begin_node.rb +44 -0
- data/lib/rubocop/ast/node/keyword_splat_node.rb +10 -3
- data/lib/rubocop/ast/node/masgn_node.rb +63 -0
- data/lib/rubocop/ast/node/mixin/basic_literal_node.rb +1 -1
- data/lib/rubocop/ast/node/mixin/collection_node.rb +1 -1
- data/lib/rubocop/ast/node/mixin/constant_node.rb +62 -0
- data/lib/rubocop/ast/node/mixin/descendence.rb +14 -13
- data/lib/rubocop/ast/node/mixin/hash_element_node.rb +2 -0
- data/lib/rubocop/ast/node/mixin/method_dispatch_node.rb +56 -24
- data/lib/rubocop/ast/node/mixin/numeric_node.rb +2 -2
- data/lib/rubocop/ast/node/mixin/parameterized_node.rb +12 -3
- data/lib/rubocop/ast/node/mixin/predicate_operator_node.rb +7 -2
- data/lib/rubocop/ast/node/mlhs_node.rb +29 -0
- data/lib/rubocop/ast/node/module_node.rb +2 -2
- data/lib/rubocop/ast/node/op_asgn_node.rb +38 -0
- data/lib/rubocop/ast/node/or_asgn_node.rb +17 -0
- data/lib/rubocop/ast/node/pair_node.rb +7 -0
- data/lib/rubocop/ast/node/procarg0_node.rb +17 -0
- data/lib/rubocop/ast/node/rational_node.rb +13 -0
- data/lib/rubocop/ast/node/regexp_node.rb +7 -1
- data/lib/rubocop/ast/node/self_class_node.rb +2 -2
- data/lib/rubocop/ast/node/send_node.rb +5 -0
- data/lib/rubocop/ast/node/str_node.rb +40 -0
- data/lib/rubocop/ast/node/until_node.rb +1 -1
- data/lib/rubocop/ast/node/var_node.rb +15 -0
- data/lib/rubocop/ast/node/when_node.rb +2 -2
- data/lib/rubocop/ast/node/while_node.rb +1 -1
- data/lib/rubocop/ast/node.rb +190 -60
- data/lib/rubocop/ast/node_pattern/compiler/atom_subcompiler.rb +1 -1
- data/lib/rubocop/ast/node_pattern/compiler/binding.rb +11 -5
- data/lib/rubocop/ast/node_pattern/compiler/debug.rb +4 -9
- data/lib/rubocop/ast/node_pattern/compiler/node_pattern_subcompiler.rb +1 -1
- data/lib/rubocop/ast/node_pattern/compiler/sequence_subcompiler.rb +22 -11
- data/lib/rubocop/ast/node_pattern/compiler.rb +3 -2
- data/lib/rubocop/ast/node_pattern/lexer.rb +1 -1
- data/lib/rubocop/ast/node_pattern/lexer.rex +6 -5
- data/lib/rubocop/ast/node_pattern/lexer.rex.rb +7 -7
- data/lib/rubocop/ast/node_pattern/method_definer.rb +2 -0
- data/lib/rubocop/ast/node_pattern/node.rb +22 -28
- data/lib/rubocop/ast/node_pattern/parser.racc.rb +42 -40
- data/lib/rubocop/ast/node_pattern/parser.rb +2 -2
- data/lib/rubocop/ast/node_pattern/with_meta.rb +3 -4
- data/lib/rubocop/ast/node_pattern.rb +25 -24
- data/lib/rubocop/ast/processed_source.rb +169 -48
- data/lib/rubocop/ast/sexp.rb +2 -1
- data/lib/rubocop/ast/token.rb +17 -2
- data/lib/rubocop/ast/traversal.rb +43 -31
- data/lib/rubocop/ast/utilities/simple_forwardable.rb +27 -0
- data/lib/rubocop/ast/version.rb +1 -1
- data/lib/rubocop/ast.rb +22 -3
- metadata +36 -26
- data/lib/rubocop/ast/ext/set.rb +0 -12
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: aad4bf15828f1db50f117c1a983e1f4c7f0cff233878a7f1a1686416ab21feff
|
|
4
|
+
data.tar.gz: 8ac8ad74b061c5fcd733e21420068edc69d0a9bfba532dc766e01dbb80be5c40
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 75f3882c819f2e10f7ef893481fbe9feddedfcdc91678c1c695d6ef36d94798dedf5667427cbfc6c022494e7e0c9581f54b4e1dcc9f05f2aea677668fe645b04
|
|
7
|
+
data.tar.gz: 94b37b0490cbf1ab81ab0c4c98a5bd8e6037b6ae5210af6ba2cbd23d4a263a3e4cfccad3f99fe621a6ab62d8356fc007fd066adb2d2379e02f5b07580ef2b2d4
|
data/README.md
CHANGED
|
@@ -1,11 +1,9 @@
|
|
|
1
1
|
# RuboCop AST
|
|
2
2
|
|
|
3
3
|
[](https://badge.fury.io/rb/rubocop-ast)
|
|
4
|
-
[](https://codeclimate.com/github/rubocop-hq/rubocop-ast/test_coverage)
|
|
6
|
-
[](https://codeclimate.com/github/rubocop-hq/rubocop-ast/maintainability)
|
|
4
|
+
[](https://github.com/rubocop/rubocop-ast/actions/workflows/rubocop.yml)
|
|
7
5
|
|
|
8
|
-
Contains the classes needed by [RuboCop](https://github.com/rubocop
|
|
6
|
+
Contains the classes needed by [RuboCop](https://github.com/rubocop/rubocop) to deal with Ruby's AST, in particular:
|
|
9
7
|
|
|
10
8
|
* `RuboCop::AST::Node` ([doc](docs/modules/ROOT/pages/node_types.adoc))
|
|
11
9
|
* `RuboCop::AST::NodePattern` ([doc](docs/modules/ROOT/pages/node_pattern.adoc))
|
|
@@ -35,7 +33,9 @@ See the [docs site](https://docs.rubocop.org/rubocop-ast) for more details.
|
|
|
35
33
|
|
|
36
34
|
### Parser compatibility switches
|
|
37
35
|
|
|
38
|
-
This gem, by default, uses most [legacy AST output from parser](https://github.com/whitequark/parser/#usage), except for
|
|
36
|
+
This gem, by default, uses most [legacy AST output from parser](https://github.com/whitequark/parser/#usage), except for the following which are set to `true`:
|
|
37
|
+
* `emit_forward_arg`
|
|
38
|
+
* `emit_match_pattern`
|
|
39
39
|
|
|
40
40
|
The main `RuboCop` gem uses these defaults (and is currently only compatible with these), but this gem can be used separately from `RuboCop` and is meant to be compatible with all settings. For example, to have `-> { ... }` emitted
|
|
41
41
|
as `LambdaNode` instead of `SendNode`:
|
data/lib/rubocop/ast/builder.rb
CHANGED
|
@@ -2,72 +2,97 @@
|
|
|
2
2
|
|
|
3
3
|
module RuboCop
|
|
4
4
|
module AST
|
|
5
|
-
#
|
|
6
|
-
#
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
# builder = RuboCop::AST::Builder.new
|
|
13
|
-
# require 'parser/ruby25'
|
|
14
|
-
# parser = Parser::Ruby25.new(builder)
|
|
15
|
-
# root_node = parser.parse(buffer)
|
|
16
|
-
class Builder < Parser::Builders::Default
|
|
17
|
-
self.emit_forward_arg = true
|
|
5
|
+
# Common functionality between the parser and prism builder
|
|
6
|
+
# @api private
|
|
7
|
+
module BuilderExtensions
|
|
8
|
+
def self.included(base)
|
|
9
|
+
base.emit_forward_arg = true
|
|
10
|
+
base.emit_match_pattern = true
|
|
11
|
+
end
|
|
18
12
|
|
|
19
13
|
# @api private
|
|
20
14
|
NODE_MAP = {
|
|
21
|
-
and:
|
|
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
|
-
|
|
15
|
+
and: AndNode,
|
|
16
|
+
and_asgn: AndAsgnNode,
|
|
17
|
+
alias: AliasNode,
|
|
18
|
+
arg: ArgNode,
|
|
19
|
+
blockarg: ArgNode,
|
|
20
|
+
forward_arg: ArgNode,
|
|
21
|
+
kwarg: ArgNode,
|
|
22
|
+
kwoptarg: ArgNode,
|
|
23
|
+
kwrestarg: ArgNode,
|
|
24
|
+
optarg: ArgNode,
|
|
25
|
+
restarg: ArgNode,
|
|
26
|
+
shadowarg: ArgNode,
|
|
27
|
+
args: ArgsNode,
|
|
28
|
+
array: ArrayNode,
|
|
29
|
+
lvasgn: AsgnNode,
|
|
30
|
+
ivasgn: AsgnNode,
|
|
31
|
+
cvasgn: AsgnNode,
|
|
32
|
+
gvasgn: AsgnNode,
|
|
33
|
+
block: BlockNode,
|
|
34
|
+
numblock: BlockNode,
|
|
35
|
+
itblock: BlockNode,
|
|
36
|
+
break: BreakNode,
|
|
37
|
+
case_match: CaseMatchNode,
|
|
38
|
+
casgn: CasgnNode,
|
|
39
|
+
case: CaseNode,
|
|
40
|
+
class: ClassNode,
|
|
41
|
+
complex: ComplexNode,
|
|
42
|
+
const: ConstNode,
|
|
43
|
+
def: DefNode,
|
|
44
|
+
defined?: DefinedNode,
|
|
45
|
+
defs: DefNode,
|
|
46
|
+
dstr: DstrNode,
|
|
47
|
+
ensure: EnsureNode,
|
|
48
|
+
for: ForNode,
|
|
49
|
+
forward_args: ForwardArgsNode,
|
|
50
|
+
forwarded_kwrestarg: KeywordSplatNode,
|
|
51
|
+
float: FloatNode,
|
|
52
|
+
hash: HashNode,
|
|
53
|
+
if: IfNode,
|
|
54
|
+
in_pattern: InPatternNode,
|
|
55
|
+
int: IntNode,
|
|
56
|
+
index: IndexNode,
|
|
57
|
+
indexasgn: IndexasgnNode,
|
|
58
|
+
irange: RangeNode,
|
|
59
|
+
erange: RangeNode,
|
|
60
|
+
kwargs: HashNode,
|
|
61
|
+
kwbegin: KeywordBeginNode,
|
|
62
|
+
kwsplat: KeywordSplatNode,
|
|
63
|
+
lambda: LambdaNode,
|
|
64
|
+
masgn: MasgnNode,
|
|
65
|
+
mlhs: MlhsNode,
|
|
66
|
+
module: ModuleNode,
|
|
67
|
+
next: NextNode,
|
|
68
|
+
op_asgn: OpAsgnNode,
|
|
69
|
+
or_asgn: OrAsgnNode,
|
|
70
|
+
or: OrNode,
|
|
71
|
+
pair: PairNode,
|
|
72
|
+
procarg0: Procarg0Node,
|
|
73
|
+
rational: RationalNode,
|
|
74
|
+
regexp: RegexpNode,
|
|
75
|
+
rescue: RescueNode,
|
|
76
|
+
resbody: ResbodyNode,
|
|
77
|
+
return: ReturnNode,
|
|
78
|
+
csend: CsendNode,
|
|
79
|
+
send: SendNode,
|
|
80
|
+
str: StrNode,
|
|
81
|
+
xstr: StrNode,
|
|
82
|
+
sclass: SelfClassNode,
|
|
83
|
+
super: SuperNode,
|
|
84
|
+
zsuper: SuperNode,
|
|
85
|
+
sym: SymbolNode,
|
|
86
|
+
until: UntilNode,
|
|
87
|
+
until_post: UntilNode,
|
|
88
|
+
lvar: VarNode,
|
|
89
|
+
ivar: VarNode,
|
|
90
|
+
cvar: VarNode,
|
|
91
|
+
gvar: VarNode,
|
|
92
|
+
when: WhenNode,
|
|
93
|
+
while: WhileNode,
|
|
94
|
+
while_post: WhileNode,
|
|
95
|
+
yield: YieldNode
|
|
71
96
|
}.freeze
|
|
72
97
|
|
|
73
98
|
# Generates {Node} from the given information.
|
|
@@ -77,7 +102,7 @@ module RuboCop
|
|
|
77
102
|
node_klass(type).new(type, children, location: source_map)
|
|
78
103
|
end
|
|
79
104
|
|
|
80
|
-
#
|
|
105
|
+
# Overwrite the base method to allow strings with invalid encoding
|
|
81
106
|
# More details here https://github.com/whitequark/parser/issues/283
|
|
82
107
|
def string_value(token)
|
|
83
108
|
value(token)
|
|
@@ -89,5 +114,20 @@ module RuboCop
|
|
|
89
114
|
NODE_MAP[type] || Node
|
|
90
115
|
end
|
|
91
116
|
end
|
|
117
|
+
|
|
118
|
+
# `RuboCop::AST::Builder` is an AST builder that is utilized to let `Parser`
|
|
119
|
+
# generate ASTs with {RuboCop::AST::Node}.
|
|
120
|
+
#
|
|
121
|
+
# @example
|
|
122
|
+
# buffer = Parser::Source::Buffer.new('(string)')
|
|
123
|
+
# buffer.source = 'puts :foo'
|
|
124
|
+
#
|
|
125
|
+
# builder = RuboCop::AST::Builder.new
|
|
126
|
+
# require 'parser/ruby25'
|
|
127
|
+
# parser = Parser::Ruby25.new(builder)
|
|
128
|
+
# root_node = parser.parse(buffer)
|
|
129
|
+
class Builder < Parser::Builders::Default
|
|
130
|
+
include BuilderExtensions
|
|
131
|
+
end
|
|
92
132
|
end
|
|
93
133
|
end
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module RuboCop
|
|
4
|
+
module AST
|
|
5
|
+
# A parser builder, based on the one provided by prism,
|
|
6
|
+
# which is capable of emitting AST for more recent Rubies.
|
|
7
|
+
class BuilderPrism < Prism::Translation::Parser::Builder
|
|
8
|
+
include BuilderExtensions
|
|
9
|
+
end
|
|
10
|
+
end
|
|
11
|
+
end
|
|
@@ -15,8 +15,8 @@ module RuboCop
|
|
|
15
15
|
# :bar
|
|
16
16
|
# ]
|
|
17
17
|
#
|
|
18
|
-
# node.loc.begin.line_span
|
|
19
|
-
# node.
|
|
18
|
+
# node.loc.begin.line_span # => 1..1
|
|
19
|
+
# node.source_range.line_span(exclude_end: true) # => 1...4
|
|
20
20
|
def line_span(exclude_end: false)
|
|
21
21
|
::Range.new(first_line, last_line, exclude_end)
|
|
22
22
|
end
|
|
@@ -25,4 +25,4 @@ module RuboCop
|
|
|
25
25
|
end
|
|
26
26
|
end
|
|
27
27
|
|
|
28
|
-
|
|
28
|
+
Parser::Source::Range.include RuboCop::AST::Ext::Range
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module RuboCop
|
|
4
|
+
module AST
|
|
5
|
+
# A node extension for `op_asgn` nodes.
|
|
6
|
+
# This will be used in place of a plain node when the builder constructs
|
|
7
|
+
# the AST, making its methods available to all assignment nodes within RuboCop.
|
|
8
|
+
class AndAsgnNode < OpAsgnNode
|
|
9
|
+
# The operator being used for assignment as a symbol.
|
|
10
|
+
#
|
|
11
|
+
# @return [Symbol] the assignment operator
|
|
12
|
+
def operator
|
|
13
|
+
:'&&'
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
end
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module RuboCop
|
|
4
|
+
module AST
|
|
5
|
+
# A node extension for `arg`, `optarg`, `restarg`, `kwarg`, `kwoptarg`,
|
|
6
|
+
# `kwrestarg`, `blockarg`, `shadowarg` and `forward_arg` nodes.
|
|
7
|
+
# This will be used in place of a plain node when the builder constructs
|
|
8
|
+
# the AST, making its methods available to all `arg` nodes within RuboCop.
|
|
9
|
+
class ArgNode < Node
|
|
10
|
+
# Returns the name of an argument.
|
|
11
|
+
#
|
|
12
|
+
# @return [Symbol, nil] the name of the argument
|
|
13
|
+
def name
|
|
14
|
+
node_parts[0]
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
# Returns the default value of the argument, if any.
|
|
18
|
+
#
|
|
19
|
+
# @return [Node, nil] the default value of the argument
|
|
20
|
+
def default_value
|
|
21
|
+
return unless default?
|
|
22
|
+
|
|
23
|
+
node_parts[1]
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
# Checks whether the argument has a default value
|
|
27
|
+
#
|
|
28
|
+
# @return [Boolean] whether the argument has a default value
|
|
29
|
+
def default?
|
|
30
|
+
optarg_type? || kwoptarg_type?
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
end
|
|
@@ -24,6 +24,16 @@ module RuboCop
|
|
|
24
24
|
def empty_and_without_delimiters?
|
|
25
25
|
loc.expression.nil?
|
|
26
26
|
end
|
|
27
|
+
|
|
28
|
+
# Yield each argument from the collection.
|
|
29
|
+
# Arguments can be inside `mlhs` nodes in the case of destructuring, so this
|
|
30
|
+
# flattens the collection to just `arg`, `optarg`, `restarg`, `kwarg`,
|
|
31
|
+
# `kwoptarg`, `kwrestarg`, `blockarg`, `forward_arg` and `shadowarg`.
|
|
32
|
+
#
|
|
33
|
+
# @return [Array<Node>] array of argument nodes.
|
|
34
|
+
def argument_list
|
|
35
|
+
each_descendant(:argument).to_a.freeze
|
|
36
|
+
end
|
|
27
37
|
end
|
|
28
38
|
end
|
|
29
39
|
end
|
|
@@ -7,8 +7,8 @@ module RuboCop
|
|
|
7
7
|
# to all `array` nodes within RuboCop.
|
|
8
8
|
class ArrayNode < Node
|
|
9
9
|
PERCENT_LITERAL_TYPES = {
|
|
10
|
-
string:
|
|
11
|
-
symbol:
|
|
10
|
+
string: /\A%[wW]/,
|
|
11
|
+
symbol: /\A%[iI]/
|
|
12
12
|
}.freeze
|
|
13
13
|
private_constant :PERCENT_LITERAL_TYPES
|
|
14
14
|
|
|
@@ -17,9 +17,13 @@ module RuboCop
|
|
|
17
17
|
# @return [Array<Node>] an array of value nodes
|
|
18
18
|
alias values children
|
|
19
19
|
|
|
20
|
-
#
|
|
20
|
+
# Calls the given block for each `value` node in the `array` literal.
|
|
21
|
+
# If no block is given, an `Enumerator` is returned.
|
|
22
|
+
#
|
|
23
|
+
# @return [self] if a block is given
|
|
24
|
+
# @return [Enumerator] if no block is given
|
|
21
25
|
def each_value(&block)
|
|
22
|
-
return to_enum(__method__) unless
|
|
26
|
+
return to_enum(__method__) unless block
|
|
23
27
|
|
|
24
28
|
values.each(&block)
|
|
25
29
|
|
|
@@ -30,7 +34,7 @@ module RuboCop
|
|
|
30
34
|
#
|
|
31
35
|
# @return [Boolean] whether the array is enclosed in square brackets
|
|
32
36
|
def square_brackets?
|
|
33
|
-
|
|
37
|
+
loc_is?(:begin, '[')
|
|
34
38
|
end
|
|
35
39
|
|
|
36
40
|
# Checks whether the `array` literal is delimited by percent brackets.
|
|
@@ -46,7 +50,7 @@ module RuboCop
|
|
|
46
50
|
# @return [Boolean] whether the array is enclosed in percent brackets
|
|
47
51
|
def percent_literal?(type = nil)
|
|
48
52
|
if type
|
|
49
|
-
loc.begin
|
|
53
|
+
loc.begin&.source&.match?(PERCENT_LITERAL_TYPES.fetch(type))
|
|
50
54
|
else
|
|
51
55
|
loc.begin&.source&.start_with?('%')
|
|
52
56
|
end
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module RuboCop
|
|
4
|
+
module AST
|
|
5
|
+
# A node extension for `lvasgn`, `ivasgn`, `cvasgn`, and `gvasgn` nodes.
|
|
6
|
+
# This will be used in place of a plain node when the builder constructs
|
|
7
|
+
# the AST, making its methods available to all assignment nodes within RuboCop.
|
|
8
|
+
class AsgnNode < Node
|
|
9
|
+
# The name of the variable being assigned as a symbol.
|
|
10
|
+
#
|
|
11
|
+
# @return [Symbol] the name of the variable being assigned
|
|
12
|
+
def name
|
|
13
|
+
node_parts[0]
|
|
14
|
+
end
|
|
15
|
+
alias lhs name
|
|
16
|
+
|
|
17
|
+
# The expression being assigned to the variable.
|
|
18
|
+
#
|
|
19
|
+
# @return [Node] the expression being assigned.
|
|
20
|
+
def expression
|
|
21
|
+
node_parts[1]
|
|
22
|
+
end
|
|
23
|
+
alias rhs expression
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
end
|
|
@@ -11,6 +11,8 @@ module RuboCop
|
|
|
11
11
|
class BlockNode < Node
|
|
12
12
|
include MethodIdentifierPredicates
|
|
13
13
|
|
|
14
|
+
IT_BLOCK_ARGUMENT = [ArgNode.new(:arg, [:it])].freeze
|
|
15
|
+
private_constant :IT_BLOCK_ARGUMENT
|
|
14
16
|
VOID_CONTEXT_METHODS = %i[each tap].freeze
|
|
15
17
|
private_constant :VOID_CONTEXT_METHODS
|
|
16
18
|
|
|
@@ -21,14 +23,49 @@ module RuboCop
|
|
|
21
23
|
node_parts[0]
|
|
22
24
|
end
|
|
23
25
|
|
|
26
|
+
# A shorthand for getting the first argument of this block.
|
|
27
|
+
# Equivalent to `arguments.first`.
|
|
28
|
+
#
|
|
29
|
+
# @return [Node, nil] the first argument of this block,
|
|
30
|
+
# or `nil` if there are no arguments
|
|
31
|
+
def first_argument
|
|
32
|
+
arguments[0]
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
# A shorthand for getting the last argument of this block.
|
|
36
|
+
# Equivalent to `arguments.last`.
|
|
37
|
+
#
|
|
38
|
+
# @return [Node, nil] the last argument of this block,
|
|
39
|
+
# or `nil` if there are no arguments
|
|
40
|
+
def last_argument
|
|
41
|
+
arguments[-1]
|
|
42
|
+
end
|
|
43
|
+
|
|
24
44
|
# The arguments of this block.
|
|
45
|
+
# Note that if the block has destructured arguments, `arguments` will
|
|
46
|
+
# return a `mlhs` node, whereas `argument_list` will return only
|
|
47
|
+
# actual argument nodes.
|
|
25
48
|
#
|
|
26
49
|
# @return [Array<Node>]
|
|
27
50
|
def arguments
|
|
51
|
+
if block_type?
|
|
52
|
+
node_parts[1]
|
|
53
|
+
else
|
|
54
|
+
[].freeze # Numblocks and itblocks have no explicit block arguments.
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
# Returns a collection of all descendants of this node that are
|
|
59
|
+
# argument type nodes. See `ArgsNode#argument_list` for details.
|
|
60
|
+
#
|
|
61
|
+
# @return [Array<Node>]
|
|
62
|
+
def argument_list
|
|
28
63
|
if numblock_type?
|
|
29
|
-
|
|
64
|
+
numbered_arguments
|
|
65
|
+
elsif itblock_type?
|
|
66
|
+
IT_BLOCK_ARGUMENT
|
|
30
67
|
else
|
|
31
|
-
|
|
68
|
+
arguments.argument_list
|
|
32
69
|
end
|
|
33
70
|
end
|
|
34
71
|
|
|
@@ -57,14 +94,14 @@ module RuboCop
|
|
|
57
94
|
#
|
|
58
95
|
# @return [Boolean] whether the `block` literal is enclosed in braces
|
|
59
96
|
def braces?
|
|
60
|
-
loc.end
|
|
97
|
+
loc.end.is?('}')
|
|
61
98
|
end
|
|
62
99
|
|
|
63
100
|
# Checks whether the `block` literal is delimited by `do`-`end` keywords.
|
|
64
101
|
#
|
|
65
102
|
# @return [Boolean] whether the `block` literal is enclosed in `do`-`end`
|
|
66
103
|
def keywords?
|
|
67
|
-
loc.end
|
|
104
|
+
loc.end.is?('end')
|
|
68
105
|
end
|
|
69
106
|
|
|
70
107
|
# The delimiters for this `block` literal.
|
|
@@ -117,6 +154,15 @@ module RuboCop
|
|
|
117
154
|
def void_context?
|
|
118
155
|
VOID_CONTEXT_METHODS.include?(method_name)
|
|
119
156
|
end
|
|
157
|
+
|
|
158
|
+
private
|
|
159
|
+
|
|
160
|
+
def numbered_arguments
|
|
161
|
+
max_param = children[1]
|
|
162
|
+
1.upto(max_param).map do |i|
|
|
163
|
+
ArgNode.new(:arg, [:"_#{i}"])
|
|
164
|
+
end.freeze
|
|
165
|
+
end
|
|
120
166
|
end
|
|
121
167
|
end
|
|
122
168
|
end
|
|
@@ -17,23 +17,37 @@ module RuboCop
|
|
|
17
17
|
|
|
18
18
|
# @deprecated Use `in_pattern_branches.each`
|
|
19
19
|
def each_in_pattern(&block)
|
|
20
|
-
return in_pattern_branches.to_enum(__method__) unless
|
|
20
|
+
return in_pattern_branches.to_enum(__method__) unless block
|
|
21
21
|
|
|
22
22
|
in_pattern_branches.each(&block)
|
|
23
23
|
|
|
24
24
|
self
|
|
25
25
|
end
|
|
26
26
|
|
|
27
|
-
# Returns an array of all the
|
|
27
|
+
# Returns an array of all the `in` pattern branches in the `case` statement.
|
|
28
28
|
#
|
|
29
|
-
# @return [Array<
|
|
29
|
+
# @return [Array<InPatternNode>] an array of `in_pattern` nodes
|
|
30
30
|
def in_pattern_branches
|
|
31
31
|
node_parts[1...-1]
|
|
32
32
|
end
|
|
33
33
|
|
|
34
|
+
# Returns an array of all the when branches in the `case` statement.
|
|
35
|
+
#
|
|
36
|
+
# @return [Array<Node, nil>] an array of the bodies of the `in` branches
|
|
37
|
+
# and the `else` (if any). Note that these bodies could be nil.
|
|
38
|
+
def branches
|
|
39
|
+
bodies = in_pattern_branches.map(&:body)
|
|
40
|
+
if else?
|
|
41
|
+
# `empty-else` node sets nil because it has no body.
|
|
42
|
+
else_branch.empty_else_type? ? bodies.push(nil) : bodies.push(else_branch)
|
|
43
|
+
end
|
|
44
|
+
bodies
|
|
45
|
+
end
|
|
46
|
+
|
|
34
47
|
# Returns the else branch of the `case` statement, if any.
|
|
35
48
|
#
|
|
36
49
|
# @return [Node] the else branch node of the `case` statement
|
|
50
|
+
# @return [EmptyElse] the empty else branch node of the `case` statement
|
|
37
51
|
# @return [nil] if the case statement does not have an else branch.
|
|
38
52
|
def else_branch
|
|
39
53
|
node_parts[-1]
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module RuboCop
|
|
4
|
+
module AST
|
|
5
|
+
# A node extension for `casgn` nodes.
|
|
6
|
+
# This will be used in place of a plain node when the builder constructs
|
|
7
|
+
# the AST, making its methods available to all assignment nodes within RuboCop.
|
|
8
|
+
class CasgnNode < Node
|
|
9
|
+
include ConstantNode
|
|
10
|
+
|
|
11
|
+
alias name short_name
|
|
12
|
+
alias lhs short_name
|
|
13
|
+
|
|
14
|
+
# The expression being assigned to the variable.
|
|
15
|
+
#
|
|
16
|
+
# @return [Node] the expression being assigned.
|
|
17
|
+
def expression
|
|
18
|
+
node_parts[2]
|
|
19
|
+
end
|
|
20
|
+
alias rhs expression
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
end
|
|
@@ -6,9 +6,9 @@ module RuboCop
|
|
|
6
6
|
# node when the builder constructs the AST, making its methods available
|
|
7
7
|
# to all `class` nodes within RuboCop.
|
|
8
8
|
class ClassNode < Node
|
|
9
|
-
# The
|
|
9
|
+
# The identifier for this `class` node.
|
|
10
10
|
#
|
|
11
|
-
# @return [Node] the
|
|
11
|
+
# @return [Node] the identifier of the class
|
|
12
12
|
def identifier
|
|
13
13
|
node_parts[0]
|
|
14
14
|
end
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module RuboCop
|
|
4
|
+
module AST
|
|
5
|
+
# A node extension for `complex` nodes. This will be used in place of a plain
|
|
6
|
+
# node when the builder constructs the AST, making its methods available to
|
|
7
|
+
# all `complex` nodes within RuboCop.
|
|
8
|
+
class ComplexNode < Node
|
|
9
|
+
include BasicLiteralNode
|
|
10
|
+
include NumericNode
|
|
11
|
+
end
|
|
12
|
+
end
|
|
13
|
+
end
|
|
@@ -4,62 +4,7 @@ module RuboCop
|
|
|
4
4
|
module AST
|
|
5
5
|
# A node extension for `const` nodes.
|
|
6
6
|
class ConstNode < Node
|
|
7
|
-
|
|
8
|
-
#
|
|
9
|
-
# @return [Node, nil] the node associated with the scope (e.g. cbase, const, ...)
|
|
10
|
-
def namespace
|
|
11
|
-
children[0]
|
|
12
|
-
end
|
|
13
|
-
|
|
14
|
-
# @return [Symbol] the demodulized name of the constant: "::Foo::Bar" => :Bar
|
|
15
|
-
def short_name
|
|
16
|
-
children[1]
|
|
17
|
-
end
|
|
18
|
-
|
|
19
|
-
# The body of this block.
|
|
20
|
-
#
|
|
21
|
-
# @return [Boolean] if the constant is a Module / Class, according to the standard convention.
|
|
22
|
-
# Note: some classes might have uppercase in which case this method
|
|
23
|
-
# returns false
|
|
24
|
-
def module_name?
|
|
25
|
-
short_name.match?(/[[:lower:]]/)
|
|
26
|
-
end
|
|
27
|
-
alias class_name? module_name?
|
|
28
|
-
|
|
29
|
-
# @return [Boolean] if the constant starts with `::` (aka s(:cbase))
|
|
30
|
-
def absolute?
|
|
31
|
-
return false unless namespace
|
|
32
|
-
|
|
33
|
-
each_path.first.cbase_type?
|
|
34
|
-
end
|
|
35
|
-
|
|
36
|
-
# @return [Boolean] if the constant does not start with `::` (aka s(:cbase))
|
|
37
|
-
def relative?
|
|
38
|
-
!absolute?
|
|
39
|
-
end
|
|
40
|
-
|
|
41
|
-
# Yield nodes for the namespace
|
|
42
|
-
#
|
|
43
|
-
# For `::Foo::Bar::BAZ` => yields:
|
|
44
|
-
# s(:cbase), then
|
|
45
|
-
# s(:const, :Foo), then
|
|
46
|
-
# s(:const, s(:const, :Foo), :Bar)
|
|
47
|
-
def each_path(&block)
|
|
48
|
-
return to_enum(__method__) unless block_given?
|
|
49
|
-
|
|
50
|
-
descendants = []
|
|
51
|
-
last = self
|
|
52
|
-
loop do
|
|
53
|
-
last = last.children.first
|
|
54
|
-
break if last.nil?
|
|
55
|
-
|
|
56
|
-
descendants << last
|
|
57
|
-
break unless last.const_type?
|
|
58
|
-
end
|
|
59
|
-
descendants.reverse_each(&block)
|
|
60
|
-
|
|
61
|
-
self
|
|
62
|
-
end
|
|
7
|
+
include ConstantNode
|
|
63
8
|
end
|
|
64
9
|
end
|
|
65
10
|
end
|