-
Notifications
You must be signed in to change notification settings - Fork 32
/
Copy pathcheck_method_implementation.jl
92 lines (81 loc) · 2.94 KB
/
check_method_implementation.jl
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
"""
check_method_implementation(interface::Type,
func_name,
args_funcs::AbstractVector{Function};
[ignore_types]::Vector{Type}=Type[],
[print_results]::Bool=false
)::Bool
Check that a given (interface) function is implemented by all subtypes.
### Input
- `interface` -- parent interface type
- `func_name` -- function name
- `args_funcs` -- list of functions that each map a type to an argument
signature tuple
- `ignore_types` -- (optional, default: `Type[]`) list of types that should be
ignored
- `print_results` -- (optional, default: `false`) flag for printing intermediate
results
### Output
`true` iff all subtypes implement the given function.
### Notes
It is sufficient that a subinterface implements the function, i.e., it is not
required that every *concrete* type implements the function.
This function can also print all intermediate results to STDOUT.
### Examples
```jldoctest
julia> check_method_implementation(LazySet, σ,
Function[S -> (AbstractVector{Float64}, S)])
true
```
"""
function check_method_implementation(interface::Type,
func_name,
args_funcs::AbstractVector{Function};
ignore_types::Vector{Type}=Type[],
print_results::Bool=false
)::Bool
# first collect all base types that are subtypes of this interface
# NOTE: 'isleaftype' does not work due to type parameters
subtypes_to_test = subtypes(interface)
@assert !isempty(subtypes_to_test) "an interface must have a subtype"
base_types = Vector{Type}()
i = 0
while i < length(subtypes_to_test)
i += 1
subtype = subtypes_to_test[i]
new_subtypes = subtypes(subtype)
if isempty(new_subtypes)
# base type found
push!(base_types, subtype)
else
# yet another interface layer
append!(subtypes_to_test, new_subtypes)
end
end
# now check all base types
for subtype in base_types
if subtype ∈ ignore_types
if print_results
println("ignoring type $subtype")
end
continue
end
found = false
for args_func in args_funcs
if hasmethod(func_name, args_func(subtype))
if print_results
println("found implementation of $func_name for $subtype")
end
found = true
break
end
end
if !found
if print_results
println("no implementation of $func_name for $subtype")
end
return false
end
end
return true
end