-
Notifications
You must be signed in to change notification settings - Fork 10.5k
Migrate mirrors to use CustomReflectable API, rewrite dump() #838
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
Conversation
print(_reflect(CGSize(width: 30, height: 60)).summary) | ||
// CHECK-NEXT: (50.0, 60.0, 100.0, 150.0) | ||
print(_reflect(CGRect(x: 50, y: 60, width: 100, height: 150)).summary) | ||
// CHECK-NEXT: ▿ {( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This test needs to be rewritten to not assume a specific ordering of items.
Very awesome to see this finally getting done, Austin! Just one big question: I expected to see all the gyb’d nonsense fall away when we got to this point. Is it really still pulling its weight? |
Thanks! I would say that gyb is still pulling its weight in files like Arrays.swift.gyb and CGFloat.swift.gyb, where mirror conformance was only a small part. However, there are a bunch of mirror-specific .gyb files that I could get rid of, moving the conformances directly into the 'base' source files for each type. That might improve code structure/readability at the cost of a little duplication. Let me know what your thoughts are, and I'll make the appropriate changes for the next revision of this PR. |
One further note - there's one remaining use of _reflect(), in OutputStream.swift's _adHocPrint() method. I didn't remove it because that method depends on switching on the concrete type of the _MirrorType instance returned by _reflect(), and then doing stuff based on it. I can hold off removing it if there's a plan to replace or rewrite that method, or I can rewrite it myself. Up to you. |
@austinzheng yes, all the mirror-specific .gyb files, and the mirror-specific gyb usage within files that are gyb’d for other reasons, were what I had in mind. What kind of code duplication do you envision? The current design of Mirror was specifically crafted to avoid that duplication and the need for gyb. |
@austinzheng I don’t see why that switching should be needed since all the |
@dabrahams Sounds good, I'll remove the mirror-specific gyb usage. "Code duplication" was more of a strawman than anything else; I don't think it's an actual issue. As for _adHocPrint(), what I meant was that the existing implementation switches on _MirrorType's concrete type. I'll rewrite that function to not depend on _reflect(), if you have no objections. |
One thing I need to figure out is how to tell that a Mirror is reflecting a metatype. The existing code checks if the _MirrorType is a _MetatypeMirror, which isn't a good solution going forward. The Mirror API doesn't provide access to the object being reflected, and the |
Rewriting _adHocPrint sounds like the right move. We want to retire |
Why do you need to get this from the mirror? Don’t you have the original object at some level in the call chain? You needed it to get the mirror in the first place. Don’t forget, |
You're absolutely right, the original object is in fact passed to the function. I'll be sure to get some fresh air before I write any more code :).
|
The last obstacle before I can finish rewriting my function is getting the string representing a particular enum case. (The generic mirror created by Mirror(reflecting:) doesn't have any case name information.) The way it works right now is that _EnumMirror has a property called |
I think @jckarter is the knower of these things; hopefully this mention gets his attention. |
@@ -121,7 +120,6 @@ set(SWIFTLIB_SOURCES | |||
### PLEASE KEEP THIS LIST IN ALPHABETICAL ORDER ### | |||
Availability.swift | |||
Bit.swift | |||
CollectionMirrors.swift.gyb | |||
CollectionOfOne.swift | |||
ExistentialCollection.swift.gyb | |||
Mirror.swift |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Speaking of Mirror.swift, the _legacyMirror
method should obviously be gone when this PR is done.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hi Dave,
_legacyMirror
is tightly integrated with the Mirror
initializers that generate mirrors from _reflect()
if no custom mirror is available. I don't think it can be removed until Phase 3 of SR-88 is complete, at which point we'd rip all use of _reflect()
out of Mirror
and use the new runtime entry points.
What do you think?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it makes sense to make as much progress as possible in the incremental development spirit. If we can't remove something without redesigning the runtime, it shouldn't block progress where we can make it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Agreed, this PR is already pretty big as-is. I'm happy to do follow-up work that only makes sense after other dependencies are resolved.
I'm still working on this. Goals for next update:
|
@@ -73,12 +73,11 @@ public enum ImplicitlyUnwrappedOptional<Wrapped> | |||
} | |||
|
|||
/// Returns a mirror that reflects `self`. | |||
public func _getMirror() -> _MirrorType { | |||
// FIXME: This should probably use _OptionalMirror in both cases. | |||
public func customMirror() -> Mirror { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Doesn't the usual enum mirror produce the same output? I don't think Optional needs anything custom anymore.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'll investigate, but I think that you are right; there are probably a few custom mirrors that don't need to exist. I'll do an audit and see what else is redundant.
4eb1341
to
a4d678f
Compare
I updated this PR. (As part of the update I did some rebasing and force pushing; it looks like the PR is still intact.) Slava pointed out a few things that should be addressed before this goes in. I'll also need to spin up a Ubuntu VM and run the tests there. |
I removed a few more GYB files. I left GYB mirror implementations when it 'made sense' - e.g. there was no good place to put the code otherwise, since a type's entire implementation was in a GYB file, or moving the mirrors out of the GYB would have caused significant repetition. |
a4d678f
to
2aa2705
Compare
I pushed an update.
I figured the work to make the above possible was simple enough that it didn't need to be discussed extensively before an initial implementation. If anyone thinks that the algorithm above should be changed, I'm happy to update the PR. Unfortunately, the regression that @slavapestov mentioned in a line comment (involving Many of the test changes that were in previous versions of this PR have been removed, since they are no longer necessary. Also of note:
|
new (result) String("(ErrorType Object)"); | ||
break; | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Seems like swift_OpaqueSummary could be simplified by just returning a
const char* and letting the conversion happen in Swift code
on Tue Jan 19 2016, Austin Zheng <notifications-AT-i.8713187.xyz> wrote:
Through what path were we getting a sensible result in these cases
The less code, the mo' better.
Thanks for your diligence.
Done, thanks! |
I'll look into how NSObjects were printed and figure out how to replicate that behavior. Unfortunately, although https://bugs.swift.org/browse/SR-426 has been fixed for the mini test case I wrote up, the unit test that prompted me to file it still fails. I'm going to have to dig into my new dump() tonight to figure out what is going on, and possibly file a new bug. |
2aa2705
to
5466797
Compare
I pushed another update. All unit and validation tests pass on OS X now. Changes:
I also did some digging into the ugly Objective-C description. In the existing code, the The new Let me know if you have any questions. |
@@ -0,0 +1,22 @@ | |||
%{ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we sink this file into stdlib/public/core/Mirrors.swift.gyb
so we don't have to do that parseTemplate
/executeTemplate
dance?
Note: on the whole, this work is a thing of beauty that I'm dyin' to accept!
…te dump() Jira: SR-88 Changes: - Removed stdlib type conformances to _Reflectable - Conformed stdlib types to CustomReflectable, CustomPlaygroundQuickLookable - Rewrote dump() function to not use _reflect() - CGRect, CGPoint, CGSize now conform to CustomDebugStringConvertible - Rewrote unit tests for compatibility with new API
5466797
to
9798dfd
Compare
Good call. Got rid of Let me know if you see any other issues or want any other changes! |
on Thu Jan 21 2016, Austin Zheng <notifications-AT-i.8713187.xyz> wrote:
If we had public CI infrastructure I'd just merge it now, but since |
Migrate mirrors to use CustomReflectable API, rewrite dump() ...and there was much rejoicing.
I had to revert this in 8917eb0. It looks like it's breaking the stdlib build, at least when building with 'build-script -r'. swift/stdlib/public/core/Arrays.swift.gyb:787:12: error: cannot invoke initializer for type 'Mirror' with an argument list of type '(ContiguousArray, children: ArrayTypeMirrorCollection<>, displayStyle: _)' |
Thanks for bringing this to my attention. I'll try building tonight with the '-r' flag to troubleshoot the issue. Austtin Sent from my iPhone
|
I determined why it broke (although I still need to root cause it). For some reason my master got out of sync with upstream's master. My branch's parent was my out-of-date master. One of the diffs between the upstream master and the out-of-date old master changed something that caused my code to become invalid. I'll troubleshoot the exact cause and open a new PR tonight. |
Thanks, Austin! |
Awesome. I suspected something like that might have been the cause. Our commit rate is pretty high so it's not hard to end up in a situation like that (in fact it happened with a pair of commits today that came in at about the same time!). |
@rudkx Thanks for catching the issue and reverting the commit. I'll look into how I can make my workflow less prone to this sort of thing. |
Jira: SR-88
Changes:
NOTES: Jira here: https://bugs.swift.org/browse/SR-88. The commit turned out quite a bit larger than I anticipated, so if you want me to try breaking it down I'd be happy to do so. All tests pass on OS X. Note that I disabled a few tests that were affected by the linked bugs in the Jira ticket. A later PR will contain additional unit tests for any types that I missed. Let me know if you have any questions.