Skip to content

[Index][CodeCompletion] Fix #keyPath indexing when a type is referenced #20020

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

Closed

Conversation

rockbruno
Copy link
Contributor

@rockbruno rockbruno commented Oct 24, 2018

From SR-9020: Type references in #keyPath were being resolved but were not being added to the components list, which prevented the expression from being indexed when the expression included a type.

I think referencing a type in #keyPath is rather common as this keyword is normally created outside the scope of the watched property (like in iOS with AVFoundation types), so I created a new component type and assigned the resolved reference to it, which fixed the indexing issue.

It also seems like code completion was crashing when accessing inner properties, so I made a change to it in order to make expressions like #keyPath(myInt.hashValue) complete.

@rockbruno rockbruno changed the title [Index][SR-9020] Fix #keyPath indexing when a type is referenced [Index][CodeCompletion] Fix #keyPath indexing when a type is referenced Oct 24, 2018
@rockbruno
Copy link
Contributor Author

CC @akyrtzi

@@ -57,7 +57,7 @@ func testKeyPath(a: A, b: B) {
let _: String = #keyPath(A.propString)

// Property of String property (which looks on NSString)
let _: String = #keyPath(A.propString.URLsInText)
let _: String = #keyPath(A.propString.urlsInText)
Copy link
Contributor

Choose a reason for hiding this comment

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

It's not clear to me, was this change necessary because of your other changes ? I don't see how.

Copy link
Contributor Author

@rockbruno rockbruno Oct 29, 2018

Choose a reason for hiding this comment

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

The test started to fail stating the name of the property changed, and I assumed it wasn't the case before because the expression wasn't being indexed, although it does seem weird. Was it not supposed to happen?

unexpected error produced: 'URLsInText' has been renamed to 'urlsInText'

Copy link
Contributor

Choose a reason for hiding this comment

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

'Indexing' them should not have any effect in compiler errors, is the case that these were not even typechecked before ?

Copy link
Contributor

Choose a reason for hiding this comment

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

Are you 100% sure your changes are triggering the failure ?

Copy link
Contributor Author

@rockbruno rockbruno Oct 29, 2018

Choose a reason for hiding this comment

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

You can actually reproduce this in Xcode 10 with old Swift 2 properties:

import Foundation
let a = #keyPath(Bundle.mainBundle)
print(a)

It will work and return mainBundle, despite the property being called main now. You can get it to throw the error if you get the property directly, which is the case where indexing was fine:

import Foundation
extension Bundle {
    func getPath() {
        let a = #keyPath(mainBundle)
        print(a)
    }
}

EDIT: After debugging the rename warning, I was able to confirm that they weren't being fully typechecked before as the changes now result in this specific logic getting called:

https://github.com/apple/swift/blob/df64e8a5dcd96e2b402be4445e0d8e913fedf71b/lib/Sema/TypeCheckAvailability.cpp#L2437

As the key paths that included types never stopped being UnresolvedProperties, this case was never being reached by them. Interesting that it used to work, I didn't know the old un-renamed properties could still be used like that!

This was the main culprit: https://github.com/apple/swift/blob/df64e8a5dcd96e2b402be4445e0d8e913fedf71b/lib/Sema/TypeCheckExprObjC.cpp#L417

which got treated by:
https://github.com/apple/swift/blob/df64e8a5dcd96e2b402be4445e0d8e913fedf71b/lib/Sema/TypeCheckExprObjC.cpp#L400

Copy link
Contributor

@akyrtzi akyrtzi Oct 29, 2018

Choose a reason for hiding this comment

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

@DougGregor @rudkx please review, with these changes, properties from type references in #keypaths are properly typechecked now.

@akyrtzi akyrtzi requested a review from rintaro October 29, 2018 17:05
@akyrtzi
Copy link
Contributor

akyrtzi commented Oct 29, 2018

@rintaro please review.

@rockbruno
Copy link
Contributor Author

Just a friendly review ping as this got buried on our feeds but no rush, hope you guys can find some time to see this soon!

case KeyPathExpr::Component::Kind::Property:
case KeyPathExpr::Component::Kind::Type: {
//For code completion purposes, we only care about the last expression.
Copy link
Contributor

Choose a reason for hiding this comment

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

It's not clear to me how this relates to code completion.

Copy link
Contributor Author

@rockbruno rockbruno Nov 13, 2018

Choose a reason for hiding this comment

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

I might have treated this in the wrong place, but the issue I was having was that this method seems to be called twice on code completion - first to resolve the properties and then again in order to return the property that's trying to be completed, as far as I could tell. I couldn't find another case where this happened, so I assumed that code completion was the only case where the resolved enum cases would trigger here. Is it the wrong place?

The main idea for this block is that if I had something like#keyPath(MyType.myProperty., I had to ignore the type and return myProperty for code completion to show the correct results.

if (&component == &expr->getComponents().back()) {
return component.getComponentType();
} else {
continue;
Copy link
Contributor

Choose a reason for hiding this comment

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

This is also changing the behavior for Kind::Property, is that intentional?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

That's because you could in theory be reaching the keypath property from other properties too, like in #keyPath(MyType.myProperty.hashValue).

@rudkx
Copy link
Contributor

rudkx commented Nov 13, 2018

@swift-ci Please smoke test

@rudkx rudkx requested review from jckarter and DougGregor November 14, 2018 18:50
@CodaFi
Copy link
Contributor

CodaFi commented Nov 18, 2019

It's been a year. Sorry @rockbruno, could you update this? I'll take a look and tag @xedin as well if you do.

@rockbruno
Copy link
Contributor Author

Sure, I'll rebase this in the next hours.

@rockbruno rockbruno force-pushed the objc-keypath-indexing-fix branch from df64e8a to e0a4f2f Compare November 18, 2019 21:48
@rockbruno
Copy link
Contributor Author

I've rebased but there are two pieces of logic that don't exist anymore, so this might not be building. I'll be able to take a look soon.

@akyrtzi
Copy link
Contributor

akyrtzi commented Nov 18, 2019

@nathawes please take a look.

@DougGregor
Copy link
Member

@swift-ci please smoke test

@rockbruno rockbruno force-pushed the objc-keypath-indexing-fix branch from e0a4f2f to a3204b9 Compare January 3, 2020 12:37
@rockbruno
Copy link
Contributor Author

Sorry for the delay, there were indeed new cases to be considered after rebasing.
Should be working correctly now 👍

@nathawes
Copy link
Contributor

nathawes commented Jan 6, 2020

@swift-ci please test

@swift-ci
Copy link
Contributor

swift-ci commented Jan 6, 2020

Build failed
Swift Test OS X Platform
Git Sha - e0a4f2fb03102d69c4a05213220474f9362a80f2

@swift-ci
Copy link
Contributor

swift-ci commented Jan 6, 2020

Build failed
Swift Test Linux Platform
Git Sha - e0a4f2fb03102d69c4a05213220474f9362a80f2

@rockbruno
Copy link
Contributor Author

I missed that test case, sorry for that. Fixing it

@rockbruno
Copy link
Contributor Author

Unfortunately, these changes aren't working anymore 😢The properties aren't getting type-checked anymore post-rebase.

I think I need to do this from scratch. If it ends up being the case, I'll open a new PR for this. Sorry!

@CodaFi
Copy link
Contributor

CodaFi commented Apr 10, 2020

I'm going to close this out since it seems like the approach taken here has fizzled. I appreciate your interest in fixing this bug, it sounds like you were really close.

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.

7 participants