Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Move bin/sort implementation to under lib/ #1051

Merged
merged 1 commit into from
Jun 30, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
154 changes: 2 additions & 152 deletions bin/sort
Original file line number Diff line number Diff line change
Expand Up @@ -2,158 +2,8 @@

require "bundler/setup"
require "rbs"

Members = RBS::AST::Members
Decls = RBS::AST::Declarations

def group(member)
case member
when Decls::Alias
-3
when Decls::Constant
-2
when Decls::Class, Decls::Module
-1
when Members::Include
0.0
when Members::Prepend
0.2
when Members::Extend
0.4
when Members::ClassVariable
1
when Members::ClassInstanceVariable
2
when Members::InstanceVariable
3
when Members::AttrAccessor, Members::AttrWriter, Members::AttrReader
if member.kind == :singleton
5.0
else
6.0
end
when Members::MethodDefinition
case member.kind
when :singleton_instance
4
when :singleton
if member.name == :new
5.2
elsif member.visibility == :public
5.4
else
5.6
end
else
if member.name == :initialize
6.2
elsif member.visibility == :public
6.4
else
6.6
end
end
when Members::Alias
if member.singleton?
5.4
else
6.4
end
end
end

def key(member)
case member
when Members::Include, Members::Extend, Members::Prepend
member.name.to_s
when Members::ClassVariable, Members::ClassInstanceVariable, Members::InstanceVariable
member.name.to_s
when Members::AttrAccessor, Members::AttrWriter, Members::AttrReader
member.name.to_s
when Members::MethodDefinition
member.name.to_s
when Members::Alias
member.new_name.to_s
when Decls::Constant
member.name.to_s
when Decls::Alias
member.name.to_s
when Decls::Class, Decls::Module
member.name.to_s
else
1
end
end

def sort_decl!(decl)
case decl
when Decls::Class, Decls::Module, Decls::Interface
decl.members.each { |m| sort_decl! m }

current_visibility = :public
decl.members.map! do |m|
case m
when Members::Public
current_visibility = :public
nil
when Members::Private
current_visibility = :private
nil
when Members::MethodDefinition, Members::AttrReader, Members::AttrWriter, Members::AttrAccessor
m.update(visibility: m.visibility || current_visibility)
else
m
end
end
decl.members.compact!

decl.members.sort! do |m1, m2|
group1 = group(m1)
group2 = group(m2)

if group1 == group2
key(m1) <=> key(m2)
else
group1 <=> group2
end
end

current_visibility = :public
decl.members.map! do |m|
case m
when Members::MethodDefinition, Members::AttrReader, Members::AttrWriter, Members::AttrAccessor
new = m.update(visibility: nil)
cur = current_visibility
current_visibility = m.visibility
if cur != m.visibility
[
m.visibility == :public ? Members::Public.new(location: nil) : Members::Private.new(location: nil),
new
]
else
new
end
else
m
end
end
decl.members.flatten!
end
end
require "rbs/sorter"

ARGV.map {|f| Pathname(f) }.each do |path|
puts "Opening #{path}..."

buffer = RBS::Buffer.new(name: path, content: path.read)
sigs = RBS::Parser.parse_signature(buffer)

sigs.each do |m|
sort_decl! m
end

puts "Writing #{path}..."
path.open('w') do |out|
writer = RBS::Writer.new(out: out)
writer.write sigs
end
RBS::Sorter.new(path).run
end
166 changes: 166 additions & 0 deletions lib/rbs/sorter.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,166 @@
module RBS
class Sorter
include RBS::AST

attr_reader :path, :stdout

def initialize(path, stdout: $stdout)
@path = path
@stdout = stdout
end

def run
stdout.puts "Opening #{path}..."

buffer = Buffer.new(name: path, content: path.read)
sigs = Parser.parse_signature(buffer)

sigs.each do |m|
sort_decl! m
end

stdout.puts "Writing #{path}..."
path.open('w') do |out|
writer = RBS::Writer.new(out: out)
writer.write sigs
end
end

