Skip to content

Commit

Permalink
Add VarNode class for lvar, ivar, cvar and gvar node types.
Browse files Browse the repository at this point in the history
  • Loading branch information
dvandersluis authored and marcandre committed Oct 29, 2024
1 parent 742450b commit 0b334f8
Show file tree
Hide file tree
Showing 6 changed files with 84 additions and 4 deletions.
1 change: 1 addition & 0 deletions changelog/new_add_varnode_class_for_lvar_ivar_cvar_and.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
* [#204](https://github.com/rubocop-hq/rubocop-ast/pull/204): Add `VarNode` class for `lvar`, `ivar`, `cvar` and `gvar` node types. ([@dvandersluis][])
8 changes: 4 additions & 4 deletions docs/modules/ROOT/pages/node_types.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ The following fields are given when relevant to nodes in the source code:

|csend|Null-safe method invocation, i.e. using `&.`|First child is the receiver node (e.g. `self`), second child is the method name (e.g. `:foo=`) and the remaining children (if any) are nodes representing arguments.|foo&.bar|https://rubydoc.info/github/rubocop/rubocop-ast/RuboCop/AST/SendNode[SendNode]

|cvar|Class variable access|One child, the variable name `:@@cfoo`|@@cfoo|N/A
|cvar|Class variable access|One child, the variable name `:@@cfoo`|@@cfoo|https://rubydoc.info/github/rubocop/rubocop-ast/RuboCop/AST/VarNode[VarNode]

|cvasgn|Class variable assignment|Two children: the variable name `:@@foo` and the expression being assigned|@@foo = 5|https://rubydoc.info/github/rubocop/rubocop-ast/RuboCop/AST/AsgnNode[AsgnNode]

Expand Down Expand Up @@ -124,7 +124,7 @@ The following fields are given when relevant to nodes in the source code:

|forwarded_kwrestarg|Forwarding keyword arguments into a method call|None|foo(**)|N/A

|gvar|Global variable access|One child, the variable name as a symbol `:$foo`|$foo|N/A
|gvar|Global variable access|One child, the variable name as a symbol `:$foo`|$foo|https://rubydoc.info/github/rubocop/rubocop-ast/RuboCop/AST/VarNode[VarNode]

|gvasgn|Global variable assignment|Two children, the variable name `:$foo` and the expression being assigned|$foo = 5|https://rubydoc.info/github/rubocop/rubocop-ast/RuboCop/AST/AsgnNode[AsgnNode]

Expand All @@ -134,7 +134,7 @@ The following fields are given when relevant to nodes in the source code:

|int|Integer literal|1, the integer value|-123|https://rubydoc.info/github/rubocop/rubocop-ast/RuboCop/AST/IntNode[IntNode]

|ivar|Instance variable access|One child, the variable name `:@foo`|@foo|N/A
|ivar|Instance variable access|One child, the variable name `:@foo`|@foo|https://rubydoc.info/github/rubocop/rubocop-ast/RuboCop/AST/VarNode[VarNode]

|ivasgn|Instance variable assignment|Two children, the variable name `:@foo` and the expression being assigned|@foo = 5|https://rubydoc.info/github/rubocop/rubocop-ast/RuboCop/AST/AsgnNode[AsgnNode]

Expand All @@ -152,7 +152,7 @@ The following fields are given when relevant to nodes in the source code:

|kwrestargs|Double splat used for keyword arguments inside a function definition (as opposed to a function call). Must come inside an `args`.|One child - a symbol, representing the argument name, if a name is given. If no name given, it has no children..|def foo(**kwargs)|https://rubydoc.info/github/rubocop/rubocop-ast/RuboCop/AST/ArgNode[ArgNode]

|lvar|Local variable access|One child, the variable name|foo|N/A
|lvar|Local variable access|One child, the variable name|foo|https://rubydoc.info/github/rubocop/rubocop-ast/RuboCop/AST/VarNode[VarNode]

|lvasgn|Local variable assignment|Two children: The variable name (symbol) and the expression.|a = some_thing|https://rubydoc.info/github/rubocop/rubocop-ast/RuboCop/AST/AsgnNode[AsgnNode]

Expand Down
1 change: 1 addition & 0 deletions lib/rubocop/ast.rb
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,7 @@
require_relative 'ast/node/super_node'
require_relative 'ast/node/symbol_node'
require_relative 'ast/node/until_node'
require_relative 'ast/node/var_node'
require_relative 'ast/node/when_node'
require_relative 'ast/node/while_node'
require_relative 'ast/node/yield_node'
Expand Down
4 changes: 4 additions & 0 deletions lib/rubocop/ast/builder.rb
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,10 @@ class Builder < Parser::Builders::Default
sym: SymbolNode,
until: UntilNode,
until_post: UntilNode,
lvar: VarNode,
ivar: VarNode,
cvar: VarNode,
gvar: VarNode,
when: WhenNode,
while: WhileNode,
while_post: WhileNode,
Expand Down
15 changes: 15 additions & 0 deletions lib/rubocop/ast/node/var_node.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
# frozen_string_literal: true

module RuboCop
module AST
# A node extension for `lvar`, `ivar`, `cvar` and `gvar` nodes.
# This will be used in place of a plain node when the builder constructs
# the AST, making its methods available to all assignment nodes within RuboCop.
class VarNode < Node
# @return [Symbol] The name of the variable.
def name
node_parts[0]
end
end
end
end
59 changes: 59 additions & 0 deletions spec/rubocop/ast/var_node_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
# frozen_string_literal: true

RSpec.describe RuboCop::AST::VarNode do
let(:node) { parse_source(source).node }

describe '.new' do
context 'with a `lvar` node' do
let(:source) { 'x = 1; >>x<<' }

it { expect(node).to be_a(described_class) }
end

context 'with an `ivar` node' do
let(:source) { '@x' }

it { expect(node).to be_a(described_class) }
end

context 'with an `cvar` node' do
let(:source) { '@@x' }

it { expect(node).to be_a(described_class) }
end

context 'with an `gvar` node' do
let(:source) { '$x' }

it { expect(node).to be_a(described_class) }
end
end

describe '#name' do
subject { node.name }

context 'with a `lvar` node' do
let(:source) { 'x = 1; >>x<<' }

it { is_expected.to eq(:x) }
end

context 'with an `ivar` node' do
let(:source) { '@x' }

it { is_expected.to eq(:@x) }
end

context 'with an `cvar` node' do
let(:source) { '@@x' }

it { is_expected.to eq(:@@x) }
end

context 'with an `gvar` node' do
let(:source) { '$x' }

it { is_expected.to eq(:$x) }
end
end
end

0 comments on commit 0b334f8

Please sign in to comment.