K2 Scripting: deprecate top level script inner classes
no LT support yet
This commit is contained in:
committed by
Space Team
parent
7484ccb9ee
commit
70d2fcd9c4
+12
@@ -253,6 +253,18 @@ internal val KT_DIAGNOSTIC_CONVERTER = KtDiagnosticConverterBuilder.buildConvert
|
||||
token,
|
||||
)
|
||||
}
|
||||
add(FirErrors.INNER_ON_TOP_LEVEL_SCRIPT_CLASS.errorFactory) { firDiagnostic ->
|
||||
InnerOnTopLevelScriptClassErrorImpl(
|
||||
firDiagnostic as KtPsiDiagnostic,
|
||||
token,
|
||||
)
|
||||
}
|
||||
add(FirErrors.INNER_ON_TOP_LEVEL_SCRIPT_CLASS.warningFactory) { firDiagnostic ->
|
||||
InnerOnTopLevelScriptClassWarningImpl(
|
||||
firDiagnostic as KtPsiDiagnostic,
|
||||
token,
|
||||
)
|
||||
}
|
||||
add(FirErrors.INVISIBLE_REFERENCE) { firDiagnostic ->
|
||||
InvisibleReferenceImpl(
|
||||
firSymbolBuilder.buildSymbol(firDiagnostic.a),
|
||||
|
||||
+8
@@ -217,6 +217,14 @@ sealed interface KtFirDiagnostic<PSI : PsiElement> : KtDiagnosticWithPsi<PSI> {
|
||||
val callableId: CallableId
|
||||
}
|
||||
|
||||
interface InnerOnTopLevelScriptClassError : KtFirDiagnostic<PsiElement> {
|
||||
override val diagnosticClass get() = InnerOnTopLevelScriptClassError::class
|
||||
}
|
||||
|
||||
interface InnerOnTopLevelScriptClassWarning : KtFirDiagnostic<PsiElement> {
|
||||
override val diagnosticClass get() = InnerOnTopLevelScriptClassWarning::class
|
||||
}
|
||||
|
||||
interface InvisibleReference : KtFirDiagnostic<PsiElement> {
|
||||
override val diagnosticClass get() = InvisibleReference::class
|
||||
val reference: KtSymbol
|
||||
|
||||
+10
@@ -246,6 +246,16 @@ internal class InvisibleSetterImpl(
|
||||
token: KtLifetimeToken,
|
||||
) : KtAbstractFirDiagnostic<PsiElement>(firDiagnostic, token), KtFirDiagnostic.InvisibleSetter
|
||||
|
||||
internal class InnerOnTopLevelScriptClassErrorImpl(
|
||||
firDiagnostic: KtPsiDiagnostic,
|
||||
token: KtLifetimeToken,
|
||||
) : KtAbstractFirDiagnostic<PsiElement>(firDiagnostic, token), KtFirDiagnostic.InnerOnTopLevelScriptClassError
|
||||
|
||||
internal class InnerOnTopLevelScriptClassWarningImpl(
|
||||
firDiagnostic: KtPsiDiagnostic,
|
||||
token: KtLifetimeToken,
|
||||
) : KtAbstractFirDiagnostic<PsiElement>(firDiagnostic, token), KtFirDiagnostic.InnerOnTopLevelScriptClassWarning
|
||||
|
||||
internal class InvisibleReferenceImpl(
|
||||
override val reference: KtSymbol,
|
||||
override val visible: Visibility,
|
||||
|
||||
+12
@@ -29134,6 +29134,18 @@ public class FirPsiOldFrontendDiagnosticsTestGenerated extends AbstractFirPsiDia
|
||||
runTest("compiler/testData/diagnostics/tests/script/imports.kts");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("innerClassError.kts")
|
||||
public void testInnerClassError() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/script/innerClassError.kts");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("innerClassWarning.kts")
|
||||
public void testInnerClassWarning() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/script/innerClassWarning.kts");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("LateInit.kts")
|
||||
public void testLateInit() throws Exception {
|
||||
|
||||
+1
@@ -99,6 +99,7 @@ object DIAGNOSTICS_LIST : DiagnosticList("FirErrors") {
|
||||
parameter<Visibility>("visibility")
|
||||
parameter<CallableId>("callableId")
|
||||
}
|
||||
val INNER_ON_TOP_LEVEL_SCRIPT_CLASS by deprecationError<PsiElement>(LanguageFeature.ProhibitScriptTopLevelInnerClasses)
|
||||
}
|
||||
|
||||
val UNRESOLVED by object : DiagnosticGroup("Unresolved") {
|
||||
|
||||
@@ -21,6 +21,7 @@ import org.jetbrains.kotlin.config.LanguageFeature.ProhibitCyclesInAnnotations
|
||||
import org.jetbrains.kotlin.config.LanguageFeature.ProhibitImplementingVarByInheritedVal
|
||||
import org.jetbrains.kotlin.config.LanguageFeature.ProhibitInvisibleAbstractMethodsInSuperclasses
|
||||
import org.jetbrains.kotlin.config.LanguageFeature.ProhibitNonReifiedArraysAsReifiedTypeArguments
|
||||
import org.jetbrains.kotlin.config.LanguageFeature.ProhibitScriptTopLevelInnerClasses
|
||||
import org.jetbrains.kotlin.config.LanguageFeature.ProhibitUseSiteTargetAnnotationsOnSuperTypes
|
||||
import org.jetbrains.kotlin.config.LanguageFeature.RestrictRetentionForExpressionAnnotations
|
||||
import org.jetbrains.kotlin.config.LanguageFeature.RestrictionOfValReassignmentViaBackingField
|
||||
@@ -146,6 +147,7 @@ object FirErrors {
|
||||
val VAL_OR_VAR_ON_CATCH_PARAMETER by error1<KtParameter, KtKeywordToken>(SourceElementPositioningStrategies.VAL_OR_VAR_NODE)
|
||||
val VAL_OR_VAR_ON_SECONDARY_CONSTRUCTOR_PARAMETER by error1<KtParameter, KtKeywordToken>(SourceElementPositioningStrategies.VAL_OR_VAR_NODE)
|
||||
val INVISIBLE_SETTER by error3<PsiElement, FirPropertySymbol, Visibility, CallableId>(SourceElementPositioningStrategies.SELECTOR_BY_QUALIFIED)
|
||||
val INNER_ON_TOP_LEVEL_SCRIPT_CLASS by deprecationError0<PsiElement>(ProhibitScriptTopLevelInnerClasses)
|
||||
|
||||
// Unresolved
|
||||
val INVISIBLE_REFERENCE by error3<PsiElement, FirBasedSymbol<*>, Visibility, ClassId?>(SourceElementPositioningStrategies.REFERENCE_BY_QUALIFIED)
|
||||
|
||||
+11
-7
@@ -262,13 +262,17 @@ object FirModifierChecker : FirBasicDeclarationChecker() {
|
||||
val possibleParentPredicate = possibleParentTargetPredicateMap[modifierToken] ?: return true
|
||||
if (actualParents.any { possibleParentPredicate.isAllowed(it, context.session.languageVersionSettings) }) return true
|
||||
|
||||
reporter.reportOn(
|
||||
modifierSource,
|
||||
FirErrors.WRONG_MODIFIER_CONTAINING_DECLARATION,
|
||||
modifierToken,
|
||||
actualParents.firstOrThis(),
|
||||
context
|
||||
)
|
||||
if (modifierToken == KtTokens.INNER_KEYWORD && parent is FirScript) {
|
||||
reporter.reportOn(modifierSource, FirErrors.INNER_ON_TOP_LEVEL_SCRIPT_CLASS, context)
|
||||
} else {
|
||||
reporter.reportOn(
|
||||
modifierSource,
|
||||
FirErrors.WRONG_MODIFIER_CONTAINING_DECLARATION,
|
||||
modifierToken,
|
||||
actualParents.firstOrThis(),
|
||||
context
|
||||
)
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
+2
@@ -301,6 +301,7 @@ import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.INLINE_SUSPEND_FU
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.INNER_CLASS_CONSTRUCTOR_NO_RECEIVER
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.INNER_CLASS_INSIDE_VALUE_CLASS
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.INNER_CLASS_OF_GENERIC_THROWABLE_SUBCLASS
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.INNER_ON_TOP_LEVEL_SCRIPT_CLASS
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.INSTANCE_ACCESS_BEFORE_SUPER_CALL
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.INTERFACE_AS_FUNCTION
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.INTERFACE_WITH_SUPERCLASS
|
||||
@@ -714,6 +715,7 @@ object FirErrorsDefaultMessages : BaseDiagnosticRendererFactory() {
|
||||
VISIBILITY,
|
||||
NAME_OF_CONTAINING_DECLARATION_OR_FILE
|
||||
)
|
||||
map.put(INNER_ON_TOP_LEVEL_SCRIPT_CLASS, "Top level script class cannot be inner.")
|
||||
map.put(UNRESOLVED_REFERENCE, "Unresolved reference: {0}", NULLABLE_STRING)
|
||||
map.put(UNRESOLVED_IMPORT, "Unresolved reference: {0}", NULLABLE_STRING) // &
|
||||
map.put(UNRESOLVED_LABEL, "Unresolved label")
|
||||
|
||||
+5
-4
@@ -1023,7 +1023,7 @@ open class PsiRawFirBuilder(
|
||||
val status = FirDeclarationStatusImpl(explicitVisibility ?: defaultVisibility(), Modality.FINAL).apply {
|
||||
isExpect = this@toFirConstructor?.hasExpectModifier() == true || this@PsiRawFirBuilder.context.containerIsExpect
|
||||
isActual = this@toFirConstructor?.hasActualModifier() == true
|
||||
isInner = owner.hasModifier(INNER_KEYWORD)
|
||||
isInner = owner.parent.parent !is KtScript && owner.hasModifier(INNER_KEYWORD) // a warning about inner script class is reported on the class itself
|
||||
isFromSealedClass = owner.hasModifier(SEALED_KEYWORD) && explicitVisibility !== Visibilities.Private
|
||||
isFromEnumClass = owner.hasModifier(ENUM_KEYWORD)
|
||||
}
|
||||
@@ -1244,6 +1244,7 @@ open class PsiRawFirBuilder(
|
||||
// NB: enum entry nested classes are considered local by FIR design (see discussion in KT-45115)
|
||||
val isLocal = classOrObject.isLocal || classOrObject.getStrictParentOfType<KtEnumEntry>() != null
|
||||
val classIsExpect = classOrObject.hasExpectModifier() || context.containerIsExpect
|
||||
val sourceElement = classOrObject.toFirSourceElement()
|
||||
return withChildClassName(
|
||||
classOrObject.nameAsSafeName,
|
||||
isExpect = classIsExpect,
|
||||
@@ -1265,7 +1266,7 @@ open class PsiRawFirBuilder(
|
||||
).apply {
|
||||
isExpect = classIsExpect
|
||||
isActual = classOrObject.hasActualModifier()
|
||||
isInner = classOrObject.hasModifier(INNER_KEYWORD)
|
||||
isInner = classOrObject.hasModifier(INNER_KEYWORD) && classOrObject.parent.parent !is KtScript
|
||||
isCompanion = (classOrObject as? KtObjectDeclaration)?.isCompanion() == true
|
||||
isData = classOrObject.hasModifier(DATA_KEYWORD)
|
||||
isInline = classOrObject.hasModifier(INLINE_KEYWORD) || classOrObject.hasModifier(VALUE_KEYWORD)
|
||||
@@ -1273,10 +1274,10 @@ open class PsiRawFirBuilder(
|
||||
isExternal = classOrObject.hasModifier(EXTERNAL_KEYWORD)
|
||||
}
|
||||
|
||||
withCapturedTypeParameters(status.isInner || isLocal, classOrObject.toFirSourceElement(), listOf()) {
|
||||
withCapturedTypeParameters(status.isInner || isLocal, sourceElement, listOf()) {
|
||||
var delegatedFieldsMap: Map<Int, FirFieldSymbol>?
|
||||
buildRegularClass {
|
||||
source = classOrObject.toFirSourceElement()
|
||||
source = sourceElement
|
||||
moduleData = baseModuleData
|
||||
origin = FirDeclarationOrigin.Source
|
||||
name = classOrObject.nameAsSafeName
|
||||
|
||||
@@ -10,7 +10,7 @@ class Nested {
|
||||
}
|
||||
|
||||
|
||||
<!WRONG_MODIFIER_CONTAINING_DECLARATION!>inner<!> class Inner {
|
||||
<!INNER_ON_TOP_LEVEL_SCRIPT_CLASS_WARNING!>inner<!> class Inner {
|
||||
fun innerFun() = function()
|
||||
val innerProp = property
|
||||
fun innerThisFun() = this<!UNRESOLVED_LABEL!>@NestedInnerClass<!>.function()
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
// TARGET_BACKEND: JVM_IR
|
||||
// !LANGUAGE: +ProhibitScriptTopLevelInnerClasses
|
||||
|
||||
<!INNER_ON_TOP_LEVEL_SCRIPT_CLASS_ERROR!>inner<!> class A
|
||||
@@ -0,0 +1,3 @@
|
||||
// TARGET_BACKEND: JVM_IR
|
||||
|
||||
inner class A
|
||||
@@ -0,0 +1,4 @@
|
||||
// TARGET_BACKEND: JVM_IR
|
||||
// !LANGUAGE: -ProhibitScriptTopLevelInnerClasses
|
||||
|
||||
<!INNER_ON_TOP_LEVEL_SCRIPT_CLASS_WARNING!>inner<!> class A
|
||||
@@ -0,0 +1,3 @@
|
||||
// TARGET_BACKEND: JVM_IR
|
||||
|
||||
inner class A
|
||||
Generated
+12
@@ -29972,6 +29972,18 @@ public class DiagnosticTestGenerated extends AbstractDiagnosticTest {
|
||||
runTest("compiler/testData/diagnostics/tests/script/imports.kts");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("innerClassError.kts")
|
||||
public void testInnerClassError() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/script/innerClassError.kts");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("innerClassWarning.kts")
|
||||
public void testInnerClassWarning() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/script/innerClassWarning.kts");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("LateInit.kts")
|
||||
public void testLateInit() throws Exception {
|
||||
|
||||
@@ -332,6 +332,11 @@ enum class LanguageFeature(
|
||||
// When this feature is enabled, no such errors are reported.
|
||||
NoAdditionalErrorsInK1DiagnosticReporter(sinceVersion = null, kind = OTHER),
|
||||
|
||||
// top-level script inner classes never made any sense, but used for some time to overcome the capturing logic limitations
|
||||
// Now capturing logic works properly, therefore the warning is reported in K2
|
||||
// this feature will eventually switch this warning to an error
|
||||
ProhibitScriptTopLevelInnerClasses(sinceVersion = null, kind = OTHER),
|
||||
|
||||
// Experimental features
|
||||
|
||||
BreakContinueInInlineLambdas(null), // KT-1436
|
||||
|
||||
Reference in New Issue
Block a user