Use clsDelegate to calculate hasModifierProperty("final") for light psi
AllOpen plugin can make some changes and we don't have the tools to make
correct decision based on psi
#KT-17857 Fixed
This commit is contained in:
+23
-3
@@ -44,8 +44,8 @@ import org.jetbrains.kotlin.asJava.builder.LightClassData
|
||||
import org.jetbrains.kotlin.asJava.builder.LightClassDataHolder
|
||||
import org.jetbrains.kotlin.asJava.builder.LightClassDataProviderForClassOrObject
|
||||
import org.jetbrains.kotlin.asJava.elements.FakeFileForLightClass
|
||||
import org.jetbrains.kotlin.asJava.elements.KtLightSimpleModifierList
|
||||
import org.jetbrains.kotlin.asJava.elements.KtLightIdentifier
|
||||
import org.jetbrains.kotlin.asJava.elements.KtLightModifierList
|
||||
import org.jetbrains.kotlin.asJava.elements.KtLightPsiReferenceList
|
||||
import org.jetbrains.kotlin.asJava.hasInterfaceDefaultImpls
|
||||
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
||||
@@ -180,7 +180,7 @@ abstract class KtLightClassForSourceDeclaration(protected val classOrObject: KtC
|
||||
|
||||
override fun getName(): String? = classOrObject.nameAsName?.asString()
|
||||
|
||||
private val _modifierList: PsiModifierList by lazyPub { KtLightSimpleModifierList(this@KtLightClassForSourceDeclaration, computeModifiers()) }
|
||||
private val _modifierList: PsiModifierList by lazyPub { KtLightClassModifierList(this) }
|
||||
|
||||
override fun getModifierList(): PsiModifierList? = _modifierList
|
||||
|
||||
@@ -452,8 +452,28 @@ abstract class KtLightClassForSourceDeclaration(protected val classOrObject: KtC
|
||||
|
||||
override val originKind: LightClassOriginKind
|
||||
get() = LightClassOriginKind.SOURCE
|
||||
|
||||
private class KtLightClassModifierList(containingClass: KtLightClassForSourceDeclaration)
|
||||
: KtLightModifierList<KtLightClassForSourceDeclaration>(containingClass) {
|
||||
|
||||
private val modifiers by lazyPub { containingClass.computeModifiers() }
|
||||
|
||||
override fun hasModifierProperty(name: String): Boolean {
|
||||
if (name != PsiModifier.FINAL) {
|
||||
return name in modifiers
|
||||
}
|
||||
|
||||
val isFinalByPsi = PsiModifier.FINAL in modifiers
|
||||
// annotations can make class open via 'allopen' plugin
|
||||
if (!owner.isPossiblyAffectedByAllOpen() || !isFinalByPsi) return isFinalByPsi
|
||||
|
||||
return clsDelegate.hasModifierProperty(PsiModifier.FINAL)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun KtLightClassForSourceDeclaration.isPossiblyAffectedByAllOpen() = !isAnnotationType && !isInterface && kotlinOrigin.annotationEntries.isNotEmpty()
|
||||
|
||||
fun getOutermostClassOrObject(classOrObject: KtClassOrObject): KtClassOrObject {
|
||||
val outermostClass = KtPsiUtil.getOutermostClassOrObject(classOrObject) ?:
|
||||
throw IllegalStateException("Attempt to build a light class for a local class: " + classOrObject.text)
|
||||
@@ -487,4 +507,4 @@ fun KtClassOrObject.defaultJavaAncestorQualifiedName(): String? {
|
||||
isInterface() -> CommonClassNames.JAVA_LANG_OBJECT // see com.intellij.psi.impl.PsiClassImplUtil.getSuperClass
|
||||
else -> CommonClassNames.JAVA_LANG_OBJECT
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -24,6 +24,8 @@ import org.jetbrains.kotlin.asJava.builder.LightElementOrigin
|
||||
import org.jetbrains.kotlin.asJava.builder.LightMemberOrigin
|
||||
import org.jetbrains.kotlin.asJava.builder.LightMemberOriginForDeclaration
|
||||
import org.jetbrains.kotlin.asJava.classes.KtLightClass
|
||||
import org.jetbrains.kotlin.asJava.classes.KtLightClassForSourceDeclaration
|
||||
import org.jetbrains.kotlin.asJava.classes.isPossiblyAffectedByAllOpen
|
||||
import org.jetbrains.kotlin.asJava.classes.lazyPub
|
||||
import org.jetbrains.kotlin.lexer.KtTokens
|
||||
import org.jetbrains.kotlin.psi.KtDeclaration
|
||||
@@ -81,6 +83,8 @@ private class KtLightMemberModifierList(
|
||||
name == PsiModifier.ABSTRACT && isImplementationInInterface() -> false
|
||||
// pretend this method behaves like a default method
|
||||
name == PsiModifier.DEFAULT && isImplementationInInterface() -> true
|
||||
name == PsiModifier.FINAL && ((owner.containingClass as? KtLightClassForSourceDeclaration)?.isPossiblyAffectedByAllOpen() ?: false) ->
|
||||
clsDelegate.hasModifierProperty(name)
|
||||
dummyDelegate != null -> {
|
||||
when {
|
||||
name in visibilityModifiers && isMethodOverride() ->
|
||||
|
||||
+25
@@ -0,0 +1,25 @@
|
||||
@test.AllOpen
|
||||
public class C {
|
||||
private final int p;
|
||||
|
||||
public void f() { /* compiled code */ }
|
||||
|
||||
public void g() { /* compiled code */ }
|
||||
|
||||
public int getP() { /* compiled code */ }
|
||||
|
||||
public C() { /* compiled code */ }
|
||||
|
||||
public static final class D {
|
||||
public final void z() { /* compiled code */ }
|
||||
|
||||
public D() { /* compiled code */ }
|
||||
}
|
||||
|
||||
@test.AllOpen
|
||||
public static class H {
|
||||
public void j() { /* compiled code */ }
|
||||
|
||||
public H() { /* compiled code */ }
|
||||
}
|
||||
}
|
||||
+26
@@ -0,0 +1,26 @@
|
||||
// test.C
|
||||
package test
|
||||
|
||||
annotation class AllOpen
|
||||
|
||||
@AllOpen
|
||||
class C {
|
||||
fun f() {}
|
||||
|
||||
fun g() {}
|
||||
|
||||
val p: Int
|
||||
|
||||
class D {
|
||||
fun z() {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@AllOpen
|
||||
class H {
|
||||
fun j() {}
|
||||
}
|
||||
}
|
||||
|
||||
// LAZINESS:NoLaziness
|
||||
@@ -236,6 +236,12 @@ public class IdeLightClassTestGenerated extends AbstractIdeLightClassTest {
|
||||
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/asJava/lightClasses/ideRegression"), Pattern.compile("^([^.]+)\\.kt$"), TargetBackend.ANY, true);
|
||||
}
|
||||
|
||||
@TestMetadata("AllOpenAnnotatedClasses.kt")
|
||||
public void testAllOpenAnnotatedClasses() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/asJava/lightClasses/ideRegression/AllOpenAnnotatedClasses.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("ImplementingCharSequenceAndNumber.kt")
|
||||
public void testImplementingCharSequenceAndNumber() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/asJava/lightClasses/ideRegression/ImplementingCharSequenceAndNumber.kt");
|
||||
|
||||
Reference in New Issue
Block a user