def group(member)
case member
when Declarations::Alias
-3
when Declarations::Constant
-2
when Declarations::Class, Declarations::Module
-1
when Members::Include
0.0
when Members::Prepend
0.2
when Members::Extend
0.4
when Members::ClassVariable
1
when Members::ClassInstanceVariable
2
when Members::InstanceVariable
3
when Members::AttrAccessor, Members::AttrWriter, Members::AttrReader
if member.kind == :singleton
5.0
else
6.0
end
when Members::MethodDefinition
case member.kind
when :singleton_instance
4
when :singleton
if member.name == :new
5.2
elsif member.visibility == :public
5.4
else
5.6
end
else
if member.name == :initialize
6.2
elsif member.visibility == :public
6.4
else
6.6
end
end
when Members::Alias
if member.singleton?
5.4
else
6.4
end
else
raise
end
end

def key(member)
case member
when Members::Include, Members::Extend, Members::Prepend
member.name.to_s
when Members::ClassVariable, Members::ClassInstanceVariable, Members::InstanceVariable
member.name.to_s
when Members::AttrAccessor, Members::AttrWriter, Members::AttrReader
member.name.to_s
when Members::MethodDefinition
member.name.to_s
when Members::Alias
member.new_name.to_s
when Declarations::Constant
member.name.to_s
when Declarations::Alias
member.name.to_s
when Declarations::Class, Declarations::Module
member.name.to_s
else
raise
end
end

def sort_decl!(decl)
case decl
when Declarations::Class, Declarations::Module, Declarations::Interface
decl.members.each { |m| sort_decl! m }

current_visibility = :public
decl.members.map! do |m|
case m
when Members::Public
current_visibility = :public
nil
when Members::Private
current_visibility = :private
nil
when Members::MethodDefinition, Members::AttrReader, Members::AttrWriter, Members::AttrAccessor
m.update(visibility: m.visibility || current_visibility)
else
m
end
end
decl.members.compact!

decl.members.sort! do |m1, m2|
group1 = group(m1)
group2 = group(m2)

if group1 == group2
key(m1) <=> key(m2)
else
group1 <=> group2
end
end

current_visibility = :public
decl.members.map! do |m|
case m
when Members::MethodDefinition, Members::AttrReader, Members::AttrWriter, Members::AttrAccessor
new = m.update(visibility: nil)
cur = current_visibility
current_visibility = m.visibility
if cur != m.visibility
[
m.visibility == :public ? Members::Public.new(location: nil) : Members::Private.new(location: nil),
new
]
else
new
end
else
m
end
end
decl.members.flatten!
end
end
end
end
23 changes: 23 additions & 0 deletions sig/sorter.rbs
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
module RBS
class Sorter
include RBS::AST

type member = AST::Declarations::Class::member
| AST::Declarations::Module::member
| AST::Declarations::Interface::member

attr_reader path: Pathname

attr_reader stdout: IO

def initialize: (Pathname path, ?stdout: IO) -> void

def run: () -> void

def group: (member member) -> Numeric

def key: (member member) -> String

def sort_decl!: (AST::Declarations::t decl) -> void
end
end
5 changes: 3 additions & 2 deletions test/tools/sort_test.rb → test/rbs/sorter_test.rb
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
require "test_helper"
require 'tempfile'
require 'rbs/sorter'

class RBS::ToolSortTest < Test::Unit::TestCase
class RBS::SorterTest < Test::Unit::TestCase
def test_sort
assert_sort <<~RUBY_EXPECTED, <<~RUBY_ORIG
class C
Expand Down Expand Up @@ -122,7 +123,7 @@ def assert_sort(expected, original)
actual = Tempfile.create('rbs-sort-test-') do |f|
f.write original
f.close
system File.join(__dir__, '../../bin/sort'), f.path, exception: true, out: IO::NULL
RBS::Sorter.new(Pathname(f.path), stdout: StringIO.new).run

File.read(f.path)
end
Expand Down