diff --git a/src/ObjectiveC.jl b/src/ObjectiveC.jl index 7256a75..dae721a 100644 --- a/src/ObjectiveC.jl +++ b/src/ObjectiveC.jl @@ -19,6 +19,25 @@ function enable_tracing(enabled::Bool) end const tracing = @load_preference("tracing", false)::Bool +@static if Sys.isapple() +function macos_version() + size = Ref{Csize_t}() + err = @ccall sysctlbyname("kern.osproductversion"::Cstring, C_NULL::Ptr{Cvoid}, size::Ptr{Csize_t}, + C_NULL::Ptr{Cvoid}, 0::Csize_t)::Cint + Base.systemerror("sysctlbyname", err != 0) + + osrelease = Vector{UInt8}(undef, size[]) + err = @ccall sysctlbyname("kern.osproductversion"::Cstring, osrelease::Ptr{Cvoid}, size::Ptr{Csize_t}, + C_NULL::Ptr{Cvoid}, 0::Csize_t)::Cint + Base.systemerror("sysctlbyname", err != 0) + + verstr = view(String(osrelease), 1:size[]-1) + parse(VersionNumber, verstr) +end +else + macos_version() = v"0" +end + # Types & Reflection include("primitives.jl") include("methods.jl") diff --git a/src/syntax.jl b/src/syntax.jl index b15c3b6..32bb987 100644 --- a/src/syntax.jl +++ b/src/syntax.jl @@ -415,6 +415,8 @@ contains a series of property declarations: check, returning `nothing` if the check fails). - `setter`: specifies the name of the Objective-C setter method. Without this, no `setproperty!` definition will be generated. + - `minver`: specifies the minimum macOS version supported by the property. Will only define + the property if the compatibility is met. - `@getproperty myProperty function(obj) ... end`: define a custom getter for the property. The function should take a single argument `obj`, which is the object that the property is being accessed on. The function should return the property value. @@ -427,6 +429,7 @@ macro objcproperties(typ, ex) isa(typ, Symbol) || propertyerror("expected a type name") Meta.isexpr(ex, :block) || propertyerror("expected a block of property declarations") + unsupportednames = Set{Symbol}() propertynames = Set{Symbol}() read_properties = Dict{Symbol,Expr}() write_properties = Dict{Symbol,Expr}() @@ -461,7 +464,20 @@ macro objcproperties(typ, ex) else propertyerror("invalid property specification $(property_arg)") end - push!(propertynames, property) + + # This complexity is so not definitions are created even if there is a @setproperty/@getproperty + supported = if haskey(kwargs, :minver) + (VersionNumber(get(kwargs, :minver, "0")) < macos_version()) && property ∉ unsupportednames + else + true + end + if supported + push!(propertynames, property) + else + push!(unsupportednames, property) + delete!(propertynames, property) + continue + end # handle the various property declarations. this assumes :object and :value symbol # names for the arguments to `getproperty` and `setproperty!`, as generated below.