[FE] Prohibit actual typealias to certain compiler annotations
^KT-58554
This commit is contained in:
committed by
Space Team
parent
f4a648aa3e
commit
a79282cec1
+7
@@ -3464,6 +3464,13 @@ internal val KT_DIAGNOSTIC_CONVERTER = KtDiagnosticConverterBuilder.buildConvert
|
||||
token,
|
||||
)
|
||||
}
|
||||
add(FirErrors.ACTUAL_TYPEALIAS_TO_SPECIAL_ANNOTATION) { firDiagnostic ->
|
||||
ActualTypealiasToSpecialAnnotationImpl(
|
||||
firDiagnostic.a,
|
||||
firDiagnostic as KtPsiDiagnostic,
|
||||
token,
|
||||
)
|
||||
}
|
||||
add(FirErrors.INITIALIZER_REQUIRED_FOR_DESTRUCTURING_DECLARATION) { firDiagnostic ->
|
||||
InitializerRequiredForDestructuringDeclarationImpl(
|
||||
firDiagnostic as KtPsiDiagnostic,
|
||||
|
||||
+5
@@ -2420,6 +2420,11 @@ sealed interface KtFirDiagnostic<PSI : PsiElement> : KtDiagnosticWithPsi<PSI> {
|
||||
override val diagnosticClass get() = ExpectActualOptInAnnotation::class
|
||||
}
|
||||
|
||||
interface ActualTypealiasToSpecialAnnotation : KtFirDiagnostic<KtTypeAlias> {
|
||||
override val diagnosticClass get() = ActualTypealiasToSpecialAnnotation::class
|
||||
val typealiasedClassId: ClassId
|
||||
}
|
||||
|
||||
interface InitializerRequiredForDestructuringDeclaration : KtFirDiagnostic<KtDestructuringDeclaration> {
|
||||
override val diagnosticClass get() = InitializerRequiredForDestructuringDeclaration::class
|
||||
}
|
||||
|
||||
+6
@@ -2918,6 +2918,12 @@ internal class ExpectActualOptInAnnotationImpl(
|
||||
token: KtLifetimeToken,
|
||||
) : KtAbstractFirDiagnostic<KtNamedDeclaration>(firDiagnostic, token), KtFirDiagnostic.ExpectActualOptInAnnotation
|
||||
|
||||
internal class ActualTypealiasToSpecialAnnotationImpl(
|
||||
override val typealiasedClassId: ClassId,
|
||||
firDiagnostic: KtPsiDiagnostic,
|
||||
token: KtLifetimeToken,
|
||||
) : KtAbstractFirDiagnostic<KtTypeAlias>(firDiagnostic, token), KtFirDiagnostic.ActualTypealiasToSpecialAnnotation
|
||||
|
||||
internal class InitializerRequiredForDestructuringDeclarationImpl(
|
||||
firDiagnostic: KtPsiDiagnostic,
|
||||
token: KtLifetimeToken,
|
||||
|
||||
+6
@@ -20,6 +20,12 @@ import java.util.regex.Pattern;
|
||||
@TestMetadata("compiler/testData/diagnostics/tests/multiplatform")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
public class FirOldFrontendMPPDiagnosticsWithLightTreeTestGenerated extends AbstractFirLightTreeWithActualizerDiagnosticsTest {
|
||||
@Test
|
||||
@TestMetadata("actualTypealiasToSpecialAnnotation.kt")
|
||||
public void testActualTypealiasToSpecialAnnotation() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/multiplatform/actualTypealiasToSpecialAnnotation.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAllFilesPresentInMultiplatform() throws Exception {
|
||||
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/diagnostics/tests/multiplatform"), Pattern.compile("^(.*)\\.kts?$"), Pattern.compile("^(.+)\\.(reversed|fir|ll)\\.kts?$"), TargetBackend.JVM_IR, true);
|
||||
|
||||
+6
@@ -20,6 +20,12 @@ import java.util.regex.Pattern;
|
||||
@TestMetadata("compiler/testData/diagnostics/tests/multiplatform")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
public class FirOldFrontendMPPDiagnosticsWithPsiTestGenerated extends AbstractFirPsiWithActualizerDiagnosticsTest {
|
||||
@Test
|
||||
@TestMetadata("actualTypealiasToSpecialAnnotation.kt")
|
||||
public void testActualTypealiasToSpecialAnnotation() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/multiplatform/actualTypealiasToSpecialAnnotation.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAllFilesPresentInMultiplatform() throws Exception {
|
||||
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/diagnostics/tests/multiplatform"), Pattern.compile("^(.*)\\.kts?$"), Pattern.compile("^(.+)\\.(reversed|fir|ll)\\.kts?$"), TargetBackend.JVM_IR, true);
|
||||
|
||||
+5
@@ -21,6 +21,7 @@ import org.jetbrains.kotlin.fir.FirModuleData
|
||||
import org.jetbrains.kotlin.fir.PrivateForInline
|
||||
import org.jetbrains.kotlin.fir.checkers.generator.diagnostics.model.*
|
||||
import org.jetbrains.kotlin.fir.declarations.FirFunction
|
||||
import org.jetbrains.kotlin.fir.declarations.FirTypeAlias
|
||||
import org.jetbrains.kotlin.fir.expressions.FirExpression
|
||||
import org.jetbrains.kotlin.fir.symbols.FirBasedSymbol
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.*
|
||||
@@ -1176,6 +1177,10 @@ object DIAGNOSTICS_LIST : DiagnosticList("FirErrors") {
|
||||
val NOT_A_MULTIPLATFORM_COMPILATION by error<PsiElement>()
|
||||
|
||||
val EXPECT_ACTUAL_OPT_IN_ANNOTATION by error<KtNamedDeclaration>(PositioningStrategy.EXPECT_ACTUAL_MODIFIER)
|
||||
|
||||
val ACTUAL_TYPEALIAS_TO_SPECIAL_ANNOTATION by error<KtTypeAlias>(PositioningStrategy.TYPEALIAS_TYPE_REFERENCE) {
|
||||
parameter<ClassId>("typealiasedClassId")
|
||||
}
|
||||
}
|
||||
|
||||
val DESTRUCTING_DECLARATION by object : DiagnosticGroup("Destructuring declaration") {
|
||||
|
||||
+1
@@ -114,6 +114,7 @@ enum class PositioningStrategy(private val strategy: String? = null) {
|
||||
INLINE_FUN_MODIFIER,
|
||||
CALL_ELEMENT_WITH_DOT,
|
||||
EXPECT_ACTUAL_MODIFIER,
|
||||
TYPEALIAS_TYPE_REFERENCE,
|
||||
;
|
||||
|
||||
val expressionToCreate get() = "SourceElementPositioningStrategies.${strategy ?: name}"
|
||||
|
||||
@@ -627,6 +627,7 @@ object FirErrors {
|
||||
val ACTUAL_MISSING by error0<KtNamedDeclaration>(SourceElementPositioningStrategies.ACTUAL_DECLARATION_NAME)
|
||||
val NOT_A_MULTIPLATFORM_COMPILATION by error0<PsiElement>()
|
||||
val EXPECT_ACTUAL_OPT_IN_ANNOTATION by error0<KtNamedDeclaration>(SourceElementPositioningStrategies.EXPECT_ACTUAL_MODIFIER)
|
||||
val ACTUAL_TYPEALIAS_TO_SPECIAL_ANNOTATION by error1<KtTypeAlias, ClassId>(SourceElementPositioningStrategies.TYPEALIAS_TYPE_REFERENCE)
|
||||
|
||||
// Destructuring declaration
|
||||
val INITIALIZER_REQUIRED_FOR_DESTRUCTURING_DECLARATION by error0<KtDestructuringDeclaration>()
|
||||
|
||||
+1
@@ -159,6 +159,7 @@ object CommonDeclarationCheckers : DeclarationCheckers() {
|
||||
get() = setOf(
|
||||
FirTopLevelTypeAliasChecker,
|
||||
FirActualTypeAliasChecker,
|
||||
FirActualTypealiasToSpecialAnnotationChecker,
|
||||
)
|
||||
|
||||
override val anonymousFunctionCheckers: Set<FirAnonymousFunctionChecker>
|
||||
|
||||
+32
@@ -0,0 +1,32 @@
|
||||
/*
|
||||
* Copyright 2010-2023 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.checkers.declaration
|
||||
|
||||
import org.jetbrains.kotlin.descriptors.ClassKind
|
||||
import org.jetbrains.kotlin.diagnostics.DiagnosticReporter
|
||||
import org.jetbrains.kotlin.diagnostics.reportOn
|
||||
import org.jetbrains.kotlin.fir.analysis.checkers.classKind
|
||||
import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors
|
||||
import org.jetbrains.kotlin.fir.declarations.FirTypeAlias
|
||||
import org.jetbrains.kotlin.fir.declarations.utils.expandedConeType
|
||||
import org.jetbrains.kotlin.fir.declarations.utils.isActual
|
||||
import org.jetbrains.kotlin.fir.types.toSymbol
|
||||
import org.jetbrains.kotlin.resolve.calls.mpp.ActualTypealiasToSpecialAnnotationUtils.isAnnotationProhibitedInActualTypeAlias
|
||||
|
||||
internal object FirActualTypealiasToSpecialAnnotationChecker : FirTypeAliasChecker() {
|
||||
override fun check(declaration: FirTypeAlias, context: CheckerContext, reporter: DiagnosticReporter) {
|
||||
if (!declaration.isActual) return
|
||||
val typealiasedClassSymbol = declaration.expandedConeType?.toSymbol(context.session) ?: return
|
||||
if (typealiasedClassSymbol.classKind != ClassKind.ANNOTATION_CLASS) {
|
||||
return
|
||||
}
|
||||
val classId = typealiasedClassSymbol.classId
|
||||
if (isAnnotationProhibitedInActualTypeAlias(classId)) {
|
||||
reporter.reportOn(declaration.source, FirErrors.ACTUAL_TYPEALIAS_TO_SPECIAL_ANNOTATION, classId, context)
|
||||
}
|
||||
}
|
||||
}
|
||||
+6
@@ -54,6 +54,7 @@ import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.ACCESSOR_FOR_DELE
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.ACTUAL_ANNOTATION_CONFLICTING_DEFAULT_ARGUMENT_VALUE
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.ACTUAL_FUNCTION_WITH_DEFAULT_ARGUMENTS
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.ACTUAL_MISSING
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.ACTUAL_TYPEALIAS_TO_SPECIAL_ANNOTATION
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.ACTUAL_TYPE_ALIAS_NOT_TO_CLASS
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.ACTUAL_TYPE_ALIAS_TO_CLASS_WITH_DECLARATION_SITE_VARIANCE
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.ACTUAL_TYPE_ALIAS_WITH_COMPLEX_SUBSTITUTION
|
||||
@@ -1847,6 +1848,11 @@ object FirErrorsDefaultMessages : BaseDiagnosticRendererFactory() {
|
||||
map.put(ACTUAL_MISSING, "Declaration must be marked with 'actual'")
|
||||
map.put(NOT_A_MULTIPLATFORM_COMPILATION, "'expect' and 'actual' declarations can be used only in multiplatform projects. Learn more about Kotlin Multiplatform: https://kotl.in/multiplatform-setup")
|
||||
map.put(EXPECT_ACTUAL_OPT_IN_ANNOTATION, "Opt-in annotations are prohibited to be `expect` or `actual`. Instead, declare annotation once in common sources.")
|
||||
map.put(
|
||||
ACTUAL_TYPEALIAS_TO_SPECIAL_ANNOTATION,
|
||||
"`actual typealias` to annotation which affects code compilation can lead to incorrect behavior. Instead, use ''{0}'' annotation directly.",
|
||||
TO_STRING
|
||||
)
|
||||
|
||||
// Destructuring declaration
|
||||
map.put(INITIALIZER_REQUIRED_FOR_DESTRUCTURING_DECLARATION, "Initializer required for destructuring declaration")
|
||||
|
||||
+11
@@ -1208,6 +1208,17 @@ object LightTreePositioningStrategies {
|
||||
}
|
||||
}
|
||||
|
||||
val TYPEALIAS_TYPE_REFERENCE: LightTreePositioningStrategy = object : LightTreePositioningStrategy() {
|
||||
override fun mark(
|
||||
node: LighterASTNode,
|
||||
startOffset: Int,
|
||||
endOffset: Int,
|
||||
tree: FlyweightCapableTreeStructure<LighterASTNode>
|
||||
): List<TextRange> {
|
||||
val nodeToMark = tree.findChildByType(node, KtNodeTypes.TYPE_REFERENCE) ?: node
|
||||
return markElement(nodeToMark, startOffset, endOffset, tree, node)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun KtSourceElement.hasValOrVar(): Boolean =
|
||||
|
||||
+7
@@ -1031,6 +1031,13 @@ object PositioningStrategies {
|
||||
}
|
||||
}
|
||||
|
||||
@JvmField
|
||||
val TYPEALIAS_TYPE_REFERENCE = object : PositioningStrategy<KtTypeAlias>() {
|
||||
override fun mark(element: KtTypeAlias): List<TextRange> {
|
||||
return markElement(element.getTypeReference() ?: element)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param locateReferencedName whether to remove any nested parentheses while locating the reference element. This is useful for
|
||||
* diagnostics on super and unresolved references. For example, with the following, only the part inside the parentheses should be
|
||||
|
||||
+5
@@ -384,4 +384,9 @@ object SourceElementPositioningStrategies {
|
||||
LightTreePositioningStrategies.CALL_ELEMENT_WITH_DOT,
|
||||
PositioningStrategies.CALL_ELEMENT_WITH_DOT
|
||||
)
|
||||
|
||||
val TYPEALIAS_TYPE_REFERENCE = SourceElementPositioningStrategy(
|
||||
LightTreePositioningStrategies.TYPEALIAS_TYPE_REFERENCE,
|
||||
PositioningStrategies.TYPEALIAS_TYPE_REFERENCE,
|
||||
)
|
||||
}
|
||||
|
||||
@@ -21,6 +21,7 @@ import org.jetbrains.kotlin.lexer.KtKeywordToken;
|
||||
import org.jetbrains.kotlin.lexer.KtModifierKeywordToken;
|
||||
import org.jetbrains.kotlin.lexer.KtTokens;
|
||||
import org.jetbrains.kotlin.metadata.deserialization.VersionRequirement;
|
||||
import org.jetbrains.kotlin.name.ClassId;
|
||||
import org.jetbrains.kotlin.name.FqName;
|
||||
import org.jetbrains.kotlin.name.Name;
|
||||
import org.jetbrains.kotlin.psi.*;
|
||||
@@ -837,6 +838,8 @@ public interface Errors {
|
||||
DiagnosticFactory0<PsiElement> OPTIONAL_DECLARATION_USAGE_IN_NON_COMMON_SOURCE = DiagnosticFactory0.create(ERROR);
|
||||
DiagnosticFactory0<PsiElement> NOT_A_MULTIPLATFORM_COMPILATION = DiagnosticFactory0.create(ERROR);
|
||||
DiagnosticFactory0<KtNamedDeclaration> EXPECT_ACTUAL_OPT_IN_ANNOTATION = DiagnosticFactory0.create(ERROR, EXPECT_ACTUAL_MODIFIER);
|
||||
DiagnosticFactory1<KtTypeAlias, ClassId> ACTUAL_TYPEALIAS_TO_SPECIAL_ANNOTATION =
|
||||
DiagnosticFactory1.create(ERROR, TYPEALIAS_TYPE_REFERENCE);
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
+3
@@ -393,6 +393,9 @@ public class DefaultErrorMessages {
|
||||
MAP.put(OPTIONAL_DECLARATION_USAGE_IN_NON_COMMON_SOURCE, "Declaration annotated with '@OptionalExpectation' can only be used in common module sources");
|
||||
MAP.put(NOT_A_MULTIPLATFORM_COMPILATION, "'expect' and 'actual' declarations can be used only in multiplatform projects. Learn more about Kotlin Multiplatform: https://kotl.in/multiplatform-setup");
|
||||
MAP.put(EXPECT_ACTUAL_OPT_IN_ANNOTATION, "Opt-in annotations are prohibited to be `expect` or `actual`. Instead, declare annotation once in common sources.");
|
||||
MAP.put(ACTUAL_TYPEALIAS_TO_SPECIAL_ANNOTATION,
|
||||
"`actual typealias` to annotation which affects code compilation can lead to incorrect behavior. Instead, use ''{0}'' annotation directly.",
|
||||
TO_STRING);
|
||||
|
||||
MAP.put(PROJECTION_ON_NON_CLASS_TYPE_ARGUMENT, "Projections are not allowed on type arguments of functions and properties");
|
||||
MAP.put(SUPERTYPE_NOT_INITIALIZED, "This type has a constructor, and thus must be initialized here");
|
||||
|
||||
@@ -58,6 +58,7 @@ private val DEFAULT_DECLARATION_CHECKERS = listOf(
|
||||
DataObjectContentChecker,
|
||||
EnumEntriesRedeclarationChecker,
|
||||
VolatileAnnotationChecker,
|
||||
ActualTypealiasToSpecialAnnotationChecker,
|
||||
)
|
||||
|
||||
private val DEFAULT_CALL_CHECKERS = listOf(
|
||||
|
||||
+31
@@ -0,0 +1,31 @@
|
||||
/*
|
||||
* Copyright 2010-2023 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.resolve.checkers
|
||||
|
||||
import org.jetbrains.kotlin.descriptors.ClassKind
|
||||
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.TypeAliasDescriptor
|
||||
import org.jetbrains.kotlin.diagnostics.Errors
|
||||
import org.jetbrains.kotlin.psi.KtDeclaration
|
||||
import org.jetbrains.kotlin.psi.KtTypeAlias
|
||||
import org.jetbrains.kotlin.resolve.calls.mpp.ActualTypealiasToSpecialAnnotationUtils.isAnnotationProhibitedInActualTypeAlias
|
||||
import org.jetbrains.kotlin.resolve.descriptorUtil.classId
|
||||
|
||||
internal object ActualTypealiasToSpecialAnnotationChecker : DeclarationChecker {
|
||||
override fun check(declaration: KtDeclaration, descriptor: DeclarationDescriptor, context: DeclarationCheckerContext) {
|
||||
if (declaration !is KtTypeAlias || descriptor !is TypeAliasDescriptor || !descriptor.isActual) {
|
||||
return
|
||||
}
|
||||
val classDescriptor = descriptor.classDescriptor ?: return
|
||||
if (classDescriptor.kind != ClassKind.ANNOTATION_CLASS) {
|
||||
return
|
||||
}
|
||||
val classId = classDescriptor.classId ?: return
|
||||
if (isAnnotationProhibitedInActualTypeAlias(classId)) {
|
||||
context.trace.report(Errors.ACTUAL_TYPEALIAS_TO_SPECIAL_ANNOTATION.on(declaration, classId))
|
||||
}
|
||||
}
|
||||
}
|
||||
+27
@@ -0,0 +1,27 @@
|
||||
/*
|
||||
* Copyright 2010-2023 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.resolve.calls.mpp
|
||||
|
||||
import org.jetbrains.kotlin.builtins.StandardNames
|
||||
import org.jetbrains.kotlin.name.ClassId
|
||||
|
||||
object ActualTypealiasToSpecialAnnotationUtils {
|
||||
/**
|
||||
* Type aliases may be useful to commonize some platform-specific annotations, e.g. [kotlin.jvm.Synchronized].
|
||||
* We cannot universally determine at compile time whether annotation is accessible in common code.
|
||||
* Instead, we prohibit certain package names because we are sure that annotations from them
|
||||
* are visible in common and there is no point to typealias them.
|
||||
*/
|
||||
private val FORBIDDEN_PACKAGES = setOf(
|
||||
StandardNames.ANNOTATION_PACKAGE_FQ_NAME,
|
||||
StandardNames.BUILT_INS_PACKAGE_FQ_NAME,
|
||||
StandardNames.KOTLIN_INTERNAL_FQ_NAME,
|
||||
)
|
||||
|
||||
fun isAnnotationProhibitedInActualTypeAlias(classId: ClassId): Boolean {
|
||||
return classId.packageFqName in FORBIDDEN_PACKAGES
|
||||
}
|
||||
}
|
||||
+28
@@ -0,0 +1,28 @@
|
||||
// FIR_IDENTICAL
|
||||
// WITH_STDLIB
|
||||
// MODULE: m1-common
|
||||
// FILE: common.kt
|
||||
expect annotation class TypealiasToKotlinPkg
|
||||
|
||||
internal expect annotation class TypealiasToInternalPkg
|
||||
|
||||
expect annotation class TypealiasToAnnotationPkg
|
||||
|
||||
expect annotation class TypealiasToPlatformPkg
|
||||
|
||||
expect enum class TypealiasNotToAnnotation
|
||||
|
||||
// MODULE: m1-jvm()()(m1-common)
|
||||
// FILE: jvm.kt
|
||||
actual typealias TypealiasToKotlinPkg = <!ACTUAL_TYPEALIAS_TO_SPECIAL_ANNOTATION!>kotlin.Deprecated<!>
|
||||
|
||||
@Suppress("INVISIBLE_REFERENCE")
|
||||
internal actual typealias TypealiasToInternalPkg = <!ACTUAL_TYPEALIAS_TO_SPECIAL_ANNOTATION!>kotlin.internal.RequireKotlin<!>
|
||||
|
||||
actual typealias TypealiasToAnnotationPkg = <!ACTUAL_TYPEALIAS_TO_SPECIAL_ANNOTATION!>kotlin.annotation.Target<!>
|
||||
|
||||
actual typealias TypealiasToPlatformPkg = kotlin.jvm.Synchronized
|
||||
|
||||
typealias NonActualTypealias = kotlin.Deprecated
|
||||
|
||||
actual typealias TypealiasNotToAnnotation = kotlin.DeprecationLevel
|
||||
Generated
+6
@@ -22529,6 +22529,12 @@ public class DiagnosticTestGenerated extends AbstractDiagnosticTest {
|
||||
@TestMetadata("compiler/testData/diagnostics/tests/multiplatform")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
public class Multiplatform {
|
||||
@Test
|
||||
@TestMetadata("actualTypealiasToSpecialAnnotation.kt")
|
||||
public void testActualTypealiasToSpecialAnnotation() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/multiplatform/actualTypealiasToSpecialAnnotation.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAllFilesPresentInMultiplatform() throws Exception {
|
||||
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/diagnostics/tests/multiplatform"), Pattern.compile("^(.*)\\.kts?$"), Pattern.compile("^(.+)\\.(reversed|fir|ll)\\.kts?$"), true);
|
||||
|
||||
Reference in New Issue
Block a user