[FIR] KT-54260: Fix the compiler crash

AllOpen plugin makes the properties all-open, but the annotation class
is left closed, because allopen for k2 literally checks
`classKind == CLASS`.

Since the properties are open, a
`NON_FINAL_MEMBER_IN_FINAL_CLASS` diagnostic is reported for them. It's
positioning strategy seeks for the explicit `open` modifier which is
not present.

The added test should not crash the compiler.

^KT-54260 Fixed
This commit is contained in:
Nikolay Lunyak
2022-11-17 10:54:34 +02:00
committed by teamcity
parent c79d65536b
commit 4b3dc008f0
7 changed files with 185 additions and 50 deletions
@@ -345,6 +345,8 @@ object LightTreePositioningStrategies {
}
private open class ModifierSetBasedLightTreePositioningStrategy(private val modifierSet: TokenSet) : LightTreePositioningStrategy() {
constructor(vararg tokens: IElementType) : this(TokenSet.create(*tokens))
protected fun markModifier(
node: LighterASTNode?,
startOffset: Int,
@@ -387,7 +389,7 @@ object LightTreePositioningStrategies {
}
}
private class InlineFunLightTreePositioningStrategy : ModifierSetBasedLightTreePositioningStrategy(TokenSet.create(INLINE_KEYWORD)) {
private class InlineFunLightTreePositioningStrategy : ModifierSetBasedLightTreePositioningStrategy(INLINE_KEYWORD) {
override fun mark(
node: LighterASTNode,
startOffset: Int,
@@ -408,52 +410,52 @@ object LightTreePositioningStrategies {
val MODALITY_MODIFIER: LightTreePositioningStrategy = ModifierSetBasedLightTreePositioningStrategy(MODALITY_MODIFIERS)
val ABSTRACT_MODIFIER: LightTreePositioningStrategy =
ModifierSetBasedLightTreePositioningStrategy(TokenSet.create(KtTokens.ABSTRACT_KEYWORD))
ModifierSetBasedLightTreePositioningStrategy(KtTokens.ABSTRACT_KEYWORD)
val OPEN_MODIFIER: LightTreePositioningStrategy =
ModifierSetBasedLightTreePositioningStrategy(TokenSet.create(KtTokens.OPEN_KEYWORD))
ModifierSetBasedLightTreePositioningStrategy(KtTokens.OPEN_KEYWORD)
val OVERRIDE_MODIFIER: LightTreePositioningStrategy =
ModifierSetBasedLightTreePositioningStrategy(TokenSet.create(KtTokens.OVERRIDE_KEYWORD))
ModifierSetBasedLightTreePositioningStrategy(KtTokens.OVERRIDE_KEYWORD)
val PRIVATE_MODIFIER: LightTreePositioningStrategy =
ModifierSetBasedLightTreePositioningStrategy(TokenSet.create(KtTokens.PRIVATE_KEYWORD))
ModifierSetBasedLightTreePositioningStrategy(KtTokens.PRIVATE_KEYWORD)
val LATEINIT_MODIFIER: LightTreePositioningStrategy =
ModifierSetBasedLightTreePositioningStrategy(TokenSet.create(KtTokens.LATEINIT_KEYWORD))
ModifierSetBasedLightTreePositioningStrategy(KtTokens.LATEINIT_KEYWORD)
val VARIANCE_MODIFIER: LightTreePositioningStrategy =
ModifierSetBasedLightTreePositioningStrategy(TokenSet.create(KtTokens.IN_KEYWORD, KtTokens.OUT_KEYWORD))
ModifierSetBasedLightTreePositioningStrategy(KtTokens.IN_KEYWORD, KtTokens.OUT_KEYWORD)
val CONST_MODIFIER: LightTreePositioningStrategy =
ModifierSetBasedLightTreePositioningStrategy(TokenSet.create(KtTokens.CONST_KEYWORD))
ModifierSetBasedLightTreePositioningStrategy(KtTokens.CONST_KEYWORD)
val FUN_MODIFIER: LightTreePositioningStrategy =
ModifierSetBasedLightTreePositioningStrategy(TokenSet.create(KtTokens.FUN_KEYWORD))
ModifierSetBasedLightTreePositioningStrategy(KtTokens.FUN_KEYWORD)
val SUSPEND_MODIFIER: LightTreePositioningStrategy =
ModifierSetBasedLightTreePositioningStrategy(TokenSet.create(KtTokens.SUSPEND_KEYWORD))
ModifierSetBasedLightTreePositioningStrategy(KtTokens.SUSPEND_KEYWORD)
private val SUSPEND_OR_FUN_MODIFIER: LightTreePositioningStrategy =
ModifierSetBasedLightTreePositioningStrategy(TokenSet.create(KtTokens.SUSPEND_KEYWORD, KtTokens.FUN_KEYWORD))
ModifierSetBasedLightTreePositioningStrategy(KtTokens.SUSPEND_KEYWORD, KtTokens.FUN_KEYWORD)
val INLINE_OR_VALUE_MODIFIER: LightTreePositioningStrategy =
ModifierSetBasedLightTreePositioningStrategy(TokenSet.create(INLINE_KEYWORD, KtTokens.VALUE_KEYWORD))
ModifierSetBasedLightTreePositioningStrategy(INLINE_KEYWORD, KtTokens.VALUE_KEYWORD)
val INNER_MODIFIER: LightTreePositioningStrategy =
ModifierSetBasedLightTreePositioningStrategy(TokenSet.create(KtTokens.INNER_KEYWORD))
ModifierSetBasedLightTreePositioningStrategy(KtTokens.INNER_KEYWORD)
val DATA_MODIFIER: LightTreePositioningStrategy =
ModifierSetBasedLightTreePositioningStrategy(TokenSet.create(KtTokens.DATA_KEYWORD))
ModifierSetBasedLightTreePositioningStrategy(KtTokens.DATA_KEYWORD)
val OPERATOR_MODIFIER: LightTreePositioningStrategy =
ModifierSetBasedLightTreePositioningStrategy(TokenSet.create(KtTokens.OPERATOR_KEYWORD))
ModifierSetBasedLightTreePositioningStrategy(KtTokens.OPERATOR_KEYWORD)
val ENUM_MODIFIER: LightTreePositioningStrategy =
ModifierSetBasedLightTreePositioningStrategy(TokenSet.create(KtTokens.ENUM_KEYWORD))
ModifierSetBasedLightTreePositioningStrategy(KtTokens.ENUM_KEYWORD)
val TAILREC_MODIFIER: LightTreePositioningStrategy =
ModifierSetBasedLightTreePositioningStrategy(TokenSet.create(KtTokens.TAILREC_KEYWORD))
ModifierSetBasedLightTreePositioningStrategy(KtTokens.TAILREC_KEYWORD)
val OBJECT_KEYWORD: LightTreePositioningStrategy = keywordStrategy { objectKeyword(it) }
@@ -476,7 +478,7 @@ object LightTreePositioningStrategies {
}
val INLINE_PARAMETER_MODIFIER: LightTreePositioningStrategy =
ModifierSetBasedLightTreePositioningStrategy(TokenSet.create(KtTokens.NOINLINE_KEYWORD, KtTokens.CROSSINLINE_KEYWORD))
ModifierSetBasedLightTreePositioningStrategy(KtTokens.NOINLINE_KEYWORD, KtTokens.CROSSINLINE_KEYWORD)
val INLINE_FUN_MODIFIER: LightTreePositioningStrategy = InlineFunLightTreePositioningStrategy()
@@ -850,7 +852,7 @@ object LightTreePositioningStrategies {
}
val REIFIED_MODIFIER: LightTreePositioningStrategy =
ModifierSetBasedLightTreePositioningStrategy(TokenSet.create(KtTokens.REIFIED_KEYWORD))
ModifierSetBasedLightTreePositioningStrategy(KtTokens.REIFIED_KEYWORD)
val TYPE_PARAMETERS_LIST: LightTreePositioningStrategy = object : LightTreePositioningStrategy() {
override fun mark(
@@ -8,6 +8,7 @@ package org.jetbrains.kotlin.diagnostics
import com.intellij.lang.ASTNode
import com.intellij.openapi.util.TextRange
import com.intellij.psi.*
import com.intellij.psi.tree.IElementType
import com.intellij.psi.tree.TokenSet
import org.jetbrains.kotlin.KtNodeTypes
import org.jetbrains.kotlin.lexer.KtModifierKeywordToken
@@ -258,43 +259,55 @@ object PositioningStrategies {
}
@JvmField
val ABSTRACT_MODIFIER: PositioningStrategy<KtModifierListOwner> = modifierSetPosition(KtTokens.ABSTRACT_KEYWORD)
val ABSTRACT_MODIFIER: PositioningStrategy<KtModifierListOwner> =
ModifierSetBasedPositioningStrategy(KtTokens.ABSTRACT_KEYWORD)
@JvmField
val OPEN_MODIFIER: PositioningStrategy<KtModifierListOwner> = modifierSetPosition(KtTokens.OPEN_KEYWORD)
val OPEN_MODIFIER: PositioningStrategy<KtModifierListOwner> =
ModifierSetBasedPositioningStrategy(KtTokens.OPEN_KEYWORD)
@JvmField
val OVERRIDE_MODIFIER: PositioningStrategy<KtModifierListOwner> = modifierSetPosition(KtTokens.OVERRIDE_KEYWORD)
val OVERRIDE_MODIFIER: PositioningStrategy<KtModifierListOwner> =
ModifierSetBasedPositioningStrategy(KtTokens.OVERRIDE_KEYWORD)
@JvmField
val PRIVATE_MODIFIER: PositioningStrategy<KtModifierListOwner> = modifierSetPosition(KtTokens.PRIVATE_KEYWORD)
val PRIVATE_MODIFIER: PositioningStrategy<KtModifierListOwner> =
ModifierSetBasedPositioningStrategy(KtTokens.PRIVATE_KEYWORD)
@JvmField
val LATEINIT_MODIFIER: PositioningStrategy<KtModifierListOwner> = modifierSetPosition(KtTokens.LATEINIT_KEYWORD)
val LATEINIT_MODIFIER: PositioningStrategy<KtModifierListOwner> =
ModifierSetBasedPositioningStrategy(KtTokens.LATEINIT_KEYWORD)
@JvmField
val VARIANCE_MODIFIER: PositioningStrategy<KtModifierListOwner> = projectionPosition()
@JvmField
val CONST_MODIFIER: PositioningStrategy<KtModifierListOwner> = modifierSetPosition(KtTokens.CONST_KEYWORD)
val CONST_MODIFIER: PositioningStrategy<KtModifierListOwner> =
ModifierSetBasedPositioningStrategy(KtTokens.CONST_KEYWORD)
@JvmField
val FUN_MODIFIER: PositioningStrategy<KtModifierListOwner> = modifierSetPosition(KtTokens.FUN_KEYWORD)
val FUN_MODIFIER: PositioningStrategy<KtModifierListOwner> =
ModifierSetBasedPositioningStrategy(KtTokens.FUN_KEYWORD)
@JvmField
val SUSPEND_MODIFIER: PositioningStrategy<KtModifierListOwner> = modifierSetPosition(KtTokens.SUSPEND_KEYWORD)
val SUSPEND_MODIFIER: PositioningStrategy<KtModifierListOwner> =
ModifierSetBasedPositioningStrategy(KtTokens.SUSPEND_KEYWORD)
@JvmField
val DATA_MODIFIER: PositioningStrategy<KtModifierListOwner> = modifierSetPosition(KtTokens.DATA_KEYWORD)
val DATA_MODIFIER: PositioningStrategy<KtModifierListOwner> =
ModifierSetBasedPositioningStrategy(KtTokens.DATA_KEYWORD)
@JvmField
val OPERATOR_MODIFIER: PositioningStrategy<KtModifierListOwner> = modifierSetPosition(KtTokens.OPERATOR_KEYWORD)
val OPERATOR_MODIFIER: PositioningStrategy<KtModifierListOwner> =
ModifierSetBasedPositioningStrategy(KtTokens.OPERATOR_KEYWORD)
@JvmField
val ENUM_MODIFIER: PositioningStrategy<KtModifierListOwner> = modifierSetPosition(KtTokens.ENUM_KEYWORD)
val ENUM_MODIFIER: PositioningStrategy<KtModifierListOwner> =
ModifierSetBasedPositioningStrategy(KtTokens.ENUM_KEYWORD)
@JvmField
val TAILREC_MODIFIER: PositioningStrategy<KtModifierListOwner> = modifierSetPosition(KtTokens.TAILREC_KEYWORD)
val TAILREC_MODIFIER: PositioningStrategy<KtModifierListOwner> =
ModifierSetBasedPositioningStrategy(KtTokens.TAILREC_KEYWORD)
@JvmField
val OBJECT_KEYWORD: PositioningStrategy<KtObjectDeclaration> = object : PositioningStrategy<KtObjectDeclaration>() {
@@ -354,7 +367,7 @@ object PositioningStrategies {
fun modifierSetPosition(vararg tokens: KtModifierKeywordToken): PositioningStrategy<KtModifierListOwner> {
return object : PositioningStrategy<KtModifierListOwner>() {
override fun mark(element: KtModifierListOwner): List<TextRange> {
val modifierList = element.modifierList.sure { "No modifier list, but modifier has been found by the analyzer" }
val modifierList = element.modifierList ?: return DEFAULT.mark(element)
for (token in tokens) {
val modifier = modifierList.getModifier(token)
@@ -363,7 +376,7 @@ object PositioningStrategies {
}
}
throw IllegalStateException("None of the modifiers is found: " + listOf(*tokens))
return DEFAULT.mark(element)
}
}
}
@@ -400,6 +413,8 @@ object PositioningStrategies {
}
private open class ModifierSetBasedPositioningStrategy(private val modifierSet: TokenSet) : PositioningStrategy<KtModifierListOwner>() {
constructor(vararg tokens: IElementType) : this(TokenSet.create(*tokens))
protected fun markModifier(element: KtModifierListOwner?): List<TextRange>? =
modifierSet.types.mapNotNull {
element?.modifierList?.getModifier(it as KtModifierKeywordToken)?.textRange
@@ -429,7 +444,7 @@ object PositioningStrategies {
}
}
private class InlineFunPositioningStrategy : ModifierSetBasedPositioningStrategy(TokenSet.create(KtTokens.INLINE_KEYWORD)) {
private class InlineFunPositioningStrategy : ModifierSetBasedPositioningStrategy(KtTokens.INLINE_KEYWORD) {
override fun mark(element: KtModifierListOwner): List<TextRange> {
if (element is KtProperty) {
return markModifier(element.getter) ?: markModifier(element.setter) ?: super.mark(element)
@@ -446,15 +461,15 @@ object PositioningStrategies {
@JvmField
val INLINE_OR_VALUE_MODIFIER: PositioningStrategy<KtModifierListOwner> =
ModifierSetBasedPositioningStrategy(TokenSet.create(KtTokens.INLINE_KEYWORD, KtTokens.VALUE_KEYWORD))
ModifierSetBasedPositioningStrategy(KtTokens.INLINE_KEYWORD, KtTokens.VALUE_KEYWORD)
@JvmField
val INNER_MODIFIER: PositioningStrategy<KtModifierListOwner> =
ModifierSetBasedPositioningStrategy(TokenSet.create(KtTokens.INNER_KEYWORD))
ModifierSetBasedPositioningStrategy(KtTokens.INNER_KEYWORD)
@JvmField
val INLINE_PARAMETER_MODIFIER: PositioningStrategy<KtModifierListOwner> =
ModifierSetBasedPositioningStrategy(TokenSet.create(KtTokens.NOINLINE_KEYWORD, KtTokens.CROSSINLINE_KEYWORD))
ModifierSetBasedPositioningStrategy(KtTokens.NOINLINE_KEYWORD, KtTokens.CROSSINLINE_KEYWORD)
@JvmField
val INLINE_FUN_MODIFIER: PositioningStrategy<KtModifierListOwner> = InlineFunPositioningStrategy()
@@ -717,14 +732,8 @@ object PositioningStrategies {
}
@JvmField
val COMPANION_OBJECT: PositioningStrategy<KtObjectDeclaration> = object : PositioningStrategy<KtObjectDeclaration>() {
override fun mark(element: KtObjectDeclaration): List<TextRange> {
if (element.hasModifier(KtTokens.COMPANION_KEYWORD)) {
return modifierSetPosition(KtTokens.COMPANION_KEYWORD).mark(element)
}
return DEFAULT.mark(element)
}
}
val COMPANION_OBJECT: PositioningStrategy<KtModifierListOwner> =
ModifierSetBasedPositioningStrategy(KtTokens.COMPANION_KEYWORD)
@JvmField
val SECONDARY_CONSTRUCTOR_DELEGATION_CALL: PositioningStrategy<PsiElement> =
@@ -905,7 +914,8 @@ object PositioningStrategies {
val REFERENCE_BY_QUALIFIED: PositioningStrategy<PsiElement> = FindReferencePositioningStrategy(false)
val REFERENCED_NAME_BY_QUALIFIED: PositioningStrategy<PsiElement> = FindReferencePositioningStrategy(true)
val REIFIED_MODIFIER: PositioningStrategy<KtModifierListOwner> = modifierSetPosition(KtTokens.REIFIED_KEYWORD)
val REIFIED_MODIFIER: PositioningStrategy<KtModifierListOwner> =
ModifierSetBasedPositioningStrategy(KtTokens.REIFIED_KEYWORD)
val PROPERTY_INITIALIZER: PositioningStrategy<KtProperty> = object : PositioningStrategy<KtProperty>() {
override fun mark(element: KtProperty): List<TextRange> {
@@ -981,7 +991,7 @@ object PositioningStrategies {
}
val NON_FINAL_MODIFIER_OR_NAME: PositioningStrategy<KtModifierListOwner> =
ModifierSetBasedPositioningStrategy(TokenSet.create(KtTokens.ABSTRACT_KEYWORD, KtTokens.OPEN_KEYWORD, KtTokens.SEALED_KEYWORD))
ModifierSetBasedPositioningStrategy(KtTokens.ABSTRACT_KEYWORD, KtTokens.OPEN_KEYWORD, KtTokens.SEALED_KEYWORD)
val DELEGATED_SUPERTYPE_BY_KEYWORD: PositioningStrategy<KtTypeReference> = object : PositioningStrategy<KtTypeReference>() {
override fun mark(element: KtTypeReference): List<TextRange> {
@@ -5,9 +5,7 @@
package org.jetbrains.kotlin.generators.tests
import org.jetbrains.kotlin.allopen.AbstractBytecodeListingTestForAllOpen
import org.jetbrains.kotlin.allopen.AbstractFirBytecodeListingTestForAllOpen
import org.jetbrains.kotlin.allopen.AbstractIrBytecodeListingTestForAllOpen
import org.jetbrains.kotlin.allopen.*
import org.jetbrains.kotlin.android.parcel.AbstractParcelBoxTest
import org.jetbrains.kotlin.android.parcel.AbstractParcelBytecodeListingTest
import org.jetbrains.kotlin.android.parcel.AbstractParcelIrBoxTest
@@ -274,6 +272,12 @@ fun main(args: Array<String>) {
testClass<AbstractFirBytecodeListingTestForAllOpen> {
model("bytecodeListing", excludedPattern = excludedFirTestdataPattern)
}
testClass<AbstractFirDiagnosticTestForAllOpen>() {
model("diagnostics", excludedPattern = excludedFirTestdataPattern)
}
testClass<AbstractFirDiagnosticsWithLightTreeTestForAllOpen>() {
model("diagnostics", excludedPattern = excludedFirTestdataPattern)
}
}
testGroup("plugins/noarg/tests-gen", "plugins/noarg/testData") {
@@ -0,0 +1,45 @@
/*
* Copyright 2010-2016 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.kotlin.allopen
import org.jetbrains.kotlin.test.builders.TestConfigurationBuilder
import org.jetbrains.kotlin.test.directives.FirDiagnosticsDirectives
import org.jetbrains.kotlin.test.runners.AbstractFirDiagnosticTest
import org.jetbrains.kotlin.test.runners.configurationForClassicAndFirTestsAlongside
abstract class AbstractFirDiagnosticTestForAllOpen : AbstractFirDiagnosticTest() {
override fun configure(builder: TestConfigurationBuilder) {
super.configure(builder)
with(builder) {
useConfigurators(::AllOpenEnvironmentConfigurator)
configurationForClassicAndFirTestsAlongside()
}
}
}
abstract class AbstractFirDiagnosticsWithLightTreeTestForAllOpen : AbstractFirDiagnosticTestForAllOpen() {
override fun configure(builder: TestConfigurationBuilder) {
super.configure(builder)
with(builder) {
defaultDirectives {
+FirDiagnosticsDirectives.USE_LIGHT_TREE
}
}
}
}
+10
View File
@@ -0,0 +1,10 @@
// FIR_IDENTICAL
// WITH_STDLIB
annotation class AllOpen
@AllOpen
annotation class ConsoleCommands(
val <!NON_FINAL_MEMBER_IN_FINAL_CLASS!>value<!>: String = "",
val <!NON_FINAL_MEMBER_IN_FINAL_CLASS!>scope<!>: String
)
@@ -0,0 +1,32 @@
/*
* Copyright 2010-2022 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.allopen;
import com.intellij.testFramework.TestDataPath;
import org.jetbrains.kotlin.test.util.KtTestUtil;
import org.jetbrains.kotlin.test.TestMetadata;
import org.junit.jupiter.api.Nested;
import org.junit.jupiter.api.Test;
import java.io.File;
import java.util.regex.Pattern;
/** This class is generated by {@link org.jetbrains.kotlin.generators.tests.GenerateTestsKt}. DO NOT MODIFY MANUALLY */
@SuppressWarnings("all")
@TestMetadata("plugins/allopen/testData/diagnostics")
@TestDataPath("$PROJECT_ROOT")
public class FirDiagnosticTestForAllOpenGenerated extends AbstractFirDiagnosticTestForAllOpen {
@Test
public void testAllFilesPresentInDiagnostics() throws Exception {
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("plugins/allopen/testData/diagnostics"), Pattern.compile("^(.+)\\.kt$"), Pattern.compile("^(.+)\\.fir\\.kts?$"), true);
}
@Test
@TestMetadata("kt54260.kt")
public void testKt54260() throws Exception {
runTest("plugins/allopen/testData/diagnostics/kt54260.kt");
}
}
@@ -0,0 +1,32 @@
/*
* Copyright 2010-2022 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.allopen;
import com.intellij.testFramework.TestDataPath;
import org.jetbrains.kotlin.test.util.KtTestUtil;
import org.jetbrains.kotlin.test.TestMetadata;
import org.junit.jupiter.api.Nested;
import org.junit.jupiter.api.Test;
import java.io.File;
import java.util.regex.Pattern;
/** This class is generated by {@link org.jetbrains.kotlin.generators.tests.GenerateTestsKt}. DO NOT MODIFY MANUALLY */
@SuppressWarnings("all")
@TestMetadata("plugins/allopen/testData/diagnostics")
@TestDataPath("$PROJECT_ROOT")
public class FirDiagnosticsWithLightTreeTestForAllOpenGenerated extends AbstractFirDiagnosticsWithLightTreeTestForAllOpen {
@Test
public void testAllFilesPresentInDiagnostics() throws Exception {
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("plugins/allopen/testData/diagnostics"), Pattern.compile("^(.+)\\.kt$"), Pattern.compile("^(.+)\\.fir\\.kts?$"), true);
}
@Test
@TestMetadata("kt54260.kt")
public void testKt54260() throws Exception {
runTest("plugins/allopen/testData/diagnostics/kt54260.kt");
}
}