Skip to content

Commit 8c78cc7

Browse files
Follow-up to Availability PR (#54)
1 parent a37c331 commit 8c78cc7

File tree

4 files changed

+35
-20
lines changed

4 files changed

+35
-20
lines changed

Project.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
name = "ObjectiveC"
22
uuid = "e86c9b32-1129-44ac-8ea0-90d5bb39ded9"
3-
version = "3.4.0"
3+
version = "3.4.1"
44

55
[deps]
66
CEnum = "fa961155-64e5-5f13-b03f-caf6b980ea82"

src/availability.jl

Lines changed: 20 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,13 @@
11
export PlatformAvailability, UnavailableError
22

3-
# Each platform tuple has a symbol representing the constructor, a pretty name for errors,
4-
# and a symbol of the function used to check the version for that platform
5-
const SUPPORTED_PLATFORMS = [(:macos, "macOS", :macos_version), (:darwin, "Darwin", :darwin_version)]
3+
# Each platform tuple has a symbol representing the constructor, a pretty_name name for errors,
4+
# a symbol of the function used to check the version for that platform, and the function that
5+
# returns whether that statement applies for this device
6+
const SUPPORTED_PLATFORMS = Dict(
7+
:macos => ("macOS", :macos_version, Sys.isapple),
8+
:darwin => ("Darwin", :darwin_version, Sys.isapple),
9+
:test => ("Never applicable", :error, () -> false)
10+
)
611

712
# Based off of Clang's `CXPlatformAvailability`
813
"""
@@ -21,20 +26,20 @@ struct PlatformAvailability{P}
2126
obsoleted::Union{Nothing, VersionNumber}
2227
unavailable::Bool
2328

24-
function PlatformAvailability(platform::Symbol, introduced, deprecated = nothing, obsoleted = nothing, unavailable = false)
25-
platform in first.(SUPPORTED_PLATFORMS) || throw(ArgumentError(lazy"`:$platform` is not a supported platform for `PlatformAvailability`, see `?PlatformAvailability` for more information."))
26-
return new{platform}(introduced, deprecated, obsoleted, unavailable)
29+
function PlatformAvailability(p::Symbol, introduced, deprecated = nothing, obsoleted = nothing, unavailable = false)
30+
haskey(SUPPORTED_PLATFORMS, p) || throw(ArgumentError(lazy"`:$p` is not a supported platform for `PlatformAvailability`, see `?PlatformAvailability` for more information."))
31+
return new{p}(introduced, deprecated, obsoleted, unavailable)
2732
end
2833
end
2934
PlatformAvailability(platform; introduced = nothing, deprecated = nothing, obsoleted = nothing, unavailable = false) =
3035
PlatformAvailability(platform, introduced, deprecated, obsoleted, unavailable)
3136

32-
function is_unavailable(f::Function, avail::PlatformAvailability)
33-
return avail.unavailable ||
34-
(!isnothing(avail.obsoleted) && f() >= avail.obsoleted) ||
35-
(!isnothing(avail.introduced) && f() < avail.introduced)
37+
function is_available(f::Function, avail::PlatformAvailability)
38+
return !avail.unavailable &&
39+
(isnothing(avail.obsoleted) || f() < avail.obsoleted) &&
40+
(isnothing(avail.introduced) || f() >= avail.introduced)
3641
end
37-
is_unavailable(avails::Vector{<:PlatformAvailability}) = any(is_unavailable.(avails))
42+
is_available(avails::Vector{<:PlatformAvailability}) = all(is_available.(avails))
3843

3944
"""
4045
UnavailableError(symbol::Symbol, minver::VersionNumber)
@@ -59,7 +64,7 @@ function UnavailableError(f::Function, symbol::Symbol, platform::String, avail::
5964
return UnavailableError(symbol, msg)
6065
end
6166
function UnavailableError(symbol::Symbol, avails::Vector{<:PlatformAvailability})
62-
firsterror = findfirst(is_unavailable, avails)
67+
firsterror = findfirst(!is_available, avails)
6368
return UnavailableError(symbol, avails[firsterror])
6469
end
6570

@@ -69,11 +74,11 @@ function Base.showerror(io::IO, e::UnavailableError)
6974
end
7075

7176
# Platform-specific definitions
72-
for (name, pretty_name, version_function) in SUPPORTED_PLATFORMS
77+
for (name, (pretty_name, ver_func, plat_func)) in SUPPORTED_PLATFORMS
7378
quotname = Meta.quot(name)
7479
@eval begin
75-
is_unavailable(avail::PlatformAvailability{$quotname}) = is_unavailable($version_function, avail)
76-
UnavailableError(symbol::Symbol, avail::PlatformAvailability{$quotname}) = UnavailableError($version_function, symbol, $pretty_name, avail)
80+
is_available(avail::PlatformAvailability{$quotname}) = !$plat_func() || is_available($ver_func, avail)
81+
UnavailableError(symbol::Symbol, avail::PlatformAvailability{$quotname}) = UnavailableError($ver_func, symbol, $pretty_name, avail)
7782
end
7883
end
7984

src/syntax.jl

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -311,7 +311,7 @@ macro objcwrapper(ex...)
311311
end
312312
immutable = something(immutable, true)
313313
comparison = something(comparison, !immutable)
314-
availability = something(availability, PlatformAvailability(:macos, v"0"))
314+
availability = something(availability, PlatformAvailability[])
315315

316316
# parse class definition
317317
if Meta.isexpr(def, :(<:))
@@ -352,7 +352,7 @@ macro objcwrapper(ex...)
352352

353353
# add a pseudo constructor to the abstract type that also checks for nil pointers.
354354
function $name(ptr::id)
355-
@static if !Sys.isapple() || ObjectiveC.is_unavailable($availability)
355+
@static if !ObjectiveC.is_available($availability)
356356
throw($UnavailableError(Symbol($name), $availability))
357357
end
358358

@@ -506,7 +506,7 @@ macro objcproperties(typ, ex)
506506
if haskey(kwargs, :availability)
507507
availability = get_avail_exprs(__module__, kwargs[:availability])
508508
end
509-
availability = something(availability, PlatformAvailability(:macos, v"0"))
509+
availability = something(availability, PlatformAvailability[])
510510

511511
getterproperty = if haskey(kwargs, :getter)
512512
kwargs[:getter]
@@ -515,7 +515,7 @@ macro objcproperties(typ, ex)
515515
end
516516
getproperty_ex = objcm(__module__, :([object::id{$(esc(typ))} $getterproperty]::$srcTyp))
517517
getproperty_ex = quote
518-
@static if !Sys.isapple() || ObjectiveC.is_unavailable($availability)
518+
@static if !ObjectiveC.is_available($availability)
519519
throw($UnavailableError(Symbol($(esc(typ)), ".", field), $availability))
520520
end
521521
value = $(Expr(:var"hygienic-scope", getproperty_ex, @__MODULE__, __source__))

test/runtests.jl

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ end
1010
# Availability
1111
@objcwrapper availability = macos(v"1000") TestWrapperNoIntro1 <: Object
1212
@objcwrapper availability = macos(introduced = v"1000") TestWrapperNoIntro2 <: Object
13+
@objcwrapper availability = test(introduced = v"1000") TestIgnore <: Object
1314
@objcwrapper availability = macos(deprecated = v"1", obsoleted = v"2.3.4") TestWrapperObsolete <: Object
1415
@objcwrapper availability = macos(introduced = v"1000", unavailable = true) TestWrapperUnavailable <: Object
1516
@objcwrapper availability = macos(v"0") TestPropAvail <: Object
@@ -25,6 +26,7 @@ end
2526
@objcwrapper availability = [macos(v"1000"), darwin(v"0")] TestVectMultiple1 <: Object
2627
@objcwrapper availability = [macos(v"0"), darwin(v"1000")] TestVectMultiple2 <: Object
2728
@objcwrapper availability = [macos(v"0"), darwin(v"0")] TestVectMultiple3 <: Object
29+
@objcwrapper availability = [macos(v"0"), test(v"1000")] TestVectMultiple4 <: Object
2830
@objcwrapper availability = [macos(v"0")] TestVectAvail <: Object
2931
@objcproperties TestVectAvail begin
3032
@autoproperty length::Culong
@@ -41,6 +43,10 @@ end
4143
fakeidwrap = id{TestWrapperNoIntro2}(1)
4244
@test_throws "UnavailableError: `TestWrapperNoIntro2` was introduced on macOS v1000.0.0" TestWrapperNoIntro2(fakeidwrap)
4345
end
46+
let # Not-applicable platform ignored
47+
fakeidwrap = id{TestIgnore}(1)
48+
@test TestIgnore(fakeidwrap) isa TestIgnore
49+
end
4450
let # obsolete
4551
fakeidwrap = id{TestWrapperObsolete}(1)
4652
@test_throws "UnavailableError: `TestWrapperObsolete` is obsolete since macOS v2.3.4" TestWrapperObsolete(fakeidwrap)
@@ -65,6 +71,10 @@ end
6571
fakeidwrap = id{TestVectMultiple3}(1)
6672
@test TestVectMultiple3(fakeidwrap) isa TestVectMultiple3
6773
end
74+
let # Not-applicable platform ignored
75+
fakeidwrap = id{TestVectMultiple4}(1)
76+
@test TestVectMultiple4(fakeidwrap) isa TestVectMultiple4
77+
end
6878

6979
# property
7080
str1 = "foo"

0 commit comments

Comments
 (0)