Skip to content

Commit

Permalink
Add RuboCop::AST::RationalNode
Browse files Browse the repository at this point in the history
This PR resolves the fundamental issue mentioned in rubocop/rubocop#13051.
Although rational literal (e.g., `(0.2r)` is a basic literal that return `true` for `RuboCop::AST::Node#numeric_type?`
and `RuboCop::AST::Node#literal?`, their behavior was not sufficiently covered as a `NumericNode`.

This PR maps rational literal to `RationalNode` to enable expected node operations for rational literals.
  • Loading branch information
koic authored and marcandre committed Aug 5, 2024
1 parent 6e5e64b commit 7324d0f
Show file tree
Hide file tree
Showing 7 changed files with 51 additions and 2 deletions.
1 change: 1 addition & 0 deletions changelog/new_add_rational_node.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
* [#304](https://github.com/rubocop/rubocop-ast/pull/304): Add `RuboCop::AST::RationalNode`. ([@koic][])
1 change: 1 addition & 0 deletions lib/rubocop/ast.rb
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@
require_relative 'ast/node/pair_node'
require_relative 'ast/node/procarg0_node'
require_relative 'ast/node/range_node'
require_relative 'ast/node/rational_node'
require_relative 'ast/node/regexp_node'
require_relative 'ast/node/rescue_node'
require_relative 'ast/node/resbody_node'
Expand Down
1 change: 1 addition & 0 deletions lib/rubocop/ast/builder.rb
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@ class Builder < Parser::Builders::Default
or: OrNode,
pair: PairNode,
procarg0: Procarg0Node,
rational: RationalNode,
regexp: RegexpNode,
rescue: RescueNode,
resbody: ResbodyNode,
Expand Down
2 changes: 1 addition & 1 deletion lib/rubocop/ast/node/mixin/basic_literal_node.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
module RuboCop
module AST
# Common functionality for primitive literal nodes: `sym`, `str`,
# `int`, `float`, ...
# `int`, `float`, `rational`...
module BasicLiteralNode
# Returns the value of the literal.
#
Expand Down
2 changes: 1 addition & 1 deletion lib/rubocop/ast/node/mixin/numeric_node.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

module RuboCop
module AST
# Common functionality for primitive numeric nodes: `int`, `float`, ...
# Common functionality for primitive numeric nodes: `int`, `float`, `rational`...
module NumericNode
SIGN_REGEX = /\A[+-]/.freeze
private_constant :SIGN_REGEX
Expand Down
13 changes: 13 additions & 0 deletions lib/rubocop/ast/node/rational_node.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# frozen_string_literal: true

module RuboCop
module AST
# A node extension for `rational` nodes. This will be used in place of a plain
# node when the builder constructs the AST, making its methods available to
# all `rational` nodes within RuboCop.
class RationalNode < Node
include BasicLiteralNode
include NumericNode
end
end
end
33 changes: 33 additions & 0 deletions spec/rubocop/ast/rational_node_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
# frozen_string_literal: true

RSpec.describe RuboCop::AST::RationalNode do
subject(:rational_node) { parse_source(source).ast }

describe '.new' do
let(:source) { '0.2r' }

it { is_expected.to be_a(described_class) }
end

describe '#sign?' do
context 'when explicit positive rational' do
let(:source) { '+0.2r' }

it { is_expected.to be_sign }
end

context 'when explicit negative rational' do
let(:source) { '-0.2r' }

it { is_expected.to be_sign }
end
end

describe '#value' do
let(:source) do
'0.4r'
end

it { expect(rational_node.value).to eq(0.4r) }
end
end

0 comments on commit 7324d0f

Please sign in to comment.