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

Availability attribute support #51

Open
wants to merge 3 commits into
base: master
Choose a base branch
from

Conversation

christiangnrd
Copy link
Contributor

#50

Copy link
Contributor

github-actions bot commented Jan 28, 2025

Your PR requires formatting changes to meet the project's style guidelines.
Please consider running Runic (git runic master) to apply these changes.

Click here to view the suggested changes.
diff --git a/src/syntax.jl b/src/syntax.jl
index 0fc0adb..7e5a075 100644
--- a/src/syntax.jl
+++ b/src/syntax.jl
@@ -263,8 +263,8 @@ Attempt to contruct an Objective-C object or property that is
 not available in the current macOS version.
 """
 struct UnavailableError <: Exception
-  symbol::Symbol
-  minver::VersionNumber
+    symbol::Symbol
+    minver::VersionNumber
 end
 Base.showerror(io::IO, e::UnavailableError) = print(io, "UnavailableError: `", e.symbol, "` was introduced in macOS v", e.minver)
 
@@ -303,7 +303,7 @@ macro objcwrapper(ex...)
   # parse kwargs
   comparison = nothing
   immutable = nothing
-  availability = nothing
+    availability = nothing
   for kw in kwargs
     if kw isa Expr && kw.head == :(=)
       kw, value = kw.args
@@ -313,9 +313,9 @@ macro objcwrapper(ex...)
       elseif kw == :immutable
         value isa Bool || wrappererror("immutable keyword argument must be a literal boolean")
         immutable = value
-      elseif kw == :availability
-        Meta.isexpr(value, :macrocall) && value.args[1] == Symbol("@v_str") || wrappererror("availability keyword argument must be a `v_str` statement")
-        availability = macroexpand(__module__, value; recursive=false)
+            elseif kw == :availability
+                Meta.isexpr(value, :macrocall) && value.args[1] == Symbol("@v_str") || wrappererror("availability keyword argument must be a `v_str` statement")
+                availability = macroexpand(__module__, value; recursive = false)
       else
         wrappererror("unrecognized keyword argument: $kw")
       end
@@ -325,7 +325,7 @@ macro objcwrapper(ex...)
   end
   immutable = something(immutable, true)
   comparison = something(comparison, !immutable)
-  availability = something(availability, v"0")
+    availability = something(availability, v"0")
 
   # parse class definition
   if Meta.isexpr(def, :(<:))
@@ -366,9 +366,9 @@ macro objcwrapper(ex...)
 
     # add a pseudo constructor to the abstract type that also checks for nil pointers.
     function $name(ptr::id)
-      @static if !Sys.isapple() || ObjectiveC.macos_version() < $availability
-        throw($UnavailableError(Symbol($name), $availability))
-      end
+            @static if !Sys.isapple() || ObjectiveC.macos_version() < $availability
+                throw($UnavailableError(Symbol($name), $availability))
+            end
 
       ptr == nil && throw(UndefRefError())
       $instance(ptr)
@@ -527,7 +527,7 @@ macro objcproperties(typ, ex)
             getproperty_ex = objcm(__module__, :([object::id{$(esc(typ))} $getterproperty]::$srcTyp))
             getproperty_ex = quote
                 @static if !Sys.isapple() || ObjectiveC.macos_version() < $availability
-                  throw($UnavailableError(Symbol($(esc(typ)),".",field), $availability))
+                    throw($UnavailableError(Symbol($(esc(typ)), ".", field), $availability))
                 end
                 value = $(Expr(:var"hygienic-scope", getproperty_ex, @__MODULE__, __source__))
             end

Copy link

codecov bot commented Jan 28, 2025

Codecov Report

Attention: Patch coverage is 89.18919% with 4 lines in your changes missing coverage. Please review.

Project coverage is 76.64%. Comparing base (6911018) to head (6badbb7).
Report is 26 commits behind head on master.

Files with missing lines Patch % Lines
src/syntax.jl 83.33% 2 Missing ⚠️
src/version.jl 92.00% 2 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##           master      #51      +/-   ##
==========================================
+ Coverage   71.91%   76.64%   +4.73%     
==========================================
  Files          10       12       +2     
  Lines         769      942     +173     
==========================================
+ Hits          553      722     +169     
- Misses        216      220       +4     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

@maleadt
Copy link
Member

maleadt commented Jan 28, 2025

What about making this more generic than only checking against the macOS version, taking an arbitrary bool instead? Is there precedent for, say, platform-dependent attributes? If so, what about:

availability = is_macos(v"15")
availability = (Sys.ARCH == :aarch64)

@christiangnrd
Copy link
Contributor Author

christiangnrd commented Jan 31, 2025

I don't think there is precedence for this, I tried to have it behave like the clang attribute, and the only platform that supports both it and Julia is macOS.

I'm not opposed to it, but this would leave the need for code in the toml config for wrapping, and I would like it if the version errors were informative. Although maybe it could be changed to something like

UnavailableError: `<Symbol>` is not available on your platform, you may need to upgrade your operating system.

@christiangnrd
Copy link
Contributor Author

Did not mean to close

@christiangnrd christiangnrd reopened this Jan 31, 2025
@maleadt
Copy link
Member

maleadt commented Feb 3, 2025

this would leave the need for code in the toml config for wrapping

The TOML could always use a more specific macos_availability attribute and generate the appropriate code.

I would like it if the version errors were informative

I wonder if we could symbolize the condition:

UnavailableError: `<Symbol>` is not available on your platform, which does not fulfill the necessary predicate (`is_macos(v"15")`)

That said, I'm totally fine with mimicking Clang and providing something more specific. I'd then mimic it somewhat closer though, also including the platform and introduced/deprecated/obsolete. Just spitballing, but what about:

# in ObjectiveC.jl:
struct macOS
  # ...
  macOS(introduced::VersionNumber, deprecated=nothing, obsolete=nothing) = ...
end

# in user code
@objcwrapper availability = macOS(v"14") Foo <: Object
@objcwrapper availability = [macOS(introduced=v"14", deprecated=v"15")] Bar <: Object

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants