-
Notifications
You must be signed in to change notification settings - Fork 9
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #350 from Shopify/at-rewriter-flatten-visibility
Introduce FlattenVisibilities rewriter
- Loading branch information
Showing
3 changed files
with
173 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,65 @@ | ||
# typed: strict | ||
# frozen_string_literal: true | ||
|
||
module RBI | ||
module Rewriters | ||
# Flattens visibility nodes into method nodes | ||
# | ||
# Example: | ||
# ~~~rb | ||
# class A | ||
# def m1; end | ||
# private | ||
# def m2; end | ||
# def m3; end | ||
# end | ||
# ~~~ | ||
# | ||
# will be transformed into: | ||
# | ||
# ~~~rb | ||
# class A | ||
# def m1; end | ||
# private def m2; end | ||
# private def m3; end | ||
# end | ||
# ~~~ | ||
class FlattenVisibilities < Visitor | ||
extend T::Sig | ||
|
||
sig { void } | ||
def initialize | ||
super | ||
|
||
@current_visibility = T.let([Public.new], T::Array[Visibility]) | ||
end | ||
|
||
sig { override.params(node: T.nilable(Node)).void } | ||
def visit(node) | ||
return unless node | ||
|
||
case node | ||
when Public, Protected, Private | ||
@current_visibility[-1] = node | ||
node.detach | ||
when Tree | ||
@current_visibility << Public.new | ||
visit_all(node.nodes.dup) | ||
@current_visibility.pop | ||
when Attr, Method | ||
node.visibility = T.must(@current_visibility.last) | ||
end | ||
end | ||
end | ||
end | ||
|
||
class Tree | ||
extend T::Sig | ||
|
||
sig { void } | ||
def flatten_visibilities! | ||
visitor = Rewriters::FlattenVisibilities.new | ||
visitor.visit(self) | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,107 @@ | ||
# typed: true | ||
# frozen_string_literal: true | ||
|
||
require "test_helper" | ||
|
||
module RBI | ||
class FlattenVisibilitiesTest < Minitest::Test | ||
include TestHelper | ||
|
||
def test_flatten_visibilities_in_tree | ||
tree = parse_rbi(<<~RBI) | ||
def m1; end | ||
def m2; end | ||
protected | ||
def m3; end | ||
def m4; end | ||
private | ||
def m5; end | ||
def m6; end | ||
RBI | ||
|
||
tree.flatten_visibilities! | ||
|
||
assert_equal(<<~RBI, tree.string) | ||
def m1; end | ||
def m2; end | ||
protected def m3; end | ||
protected def m4; end | ||
private def m5; end | ||
private def m6; end | ||
RBI | ||
end | ||
|
||
def test_flatten_visibilityies_in_scopes | ||
tree = parse_rbi(<<~RBI) | ||
module S1 | ||
class S2 | ||
class << self | ||
def m1; end | ||
protected | ||
def m2; end | ||
attr_reader :m3 | ||
end | ||
def m4; end | ||
private | ||
def m5; end | ||
attr_writer m6 | ||
end | ||
def m7; end | ||
protected | ||
def m8; end | ||
end | ||
RBI | ||
|
||
tree.flatten_visibilities! | ||
|
||
assert_equal(<<~RBI, tree.string) | ||
module S1 | ||
class S2 | ||
class << self | ||
def m1; end | ||
protected def m2; end | ||
protected attr_reader :m3 | ||
end | ||
def m4; end | ||
private def m5; end | ||
private attr_writer :m6 | ||
end | ||
def m7; end | ||
protected def m8; end | ||
end | ||
RBI | ||
end | ||
|
||
def test_flatten_visibilities_for_singleton_methods | ||
tree = parse_rbi(<<~RBI) | ||
def self.m1; end | ||
protected | ||
def self.m2; end | ||
private | ||
def self.m3; end | ||
RBI | ||
|
||
tree.flatten_visibilities! | ||
|
||
assert_equal(<<~RBI, tree.string) | ||
def self.m1; end | ||
protected def self.m2; end | ||
private def self.m3; end | ||
RBI | ||
end | ||
end | ||
end |