-
Notifications
You must be signed in to change notification settings - Fork 1.9k
KE2: Upgrade to Kotlin 2.1.0; restore basic type parameter and type argument extraction #18215
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
|
|
||
| val session = buildStandaloneAnalysisAPISession { | ||
| registerProjectService(KotlinLifetimeTokenProvider::class.java, KotlinAlwaysAccessibleLifetimeTokenProvider()) | ||
| registerProjectService(KotlinLifetimeTokenFactory::class.java, KotlinAlwaysAccessibleLifetimeTokenFactory()) |
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.
Changed in Kotlin 2.1.0
| // The Kotlin compiler internal representation of Outer<A, B>.Inner<C, D>.InnerInner<E, | ||
| // F>.someFunction<G, H>.LocalClass<I, J> is LocalClass<I, J, G, H, E, F, C, D, A, B>. This | ||
| // function returns [A, B, C, D, E, F, G, H, I, J]. | ||
| private fun orderTypeArgsLeftToRight( |
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.
Pleasingly this could die, because the Kotlin Analysis API represents this as [[A, B], [C, D], [E, F], [G, H], [I, K]] via the KaClassType.qualifiers property, which is a much more useful than the IR representation.
| cBeforeReplacement: KaClassSymbol, | ||
| argsIncludingOuterClassesBeforeReplacement: List<Nothing>? | ||
| ): Pair<KaClassSymbol, List<Nothing>?> { | ||
| argsIncludingOuterClassesBeforeReplacement: List<List<KaTypeProjection>>? |
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.
Note this List<List<KaTypeProjection>> format occurs quite a lot, and represents the type-args of outer classes, if any.
| val functionSyntax = f.psi as? KtDeclarationWithBody | ||
| val locId = functionSyntax?.let { | ||
| tw.getLocation(functionSyntax ?: TODO()) | ||
| tw.getLocation(functionSyntax) |
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.
Incidental cleanup -- the ?: was unreachable
| // Note this function doesn't return a signature because type arguments are never | ||
| // incorporated into function signatures. | ||
| return when (arg) { | ||
| is KaStarTypeProjection -> { |
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 is all basically unchanged from the IR format -- the representation of variances is essentially the same. Basic translation to wildcards (out T == ? extends T, in T == ? super T) was likewise restored.
| } | ||
|
|
||
| // extractAnnotations(tp, id) | ||
| // TODO: introduce annotations once they can be disambiguated from bounds, which are |
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.
Note this is an old TODO; this was commented out in KE1
| } | ||
|
|
||
| context(KaSession) | ||
| fun KotlinUsesExtractor.getTypeParameterLabel(param: KaTypeParameterType): String { |
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.
Gone to TypeParameter.kt
| val shortName: String | ||
| */ | ||
| // OLD: KE1: val signature: SignatureType?, | ||
| val shortName: String |
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.
Passing shortName around is restored (used to generate names for wildcard types, like "? extends Blah" where "Blah" is the shortName of the underlying type). I haven't looked into how we're using signature yet so the relevant arguments are still behind OLD/KE1 comments.
Caffeine doesn’t create any threads directly or default to use any non-daemon threads indirectly. It will defers anything that can be async and calls foreign user code to an executor, like eviction and its listener. That by default is ForkJoinPool.commonPool() which uses daemon threads. Users can set a custom pool, many use Runnable::run to execute on the caller since caffeine’s own logic is inexpensive. You can use jstack to find the blocking thread. If it’s related to the cache then it would be custom configuration. |
|
Confirmed the thread in question doesn't belong to Caffeine; rather it is a thread associated with An hour of digging later I am not much closer to identifying what the ownership structure for that is supposed to be, and while there are various shutdown functions I can't see any paths from disposing of standalone analysis sessions or similar that would clean up the thread pool. Bleeding-edge Kotlin provides https://github.com/JetBrains/kotlin/blob/196ae1b0d009f633000910da5d5e6e50433cdb96/analysis/analysis-api-standalone/src/org/jetbrains/kotlin/analysis/api/standalone/StandaloneAnalysisAPISessionBuilder.kt#L275 but warns about how calling that shouldn't be necessary. It isn't present in Kotlin 2.1.0, and neither is the destroy function that it calls despite that having been in IntelliJ for years. In summary, I suggest we shrug and continue to simply hard-kill the JVM when we're done. |
| "org.jetbrains.kotlin:%s:2.1.0" % kotlin_lib | ||
| for kotlin_lib in ("kotlin-annotation-processing", "kotlin-compiler") | ||
| ], | ||
| ] + [ "com.github.ben-manes.caffeine:caffeine:2.9.3" ] , |
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 would be worth adding a comment like
We need the version specified in https://github.com/JetBrains/kotlin/blob/master/gradle/libs.versions.toml
so we don't upgrade to the latest version without thinking.
Depending on what happens with https://youtrack.jetbrains.com/issue/KT-73751/Analysis-API-Caffeine-dependency we might be able to do better here in the future.
| ) | ||
| dtw.flush() | ||
| loggerBase.close() | ||
| System.exit(0) // TODO: figure out what's keeping the JVM awake |
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.
Filed a ticket for this here: https://youtrack.jetbrains.com/issue/KT-73753/Analysis-API-doesnt-terminate
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.
You might want to include the context at #18215 (comment) identifying thread-pool cleanup as the cause
| private fun KotlinUsesExtractor.getClassLabel( | ||
| c: KaClassSymbol, | ||
| argsIncludingOuterClasses: List<Nothing>? | ||
| argsIncludingOuterClasses: List<List<KaTypeProjection>>? |
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 would be worth including a comment with a small example explaining what this list-of-lists means.
| } | ||
| } | ||
| else -> { | ||
| logger.error("Unexpected type argument.") |
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 include the .javaClass in the error please?
| javaTypeParameter: JavaTypeParameter? */ | ||
| ): Label<out DbTypevariable>? { | ||
| with("type parameter", tp) { | ||
| val parentId = getTypeParameterParentLabel(tp) ?: return null |
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.
Should we log an error in the null case?
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.
The callee already logs, but I've added error-cascading per this and the comment below.
| // ensuring that e.g. a method-scoped type variable declared on kotlin.String.transform<R> gets | ||
| // a different name to the corresponding java.lang.String.transform<R>, even though | ||
| // useFunction will usually replace references to one function with the other. | ||
| val parentLabel = getTypeParameterParentLabel(param) |
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 this wants to fail, or possibly return some other best-attempt string, if parentLabel is null
| tw.getLabelFor<DbKt_class_type>("@\"kt_class;{$classId}\"") { | ||
| tw.writeKt_class_types(it, classId) | ||
| tw.getLabelFor<DbKt_class_type>("@\"kt_class;{${javaResult.id}}\"") { | ||
| tw.writeKt_class_types(it, javaResult.id) |
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 don't think this refactoring is going to do the right thing in the future, e.g. for Int, where the Java ID might be for int but the Kotlin ID should be for Int
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.
Added a TODO -- I wasn't intending to address this here, only to keep the existing behaviour.
| val kotlinAliasTypeId = | ||
| tw.getLabelFor<DbKt_type_alias>("@\"kt_type_alias;{$classId};{$kotlinBaseTypeId}\"") { | ||
| tw.writeKt_type_aliases(it, classId, kotlinBaseTypeId) | ||
| tw.writeKt_type_aliases(it, classId.id, kotlinBaseTypeId) |
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.
classId should probably be renamed classResult or similar.
|
@igfoo comments addressed |
Kotlin 2.1.0
Needed to upgrade this due to finding compiler crashes when dealing with Java classes that declare type parameters against constructors.
Two snags with this:
System.exit(0)once all our work is done. Ideally we'd work out (a) is it actually Caffeine keeping the JVM awake (snork), and (b) if it is, how should it be asked to make an orderly shutdown.Generics extraction
Done here:
Not done yet:
Map<String, String>) -- requires re-enabling the logic to emit a class outline into the current trap file, and type substitutionf(Int, Float?)will extract iskotlin.Int, kotlin.Floatnotint, java.lang.Floatas it ought to for J/K compatibility.