Skip to content

Commit 831cdc6

Browse files
committed
Unused protocols
1 parent 8a0ccfb commit 831cdc6

File tree

5 files changed

+68
-20
lines changed

5 files changed

+68
-20
lines changed

unused-via-ast/XcodeProj/Unused/Unused/A.swift

+5-1
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,10 @@ import Foundation
33
class A {} // unused
44
class B {} // unused
55

6-
76
class C {} // used by inheritance
87
class D: C {} // unused
8+
9+
protocol E {} // unused
10+
protocol F {} // used by inheritance
11+
protocol G: F {} // unused
12+

unused-via-ast/bin/swift-unused

+4-1
Original file line numberDiff line numberDiff line change
@@ -3,4 +3,7 @@
33

44
require 'swift-unused'
55

6-
SwiftUnused.hi
6+
unused = SwiftUnused.new(ARGV[0])
7+
unused.search
8+
puts "Classes: #{unused.classes}"
9+
puts "Protocols: #{unused.protocols}"

unused-via-ast/lib/swift-unused.rb

+36-8
Original file line numberDiff line numberDiff line change
@@ -4,29 +4,57 @@ class SwiftUnused
44
def initialize(ast_path)
55
@ast_path = ast_path
66
@tree = SwiftAST::Parser.new().parse_build_log_output(File.read(ast_path))
7-
@used_classes = Hash.new
7+
88
end
99

10-
def classes
11-
result = []
10+
def search
11+
@used_classes = Hash.new
12+
@used_protocols = Hash.new
13+
14+
unused_classes = []
15+
unused_protocols = []
1216
classes = @tree.find_nodes("class_decl")
17+
protocols = @tree.find_nodes("protocol")
18+
19+
1320
classes.each { |classnode|
14-
register_inheritance(classnode)
21+
register_inheritance(classnode) { |inh| @used_classes[inh] = "inherited" }
22+
}
23+
24+
protocols.each { |protocolnode|
25+
register_inheritance(protocolnode) { |inh| @used_protocols[inh] = "inherited"}
1526
}
27+
1628
classes.each { |node|
1729
next unless classname = node.parameters.first
1830
next unless @used_classes[classname].nil? #// skip already used classes
19-
result += [classname]
31+
unused_classes += [classname]
32+
}
33+
34+
protocols.each { |node|
35+
next unless protocol_name = node.parameters.first
36+
next unless @used_protocols[protocol_name].nil? #// skip already used classes
37+
unused_protocols += [protocol_name]
2038
}
21-
result
39+
40+
@classes = unused_classes
41+
@protocols = unused_protocols
2242
end
2343

24-
def register_inheritance(node)
44+
def classes
45+
@classes
46+
end
47+
48+
def protocols
49+
@protocols
50+
end
51+
52+
def register_inheritance(node, &block)
2553
inheritance = node.parameters.drop_while { |el| el != "inherits:" }
2654
inheritance = inheritance.drop(1)
2755
inheritance.each { |inh|
2856
inh_name = inh.chomp(",")
29-
add_usage(inh_name, "inheritance")
57+
yield inh_name
3058
}
3159
end
3260

unused-via-ast/test/fixtures/Unused.ast

