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

Remove usages of ExtensionsArea.registerExtensionPoint(java.lang.String, java.lang.String, com.intellij.openapi.extensions.ExtensionPoint.Kind) #1981

Closed
goodwinnk opened this issue Apr 26, 2023 · 4 comments
Milestone

Comments

@goodwinnk
Copy link

The method is deprecated and going to be deleted in the IntelliJ platform.

https://github.com/JetBrains/intellij-community/blob/3d5848904794db7cbff9473e2fea7e9689e251e9/platform/extensions/src/com/intellij/openapi/extensions/ExtensionsArea.java#L19

Once it is deleted from the platform and after Kotlin updates the platform, the klint will fail on runtime.

@paul-dingemans
Copy link
Collaborator

Tnx for the heads up. Can you point me in a direction how to mitigate this? I am not familiar with the piece of code in Ktlint where this is invoked. From the comments I do understand that we need it for the format (autocorrect) mode which is quite an essential piece of functionality.

@goodwinnk
Copy link
Author

goodwinnk commented Apr 28, 2023

Can you point me in a direction how to mitigate this?

We did the following replacement in the Kotlin.

There was a recent bootstrap 1.9.0-dev-6976 (shouldn't be used in production) with the upgrade of the platform in the https://maven.pkg.jetbrains.space/kotlin/p/kotlin/bootstrap repository, where this fix can be tested. I think such test might reveal more problems, unfortunately.

Currently, there is no guarantee of binary compatibility in the Kotlin compiler, especially for third-party classes which are not present in the Kotlin repository and packed into kotlin-compiler-embeddable. With the evolution of the Kotlin compiler, I anticipate that there will be many more compatibility issues.

As a temporary measure, I suggest being very explicit about all undocumented usages (even proposed CoreApplicationEnvironment.registerExtensionPoint) that are in the core of the project, and raise issues in YouTrack asking Kotlin team to document and support them.

@paul-dingemans
Copy link
Collaborator

Tnx for your reply which was very helpful. I have analyzed the impact on Ktlint and reported below as https://youtrack.jetbrains.com/issue/KT-58704/Support-and-document-extension-point-org.jetbrains.kotlin.com.intellij.treeCopyHandler

===

Ktlint lint and formats Kotlin code. For formatting of the code it is necessary that Ktlint is able to mutate the AST of files in which lint violations are found. For this an extension point on class org.jetbrains.kotlin.com.intellij.treeCopyHandler is registered in

private fun MockProject.enableASTMutations() {
val extensionPoint = "org.jetbrains.kotlin.com.intellij.treeCopyHandler"
val extensionClassName = TreeCopyHandler::class.java.name
for (area in arrayOf(extensionArea, getRootArea())) {
if (!area.hasExtensionPoint(extensionPoint)) {
area.registerExtensionPoint(extensionPoint, extensionClassName, ExtensionPoint.Kind.INTERFACE)
}
}

In ktlint issue 1981 it was reported that ktlint uses a deprecated endpoint which is to be removed in Kotlin 1.9 resulting in runtime failures in Ktlint. We have applied a fix similar to this suggestion for the kotlin embeddable compiler and compiled and run Ktlint with kotlin 1.9.0-dev-6976 bootstrap. Some tests of Ktlint fail with exceptions like below:

Stacktrace ```text Rule 'test:auto-correct' throws exception in file '' at position (0:0) Rule maintainer: Not specified (and not maintained by the Ktlint project) Issue tracker : Not specified Repository : Not specified com.pinterest.ktlint.rule.engine.api.KtLintRuleException: Rule 'test:auto-correct' throws exception in file '' at position (0:0) Rule maintainer: Not specified (and not maintained by the Ktlint project) Issue tracker : Not specified Repository : Not specified at app//com.pinterest.ktlint.rule.engine.internal.RuleExecutionContext.executeRule(RuleExecutionContext.kt:64) at app//com.pinterest.ktlint.rule.engine.api.KtLintRuleEngine$format$3.invoke(KtLintRuleEngine.kt:136) at app//com.pinterest.ktlint.rule.engine.api.KtLintRuleEngine$format$3.invoke(KtLintRuleEngine.kt:135) at app//com.pinterest.ktlint.rule.engine.internal.VisitorProvider$visitor$3.invoke(VisitorProvider.kt:46) at app//com.pinterest.ktlint.rule.engine.internal.VisitorProvider$visitor$3.invoke(VisitorProvider.kt:44) at app//com.pinterest.ktlint.rule.engine.api.KtLintRuleEngine.format(KtLintRuleEngine.kt:135) at app//com.pinterest.ktlint.rule.engine.api.KtLintTest$Given an API consumer$Given that format is invoked via the KtLintRuleEngine.Given a rule returning errors which can and can not be autocorrected than that state of the error can be retrieved in the callback(KtLintTest.kt:146) at java.base@17.0.3/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at java.base@17.0.3/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77) at java.base@17.0.3/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.base@17.0.3/java.lang.reflect.Method.invoke(Method.java:568) at app//org.junit.platform.commons.util.ReflectionUtils.invokeMethod(ReflectionUtils.java:727) at app//org.junit.jupiter.engine.execution.MethodInvocation.proceed(MethodInvocation.java:60) at app//org.junit.jupiter.engine.execution.InvocationInterceptorChain$ValidatingInvocation.proceed(InvocationInterceptorChain.java:131) at app//org.junit.jupiter.engine.extension.TimeoutExtension.intercept(TimeoutExtension.java:156) at app//org.junit.jupiter.engine.extension.TimeoutExtension.interceptTestableMethod(TimeoutExtension.java:147) at app//org.junit.jupiter.engine.extension.TimeoutExtension.interceptTestMethod(TimeoutExtension.java:86) at app//org.junit.jupiter.engine.execution.InterceptingExecutableInvoker$ReflectiveInterceptorCall.lambda$ofVoidMethod$0(InterceptingExecutableInvoker.java:103) at app//org.junit.jupiter.engine.execution.InterceptingExecutableInvoker.lambda$invoke$0(InterceptingExecutableInvoker.java:93) at app//org.junit.jupiter.engine.execution.InvocationInterceptorChain$InterceptedInvocation.proceed(InvocationInterceptorChain.java:106) at app//org.junit.jupiter.engine.execution.InvocationInterceptorChain.proceed(InvocationInterceptorChain.java:64) at app//org.junit.jupiter.engine.execution.InvocationInterceptorChain.chainAndInvoke(InvocationInterceptorChain.java:45) at app//org.junit.jupiter.engine.execution.InvocationInterceptorChain.invoke(InvocationInterceptorChain.java:37) at app//org.junit.jupiter.engine.execution.InterceptingExecutableInvoker.invoke(InterceptingExecutableInvoker.java:92) at app//org.junit.jupiter.engine.execution.InterceptingExecutableInvoker.invoke(InterceptingExecutableInvoker.java:86) at app//org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.lambda$invokeTestMethod$7(TestMethodTestDescriptor.java:217) at app//org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73) at app//org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.invokeTestMethod(TestMethodTestDescriptor.java:213) at app//org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.execute(TestMethodTestDescriptor.java:138) at app//org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.execute(TestMethodTestDescriptor.java:68) at app//org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$6(NodeTestTask.java:151) at app//org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73) at app//org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:141) at app//org.junit.platform.engine.support.hierarchical.Node.around(Node.java:137) at app//org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$9(NodeTestTask.java:139) at app//org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73) at app//org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:138) at app//org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:95) at java.base@17.0.3/java.util.ArrayList.forEach(ArrayList.java:1511) at app//org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.invokeAll(SameThreadHierarchicalTestExecutorService.java:41) at app//org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$6(NodeTestTask.java:155) at app//org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73) at app//org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:141) at app//org.junit.platform.engine.support.hierarchical.Node.around(Node.java:137) at app//org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$9(NodeTestTask.java:139) at app//org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73) at app//org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:138) at app//org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:95) at java.base@17.0.3/java.util.ArrayList.forEach(ArrayList.java:1511) at app//org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.invokeAll(SameThreadHierarchicalTestExecutorService.java:41) at app//org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$6(NodeTestTask.java:155) at app//org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73) at app//org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:141) at app//org.junit.platform.engine.support.hierarchical.Node.around(Node.java:137) at app//org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$9(NodeTestTask.java:139) at app//org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73) at app//org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:138) at app//org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:95) at java.base@17.0.3/java.util.ArrayList.forEach(ArrayList.java:1511) at app//org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.invokeAll(SameThreadHierarchicalTestExecutorService.java:41) at app//org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$6(NodeTestTask.java:155) at app//org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73) at app//org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:141) at app//org.junit.platform.engine.support.hierarchical.Node.around(Node.java:137) at app//org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$9(NodeTestTask.java:139) at app//org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73) at app//org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:138) at app//org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:95) at java.base@17.0.3/java.util.ArrayList.forEach(ArrayList.java:1511) at app//org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.invokeAll(SameThreadHierarchicalTestExecutorService.java:41) at app//org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$6(NodeTestTask.java:155) at app//org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73) at app//org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:141) at app//org.junit.platform.engine.support.hierarchical.Node.around(Node.java:137) at app//org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$9(NodeTestTask.java:139) at app//org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73) at app//org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:138) at app//org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:95) at app//org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.submit(SameThreadHierarchicalTestExecutorService.java:35) at app//org.junit.platform.engine.support.hierarchical.HierarchicalTestExecutor.execute(HierarchicalTestExecutor.java:57) at app//org.junit.platform.engine.support.hierarchical.HierarchicalTestEngine.execute(HierarchicalTestEngine.java:54) at app//org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:107) at app//org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:88) at app//org.junit.platform.launcher.core.EngineExecutionOrchestrator.lambda$execute$0(EngineExecutionOrchestrator.java:54) at app//org.junit.platform.launcher.core.EngineExecutionOrchestrator.withInterceptedStreams(EngineExecutionOrchestrator.java:67) at app//org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:52) at app//org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:114) at app//org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:86) at app//org.junit.platform.launcher.core.DefaultLauncherSession$DelegatingLauncher.execute(DefaultLauncherSession.java:86) at org.gradle.api.internal.tasks.testing.junitplatform.JUnitPlatformTestClassProcessor$CollectAllTestClassesExecutor.processAllTestClasses(JUnitPlatformTestClassProcessor.java:110) at org.gradle.api.internal.tasks.testing.junitplatform.JUnitPlatformTestClassProcessor$CollectAllTestClassesExecutor.access$000(JUnitPlatformTestClassProcessor.java:90) at org.gradle.api.internal.tasks.testing.junitplatform.JUnitPlatformTestClassProcessor.stop(JUnitPlatformTestClassProcessor.java:85) at org.gradle.api.internal.tasks.testing.SuiteTestClassProcessor.stop(SuiteTestClassProcessor.java:62) at java.base@17.0.3/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at java.base@17.0.3/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77) at java.base@17.0.3/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.base@17.0.3/java.lang.reflect.Method.invoke(Method.java:568) at org.gradle.internal.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:36) at org.gradle.internal.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:24) at org.gradle.internal.dispatch.ContextClassLoaderDispatch.dispatch(ContextClassLoaderDispatch.java:33) at org.gradle.internal.dispatch.ProxyDispatchAdapter$DispatchingInvocationHandler.invoke(ProxyDispatchAdapter.java:94) at jdk.proxy1/jdk.proxy1.$Proxy2.stop(Unknown Source) at org.gradle.api.internal.tasks.testing.worker.TestWorker$3.run(TestWorker.java:193) at org.gradle.api.internal.tasks.testing.worker.TestWorker.executeAndMaintainThreadName(TestWorker.java:129) at org.gradle.api.internal.tasks.testing.worker.TestWorker.execute(TestWorker.java:100) at org.gradle.api.internal.tasks.testing.worker.TestWorker.execute(TestWorker.java:60) at org.gradle.process.internal.worker.child.ActionExecutionWorker.execute(ActionExecutionWorker.java:56) at org.gradle.process.internal.worker.child.SystemApplicationClassLoaderWorker.call(SystemApplicationClassLoaderWorker.java:113) at org.gradle.process.internal.worker.child.SystemApplicationClassLoaderWorker.call(SystemApplicationClassLoaderWorker.java:65) at app//worker.org.gradle.process.internal.worker.GradleWorkerMain.run(GradleWorkerMain.java:69) at app//worker.org.gradle.process.internal.worker.GradleWorkerMain.main(GradleWorkerMain.java:74) Caused by: java.lang.IllegalArgumentException: Missing extension point: org.jetbrains.kotlin.com.intellij.treeCopyHandler in container {} at org.jetbrains.kotlin.com.intellij.openapi.extensions.impl.ExtensionsAreaImpl.getExtensionPoint(ExtensionsAreaImpl.java:250) at org.jetbrains.kotlin.com.intellij.openapi.extensions.BaseExtensionPointName.getPointImpl(BaseExtensionPointName.java:28) at org.jetbrains.kotlin.com.intellij.openapi.extensions.ExtensionPointName.getExtensionList(ExtensionPointName.java:39) at org.jetbrains.kotlin.com.intellij.psi.impl.source.tree.ChangeUtil.encodeInformation(ChangeUtil.java:43) at org.jetbrains.kotlin.com.intellij.psi.impl.source.tree.ChangeUtil.lambda$encodeInformation$0(ChangeUtil.java:39) at org.jetbrains.kotlin.com.intellij.psi.impl.DebugUtil.performPsiModification(DebugUtil.java:481) at org.jetbrains.kotlin.com.intellij.psi.impl.source.tree.ChangeUtil.encodeInformation(ChangeUtil.java:39) at org.jetbrains.kotlin.com.intellij.psi.impl.source.tree.ChangeUtil.copyLeafWithText(ChangeUtil.java:78) at org.jetbrains.kotlin.com.intellij.psi.impl.source.tree.LeafElement.replaceWithText(LeafElement.java:153) at com.pinterest.ktlint.rule.engine.api.AutoCorrectErrorRule.beforeVisitChildNodes(KtLintTest.kt:506) at com.pinterest.ktlint.rule.engine.internal.RuleExecutionContext$executeRuleOnNodeRecursively$1.invoke(RuleExecutionContext.kt:93) at com.pinterest.ktlint.rule.engine.internal.RuleExecutionContext$executeRuleOnNodeRecursively$1.invoke(RuleExecutionContext.kt:92) at com.pinterest.ktlint.rule.engine.internal.SuppressHandler.handle-dhiVX_g(SuppressHandler.kt:28) at com.pinterest.ktlint.rule.engine.internal.RuleExecutionContext.executeRuleOnNodeRecursively(RuleExecutionContext.kt:92) at com.pinterest.ktlint.rule.engine.internal.RuleExecutionContext.access$executeRuleOnNodeRecursively(RuleExecutionContext.kt:29) at com.pinterest.ktlint.rule.engine.internal.RuleExecutionContext$executeRuleOnNodeRecursively$2$1.invoke(RuleExecutionContext.kt:100) at com.pinterest.ktlint.rule.engine.internal.RuleExecutionContext$executeRuleOnNodeRecursively$2$1.invoke(RuleExecutionContext.kt:99) at com.pinterest.ktlint.rule.engine.internal.SuppressHandler.handle-dhiVX_g(SuppressHandler.kt:28) at com.pinterest.ktlint.rule.engine.internal.RuleExecutionContext.executeRuleOnNodeRecursively(RuleExecutionContext.kt:99) at com.pinterest.ktlint.rule.engine.internal.RuleExecutionContext.access$executeRuleOnNodeRecursively(RuleExecutionContext.kt:29) at com.pinterest.ktlint.rule.engine.internal.RuleExecutionContext$executeRuleOnNodeRecursively$2$1.invoke(RuleExecutionContext.kt:100) at com.pinterest.ktlint.rule.engine.internal.RuleExecutionContext$executeRuleOnNodeRecursively$2$1.invoke(RuleExecutionContext.kt:99) at com.pinterest.ktlint.rule.engine.internal.SuppressHandler.handle-dhiVX_g(SuppressHandler.kt:28) at com.pinterest.ktlint.rule.engine.internal.RuleExecutionContext.executeRuleOnNodeRecursively(RuleExecutionContext.kt:99) at com.pinterest.ktlint.rule.engine.internal.RuleExecutionContext.access$executeRuleOnNodeRecursively(RuleExecutionContext.kt:29) at com.pinterest.ktlint.rule.engine.internal.RuleExecutionContext$executeRuleOnNodeRecursively$2$1.invoke(RuleExecutionContext.kt:100) at com.pinterest.ktlint.rule.engine.internal.RuleExecutionContext$executeRuleOnNodeRecursively$2$1.invoke(RuleExecutionContext.kt:99) at com.pinterest.ktlint.rule.engine.internal.SuppressHandler.handle-dhiVX_g(SuppressHandler.kt:28) at com.pinterest.ktlint.rule.engine.internal.RuleExecutionContext.executeRuleOnNodeRecursively(RuleExecutionContext.kt:99) at com.pinterest.ktlint.rule.engine.internal.RuleExecutionContext.access$executeRuleOnNodeRecursively(RuleExecutionContext.kt:29) at com.pinterest.ktlint.rule.engine.internal.RuleExecutionContext$executeRuleOnNodeRecursively$2$1.invoke(RuleExecutionContext.kt:100) at com.pinterest.ktlint.rule.engine.internal.RuleExecutionContext$executeRuleOnNodeRecursively$2$1.invoke(RuleExecutionContext.kt:99) at com.pinterest.ktlint.rule.engine.internal.SuppressHandler.handle-dhiVX_g(SuppressHandler.kt:28) at com.pinterest.ktlint.rule.engine.internal.RuleExecutionContext.executeRuleOnNodeRecursively(RuleExecutionContext.kt:99) at com.pinterest.ktlint.rule.engine.internal.RuleExecutionContext.executeRule(RuleExecutionContext.kt:61) ... 110 more ```

The relevant part of this stacktrace seems to be the following:

Caused by: java.lang.IllegalArgumentException: Missing extension point: org.jetbrains.kotlin.com.intellij.treeCopyHandler in container {}
	at org.jetbrains.kotlin.com.intellij.openapi.extensions.impl.ExtensionsAreaImpl.getExtensionPoint(ExtensionsAreaImpl.java:250)
	at org.jetbrains.kotlin.com.intellij.openapi.extensions.BaseExtensionPointName.getPointImpl(BaseExtensionPointName.java:28)
	at org.jetbrains.kotlin.com.intellij.openapi.extensions.ExtensionPointName.getExtensionList(ExtensionPointName.java:39)
	at org.jetbrains.kotlin.com.intellij.psi.impl.source.tree.ChangeUtil.encodeInformation(ChangeUtil.java:43)
	at org.jetbrains.kotlin.com.intellij.psi.impl.source.tree.ChangeUtil.lambda$encodeInformation$0(ChangeUtil.java:39)
	at org.jetbrains.kotlin.com.intellij.psi.impl.DebugUtil.performPsiModification(DebugUtil.java:481)
	at org.jetbrains.kotlin.com.intellij.psi.impl.source.tree.ChangeUtil.encodeInformation(ChangeUtil.java:39)
	at org.jetbrains.kotlin.com.intellij.psi.impl.source.tree.ChangeUtil.copyLeafWithText(ChangeUtil.java:78)
	at org.jetbrains.kotlin.com.intellij.psi.impl.source.tree.LeafElement.replaceWithText(LeafElement.java:153)

See below for the list of root causes found by the unit tests of ktlint:

org.jetbrains.kotlin.psi.KtExpressionImplStub.replace(KtExpressionImplStub.java:43)
org.jetbrains.kotlin.com.intellij.psi.impl.source.tree.LeafElement.replaceWithText(LeafElement.java:153)
org.jetbrains.kotlin.com.intellij.psi.impl.source.tree.LeafPsiElement.replace(LeafPsiElement.java:198)
org.jetbrains.kotlin.com.intellij.extapi.psi.ASTDelegatePsiElement.addAfter(ASTDelegatePsiElement.java:292)

Most likely we can work around those root causes as the majority of Ktlint's rules that modify the AST are not using above methods. But as Ktlint has the format of custom rulesets, similar analysis and fixes have to be applies by all maintainers of such ruleset.

Ideally, the extension point for class org.jetbrains.kotlin.com.intellij.treeCopyHandler keeps working in kotlin 1.9 and beyond. If that is not possible, it would be great if another extension point can be used that provides for similar functionality.

@paul-dingemans
Copy link
Collaborator

Analysis is done. Only one extension point, org.jetbrains.kotlin.com.intellij.treeCopyHandler, is being used by Ktlint. Rules provided by ktlint have been changed so that they will work without this extension point. Custom rule sets however might still need the extension point. Ktlint 0.50.x, still containing the Kotlin 1.8 embeddable compiler, can optionally disable the registration of this extension point so that custom rule set providers can check and fix affected rules in same way as is done in ktlint (see #2044).
A follow-up issue (#2061) created to remove the registration of the extension point when depending on the Kotlin 1.9 embeddable compiler.

3flex added a commit to 3flex/detekt that referenced this issue Jul 4, 2023
This was previously used by ktlint to support autocorrect for some rules,
but is being phased out due to pinterest/ktlint#1981.
detekt should do the same. This has no impact on any core rules, or the
formatting module (since ktlint no longer depends on this extension as of
ktlint v0.50.0).

This will impact third party rule sets, only if:
- they support autocorrect, and
- autocorrect support relies on the treeCopyHandler extension

ktlint rules were updated to remove the dependency on treeCopyHandler, so
affected third party detekt rule sets can do the same.

This is all being caused by upstream changes in Kotlin. There's some very
useful analysis in pinterest/ktlint#2044 that can
be reviewed by anyone affected downstream by this change.
3flex added a commit to detekt/detekt that referenced this issue Jul 10, 2023
* Stop applying treeCopyHandler extension in analysis environment

This was previously used by ktlint to support autocorrect for some rules,
but is being phased out due to pinterest/ktlint#1981.
detekt should do the same. This has no impact on any core rules, or the
formatting module (since ktlint no longer depends on this extension as of
ktlint v0.50.0).

This will impact third party rule sets, only if:
- they support autocorrect, and
- autocorrect support relies on the treeCopyHandler extension

ktlint rules were updated to remove the dependency on treeCopyHandler, so
affected third party detekt rule sets can do the same.

This is all being caused by upstream changes in Kotlin. There's some very
useful analysis in pinterest/ktlint#2044 that can
be reviewed by anyone affected downstream by this change.

* Remove unused test

DetektPomModel is now an object so cannot be instantiated multiple
times, avoiding concurrency issues. The problematic code that was tested
by this test has also been removed.

* Remove unused dependency

contester is not used anymore in any test or production code.
mgroth0 pushed a commit to mgroth0/detekt that referenced this issue Feb 11, 2024
…kt#6255)

* Stop applying treeCopyHandler extension in analysis environment

This was previously used by ktlint to support autocorrect for some rules,
but is being phased out due to pinterest/ktlint#1981.
detekt should do the same. This has no impact on any core rules, or the
formatting module (since ktlint no longer depends on this extension as of
ktlint v0.50.0).

This will impact third party rule sets, only if:
- they support autocorrect, and
- autocorrect support relies on the treeCopyHandler extension

ktlint rules were updated to remove the dependency on treeCopyHandler, so
affected third party detekt rule sets can do the same.

This is all being caused by upstream changes in Kotlin. There's some very
useful analysis in pinterest/ktlint#2044 that can
be reviewed by anyone affected downstream by this change.

* Remove unused test

DetektPomModel is now an object so cannot be instantiated multiple
times, avoiding concurrency issues. The problematic code that was tested
by this test has also been removed.

* Remove unused dependency

contester is not used anymore in any test or production code.
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

No branches or pull requests

2 participants