Skip to content

Codable conformance to some Foundation types #1108

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

Merged
merged 13 commits into from
Jul 18, 2017
Merged

Conversation

bubski
Copy link
Contributor

@bubski bubski commented Jul 11, 2017

This PR mirrors some changes swiftlang/swift#9715

Add conformances + unit tests for

  • PersonNameComponents
  • UUID
  • URL
  • NSRange
  • Locale
  • IndexSet
  • IndexPath
  • AffineTransform
  • Decimal
  • DateInterval
  • CGFloat (unit tested indirectly)

Not included in this PR, because of some problems that need to be solved

  • Calendar
  • CharacterSet
  • DateComponents
  • Measurement
  • TimeZone

// other type.
do {
if NativeType.self == Float.self {
self.native = NativeType(try container.decode(Float.self))
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@itaiferber Could you double check this for me please?
over at https://github.com/apple/swift/blob/master/stdlib/public/SDK/CoreGraphics/CGFloat.swift.gyb#L823 it's

if NativeType.self == Float.self {
    self.native = NativeType(try container.decode(Double.self))
} else {
    self.native = NativeType(try container.decode(Float.self))
}

But shouldn't Double.self and Float.self be the other way around?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That is behaving correctly; it is in the fallback case where it tries to decode in the reversed order because the primary type failed.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Philippe is correct. This is a fallback case for encoders which differentiate between Doubles and Floats in a way that makes them incompatible. On a platform where CGFloat.NativeType == Double.self, we will encode it as a Double. If we try to read it back on a platform where CGFloat.NativeType == Float.self, however, the decode could fail since the Double value would not fit in a Float. So this is that fallback case — if our native type is a Float but we failed to read it as a Float, try to read it as a Double since the decode may have failed.

The code is correct — you'll want to have the types the same way here as in the Foundation overlay.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@phausler fix pushed

@phausler
Copy link
Contributor

@swift-ci please test

// other type.
do {
if NativeType.self == Float.self {
self.native = NativeType(try container.decode(Float.self))
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Philippe is correct. This is a fallback case for encoders which differentiate between Doubles and Floats in a way that makes them incompatible. On a platform where CGFloat.NativeType == Double.self, we will encode it as a Double. If we try to read it back on a platform where CGFloat.NativeType == Float.self, however, the decode could fail since the Double value would not fit in a Float. So this is that fallback case — if our native type is a Float but we failed to read it as a Float, try to read it as a Double since the decode may have failed.

The code is correct — you'll want to have the types the same way here as in the Foundation overlay.

@bubski
Copy link
Contributor Author

bubski commented Jul 11, 2017

@itaiferber @phausler Oh I didn't realize that. Thanks for the explanation!

@bubski
Copy link
Contributor Author

bubski commented Jul 11, 2017

@itaiferber fix pushed 👌

@itaiferber
Copy link
Contributor

@bubski Thanks!

@itaiferber
Copy link
Contributor

@swift-ci Please test

@ianpartridge
Copy link
Contributor

ianpartridge commented Jul 14, 2017

Hi @bubski this is really great. Please could you explain what the problems are with Calendar, CharacterSet, DateComponents, Measurement and TimeZone? Are these problems tracked somewhere and do we know how to resolve them?

@bubski
Copy link
Contributor Author

bubski commented Jul 14, 2017

@ianpartridge Sure, I don't have the full picture but I can share what I've seen so far.

Oh and as for tracking, I haven't reported them anywhere yet. That's on me. I was waiting to have a bit more context and understand them better, but should have reported them.
I'll try and pick this up this weekend.

Calendar, DateComponents, TimeZone

Calendar, DateComponents and TimeZone I believe share the same issue.

CFTimeZone.c includes <tzfile.h>
https://github.com/apple/swift-corelibs-foundation/blob/master/CoreFoundation/NumberDate.subproj/CFTimeZone.c#L35
Which defines some paths.
The one we're interested in is TZDIR.

tzfile.h in macOS 10.12 SDK defines

#define TZDIR	"/usr/share/zoneinfo" /* Time zone object file directory */

tzfile.h in macOS 10.13 SDK defines

#define TZDIR	"/var/db/timezone/zoneinfo" /* Time zone object file directory */

I'm running macOS 10.12.
I can't build swift-corelibs-foundation against macOS 10.12 SDK. I'm not sure why.
So I'm running Xcode 9 and build against macOS 10.13 SDK.
But my zoneinfo doesn't exist at /var/db/timezone/zoneinfo but at /usr/share/zoneinfo since I'm on 10.12.

I don't know where to go from here and didn't have time to look into it.
Maybe I'm fundamentally wrong here and missing something.

--

Also, there's this #274 (review) but it's not as severe as the above.

CharacterSet

https://github.com/apple/swift-corelibs-foundation/blob/master/TestFoundation/TestNSCharacterSet.swift#L298

This discrepancy makes it hard for me to write reasonable tests.
I'm not sure if this was the only problem though.

Measurement

Sorry, I don't remember :(

@ianpartridge
Copy link
Contributor

ianpartridge commented Jul 14, 2017

Thanks for the comprehensive update!

The TZDIR issue is known and there has been some discussion on the swift-corelibs-dev mailing list. As you discovered, the location of the timezone database on macOS has changed in High Sierra. For now you can either symlink /var/db/timezone/zoneinfo to /usr/share/zoneinfo or add #define TZDIR "/usr/share/zoneinfo" just after the #include line here. Hopefully one of those workarounds can help move the Codable conformances forward?

@bubski
Copy link
Contributor Author

bubski commented Jul 14, 2017

@ianpartridge Thanks for the info! I appreciate it and it's very helpful.

I don't want to make a PR with anything that's breaking on macOS, so for some things I might have to hold off until they underlying reasons are fixed.

@ianpartridge
Copy link
Contributor

Thanks @bubski :)

Can we merge this PR? The team in IBM are waiting to start experimenting with these new conformances :)

@itaiferber
Copy link
Contributor

@swift-ci Please test and merge

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.

5 participants