[FIR] Add JVM_INLINE_WITHOUT_VALUE_CLASS, VALUE_CLASS_WITHOUT_JVM_INLINE_ANNOTATION
This commit is contained in:
committed by
teamcityserver
parent
7e7066d75e
commit
a816bd9a33
+1
-1
@@ -1,4 +1,4 @@
|
||||
<!ABSENCE_OF_PRIMARY_CONSTRUCTOR_FOR_INLINE_CLASS!>value<!> class WithoutConstructor {}
|
||||
<!ABSENCE_OF_PRIMARY_CONSTRUCTOR_FOR_INLINE_CLASS, VALUE_CLASS_WITHOUT_JVM_INLINE_ANNOTATION!>value<!> class WithoutConstructor {}
|
||||
|
||||
inline class WithoutParameter<!INLINE_CLASS_CONSTRUCTOR_WRONG_PARAMETERS_SIZE!>()<!> {}
|
||||
inline class WithTwoParameters<!INLINE_CLASS_CONSTRUCTOR_WRONG_PARAMETERS_SIZE!>(val x: Int, val y: String)<!> {}
|
||||
|
||||
+2
-2
@@ -3,14 +3,14 @@ class A {
|
||||
fun foo() {
|
||||
<!INLINE_CLASS_NOT_TOP_LEVEL, WRONG_MODIFIER_TARGET!>inline<!> class C(val x: Int)
|
||||
}
|
||||
inner <!INLINE_CLASS_NOT_TOP_LEVEL!>value<!> class D(val x: Int)
|
||||
inner <!INLINE_CLASS_NOT_TOP_LEVEL, VALUE_CLASS_WITHOUT_JVM_INLINE_ANNOTATION!>value<!> class D(val x: Int)
|
||||
}
|
||||
|
||||
<!INLINE_CLASS_NOT_FINAL!>open<!> inline class NotFinalClass1(val x: Int)
|
||||
<!INLINE_CLASS_NOT_FINAL!>abstract<!> inline class NotFinalClass2(val x: Int)
|
||||
<!INLINE_CLASS_NOT_FINAL!>sealed<!> inline class NotFinalClass3(val x: Int)
|
||||
|
||||
<!VALUE_CLASS_CANNOT_BE_CLONEABLE!>value<!> class CloneableClass1(val x: Int): Cloneable
|
||||
<!VALUE_CLASS_CANNOT_BE_CLONEABLE, VALUE_CLASS_WITHOUT_JVM_INLINE_ANNOTATION!>value<!> class CloneableClass1(val x: Int): Cloneable
|
||||
<!VALUE_CLASS_CANNOT_BE_CLONEABLE!>inline<!> class CloneableClass2(val x: Int): java.lang.Cloneable
|
||||
|
||||
open class Test
|
||||
|
||||
+2
-2
@@ -1,4 +1,4 @@
|
||||
value class BackingFields(val x: Int) {
|
||||
<!VALUE_CLASS_WITHOUT_JVM_INLINE_ANNOTATION!>value<!> class BackingFields(val x: Int) {
|
||||
<!PROPERTY_WITH_BACKING_FIELD_INSIDE_INLINE_CLASS!>val y<!> = 0
|
||||
var z: String
|
||||
get() = ""
|
||||
@@ -27,6 +27,6 @@ inline class SecondaryConstructors(val x: Int) {
|
||||
}<!>
|
||||
}
|
||||
|
||||
value class WithInner(val x: String) {
|
||||
<!VALUE_CLASS_WITHOUT_JVM_INLINE_ANNOTATION!>value<!> class WithInner(val x: String) {
|
||||
<!INNER_CLASS_INSIDE_INLINE_CLASS!>inner<!> class Inner
|
||||
}
|
||||
|
||||
+3
@@ -37,6 +37,9 @@ object JVM_DIAGNOSTICS_LIST : DiagnosticList("FirJvmErrors") {
|
||||
val ILLEGAL_JVM_NAME by error<PsiElement>()
|
||||
|
||||
val FUNCTION_DELEGATE_MEMBER_NAME_CLASH by error<PsiElement>(PositioningStrategy.DECLARATION_NAME)
|
||||
|
||||
val VALUE_CLASS_WITHOUT_JVM_INLINE_ANNOTATION by error<PsiElement>()
|
||||
val JVM_INLINE_WITHOUT_VALUE_CLASS by error<PsiElement>()
|
||||
}
|
||||
|
||||
val TYPES by object : DiagnosticGroup("Types") {
|
||||
|
||||
+2
@@ -40,6 +40,8 @@ object FirJvmErrors {
|
||||
val INAPPLICABLE_JVM_NAME by error0<PsiElement>()
|
||||
val ILLEGAL_JVM_NAME by error0<PsiElement>()
|
||||
val FUNCTION_DELEGATE_MEMBER_NAME_CLASH by error0<PsiElement>(SourceElementPositioningStrategies.DECLARATION_NAME)
|
||||
val VALUE_CLASS_WITHOUT_JVM_INLINE_ANNOTATION by error0<PsiElement>()
|
||||
val JVM_INLINE_WITHOUT_VALUE_CLASS by error0<PsiElement>()
|
||||
|
||||
// Types
|
||||
val JAVA_TYPE_MISMATCH by error2<KtExpression, ConeKotlinType, ConeKotlinType>()
|
||||
|
||||
+2
-1
@@ -25,12 +25,13 @@ object JvmDeclarationCheckers : DeclarationCheckers() {
|
||||
|
||||
override val classCheckers: Set<FirClassChecker>
|
||||
get() = setOf(
|
||||
FirStrictfpApplicabilityChecker,
|
||||
FirStrictfpApplicabilityChecker
|
||||
)
|
||||
|
||||
override val regularClassCheckers: Set<FirRegularClassChecker>
|
||||
get() = setOf(
|
||||
FirJvmRecordChecker,
|
||||
FirJvmInlineApplicabilityChecker
|
||||
)
|
||||
|
||||
override val propertyCheckers: Set<FirPropertyChecker>
|
||||
|
||||
+34
@@ -0,0 +1,34 @@
|
||||
/*
|
||||
* Copyright 2010-2021 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.fir.analysis.jvm.checkers.declaration
|
||||
|
||||
import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext
|
||||
import org.jetbrains.kotlin.fir.analysis.checkers.declaration.FirRegularClassChecker
|
||||
import org.jetbrains.kotlin.fir.analysis.checkers.getModifier
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.DiagnosticReporter
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.jvm.FirJvmErrors
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.reportOn
|
||||
import org.jetbrains.kotlin.fir.declarations.FirRegularClass
|
||||
import org.jetbrains.kotlin.fir.declarations.getAnnotationByClassId
|
||||
import org.jetbrains.kotlin.fir.declarations.utils.isExpect
|
||||
import org.jetbrains.kotlin.fir.declarations.utils.isInline
|
||||
import org.jetbrains.kotlin.lexer.KtTokens
|
||||
import org.jetbrains.kotlin.resolve.JVM_INLINE_ANNOTATION_CLASS_ID
|
||||
|
||||
object FirJvmInlineApplicabilityChecker : FirRegularClassChecker() {
|
||||
override fun check(declaration: FirRegularClass, context: CheckerContext, reporter: DiagnosticReporter) {
|
||||
val annotation = declaration.getAnnotationByClassId(JVM_INLINE_ANNOTATION_CLASS_ID)
|
||||
if (annotation != null && !declaration.isInline) {
|
||||
reporter.reportOn(annotation.source, FirJvmErrors.JVM_INLINE_WITHOUT_VALUE_CLASS, context)
|
||||
} else if (annotation == null && declaration.isInline && !declaration.isExpect) {
|
||||
reporter.reportOn(
|
||||
declaration.getModifier(KtTokens.VALUE_KEYWORD)?.source,
|
||||
FirJvmErrors.VALUE_CLASS_WITHOUT_JVM_INLINE_ANNOTATION,
|
||||
context
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
+5
@@ -37,6 +37,7 @@ import org.jetbrains.kotlin.fir.analysis.diagnostics.jvm.FirJvmErrors.JVM_DEFAUL
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.jvm.FirJvmErrors.JVM_DEFAULT_NOT_IN_INTERFACE
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.jvm.FirJvmErrors.JVM_DEFAULT_REQUIRED_FOR_OVERRIDE
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.jvm.FirJvmErrors.JVM_DEFAULT_THROUGH_INHERITANCE
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.jvm.FirJvmErrors.JVM_INLINE_WITHOUT_VALUE_CLASS
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.jvm.FirJvmErrors.JVM_PACKAGE_NAME_CANNOT_BE_EMPTY
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.jvm.FirJvmErrors.JVM_PACKAGE_NAME_MUST_BE_VALID_NAME
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.jvm.FirJvmErrors.JVM_PACKAGE_NAME_NOT_SUPPORTED_IN_FILES_WITH_CLASSES
|
||||
@@ -79,6 +80,7 @@ import org.jetbrains.kotlin.fir.analysis.diagnostics.jvm.FirJvmErrors.SYNCHRONIZ
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.jvm.FirJvmErrors.SYNCHRONIZED_ON_INLINE
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.jvm.FirJvmErrors.UPPER_BOUND_CANNOT_BE_ARRAY
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.jvm.FirJvmErrors.USAGE_OF_JVM_DEFAULT_THROUGH_SUPER_CALL
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.jvm.FirJvmErrors.VALUE_CLASS_WITHOUT_JVM_INLINE_ANNOTATION
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.jvm.FirJvmErrors.VOLATILE_ON_DELEGATE
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.jvm.FirJvmErrors.VOLATILE_ON_VALUE
|
||||
|
||||
@@ -163,6 +165,9 @@ object FirJvmDefaultErrorMessages {
|
||||
|
||||
map.put(FUNCTION_DELEGATE_MEMBER_NAME_CLASH, "Spread operator is prohibited for arguments to signature-polymorphic calls")
|
||||
|
||||
map.put(VALUE_CLASS_WITHOUT_JVM_INLINE_ANNOTATION, "Value classes without @JvmInline annotation are not supported yet")
|
||||
map.put(JVM_INLINE_WITHOUT_VALUE_CLASS, "@JvmInline annotation is only applicable to value classes")
|
||||
|
||||
map.put(JVM_DEFAULT_NOT_IN_INTERFACE, "'@JvmDefault' is only supported on interface members")
|
||||
map.put(
|
||||
JVM_DEFAULT_IN_JVM6_TARGET,
|
||||
|
||||
-14
@@ -1,14 +0,0 @@
|
||||
// !SKIP_JAVAC
|
||||
// !LANGUAGE: +InlineClasses
|
||||
|
||||
package kotlin.jvm
|
||||
|
||||
annotation class JvmInline
|
||||
|
||||
@JvmInline
|
||||
value class Foo(val x: Int)
|
||||
|
||||
<!WRONG_MODIFIER_TARGET!>value<!> interface InlineInterface
|
||||
<!WRONG_MODIFIER_TARGET!>value<!> annotation class InlineAnn
|
||||
<!WRONG_MODIFIER_TARGET!>value<!> object InlineObject
|
||||
<!WRONG_MODIFIER_TARGET!>value<!> enum class InlineEnum
|
||||
+1
@@ -1,3 +1,4 @@
|
||||
// FIR_IDENTICAL
|
||||
// !SKIP_JAVAC
|
||||
// !LANGUAGE: +InlineClasses
|
||||
|
||||
|
||||
-17
@@ -1,17 +0,0 @@
|
||||
// !SKIP_JAVAC
|
||||
// !API_VERSION: 1.4
|
||||
// !LANGUAGE: -InlineClasses
|
||||
// !DIAGNOSTICS: -UNUSED_PARAMETER
|
||||
|
||||
package kotlin.jvm
|
||||
|
||||
annotation class JvmInline
|
||||
|
||||
value class Foo(val x: Int)
|
||||
|
||||
<!WRONG_MODIFIER_TARGET!>value<!> annotation class InlineAnn
|
||||
<!WRONG_MODIFIER_TARGET!>value<!> object InlineObject
|
||||
<!WRONG_MODIFIER_TARGET!>value<!> enum class InlineEnum
|
||||
|
||||
@JvmInline
|
||||
value class NotVal(<!INLINE_CLASS_CONSTRUCTOR_NOT_FINAL_READ_ONLY_PARAMETER!>x: Int<!>)
|
||||
+1
@@ -1,3 +1,4 @@
|
||||
// FIR_IDENTICAL
|
||||
// !SKIP_JAVAC
|
||||
// !API_VERSION: 1.4
|
||||
// !LANGUAGE: -InlineClasses
|
||||
|
||||
+4
-4
@@ -11,14 +11,14 @@ inline class IC(val a: Any)
|
||||
@JvmInline
|
||||
value class VC(val a: Any)
|
||||
|
||||
@JvmInline
|
||||
<!JVM_INLINE_WITHOUT_VALUE_CLASS!>@JvmInline<!>
|
||||
class C
|
||||
|
||||
@JvmInline
|
||||
<!JVM_INLINE_WITHOUT_VALUE_CLASS!>@JvmInline<!>
|
||||
interface I
|
||||
|
||||
@JvmInline
|
||||
<!JVM_INLINE_WITHOUT_VALUE_CLASS!>@JvmInline<!>
|
||||
object O
|
||||
|
||||
@JvmInline
|
||||
<!JVM_INLINE_WITHOUT_VALUE_CLASS!>@JvmInline<!>
|
||||
data class DC(val a: Any)
|
||||
|
||||
+4
-4
@@ -45,8 +45,8 @@ object B2 {
|
||||
|
||||
@JvmInline
|
||||
final value class D0(val x: Int)
|
||||
<!INLINE_CLASS_NOT_FINAL!>open<!> value class D1(val x: Int)
|
||||
<!INLINE_CLASS_NOT_FINAL!>abstract<!> value class D2(val x: Int)
|
||||
<!INLINE_CLASS_NOT_FINAL!>sealed<!> value class D3(val x: Int)
|
||||
<!INLINE_CLASS_NOT_FINAL!>open<!> <!VALUE_CLASS_WITHOUT_JVM_INLINE_ANNOTATION!>value<!> class D1(val x: Int)
|
||||
<!INLINE_CLASS_NOT_FINAL!>abstract<!> <!VALUE_CLASS_WITHOUT_JVM_INLINE_ANNOTATION!>value<!> class D2(val x: Int)
|
||||
<!INLINE_CLASS_NOT_FINAL!>sealed<!> <!VALUE_CLASS_WITHOUT_JVM_INLINE_ANNOTATION!>value<!> class D3(val x: Int)
|
||||
|
||||
<!INCOMPATIBLE_MODIFIERS!>value<!> <!INCOMPATIBLE_MODIFIERS!>data<!> class D4(val x: String)
|
||||
<!INCOMPATIBLE_MODIFIERS, VALUE_CLASS_WITHOUT_JVM_INLINE_ANNOTATION!>value<!> <!INCOMPATIBLE_MODIFIERS!>data<!> class D4(val x: String)
|
||||
|
||||
@@ -6,11 +6,13 @@
|
||||
package org.jetbrains.kotlin.resolve
|
||||
|
||||
import org.jetbrains.kotlin.descriptors.*
|
||||
import org.jetbrains.kotlin.name.ClassId
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
import org.jetbrains.kotlin.types.*
|
||||
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
|
||||
|
||||
val JVM_INLINE_ANNOTATION_FQ_NAME = FqName("kotlin.jvm.JvmInline")
|
||||
val JVM_INLINE_ANNOTATION_CLASS_ID = ClassId.topLevel(JVM_INLINE_ANNOTATION_FQ_NAME)
|
||||
|
||||
// FIXME: DeserializedClassDescriptor in reflection do not have @JvmInline annotation, that we
|
||||
// FIXME: would like to check as well.
|
||||
|
||||
+12
@@ -3632,6 +3632,18 @@ internal val KT_DIAGNOSTIC_CONVERTER = KtDiagnosticConverterBuilder.buildConvert
|
||||
token,
|
||||
)
|
||||
}
|
||||
add(FirJvmErrors.VALUE_CLASS_WITHOUT_JVM_INLINE_ANNOTATION) { firDiagnostic ->
|
||||
ValueClassWithoutJvmInlineAnnotationImpl(
|
||||
firDiagnostic as FirPsiDiagnostic,
|
||||
token,
|
||||
)
|
||||
}
|
||||
add(FirJvmErrors.JVM_INLINE_WITHOUT_VALUE_CLASS) { firDiagnostic ->
|
||||
JvmInlineWithoutValueClassImpl(
|
||||
firDiagnostic as FirPsiDiagnostic,
|
||||
token,
|
||||
)
|
||||
}
|
||||
add(FirJvmErrors.JAVA_TYPE_MISMATCH) { firDiagnostic ->
|
||||
JavaTypeMismatchImpl(
|
||||
firSymbolBuilder.typeBuilder.buildKtType(firDiagnostic.a),
|
||||
|
||||
+8
@@ -2529,6 +2529,14 @@ sealed class KtFirDiagnostic<PSI : PsiElement> : KtDiagnosticWithPsi<PSI> {
|
||||
override val diagnosticClass get() = FunctionDelegateMemberNameClash::class
|
||||
}
|
||||
|
||||
abstract class ValueClassWithoutJvmInlineAnnotation : KtFirDiagnostic<PsiElement>() {
|
||||
override val diagnosticClass get() = ValueClassWithoutJvmInlineAnnotation::class
|
||||
}
|
||||
|
||||
abstract class JvmInlineWithoutValueClass : KtFirDiagnostic<PsiElement>() {
|
||||
override val diagnosticClass get() = JvmInlineWithoutValueClass::class
|
||||
}
|
||||
|
||||
abstract class JavaTypeMismatch : KtFirDiagnostic<KtExpression>() {
|
||||
override val diagnosticClass get() = JavaTypeMismatch::class
|
||||
abstract val expectedType: KtType
|
||||
|
||||
+14
@@ -4102,6 +4102,20 @@ internal class FunctionDelegateMemberNameClashImpl(
|
||||
override val firDiagnostic: FirPsiDiagnostic by weakRef(firDiagnostic)
|
||||
}
|
||||
|
||||
internal class ValueClassWithoutJvmInlineAnnotationImpl(
|
||||
firDiagnostic: FirPsiDiagnostic,
|
||||
override val token: ValidityToken,
|
||||
) : KtFirDiagnostic.ValueClassWithoutJvmInlineAnnotation(), KtAbstractFirDiagnostic<PsiElement> {
|
||||
override val firDiagnostic: FirPsiDiagnostic by weakRef(firDiagnostic)
|
||||
}
|
||||
|
||||
internal class JvmInlineWithoutValueClassImpl(
|
||||
firDiagnostic: FirPsiDiagnostic,
|
||||
override val token: ValidityToken,
|
||||
) : KtFirDiagnostic.JvmInlineWithoutValueClass(), KtAbstractFirDiagnostic<PsiElement> {
|
||||
override val firDiagnostic: FirPsiDiagnostic by weakRef(firDiagnostic)
|
||||
}
|
||||
|
||||
internal class JavaTypeMismatchImpl(
|
||||
override val expectedType: KtType,
|
||||
override val actualType: KtType,
|
||||
|
||||
Reference in New Issue
Block a user