https://kotlinlang.org logo
Title
p

Paul Woitaschek

11/04/2021, 7:38 AM
I want to process all functions returning a
kotlinx.coroutines.flow.Flow
. When entering
visitFunctionDeclaration
is there any way to get the complete return type? (not only "Flow")? The only solution I have found so far is to call:
function.returnType?.resolve()?.declaration?.qualifiedName?.asString()
but that would force me to resolve just all functions which is documented as "expensive". Is there a way to do it without resolving all functions?
e

efemoney

11/04/2021, 8:43 AM
Use name == “Flow” as condition to gate the resolution
p

Paul Woitaschek

11/04/2021, 8:43 AM
Does that handle typealiases?
or will that if I write
typealias Wolf<T> = Flow<T>
lead to
Wolf
?
e

efemoney

11/04/2021, 8:45 AM
I’d need to confirm but there should be special consideration for type aliases side note: Just noticing wolf is flow in reverse lol 😄
p

Paul Woitaschek

11/04/2021, 8:46 AM
Yeah me too 😛
e

efemoney

11/04/2021, 8:53 AM
Just took a look at the API and type aliases make it tricky but you can still be clever and avoid unnecessary resolution. For instance you could
visit
type aliases to mark “interesting” ones (typealiases of Flow or typealiases of the aforementioned typealiases) that in a subsequent round of processing you can then search for in function return types
g

Grégory Lureau

11/04/2021, 9:42 AM
What if there is another class named Flow in another part of the project? You can't visit built dependencies, so you're forced to resolve the type no?
p

Paul Woitaschek

11/04/2021, 9:43 AM
Yes but efemoneys suggestion is good. At least it does not result into resolving everything
👍 1
g

Grégory Lureau

11/04/2021, 9:49 AM
I had to make a patch to write the original file and check import myself to get the package name. Pretty sure it's not the best approach but could it be less costly that resolution? Maybe also visiting imports/files and mark them could be an option. A bit weird to me to have simple name instead of full name as the default value when it's likely to be determined from the file itself.
e

evant

11/04/2021, 2:40 PM
been wondering about requesting something like this myself. I could see at being a performance win when checking a lot of types. It would also allow you to continue even if the type isn't resolved. (Would fixe cases like https://github.com/evant/kotlin-inject/issues/155). One big issue with it is wildcard imports though. As soon as a file has one you don't know where it came from.
g

Grégory Lureau

11/04/2021, 2:55 PM
Here's my current (shitty) patch if it can give some ideas (I wrote it when I was facing an issue when resolving classes in jsMain of a KMP project from another module). We use ktlint on the project and avoid wildcard imports but you're right it's not safe to use that approach with wildcards. Also we could check if the import is found in the file, and if not found call resolve() as a last resort, but I'm not sure if it's less or more costly than the resolve eventually.
j

Jiaxiang

11/04/2021, 6:16 PM
gating resolution based on
name
is a good optimization, however it does not handle type alias well. Actually in KSP development we had similar challenge when implementing
getSymbolsWithAnnotation
, effort to optimize with typealias in mind is non-trivial. I would suggest use annotation to mark the symbols you want to process.
1