+12-9
Original file line numberDiff line numberDiff line change
@@ -38,18 +38,21 @@
3838
(parameter_list
3939
(parameter "self" type='D' interface type='D'))
4040
(brace_stmt))
41-
(constructor_decl implicit "init()" interface type='(D.Type) -> () -> D' access=internal override=Unused.(file).C.init()@/Users/paultaykalo/Projects/swift-scripts/unused-via-ast/XcodeProj/Unused/Unused/A.swift:7:7 designated
41+
(constructor_decl implicit "init()" interface type='(D.Type) -> () -> D' access=internal override=Unused.(file).C.init()@/Users/paultaykalo/Projects/swift-scripts/unused-via-ast/XcodeProj/Unused/Unused/A.swift:6:7 designated
4242
(parameter_list
4343
(parameter "self" type='D' interface type='D'))
4444
(parameter_list)
4545
(brace_stmt
4646
(rebind_self_in_constructor_expr implicit type='()'
4747
(call_expr implicit type='C' nothrow arg_labels=
4848
(dot_syntax_call_expr implicit type='() -> C' super nothrow
49-
(other_constructor_ref_expr implicit type='(C) -> () -> C' decl=Unused.(file).C.init()@/Users/paultaykalo/Projects/swift-scripts/unused-via-ast/XcodeProj/Unused/Unused/A.swift:7:7)
49+
(other_constructor_ref_expr implicit type='(C) -> () -> C' decl=Unused.(file).C.init()@/Users/paultaykalo/Projects/swift-scripts/unused-via-ast/XcodeProj/Unused/Unused/A.swift:6:7)
5050
(super_ref_expr implicit type='C'))
5151
(tuple_expr implicit type='()')))
52-
(return_stmt implicit)))))
52+
(return_stmt implicit))))
53+
(protocol "E" <Self : E> interface type='E.Protocol' access=internal @_fixed_layout requirement signature=<Self>)
54+
(protocol "F" <Self : F> interface type='F.Protocol' access=internal @_fixed_layout requirement signature=<Self>)
55+
(protocol "G" <Self : G> interface type='G.Protocol' access=internal @_fixed_layout requirement signature=<Self where Self : F> inherits: F))
5356
(source_file
5457
(import_decl 'UIKit')
5558
(class_decl "ViewController" interface type='ViewController.Type' access=internal @objc @_fixed_layout inherits: UIViewController
@@ -121,7 +124,7 @@
121124
(tuple_expr implicit type='(nilLiteral: ())' names=nilLiteral
122125
(tuple_expr implicit type='()'))))
123126
(var_decl "window" type='UIWindow?' interface type='UIWindow?' access=internal @objc storage_kind=stored_with_trivial_accessors
124-
(func_decl implicit 'anonname=0x7fbde9274980' interface type='(AppDelegate) -> () -> UIWindow?' access=internal @objc getter_for=window
127+
(func_decl implicit 'anonname=0x7ffa443018e0' interface type='(AppDelegate) -> () -> UIWindow?' access=internal @objc getter_for=window
125128
(parameter_list
126129
(parameter "self" type='AppDelegate' interface type='AppDelegate'))
127130
(parameter_list)
@@ -130,7 +133,7 @@
130133
(load_expr implicit type='UIWindow?'
131134
(member_ref_expr implicit type='@lvalue UIWindow?' accessKind=read decl=Unused.(file).AppDelegate.window@/Users/paultaykalo/Projects/swift-scripts/unused-via-ast/XcodeProj/Unused/Unused/AppDelegate.swift:13:9 direct_to_storage
132135
(declref_expr implicit type='AppDelegate' decl=Unused.(file).AppDelegate.<anonymous>.self@/Users/paultaykalo/Projects/swift-scripts/unused-via-ast/XcodeProj/Unused/Unused/AppDelegate.swift:13:9 function_ref=unapplied))))))
133-
(func_decl implicit 'anonname=0x7fbde927a800' interface type='(AppDelegate) -> (UIWindow?) -> ()' access=internal @objc setter_for=window
136+
(func_decl implicit 'anonname=0x7ffa44301b50' interface type='(AppDelegate) -> (UIWindow?) -> ()' access=internal @objc setter_for=window
134137
(parameter_list
135138
(parameter "self" type='AppDelegate' interface type='AppDelegate'))
136139
(parameter_list
@@ -140,13 +143,13 @@
140143
(member_ref_expr implicit type='@lvalue UIWindow?' accessKind=write decl=Unused.(file).AppDelegate.window@/Users/paultaykalo/Projects/swift-scripts/unused-via-ast/XcodeProj/Unused/Unused/AppDelegate.swift:13:9 direct_to_storage
141144
(declref_expr implicit type='AppDelegate' decl=Unused.(file).AppDelegate.<anonymous>.self@/Users/paultaykalo/Projects/swift-scripts/unused-via-ast/XcodeProj/Unused/Unused/AppDelegate.swift:13:9 function_ref=unapplied))
142145
(declref_expr implicit type='UIWindow?' decl=Unused.(file).AppDelegate.<anonymous>.value@/Users/paultaykalo/Projects/swift-scripts/unused-via-ast/XcodeProj/Unused/Unused/AppDelegate.swift:13:9 function_ref=unapplied))))
143-
(func_decl implicit 'anonname=0x7fbde927adc0' interface type='(AppDelegate) -> (Builtin.RawPointer, inout Builtin.UnsafeValueBuffer) -> (Builtin.RawPointer, Builtin.RawPointer?)' access=internal materializeForSet_for=window
146+
(func_decl implicit 'anonname=0x7ffa44302110' interface type='(AppDelegate) -> (Builtin.RawPointer, inout Builtin.UnsafeValueBuffer) -> (Builtin.RawPointer, Builtin.RawPointer?)' access=internal materializeForSet_for=window
144147
(parameter_list
145148
(parameter "self" type='AppDelegate' interface type='AppDelegate'))
146149
(parameter_list
147150
(parameter "buffer" type='Builtin.RawPointer' interface type='Builtin.RawPointer')
148151
(parameter "callbackStorage" type='inout Builtin.UnsafeValueBuffer' interface type='inout Builtin.UnsafeValueBuffer' mutable))))
149-
(func_decl implicit 'anonname=0x7fbde9274980' interface type='(AppDelegate) -> () -> UIWindow?' access=internal @objc getter_for=window
152+
(func_decl implicit 'anonname=0x7ffa443018e0' interface type='(AppDelegate) -> () -> UIWindow?' access=internal @objc getter_for=window
150153
(parameter_list
151154
(parameter "self" type='AppDelegate' interface type='AppDelegate'))
152155
(parameter_list)
@@ -155,7 +158,7 @@
155158
(load_expr implicit type='UIWindow?'
156159
(member_ref_expr implicit type='@lvalue UIWindow?' accessKind=read decl=Unused.(file).AppDelegate.window@/Users/paultaykalo/Projects/swift-scripts/unused-via-ast/XcodeProj/Unused/Unused/AppDelegate.swift:13:9 direct_to_storage
157160
(declref_expr implicit type='AppDelegate' decl=Unused.(file).AppDelegate.<anonymous>.self@/Users/paultaykalo/Projects/swift-scripts/unused-via-ast/XcodeProj/Unused/Unused/AppDelegate.swift:13:9 function_ref=unapplied))))))
158-
(func_decl implicit 'anonname=0x7fbde927a800' interface type='(AppDelegate) -> (UIWindow?) -> ()' access=internal @objc setter_for=window
161+
(func_decl implicit 'anonname=0x7ffa44301b50' interface type='(AppDelegate) -> (UIWindow?) -> ()' access=internal @objc setter_for=window
159162
(parameter_list
160163
(parameter "self" type='AppDelegate' interface type='AppDelegate'))
161164
(parameter_list
@@ -165,7 +168,7 @@
165168
(member_ref_expr implicit type='@lvalue UIWindow?' accessKind=write decl=Unused.(file).AppDelegate.window@/Users/paultaykalo/Projects/swift-scripts/unused-via-ast/XcodeProj/Unused/Unused/AppDelegate.swift:13:9 direct_to_storage
166169
(declref_expr implicit type='AppDelegate' decl=Unused.(file).AppDelegate.<anonymous>.self@/Users/paultaykalo/Projects/swift-scripts/unused-via-ast/XcodeProj/Unused/Unused/AppDelegate.swift:13:9 function_ref=unapplied))
167170
(declref_expr implicit type='UIWindow?' decl=Unused.(file).AppDelegate.<anonymous>.value@/Users/paultaykalo/Projects/swift-scripts/unused-via-ast/XcodeProj/Unused/Unused/AppDelegate.swift:13:9 function_ref=unapplied))))
168-
(func_decl implicit 'anonname=0x7fbde927adc0' interface type='(AppDelegate) -> (Builtin.RawPointer, inout Builtin.UnsafeValueBuffer) -> (Builtin.RawPointer, Builtin.RawPointer?)' access=internal materializeForSet_for=window
171+
(func_decl implicit 'anonname=0x7ffa44302110' interface type='(AppDelegate) -> (Builtin.RawPointer, inout Builtin.UnsafeValueBuffer) -> (Builtin.RawPointer, Builtin.RawPointer?)' access=internal materializeForSet_for=window
169172
(parameter_list
170173
(parameter "self" type='AppDelegate' interface type='AppDelegate'))
171174
(parameter_list

unused-via-ast/test/swift-unused_test.rb

+11-1
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
class SwiftUnusedTest < Minitest::Test
55
def setup
66
@unused = create_sut
7+
@unused.search
78
end
89

910
def test_initial_state
@@ -15,11 +16,20 @@ def test_unused_classes
1516
assert_includes(@unused.classes, 'B')
1617
end
1718

18-
def test_used_by_inheritance
19+
def test_used_classes_by_inheritance
1920
assert_includes(@unused.classes, 'D')
2021
refute_includes(@unused.classes, 'C')
2122
end
2223

24+
def test_unused_protocols
25+
assert_includes(@unused.protocols, 'E')
26+
end
27+
28+
def test_used_protocols_by_inheritance
29+
assert_includes(@unused.protocols, 'G')
30+
refute_includes(@unused.protocols, 'F')
31+
end
32+
2333
def create_sut
2434
SwiftUnused.new("./test/fixtures/Unused.ast")
2535
end

0 commit comments

Comments
 (0)