Skip to content
This repository has been archived by the owner on Dec 5, 2019. It is now read-only.

[WIP] Compile time safe keypath #61

Closed
wants to merge 4 commits into from
Closed

Conversation

robrix
Copy link

@robrix robrix commented Feb 22, 2014

⚠️ Not yet ready for merge due to problems with class keypaths, e.g. @keypath(NSObject, version).

This allows it to be used to initialize static variables with the same type-safety and autocompletion benefits, at the cost of complicating the macro’s definition.

Note that this can only apply to the two-argument variant, since there is no way to split the string at compile-time.

Further, an additional change allows types to be passed as the first argument of @keypath, removing the need for workarounds like @keypath(Foo.new, …) which can be jarring, and which may be inconvenient in cases where e.g. +new is unavailable or you don’t even have a concrete class (e.g. with protocols). However, as @lldong points out, this currently breaks generation of class keypaths (e.g. @keypath(NSObject, version)).

The trick this uses to take the type of a comma express compiler-visible mechanism might be useful elsewhere; is something like that already available elsewhere? I ended up not requiring that trick at all; using the comma operator simplified this greatly. Seems like only multistatement things would need the block trick, and they’re probably already in one.

  • Can we pass classes directly for class key paths but also allow types?

This allows it to be used to initialize static variables with the same type-safety and autocompletion benefits.

Note that this can only apply to the two-argument variant, since there is no way to split the string at compile-time.
@robrix
Copy link
Author

robrix commented Feb 22, 2014

As an unanticipated benefit of this process, you can now use Xcode’s ⌃⌘E feature with @keypath(x, y) invocations to rename any instances of that method/keypath within a scope.

By further taking the type of `OBJ` and casting `nil` as the receiver, object types can be passed as the left hand side directly, e.g. `id<NSValidatedUserInterfaceItem>`, allowing type-safety, refactoring, and autocompletion of properties of types without having to resort to `Foo.new` hacks as the left hand side (which can be jarring and/or inconvenient).
@lldong
Copy link

lldong commented Feb 24, 2014

@robrix @keypath(NSObject, version) failed with:

error: used type 'typeof(NSObject)' (aka 'NSObject') where arithmetic or pointer type is required

@jakebromberg
Copy link

@lldong use
@keypath(NSObject *, version)

@robrix
Copy link
Author

robrix commented Feb 24, 2014

@lldong That’s not a valid type name; you want NSObject *.

@robrix
Copy link
Author

robrix commented Feb 24, 2014

Cheers @jakebromberg 😄

@lldong
Copy link

lldong commented Feb 24, 2014

@robrix @jakebromberg + (NSInteger)version is a class method of NSObject. The implementation on master branch allows @keypath(NSObject, version)

NSString *versionPath = @keypath(NSObject, version);
// => @"version"

@robrix
Copy link
Author

robrix commented Feb 24, 2014

Ahh, I gotcha—good catch @lldong, cheers.

@robrix
Copy link
Author

robrix commented Jun 11, 2014

@jspahrsummers I don’t know how you feel about any of this, but I’m inclined to kick it to the curb given Swift.

@jspahrsummers
Copy link
Owner

@robrix
Copy link
Author

robrix commented Jun 11, 2014

that is a surprisingly disturbing gif

(we could always revert to non-typename keypaths so that the bare class name can still be passed)

diederich added a commit to cocologics/libextobjc that referenced this pull request Jun 28, 2017
Submodule changes to be committed:

* Configuration c8e5527...4ac967d (12):
  > Merge pull request jspahrsummers#80 from cocologics/feature/xcode9-update
  > Merge pull request jspahrsummers#79 from cocologics/feature/xcode9-update
  > Merge pull request jspahrsummers#71 from fabb/analyzer_localized
  > enable CLANG_ANALYZER_NONNULL
  > enable CLANG_WARN_NULLABLE_TO_NONNULL_CONVERSION
  > enables SWIFT_TREAT_WARNINGS_AS_ERRORS
  > Merge pull request jspahrsummers#67 from fabb/enable_nullability_completeness_warning
  > Merge pull request jspahrsummers#65 from Abizern/xcode8_debug_flag
  > Merge pull request jspahrsummers#64 from diederich/enableTestability
  > Merge pull request jspahrsummers#63 from diederich/implicitCaptureOfSelf
  > Merge pull request jspahrsummers#62 from calebd/xcode-8-beta-5-warnings
  > Merge pull request jspahrsummers#61 from ikesyo/disable-framework-codesigning
diederich added a commit that referenced this pull request Jul 14, 2017
* bumped the xcconfigs to latest version
* fix build on Xcode 9 ('void' missing in strict declaration checking)

Submodule changes to be committed:

* Configuration c8e5527...4ac967d (12):
  > Merge pull request #80 from cocologics/feature/xcode9-update
  > Merge pull request #79 from cocologics/feature/xcode9-update
  > Merge pull request #71 from fabb/analyzer_localized
  > enable CLANG_ANALYZER_NONNULL
  > enable CLANG_WARN_NULLABLE_TO_NONNULL_CONVERSION
  > enables SWIFT_TREAT_WARNINGS_AS_ERRORS
  > Merge pull request #67 from fabb/enable_nullability_completeness_warning
  > Merge pull request #65 from Abizern/xcode8_debug_flag
  > Merge pull request #64 from diederich/enableTestability
  > Merge pull request #63 from diederich/implicitCaptureOfSelf
  > Merge pull request #62 from calebd/xcode-8-beta-5-warnings
  > Merge pull request #61 from ikesyo/disable-framework-codesigning
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

4 participants