Add CodegenApplicabilityCheckerExtension and use it to fallback to Heavy LigthClasses
+ Fixed #KT-33584
This commit is contained in:
@@ -7,6 +7,7 @@ plugins {
|
||||
}
|
||||
|
||||
dependencies {
|
||||
testRuntime(project(":kotlin-reflect"))
|
||||
compile(project(":kotlin-allopen-compiler-plugin"))
|
||||
compile(project(":compiler:util"))
|
||||
compile(project(":compiler:frontend"))
|
||||
@@ -18,11 +19,42 @@ dependencies {
|
||||
compileOnly(intellijDep())
|
||||
excludeInAndroidStudio(rootProject) { compileOnly(intellijPluginDep("maven")) }
|
||||
compileOnly(intellijPluginDep("gradle"))
|
||||
|
||||
testCompileOnly(project(":kotlin-serialization"))
|
||||
testCompileOnly(project(":plugins:lint"))
|
||||
testCompileOnly(project(":plugins:kapt3-idea"))
|
||||
testCompileOnly(project(":plugins:android-extensions-compiler"))
|
||||
testCompileOnly(project(":kotlin-android-extensions"))
|
||||
testCompileOnly(project(":kotlin-android-extensions-runtime"))
|
||||
testCompileOnly(project(":plugins:android-extensions-ide"))
|
||||
testCompileOnly(project(":kotlin-allopen-compiler-plugin"))
|
||||
testCompileOnly(project(":allopen-ide-plugin"))
|
||||
testCompileOnly(project(":kotlin-imports-dumper-compiler-plugin"))
|
||||
testCompileOnly(project(":kotlin-source-sections-compiler-plugin"))
|
||||
testCompileOnly(project(":kotlinx-serialization-compiler-plugin"))
|
||||
testCompileOnly(project(":kotlinx-serialization-ide-plugin"))
|
||||
testCompileOnly(project(":kotlin-sam-with-receiver-compiler-plugin"))
|
||||
testCompileOnly(project(":noarg-ide-plugin"))
|
||||
testCompileOnly(project(":sam-with-receiver-ide-plugin"))
|
||||
testCompileOnly(project(":idea:idea-native"))
|
||||
testCompileOnly(project(":idea:idea-gradle-native"))
|
||||
testCompileOnly(projectTests(":idea:idea-test-framework"))
|
||||
testCompileOnly(intellijDep())
|
||||
testRuntimeOnly(intellijDep())
|
||||
|
||||
Platform[192].orHigher {
|
||||
testCompileOnly(intellijPluginDep("java"))
|
||||
testRuntimeOnly(intellijPluginDep("java"))
|
||||
}
|
||||
}
|
||||
|
||||
sourceSets {
|
||||
"main" { projectDefault() }
|
||||
"test" {}
|
||||
"test" { projectDefault() }
|
||||
}
|
||||
|
||||
runtimeJar()
|
||||
|
||||
projectTest(parallel = true) {
|
||||
|
||||
}
|
||||
@@ -17,45 +17,27 @@
|
||||
package org.jetbrains.kotlin.allopen.ide
|
||||
|
||||
import com.intellij.openapi.application.ApplicationManager
|
||||
import com.intellij.openapi.module.Module
|
||||
import com.intellij.openapi.module.ModuleUtilCore
|
||||
import com.intellij.openapi.project.Project
|
||||
import com.intellij.openapi.roots.ProjectRootModificationTracker
|
||||
import com.intellij.psi.util.CachedValue
|
||||
import com.intellij.psi.util.CachedValueProvider
|
||||
import com.intellij.psi.util.CachedValuesManager
|
||||
import com.intellij.util.containers.ContainerUtil
|
||||
import org.jetbrains.kotlin.allopen.AbstractAllOpenDeclarationAttributeAltererExtension
|
||||
import org.jetbrains.kotlin.psi.KtModifierListOwner
|
||||
import org.jetbrains.kotlin.allopen.AllOpenCommandLineProcessor.Companion.PLUGIN_ID
|
||||
import org.jetbrains.kotlin.allopen.AllOpenCommandLineProcessor.Companion.ANNOTATION_OPTION
|
||||
import org.jetbrains.kotlin.annotation.plugin.ide.getSpecialAnnotations
|
||||
import java.util.concurrent.ConcurrentMap
|
||||
import org.jetbrains.kotlin.allopen.AllOpenCommandLineProcessor.Companion.PLUGIN_ID
|
||||
import org.jetbrains.kotlin.annotation.plugin.ide.AnnotationBasedLightClassApplicabilityExtension
|
||||
import org.jetbrains.kotlin.annotation.plugin.ide.CachedAnnotationNames
|
||||
import org.jetbrains.kotlin.annotation.plugin.ide.getAnnotationNames
|
||||
import org.jetbrains.kotlin.psi.KtModifierListOwner
|
||||
|
||||
class IdeAllOpenDeclarationAttributeAltererExtension(val project: Project) : AbstractAllOpenDeclarationAttributeAltererExtension() {
|
||||
private companion object {
|
||||
val ANNOTATION_OPTION_PREFIX = "plugin:$PLUGIN_ID:${ANNOTATION_OPTION.optionName}="
|
||||
}
|
||||
internal val ALL_OPEN_ANNOTATION_OPTION_PREFIX = "plugin:$PLUGIN_ID:${ANNOTATION_OPTION.optionName}="
|
||||
|
||||
private val cache: CachedValue<ConcurrentMap<Module, List<String>>> = cachedValue(project) {
|
||||
CachedValueProvider.Result.create(
|
||||
ContainerUtil.createConcurrentWeakMap<Module, List<String>>(),
|
||||
ProjectRootModificationTracker.getInstance(project)
|
||||
)
|
||||
}
|
||||
class IdeAllOpenApplicabilityExtension(project: Project) :
|
||||
AnnotationBasedLightClassApplicabilityExtension(project, ALL_OPEN_ANNOTATION_OPTION_PREFIX)
|
||||
|
||||
class IdeAllOpenDeclarationAttributeAltererExtension(val project: Project) :
|
||||
AbstractAllOpenDeclarationAttributeAltererExtension() {
|
||||
|
||||
private val cachedAnnotationsNames = CachedAnnotationNames(project, ALL_OPEN_ANNOTATION_OPTION_PREFIX)
|
||||
|
||||
override fun getAnnotationFqNames(modifierListOwner: KtModifierListOwner?): List<String> {
|
||||
if (ApplicationManager.getApplication().isUnitTestMode) {
|
||||
return ANNOTATIONS_FOR_TESTS
|
||||
}
|
||||
|
||||
if (modifierListOwner == null) return emptyList()
|
||||
val module = ModuleUtilCore.findModuleForPsiElement(modifierListOwner) ?: return emptyList()
|
||||
|
||||
return cache.value.getOrPut(module) { module.getSpecialAnnotations(ANNOTATION_OPTION_PREFIX) }
|
||||
}
|
||||
|
||||
private fun <T> cachedValue(project: Project, result: () -> CachedValueProvider.Result<T>): CachedValue<T> {
|
||||
return CachedValuesManager.getManager(project).createCachedValue(result, false)
|
||||
return if (ApplicationManager.getApplication().isUnitTestMode) ANNOTATIONS_FOR_TESTS
|
||||
else cachedAnnotationsNames.getAnnotationNames(modifierListOwner)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,70 @@
|
||||
/*
|
||||
* Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.noarg
|
||||
|
||||
import com.intellij.lang.jvm.JvmModifier
|
||||
import com.intellij.testFramework.LightProjectDescriptor
|
||||
import org.jetbrains.kotlin.allopen.AbstractAllOpenDeclarationAttributeAltererExtension
|
||||
import org.jetbrains.kotlin.allopen.ide.ALL_OPEN_ANNOTATION_OPTION_PREFIX
|
||||
import org.jetbrains.kotlin.config.LanguageVersion
|
||||
import org.jetbrains.kotlin.idea.facet.KotlinFacet
|
||||
import org.jetbrains.kotlin.idea.test.KotlinLightCodeInsightFixtureTestCase
|
||||
import org.jetbrains.kotlin.idea.test.KotlinProjectDescriptorWithFacet
|
||||
import org.jetbrains.kotlin.psi.KtFile
|
||||
import org.jetbrains.kotlin.test.JUnit3WithIdeaConfigurationRunner
|
||||
import org.junit.runner.RunWith
|
||||
|
||||
|
||||
|
||||
|
||||
@RunWith(JUnit3WithIdeaConfigurationRunner::class)
|
||||
class TestNoArgForLightClass : KotlinLightCodeInsightFixtureTestCase() {
|
||||
|
||||
companion object {
|
||||
val allOpenAnnotationName = AbstractAllOpenDeclarationAttributeAltererExtension.ANNOTATIONS_FOR_TESTS.first()
|
||||
const val targetClassName = "TargetClassName"
|
||||
}
|
||||
|
||||
override fun getProjectDescriptor(): LightProjectDescriptor =
|
||||
KotlinProjectDescriptorWithFacet(LanguageVersion.LATEST_STABLE, multiPlatform = false)
|
||||
|
||||
override fun setUp() {
|
||||
super.setUp()
|
||||
|
||||
val facet = KotlinFacet.get(module) ?: error { "Facet not found" }
|
||||
val configurationArguments = facet.configuration.settings.compilerArguments ?: error { "CompilerArguments not found" }
|
||||
|
||||
configurationArguments.pluginClasspaths = arrayOf("SomeClasspath")
|
||||
configurationArguments.pluginOptions = arrayOf("$ALL_OPEN_ANNOTATION_OPTION_PREFIX$allOpenAnnotationName")
|
||||
}
|
||||
|
||||
fun testAllOpenAnnotation() {
|
||||
val file = myFixture.configureByText(
|
||||
"A.kt",
|
||||
"annotation class $allOpenAnnotationName\n"
|
||||
+ "@$allOpenAnnotationName class $targetClassName(val e: Int)\n {"
|
||||
+ " fun a() {}\n"
|
||||
+ " val b = 32\n"
|
||||
+ "}"
|
||||
|
||||
|
||||
) as KtFile
|
||||
|
||||
val classes = file.classes
|
||||
assertEquals(2, classes.size)
|
||||
|
||||
val targetClass = classes.firstOrNull { it.name == targetClassName }
|
||||
?: error { "Expected class $targetClassName not found" }
|
||||
|
||||
assertFalse(targetClass.hasModifier(JvmModifier.FINAL))
|
||||
|
||||
targetClass.methods
|
||||
.filter { !it.isConstructor }
|
||||
.forEach {
|
||||
assertFalse(it.hasModifier(JvmModifier.FINAL))
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user