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.LightClassDataHolder
|
||||||
import org.jetbrains.kotlin.asJava.builder.LightClassDataProviderForClassOrObject
|
import org.jetbrains.kotlin.asJava.builder.LightClassDataProviderForClassOrObject
|
||||||
import org.jetbrains.kotlin.asJava.elements.FakeFileForLightClass
|
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.KtLightIdentifier
|
||||||
|
import org.jetbrains.kotlin.asJava.elements.KtLightModifierList
|
||||||
import org.jetbrains.kotlin.asJava.elements.KtLightPsiReferenceList
|
import org.jetbrains.kotlin.asJava.elements.KtLightPsiReferenceList
|
||||||
import org.jetbrains.kotlin.asJava.hasInterfaceDefaultImpls
|
import org.jetbrains.kotlin.asJava.hasInterfaceDefaultImpls
|
||||||
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
||||||
@@ -180,7 +180,7 @@ abstract class KtLightClassForSourceDeclaration(protected val classOrObject: KtC
|
|||||||
|
|
||||||
override fun getName(): String? = classOrObject.nameAsName?.asString()
|
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
|
override fun getModifierList(): PsiModifierList? = _modifierList
|
||||||
|
|
||||||
@@ -452,8 +452,28 @@ abstract class KtLightClassForSourceDeclaration(protected val classOrObject: KtC
|
|||||||
|
|
||||||
override val originKind: LightClassOriginKind
|
override val originKind: LightClassOriginKind
|
||||||
get() = LightClassOriginKind.SOURCE
|
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 {
|
fun getOutermostClassOrObject(classOrObject: KtClassOrObject): KtClassOrObject {
|
||||||
val outermostClass = KtPsiUtil.getOutermostClassOrObject(classOrObject) ?:
|
val outermostClass = KtPsiUtil.getOutermostClassOrObject(classOrObject) ?:
|
||||||
throw IllegalStateException("Attempt to build a light class for a local class: " + classOrObject.text)
|
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
|
isInterface() -> CommonClassNames.JAVA_LANG_OBJECT // see com.intellij.psi.impl.PsiClassImplUtil.getSuperClass
|
||||||
else -> CommonClassNames.JAVA_LANG_OBJECT
|
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.LightMemberOrigin
|
||||||
import org.jetbrains.kotlin.asJava.builder.LightMemberOriginForDeclaration
|
import org.jetbrains.kotlin.asJava.builder.LightMemberOriginForDeclaration
|
||||||
import org.jetbrains.kotlin.asJava.classes.KtLightClass
|
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.asJava.classes.lazyPub
|
||||||
import org.jetbrains.kotlin.lexer.KtTokens
|
import org.jetbrains.kotlin.lexer.KtTokens
|
||||||
import org.jetbrains.kotlin.psi.KtDeclaration
|
import org.jetbrains.kotlin.psi.KtDeclaration
|
||||||
@@ -81,6 +83,8 @@ private class KtLightMemberModifierList(
|
|||||||
name == PsiModifier.ABSTRACT && isImplementationInInterface() -> false
|
name == PsiModifier.ABSTRACT && isImplementationInInterface() -> false
|
||||||
// pretend this method behaves like a default method
|
// pretend this method behaves like a default method
|
||||||
name == PsiModifier.DEFAULT && isImplementationInInterface() -> true
|
name == PsiModifier.DEFAULT && isImplementationInInterface() -> true
|
||||||
|
name == PsiModifier.FINAL && ((owner.containingClass as? KtLightClassForSourceDeclaration)?.isPossiblyAffectedByAllOpen() ?: false) ->
|
||||||
|
clsDelegate.hasModifierProperty(name)
|
||||||
dummyDelegate != null -> {
|
dummyDelegate != null -> {
|
||||||
when {
|
when {
|
||||||
name in visibilityModifiers && isMethodOverride() ->
|
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);
|
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")
|
@TestMetadata("ImplementingCharSequenceAndNumber.kt")
|
||||||
public void testImplementingCharSequenceAndNumber() throws Exception {
|
public void testImplementingCharSequenceAndNumber() throws Exception {
|
||||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/asJava/lightClasses/ideRegression/ImplementingCharSequenceAndNumber.kt");
|
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/asJava/lightClasses/ideRegression/ImplementingCharSequenceAndNumber.kt");
|
||||||
|
|||||||
Reference in New Issue
Block a user