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

Implement Resolver.asMemberOf for Properties and Functions #110

Merged
merged 11 commits into from
Oct 21, 2020

Conversation

yigit
Copy link
Collaborator

@yigit yigit commented Oct 6, 2020

This PR implements functionality to see a property/function as member of a given type.

Internally, it uses the Substitutor from the compiler.

Since function declarations contain multiple types, I've added a new KSFunctionType which can hold this information.

It supports properties and functions declared in a class but does not support extension functions yet. We need a new API for them since they are not really a member of the receiver type.

When a substitution fails, we return the type or KSFunctionType inferred from the declaration of the property/function respectively.

Fixes: #49

@yigit
Copy link
Collaborator Author

yigit commented Oct 11, 2020

this is ready for review (besides I need to rebase w/ master).

Renamed KSFunctionType to KSFunction.
If the given KSType is an error or I cannot resolve the function declaration (not sure when it happens), I'll return a KSFunction which just returns KSError for all types but still matches the function declaration

yigit and others added 9 commits October 11, 2020 14:05
This is just a copy of the implementation in Room.
Still need more tests, support for other declarations
and possible optimizations
Old type substitutor seems to have problems with * projection
where as new one seems to work (failing test case: receiveArgs method).

I've replaced the code to use the new substitutor (even with fields) and
also implemented a fallback implementation for KSFunctionType that derives
from a KSFunctionDeclaration.
@yigit
Copy link
Collaborator Author

yigit commented Oct 11, 2020

rebased, ready for review.

}
val typeSubstitutor = containing.kotlinType.createTypeSubstitutor()
val substituted = declaration.substitute(typeSubstitutor)
return KSFunctionImpl(substituted)
Copy link
Collaborator

Choose a reason for hiding this comment

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

Can you cache the creation of KSFunctionImpl like this?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

i'm not sure if this is worth caching, the value is quite specific to an owner + declaration.
But even if I wanted to cache that, substitute returns CallableDescriptor which does not seem to enforse implementing proper equals.

I've actually tried to run substitution twice between a List<String> type and List#get and they both returned different descriptors.

image

I can try to cache in the resolverImpl's asMemberOf with a composite key of KSFunctionDeclaration,KSType though again, i'm not sure how useful that cache would be.

Copy link
Collaborator

@ting-yuan ting-yuan Oct 19, 2020

Choose a reason for hiding this comment

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

with a composite key of KSFunctionDeclaration,KSType

Sounds good to me. Besides performance[1], like what you said, it comes with proper equals.

[1] asMemberOf is inherently expensive. I'm a little bit surprised that the substituter returned different instances when called twice, which means that some of the computations are redundant.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

i implemented caching, though i don't have KSFUnction#equals, I guess probably should implement it as well?
Also, might be better to do it as a followup to get this CL in.

@ting-yuan ting-yuan merged commit 2e2e505 into google:master Oct 21, 2020
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.

Add helper for equivlent of Types.asMemeberOf
2 participants