[FIR] Forbid multiple labels per statement
^KT-53629: Fixed
This commit is contained in:
committed by
Space Team
parent
cd5b38b958
commit
d27adf6677
+6
@@ -4957,6 +4957,12 @@ internal val KT_DIAGNOSTIC_CONVERTER = KtDiagnosticConverterBuilder.buildConvert
|
|||||||
token,
|
token,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
add(FirErrors.MULTIPLE_LABELS_ARE_FORBIDDEN) { firDiagnostic ->
|
||||||
|
MultipleLabelsAreForbiddenImpl(
|
||||||
|
firDiagnostic as KtPsiDiagnostic,
|
||||||
|
token,
|
||||||
|
)
|
||||||
|
}
|
||||||
add(FirErrors.DEPRECATED_ACCESS_TO_ENUM_ENTRY_COMPANION_PROPERTY) { firDiagnostic ->
|
add(FirErrors.DEPRECATED_ACCESS_TO_ENUM_ENTRY_COMPANION_PROPERTY) { firDiagnostic ->
|
||||||
DeprecatedAccessToEnumEntryCompanionPropertyImpl(
|
DeprecatedAccessToEnumEntryCompanionPropertyImpl(
|
||||||
firDiagnostic as KtPsiDiagnostic,
|
firDiagnostic as KtPsiDiagnostic,
|
||||||
|
|||||||
+4
@@ -3450,6 +3450,10 @@ sealed interface KtFirDiagnostic<PSI : PsiElement> : KtDiagnosticWithPsi<PSI> {
|
|||||||
override val diagnosticClass get() = RedundantLabelWarning::class
|
override val diagnosticClass get() = RedundantLabelWarning::class
|
||||||
}
|
}
|
||||||
|
|
||||||
|
interface MultipleLabelsAreForbidden : KtFirDiagnostic<KtLabelReferenceExpression> {
|
||||||
|
override val diagnosticClass get() = MultipleLabelsAreForbidden::class
|
||||||
|
}
|
||||||
|
|
||||||
interface DeprecatedAccessToEnumEntryCompanionProperty : KtFirDiagnostic<PsiElement> {
|
interface DeprecatedAccessToEnumEntryCompanionProperty : KtFirDiagnostic<PsiElement> {
|
||||||
override val diagnosticClass get() = DeprecatedAccessToEnumEntryCompanionProperty::class
|
override val diagnosticClass get() = DeprecatedAccessToEnumEntryCompanionProperty::class
|
||||||
}
|
}
|
||||||
|
|||||||
+5
@@ -4161,6 +4161,11 @@ internal class RedundantLabelWarningImpl(
|
|||||||
token: KtLifetimeToken,
|
token: KtLifetimeToken,
|
||||||
) : KtAbstractFirDiagnostic<KtLabelReferenceExpression>(firDiagnostic, token), KtFirDiagnostic.RedundantLabelWarning
|
) : KtAbstractFirDiagnostic<KtLabelReferenceExpression>(firDiagnostic, token), KtFirDiagnostic.RedundantLabelWarning
|
||||||
|
|
||||||
|
internal class MultipleLabelsAreForbiddenImpl(
|
||||||
|
firDiagnostic: KtPsiDiagnostic,
|
||||||
|
token: KtLifetimeToken,
|
||||||
|
) : KtAbstractFirDiagnostic<KtLabelReferenceExpression>(firDiagnostic, token), KtFirDiagnostic.MultipleLabelsAreForbidden
|
||||||
|
|
||||||
internal class DeprecatedAccessToEnumEntryCompanionPropertyImpl(
|
internal class DeprecatedAccessToEnumEntryCompanionPropertyImpl(
|
||||||
firDiagnostic: KtPsiDiagnostic,
|
firDiagnostic: KtPsiDiagnostic,
|
||||||
token: KtLifetimeToken,
|
token: KtLifetimeToken,
|
||||||
|
|||||||
+6
@@ -23901,6 +23901,12 @@ public class DiagnosticCompilerTestFE10TestdataTestGenerated extends AbstractDia
|
|||||||
public void testLabelsMustBeNamed() throws Exception {
|
public void testLabelsMustBeNamed() throws Exception {
|
||||||
runTest("compiler/testData/diagnostics/tests/labels/labelsMustBeNamed.kt");
|
runTest("compiler/testData/diagnostics/tests/labels/labelsMustBeNamed.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("multipleLabels.kt")
|
||||||
|
public void testMultipleLabels() throws Exception {
|
||||||
|
runTest("compiler/testData/diagnostics/tests/labels/multipleLabels.kt");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nested
|
@Nested
|
||||||
|
|||||||
+6
@@ -23901,6 +23901,12 @@ public class LLFirPreresolvedReversedDiagnosticCompilerFE10TestDataTestGenerated
|
|||||||
public void testLabelsMustBeNamed() throws Exception {
|
public void testLabelsMustBeNamed() throws Exception {
|
||||||
runTest("compiler/testData/diagnostics/tests/labels/labelsMustBeNamed.kt");
|
runTest("compiler/testData/diagnostics/tests/labels/labelsMustBeNamed.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("multipleLabels.kt")
|
||||||
|
public void testMultipleLabels() throws Exception {
|
||||||
|
runTest("compiler/testData/diagnostics/tests/labels/multipleLabels.kt");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nested
|
@Nested
|
||||||
|
|||||||
+6
@@ -23895,6 +23895,12 @@ public class FirLightTreeOldFrontendDiagnosticsTestGenerated extends AbstractFir
|
|||||||
public void testLabelsMustBeNamed() throws Exception {
|
public void testLabelsMustBeNamed() throws Exception {
|
||||||
runTest("compiler/testData/diagnostics/tests/labels/labelsMustBeNamed.kt");
|
runTest("compiler/testData/diagnostics/tests/labels/labelsMustBeNamed.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("multipleLabels.kt")
|
||||||
|
public void testMultipleLabels() throws Exception {
|
||||||
|
runTest("compiler/testData/diagnostics/tests/labels/multipleLabels.kt");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nested
|
@Nested
|
||||||
|
|||||||
+6
@@ -23901,6 +23901,12 @@ public class FirPsiOldFrontendDiagnosticsTestGenerated extends AbstractFirPsiDia
|
|||||||
public void testLabelsMustBeNamed() throws Exception {
|
public void testLabelsMustBeNamed() throws Exception {
|
||||||
runTest("compiler/testData/diagnostics/tests/labels/labelsMustBeNamed.kt");
|
runTest("compiler/testData/diagnostics/tests/labels/labelsMustBeNamed.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("multipleLabels.kt")
|
||||||
|
public void testMultipleLabels() throws Exception {
|
||||||
|
runTest("compiler/testData/diagnostics/tests/labels/multipleLabels.kt");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nested
|
@Nested
|
||||||
|
|||||||
+1
@@ -1751,6 +1751,7 @@ object DIAGNOSTICS_LIST : DiagnosticList("FirErrors") {
|
|||||||
|
|
||||||
val LABEL by object : DiagnosticGroup("label") {
|
val LABEL by object : DiagnosticGroup("label") {
|
||||||
val REDUNDANT_LABEL_WARNING by warning<KtLabelReferenceExpression>(PositioningStrategy.LABEL)
|
val REDUNDANT_LABEL_WARNING by warning<KtLabelReferenceExpression>(PositioningStrategy.LABEL)
|
||||||
|
val MULTIPLE_LABELS_ARE_FORBIDDEN by error<KtLabelReferenceExpression>(PositioningStrategy.LABEL)
|
||||||
}
|
}
|
||||||
|
|
||||||
val ENUM_ENTRIES_DEPRECATIONS by object : DiagnosticGroup("Enum.entries resolve deprecations") {
|
val ENUM_ENTRIES_DEPRECATIONS by object : DiagnosticGroup("Enum.entries resolve deprecations") {
|
||||||
|
|||||||
@@ -872,6 +872,7 @@ object FirErrors {
|
|||||||
|
|
||||||
// label
|
// label
|
||||||
val REDUNDANT_LABEL_WARNING: KtDiagnosticFactory0 by warning0<KtLabelReferenceExpression>(SourceElementPositioningStrategies.LABEL)
|
val REDUNDANT_LABEL_WARNING: KtDiagnosticFactory0 by warning0<KtLabelReferenceExpression>(SourceElementPositioningStrategies.LABEL)
|
||||||
|
val MULTIPLE_LABELS_ARE_FORBIDDEN: KtDiagnosticFactory0 by error0<KtLabelReferenceExpression>(SourceElementPositioningStrategies.LABEL)
|
||||||
|
|
||||||
// Enum.entries resolve deprecations
|
// Enum.entries resolve deprecations
|
||||||
val DEPRECATED_ACCESS_TO_ENUM_ENTRY_COMPANION_PROPERTY: KtDiagnosticFactory0 by warning0<PsiElement>()
|
val DEPRECATED_ACCESS_TO_ENUM_ENTRY_COMPANION_PROPERTY: KtDiagnosticFactory0 by warning0<PsiElement>()
|
||||||
|
|||||||
+1
@@ -572,6 +572,7 @@ val FIR_NON_SUPPRESSIBLE_ERROR_NAMES: Set<String> = setOf(
|
|||||||
"RETURN_FOR_BUILT_IN_SUSPEND",
|
"RETURN_FOR_BUILT_IN_SUSPEND",
|
||||||
"MIXING_SUSPEND_AND_NON_SUSPEND_SUPERTYPES",
|
"MIXING_SUSPEND_AND_NON_SUSPEND_SUPERTYPES",
|
||||||
"MIXING_FUNCTIONAL_KINDS_IN_SUPERTYPES",
|
"MIXING_FUNCTIONAL_KINDS_IN_SUPERTYPES",
|
||||||
|
"MULTIPLE_LABELS_ARE_FORBIDDEN",
|
||||||
"INCOMPATIBLE_CLASS",
|
"INCOMPATIBLE_CLASS",
|
||||||
"PRE_RELEASE_CLASS",
|
"PRE_RELEASE_CLASS",
|
||||||
"IR_WITH_UNSTABLE_ABI_COMPILED_CLASS",
|
"IR_WITH_UNSTABLE_ABI_COMPILED_CLASS",
|
||||||
|
|||||||
+3
@@ -501,6 +501,7 @@ import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.PACKAGE_CANNOT_BE
|
|||||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.PACKAGE_OR_CLASSIFIER_REDECLARATION
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.PACKAGE_OR_CLASSIFIER_REDECLARATION
|
||||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.PLATFORM_CLASS_MAPPED_TO_KOTLIN
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.PLATFORM_CLASS_MAPPED_TO_KOTLIN
|
||||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.COMPILER_REQUIRED_ANNOTATION_AMBIGUITY
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.COMPILER_REQUIRED_ANNOTATION_AMBIGUITY
|
||||||
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.MULTIPLE_LABELS_ARE_FORBIDDEN
|
||||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.EXPECT_AND_ACTUAL_IN_THE_SAME_MODULE
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.EXPECT_AND_ACTUAL_IN_THE_SAME_MODULE
|
||||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.POTENTIALLY_NON_REPORTED_ANNOTATION
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.POTENTIALLY_NON_REPORTED_ANNOTATION
|
||||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.PRE_RELEASE_CLASS
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.PRE_RELEASE_CLASS
|
||||||
@@ -2538,6 +2539,8 @@ object FirErrorsDefaultMessages : BaseDiagnosticRendererFactory() {
|
|||||||
"Label is redundant, because it cannot be referenced in a 'break', 'continue', or 'return' expression."
|
"Label is redundant, because it cannot be referenced in a 'break', 'continue', or 'return' expression."
|
||||||
)
|
)
|
||||||
|
|
||||||
|
map.put(MULTIPLE_LABELS_ARE_FORBIDDEN, "Multiple labels per statement are forbidden.")
|
||||||
|
|
||||||
// Enum entries deprecations
|
// Enum entries deprecations
|
||||||
map.put(
|
map.put(
|
||||||
DEPRECATED_ACCESS_TO_ENUM_ENTRY_COMPANION_PROPERTY,
|
DEPRECATED_ACCESS_TO_ENUM_ENTRY_COMPANION_PROPERTY,
|
||||||
|
|||||||
+1
@@ -194,6 +194,7 @@ private fun ConeDiagnostic.toKtDiagnostic(
|
|||||||
is ConeAmbiguousFunctionTypeKinds -> FirErrors.AMBIGUOUS_FUNCTION_TYPE_KIND.createOn(source, kinds)
|
is ConeAmbiguousFunctionTypeKinds -> FirErrors.AMBIGUOUS_FUNCTION_TYPE_KIND.createOn(source, kinds)
|
||||||
is ConeUnsupportedClassLiteralsWithEmptyLhs -> FirErrors.UNSUPPORTED_CLASS_LITERALS_WITH_EMPTY_LHS.createOn(source)
|
is ConeUnsupportedClassLiteralsWithEmptyLhs -> FirErrors.UNSUPPORTED_CLASS_LITERALS_WITH_EMPTY_LHS.createOn(source)
|
||||||
is ConeMissingConstructorKeyword -> FirErrors.MISSING_CONSTRUCTOR_KEYWORD.createOn(source)
|
is ConeMissingConstructorKeyword -> FirErrors.MISSING_CONSTRUCTOR_KEYWORD.createOn(source)
|
||||||
|
is ConeMultipleLabelsAreForbidden -> FirErrors.MULTIPLE_LABELS_ARE_FORBIDDEN.createOn(this.source)
|
||||||
else -> throw IllegalArgumentException("Unsupported diagnostic type: ${this.javaClass}")
|
else -> throw IllegalArgumentException("Unsupported diagnostic type: ${this.javaClass}")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+9
-9
@@ -397,19 +397,19 @@ class LightTreeRawFirExpressionBuilder(
|
|||||||
*/
|
*/
|
||||||
private fun convertLabeledExpression(labeledExpression: LighterASTNode): FirElement {
|
private fun convertLabeledExpression(labeledExpression: LighterASTNode): FirElement {
|
||||||
var firExpression: FirElement? = null
|
var firExpression: FirElement? = null
|
||||||
var errorLabelSource: KtSourceElement? = null
|
var labelSource: KtSourceElement? = null
|
||||||
|
var forbiddenLabelKind: ForbiddenLabelKind? = null
|
||||||
|
|
||||||
|
val isRepetitiveLabel = labeledExpression.getLabeledExpression()?.tokenType == LABELED_EXPRESSION
|
||||||
|
|
||||||
labeledExpression.forEachChildren {
|
labeledExpression.forEachChildren {
|
||||||
context.setNewLabelUserNode(it)
|
context.setNewLabelUserNode(it)
|
||||||
when (it.tokenType) {
|
when (it.tokenType) {
|
||||||
LABEL_QUALIFIER -> {
|
LABEL_QUALIFIER -> {
|
||||||
val rawName = it.toString()
|
val name = it.asText.dropLast(1)
|
||||||
val pair = buildLabelAndErrorSource(
|
labelSource = it.getChildNodesByType(LABEL).single().toFirSourceElement()
|
||||||
rawName.substring(0, rawName.length - 1),
|
context.addNewLabel(buildLabel(name, labelSource!!))
|
||||||
it.getChildNodesByType(LABEL).single().toFirSourceElement()
|
forbiddenLabelKind = getForbiddenLabelKind(name, isRepetitiveLabel)
|
||||||
)
|
|
||||||
context.addNewLabel(pair.first)
|
|
||||||
errorLabelSource = pair.second
|
|
||||||
}
|
}
|
||||||
BLOCK -> firExpression = declarationBuilder.convertBlock(it)
|
BLOCK -> firExpression = declarationBuilder.convertBlock(it)
|
||||||
PROPERTY -> firExpression = declarationBuilder.convertPropertyDeclaration(it)
|
PROPERTY -> firExpression = declarationBuilder.convertPropertyDeclaration(it)
|
||||||
@@ -419,7 +419,7 @@ class LightTreeRawFirExpressionBuilder(
|
|||||||
|
|
||||||
context.dropLastLabel()
|
context.dropLastLabel()
|
||||||
|
|
||||||
return buildExpressionWithErrorLabel(firExpression, errorLabelSource, labeledExpression.toFirSourceElement())
|
return buildExpressionHandlingErrors(firExpression, labeledExpression.toFirSourceElement(), forbiddenLabelKind, labelSource)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
+14
-7
@@ -51,7 +51,10 @@ import org.jetbrains.kotlin.types.ConstantValueKind
|
|||||||
import org.jetbrains.kotlin.types.Variance
|
import org.jetbrains.kotlin.types.Variance
|
||||||
import org.jetbrains.kotlin.types.expressions.OperatorConventions
|
import org.jetbrains.kotlin.types.expressions.OperatorConventions
|
||||||
import org.jetbrains.kotlin.util.OperatorNameConventions
|
import org.jetbrains.kotlin.util.OperatorNameConventions
|
||||||
import org.jetbrains.kotlin.utils.addToStdlib.*
|
import org.jetbrains.kotlin.utils.addToStdlib.firstIsInstanceOrNull
|
||||||
|
import org.jetbrains.kotlin.utils.addToStdlib.runIf
|
||||||
|
import org.jetbrains.kotlin.utils.addToStdlib.runUnless
|
||||||
|
import org.jetbrains.kotlin.utils.addToStdlib.shouldNotBeCalled
|
||||||
import org.jetbrains.kotlin.utils.exceptions.errorWithAttachment
|
import org.jetbrains.kotlin.utils.exceptions.errorWithAttachment
|
||||||
import org.jetbrains.kotlin.utils.exceptions.requireWithAttachment
|
import org.jetbrains.kotlin.utils.exceptions.requireWithAttachment
|
||||||
import org.jetbrains.kotlin.utils.exceptions.withPsiEntry
|
import org.jetbrains.kotlin.utils.exceptions.withPsiEntry
|
||||||
@@ -3135,20 +3138,24 @@ open class PsiRawFirBuilder(
|
|||||||
|
|
||||||
override fun visitLabeledExpression(expression: KtLabeledExpression, data: FirElement?): FirElement {
|
override fun visitLabeledExpression(expression: KtLabeledExpression, data: FirElement?): FirElement {
|
||||||
val label = expression.getTargetLabel()
|
val label = expression.getTargetLabel()
|
||||||
var errorLabelSource: KtSourceElement? = null
|
var labelSource: KtSourceElement? = null
|
||||||
|
var forbiddenLabelKind: ForbiddenLabelKind? = null
|
||||||
|
|
||||||
|
val isRepetitiveLabel = expression.baseExpression is KtLabeledExpression
|
||||||
|
|
||||||
val result = if (label != null) {
|
val result = if (label != null) {
|
||||||
val rawName = label.getReferencedNameElement().node!!.text
|
val name = label.getReferencedNameElement().node!!.text
|
||||||
val labelAndErrorSource = buildLabelAndErrorSource(rawName, label.toKtPsiSourceElement())
|
forbiddenLabelKind = getForbiddenLabelKind(name, isRepetitiveLabel)
|
||||||
errorLabelSource = labelAndErrorSource.second
|
labelSource = label.toKtPsiSourceElement()
|
||||||
context.withNewLabel(labelAndErrorSource.first, expression.baseExpression) {
|
val firLabel = buildLabel(name, labelSource)
|
||||||
|
context.withNewLabel(firLabel, expression.baseExpression) {
|
||||||
expression.baseExpression?.accept(this, data)
|
expression.baseExpression?.accept(this, data)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
expression.baseExpression?.accept(this, data)
|
expression.baseExpression?.accept(this, data)
|
||||||
}
|
}
|
||||||
|
|
||||||
return buildExpressionWithErrorLabel(result, errorLabelSource, expression.toFirSourceElement())
|
return buildExpressionHandlingErrors(result, expression.toFirSourceElement(), forbiddenLabelKind, labelSource)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun visitAnnotatedExpression(expression: KtAnnotatedExpression, data: FirElement?): FirElement {
|
override fun visitAnnotatedExpression(expression: KtAnnotatedExpression, data: FirElement?): FirElement {
|
||||||
|
|||||||
+21
-6
@@ -1044,26 +1044,41 @@ abstract class AbstractRawFirBuilder<T>(val baseSession: FirSession, val context
|
|||||||
initContainingClassAttr(context)
|
initContainingClassAttr(context)
|
||||||
}
|
}
|
||||||
|
|
||||||
protected fun buildLabelAndErrorSource(rawName: String, source: KtSourceElement): Pair<FirLabel, KtSourceElement?> {
|
protected fun buildLabel(rawName: String, source: KtSourceElement): FirLabel {
|
||||||
val firLabel = buildLabel {
|
val firLabel = buildLabel {
|
||||||
name = KtPsiUtil.unquoteIdentifier(rawName)
|
name = KtPsiUtil.unquoteIdentifier(rawName)
|
||||||
this.source = source
|
this.source = source
|
||||||
}
|
}
|
||||||
|
|
||||||
return Pair(firLabel, if (rawName.isUnderscore) firLabel.source else null)
|
return firLabel
|
||||||
}
|
}
|
||||||
|
|
||||||
protected fun buildExpressionWithErrorLabel(
|
protected fun getForbiddenLabelKind(rawName: String, isMultipleLabel: Boolean): ForbiddenLabelKind? = when {
|
||||||
|
rawName.isUnderscore -> ForbiddenLabelKind.UNDERSCORE_IS_RESERVED
|
||||||
|
isMultipleLabel -> ForbiddenLabelKind.MULTIPLE_LABEL
|
||||||
|
else -> null
|
||||||
|
}
|
||||||
|
|
||||||
|
protected enum class ForbiddenLabelKind {
|
||||||
|
UNDERSCORE_IS_RESERVED, MULTIPLE_LABEL
|
||||||
|
}
|
||||||
|
|
||||||
|
protected fun buildExpressionHandlingErrors(
|
||||||
element: FirElement?,
|
element: FirElement?,
|
||||||
errorLabelSource: KtSourceElement?,
|
|
||||||
elementSource: KtSourceElement,
|
elementSource: KtSourceElement,
|
||||||
|
forbiddenLabelKind: ForbiddenLabelKind?,
|
||||||
|
forbiddenLabelSource: KtSourceElement?,
|
||||||
): FirElement {
|
): FirElement {
|
||||||
return if (element != null) {
|
return if (element != null) {
|
||||||
if (errorLabelSource != null) {
|
if (forbiddenLabelKind != null) {
|
||||||
|
require(forbiddenLabelSource != null)
|
||||||
buildErrorExpression {
|
buildErrorExpression {
|
||||||
this.source = element.source
|
this.source = element.source
|
||||||
this.expression = element as? FirExpression
|
this.expression = element as? FirExpression
|
||||||
diagnostic = ConeUnderscoreIsReserved(errorLabelSource)
|
diagnostic = when (forbiddenLabelKind) {
|
||||||
|
ForbiddenLabelKind.UNDERSCORE_IS_RESERVED -> ConeUnderscoreIsReserved(forbiddenLabelSource)
|
||||||
|
ForbiddenLabelKind.MULTIPLE_LABEL -> ConeMultipleLabelsAreForbidden(forbiddenLabelSource)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
element
|
element
|
||||||
|
|||||||
@@ -27,6 +27,10 @@ class ConeUnderscoreIsReserved(source: KtSourceElement) : ConeDiagnosticWithSour
|
|||||||
override val reason: String get() = "Names _, __, ___, ..., are reserved in Kotlin"
|
override val reason: String get() = "Names _, __, ___, ..., are reserved in Kotlin"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class ConeMultipleLabelsAreForbidden(source: KtSourceElement) : ConeDiagnosticWithSource(source) {
|
||||||
|
override val reason: String get() = "Multiple labels per statement are forbidden"
|
||||||
|
}
|
||||||
|
|
||||||
class ConeCannotInferTypeParameterType(
|
class ConeCannotInferTypeParameterType(
|
||||||
val typeParameter: FirTypeParameterSymbol,
|
val typeParameter: FirTypeParameterSymbol,
|
||||||
override val reason: String = "Cannot infer type for parameter ${typeParameter.name}"
|
override val reason: String = "Cannot infer type for parameter ${typeParameter.name}"
|
||||||
|
|||||||
@@ -102,7 +102,7 @@ fun <T : FirStatement> FirBlock.replaceFirstStatement(factory: (T) -> FirStateme
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun FirExpression.unwrapErrorExpression(): FirExpression? =
|
fun FirExpression.unwrapErrorExpression(): FirExpression? =
|
||||||
if (this is FirErrorExpression) expression?.run { unwrapErrorExpression() } else this
|
if (this is FirErrorExpression) expression?.unwrapErrorExpression() else this
|
||||||
|
|
||||||
fun FirExpression.unwrapArgument(): FirExpression = (this as? FirWrappedArgumentExpression)?.expression ?: this
|
fun FirExpression.unwrapArgument(): FirExpression = (this as? FirWrappedArgumentExpression)?.expression ?: this
|
||||||
|
|
||||||
|
|||||||
+10
@@ -0,0 +1,10 @@
|
|||||||
|
// K2: See KT-65342
|
||||||
|
|
||||||
|
fun test() {
|
||||||
|
<!MULTIPLE_LABELS_ARE_FORBIDDEN!>a@<!> b@ while(true) {
|
||||||
|
val f = {
|
||||||
|
return@a
|
||||||
|
}
|
||||||
|
break@b
|
||||||
|
}
|
||||||
|
}
|
||||||
+2
-1
@@ -1,4 +1,5 @@
|
|||||||
// FIR_IDENTICAL
|
// K2: See KT-65342
|
||||||
|
|
||||||
fun test() {
|
fun test() {
|
||||||
a@ b@ while(true) {
|
a@ b@ while(true) {
|
||||||
val f = {
|
val f = {
|
||||||
|
|||||||
+3
-3
@@ -30,12 +30,12 @@ fun testAnnotatedLambdaLabel() =
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun testLambdaMultipleLabels1() =
|
fun testLambdaMultipleLabels1() =
|
||||||
lambda1@ lambda2@ {
|
<!MULTIPLE_LABELS_ARE_FORBIDDEN!>lambda1@<!> lambda2@ {
|
||||||
<!NOT_A_FUNCTION_LABEL!>return@lambda1<!>
|
<!NOT_A_FUNCTION_LABEL!>return@lambda1<!>
|
||||||
}
|
}
|
||||||
|
|
||||||
fun testLambdaMultipleLabels2() =
|
fun testLambdaMultipleLabels2() =
|
||||||
lambda1@ lambda2@ {
|
<!MULTIPLE_LABELS_ARE_FORBIDDEN!>lambda1@<!> lambda2@ {
|
||||||
return@lambda2
|
return@lambda2
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -62,7 +62,7 @@ fun testHighOrderFunctionCallLabelInReturn() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun testMultipleLabelsWithNestedLambda() {
|
fun testMultipleLabelsWithNestedLambda() {
|
||||||
l1@ l2@{
|
<!MULTIPLE_LABELS_ARE_FORBIDDEN!>l1@<!> l2@{
|
||||||
{
|
{
|
||||||
<!NOT_A_FUNCTION_LABEL!>return@l1<!>
|
<!NOT_A_FUNCTION_LABEL!>return@l1<!>
|
||||||
}
|
}
|
||||||
|
|||||||
+3
-3
@@ -30,12 +30,12 @@ fun testAnnotatedLambdaLabel() =
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun testLambdaMultipleLabels1() =
|
fun testLambdaMultipleLabels1() =
|
||||||
lambda1@ lambda2@ {
|
<!MULTIPLE_LABELS_ARE_FORBIDDEN!>lambda1@<!> lambda2@ {
|
||||||
<!NOT_A_FUNCTION_LABEL!>return@lambda1<!>
|
<!NOT_A_FUNCTION_LABEL!>return@lambda1<!>
|
||||||
}
|
}
|
||||||
|
|
||||||
fun testLambdaMultipleLabels2() =
|
fun testLambdaMultipleLabels2() =
|
||||||
lambda1@ lambda2@ {
|
<!MULTIPLE_LABELS_ARE_FORBIDDEN!>lambda1@<!> lambda2@ {
|
||||||
return@lambda2
|
return@lambda2
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -62,7 +62,7 @@ fun testHighOrderFunctionCallLabelInReturn() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun testMultipleLabelsWithNestedLambda() {
|
fun testMultipleLabelsWithNestedLambda() {
|
||||||
l1@ l2@{
|
<!MULTIPLE_LABELS_ARE_FORBIDDEN!>l1@<!> l2@{
|
||||||
{
|
{
|
||||||
<!NOT_A_FUNCTION_LABEL!>return@l1<!>
|
<!NOT_A_FUNCTION_LABEL!>return@l1<!>
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
// !DIAGNOSTICS: -REDUNDANT_LABEL_WARNING -UNDERSCORE_IS_RESERVED
|
// !DIAGNOSTICS: -REDUNDANT_LABEL_WARNING -UNDERSCORE_IS_RESERVED -MULTIPLE_LABELS_ARE_FORBIDDEN
|
||||||
|
|
||||||
// See KT-65337
|
// See KT-65337
|
||||||
// !DIAGNOSTICS: -UNRESOLVED_REFERENCE
|
// !DIAGNOSTICS: -UNRESOLVED_REFERENCE
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
// !DIAGNOSTICS: -REDUNDANT_LABEL_WARNING -UNDERSCORE_IS_RESERVED
|
// !DIAGNOSTICS: -REDUNDANT_LABEL_WARNING -UNDERSCORE_IS_RESERVED -MULTIPLE_LABELS_ARE_FORBIDDEN
|
||||||
|
|
||||||
// See KT-65337
|
// See KT-65337
|
||||||
// !DIAGNOSTICS: -UNRESOLVED_REFERENCE
|
// !DIAGNOSTICS: -UNRESOLVED_REFERENCE
|
||||||
|
|||||||
@@ -23,5 +23,5 @@ inline fun inlineFunWithInvoke2(s: (p: Int) -> Unit) {
|
|||||||
|
|
||||||
inline fun propagation(s: (p: Int) -> Unit) {
|
inline fun propagation(s: (p: Int) -> Unit) {
|
||||||
inlineFunWithInvoke((label@ s))
|
inlineFunWithInvoke((label@ s))
|
||||||
inlineFunWithInvoke((label2@ label@ s))
|
inlineFunWithInvoke((<!MULTIPLE_LABELS_ARE_FORBIDDEN!>label2@<!> label@ s))
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,37 @@
|
|||||||
|
// !DIAGNOSTICS: -REDUNDANT_LABEL_WARNING
|
||||||
|
|
||||||
|
fun foo1() {
|
||||||
|
<!MULTIPLE_LABELS_ARE_FORBIDDEN!>l2@<!> l1@ do {
|
||||||
|
} while (true)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun foo2() {
|
||||||
|
<!MULTIPLE_LABELS_ARE_FORBIDDEN!>l4@<!> <!UNDERSCORE_IS_RESERVED!>_<!>@ <!MULTIPLE_LABELS_ARE_FORBIDDEN!>l3@<!> <!UNDERSCORE_IS_RESERVED!>__<!>@ <!MULTIPLE_LABELS_ARE_FORBIDDEN!>l2@<!> l1@ while (true) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun foo3() {
|
||||||
|
<!MULTIPLE_LABELS_ARE_FORBIDDEN!>l2@<!> l1@ 42
|
||||||
|
}
|
||||||
|
|
||||||
|
fun foo4() {
|
||||||
|
l1@ do {
|
||||||
|
l4@ { false }
|
||||||
|
} while (true)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun foo5() {
|
||||||
|
<!MULTIPLE_LABELS_ARE_FORBIDDEN!>l2@<!> l1@ do {
|
||||||
|
l4@ { false }
|
||||||
|
} while (true)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun foo6() {
|
||||||
|
<!MULTIPLE_LABELS_ARE_FORBIDDEN!>l2@<!> l1@ do {
|
||||||
|
l4@ l3@{ true }
|
||||||
|
} while (true)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun foo7() {
|
||||||
|
<!MULTIPLE_LABELS_ARE_FORBIDDEN!>l3@<!> <!MULTIPLE_LABELS_ARE_FORBIDDEN!>l2@<!> l1@ fun bar() {}
|
||||||
|
}
|
||||||
@@ -0,0 +1,37 @@
|
|||||||
|
// !DIAGNOSTICS: -REDUNDANT_LABEL_WARNING
|
||||||
|
|
||||||
|
fun foo1() {
|
||||||
|
l2@ l1@ do {
|
||||||
|
} while (true)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun foo2() {
|
||||||
|
l4@ <!UNDERSCORE_IS_RESERVED!>_<!>@ l3@ <!UNDERSCORE_IS_RESERVED!>__<!>@ l2@ l1@ while (true) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun foo3() {
|
||||||
|
l2@ l1@ 42
|
||||||
|
}
|
||||||
|
|
||||||
|
fun foo4() {
|
||||||
|
l1@ do {
|
||||||
|
l4@ { false }
|
||||||
|
} while (true)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun foo5() {
|
||||||
|
l2@ l1@ do {
|
||||||
|
l4@ { false }
|
||||||
|
} while (true)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun foo6() {
|
||||||
|
l2@ l1@ do {
|
||||||
|
l4@ l3@{ true }
|
||||||
|
} while (true)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun foo7() {
|
||||||
|
l3@ l2@ l1@ fun bar() {}
|
||||||
|
}
|
||||||
+3
-1
@@ -1,3 +1,5 @@
|
|||||||
|
// K2: See KT-65342
|
||||||
|
|
||||||
fun main() {
|
fun main() {
|
||||||
val a : Int? = null;
|
val a : Int? = null;
|
||||||
var v = 1
|
var v = 1
|
||||||
@@ -9,7 +11,7 @@ fun main() {
|
|||||||
val h1 : String = <!INITIALIZER_TYPE_MISMATCH!>--v<!>;
|
val h1 : String = <!INITIALIZER_TYPE_MISMATCH!>--v<!>;
|
||||||
val i : String = <!INITIALIZER_TYPE_MISMATCH, TYPE_MISMATCH!>!true<!>;
|
val i : String = <!INITIALIZER_TYPE_MISMATCH, TYPE_MISMATCH!>!true<!>;
|
||||||
val j : String = <!INITIALIZER_TYPE_MISMATCH!>foo@ true<!>;
|
val j : String = <!INITIALIZER_TYPE_MISMATCH!>foo@ true<!>;
|
||||||
val k : String = <!INITIALIZER_TYPE_MISMATCH!>foo@ bar@ true<!>;
|
val k : String = <!MULTIPLE_LABELS_ARE_FORBIDDEN!>foo@<!> bar@ true;
|
||||||
val l : String = <!INITIALIZER_TYPE_MISMATCH!>-1<!>;
|
val l : String = <!INITIALIZER_TYPE_MISMATCH!>-1<!>;
|
||||||
val m : String = <!INITIALIZER_TYPE_MISMATCH!>+1<!>;
|
val m : String = <!INITIALIZER_TYPE_MISMATCH!>+1<!>;
|
||||||
}
|
}
|
||||||
|
|||||||
+2
@@ -1,3 +1,5 @@
|
|||||||
|
// K2: See KT-65342
|
||||||
|
|
||||||
fun main() {
|
fun main() {
|
||||||
val a : Int? = null;
|
val a : Int? = null;
|
||||||
var v = 1
|
var v = 1
|
||||||
|
|||||||
Generated
+6
@@ -23901,6 +23901,12 @@ public class DiagnosticTestGenerated extends AbstractDiagnosticTest {
|
|||||||
public void testLabelsMustBeNamed() throws Exception {
|
public void testLabelsMustBeNamed() throws Exception {
|
||||||
runTest("compiler/testData/diagnostics/tests/labels/labelsMustBeNamed.kt");
|
runTest("compiler/testData/diagnostics/tests/labels/labelsMustBeNamed.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("multipleLabels.kt")
|
||||||
|
public void testMultipleLabels() throws Exception {
|
||||||
|
runTest("compiler/testData/diagnostics/tests/labels/multipleLabels.kt");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nested
|
@Nested
|
||||||
|
|||||||
Reference in New Issue
Block a user