FIR checker: report REDUNDANT_LABEL_WARNING
Since many labels are not present in the FIR tree, this checker is implemented as a syntax checker. Comparing with FE1.0, this change reports some REDUNDANT_LABEL_WARNING that FE1.0 has missed, especially LHS of assignments.
This commit is contained in:
committed by
TeamCityServer
parent
cbc9d08623
commit
363b25504d
+7
@@ -42,6 +42,7 @@ import org.jetbrains.kotlin.psi.KtExpressionWithLabel
|
|||||||
import org.jetbrains.kotlin.psi.KtFunction
|
import org.jetbrains.kotlin.psi.KtFunction
|
||||||
import org.jetbrains.kotlin.psi.KtIfExpression
|
import org.jetbrains.kotlin.psi.KtIfExpression
|
||||||
import org.jetbrains.kotlin.psi.KtImportDirective
|
import org.jetbrains.kotlin.psi.KtImportDirective
|
||||||
|
import org.jetbrains.kotlin.psi.KtLabelReferenceExpression
|
||||||
import org.jetbrains.kotlin.psi.KtModifierListOwner
|
import org.jetbrains.kotlin.psi.KtModifierListOwner
|
||||||
import org.jetbrains.kotlin.psi.KtNameReferenceExpression
|
import org.jetbrains.kotlin.psi.KtNameReferenceExpression
|
||||||
import org.jetbrains.kotlin.psi.KtNamedDeclaration
|
import org.jetbrains.kotlin.psi.KtNamedDeclaration
|
||||||
@@ -3744,6 +3745,12 @@ internal val KT_DIAGNOSTIC_CONVERTER = KtDiagnosticConverterBuilder.buildConvert
|
|||||||
token,
|
token,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
add(FirErrors.REDUNDANT_LABEL_WARNING) { firDiagnostic ->
|
||||||
|
RedundantLabelWarningImpl(
|
||||||
|
firDiagnostic as FirPsiDiagnostic,
|
||||||
|
token,
|
||||||
|
)
|
||||||
|
}
|
||||||
add(FirJvmErrors.CONFLICTING_JVM_DECLARATIONS) { firDiagnostic ->
|
add(FirJvmErrors.CONFLICTING_JVM_DECLARATIONS) { firDiagnostic ->
|
||||||
ConflictingJvmDeclarationsImpl(
|
ConflictingJvmDeclarationsImpl(
|
||||||
firDiagnostic as FirPsiDiagnostic,
|
firDiagnostic as FirPsiDiagnostic,
|
||||||
|
|||||||
+5
@@ -53,6 +53,7 @@ import org.jetbrains.kotlin.psi.KtExpressionWithLabel
|
|||||||
import org.jetbrains.kotlin.psi.KtFunction
|
import org.jetbrains.kotlin.psi.KtFunction
|
||||||
import org.jetbrains.kotlin.psi.KtIfExpression
|
import org.jetbrains.kotlin.psi.KtIfExpression
|
||||||
import org.jetbrains.kotlin.psi.KtImportDirective
|
import org.jetbrains.kotlin.psi.KtImportDirective
|
||||||
|
import org.jetbrains.kotlin.psi.KtLabelReferenceExpression
|
||||||
import org.jetbrains.kotlin.psi.KtModifierListOwner
|
import org.jetbrains.kotlin.psi.KtModifierListOwner
|
||||||
import org.jetbrains.kotlin.psi.KtNameReferenceExpression
|
import org.jetbrains.kotlin.psi.KtNameReferenceExpression
|
||||||
import org.jetbrains.kotlin.psi.KtNamedDeclaration
|
import org.jetbrains.kotlin.psi.KtNamedDeclaration
|
||||||
@@ -2609,6 +2610,10 @@ sealed class KtFirDiagnostic<PSI : PsiElement> : KtDiagnosticWithPsi<PSI> {
|
|||||||
override val diagnosticClass get() = ReturnForBuiltInSuspend::class
|
override val diagnosticClass get() = ReturnForBuiltInSuspend::class
|
||||||
}
|
}
|
||||||
|
|
||||||
|
abstract class RedundantLabelWarning : KtFirDiagnostic<KtLabelReferenceExpression>() {
|
||||||
|
override val diagnosticClass get() = RedundantLabelWarning::class
|
||||||
|
}
|
||||||
|
|
||||||
abstract class ConflictingJvmDeclarations : KtFirDiagnostic<PsiElement>() {
|
abstract class ConflictingJvmDeclarations : KtFirDiagnostic<PsiElement>() {
|
||||||
override val diagnosticClass get() = ConflictingJvmDeclarations::class
|
override val diagnosticClass get() = ConflictingJvmDeclarations::class
|
||||||
}
|
}
|
||||||
|
|||||||
+6
@@ -54,6 +54,7 @@ import org.jetbrains.kotlin.psi.KtExpressionWithLabel
|
|||||||
import org.jetbrains.kotlin.psi.KtFunction
|
import org.jetbrains.kotlin.psi.KtFunction
|
||||||
import org.jetbrains.kotlin.psi.KtIfExpression
|
import org.jetbrains.kotlin.psi.KtIfExpression
|
||||||
import org.jetbrains.kotlin.psi.KtImportDirective
|
import org.jetbrains.kotlin.psi.KtImportDirective
|
||||||
|
import org.jetbrains.kotlin.psi.KtLabelReferenceExpression
|
||||||
import org.jetbrains.kotlin.psi.KtModifierListOwner
|
import org.jetbrains.kotlin.psi.KtModifierListOwner
|
||||||
import org.jetbrains.kotlin.psi.KtNameReferenceExpression
|
import org.jetbrains.kotlin.psi.KtNameReferenceExpression
|
||||||
import org.jetbrains.kotlin.psi.KtNamedDeclaration
|
import org.jetbrains.kotlin.psi.KtNamedDeclaration
|
||||||
@@ -3148,6 +3149,11 @@ internal class ReturnForBuiltInSuspendImpl(
|
|||||||
override val token: ValidityToken,
|
override val token: ValidityToken,
|
||||||
) : KtFirDiagnostic.ReturnForBuiltInSuspend(), KtAbstractFirDiagnostic<KtReturnExpression>
|
) : KtFirDiagnostic.ReturnForBuiltInSuspend(), KtAbstractFirDiagnostic<KtReturnExpression>
|
||||||
|
|
||||||
|
internal class RedundantLabelWarningImpl(
|
||||||
|
override val firDiagnostic: FirPsiDiagnostic,
|
||||||
|
override val token: ValidityToken,
|
||||||
|
) : KtFirDiagnostic.RedundantLabelWarning(), KtAbstractFirDiagnostic<KtLabelReferenceExpression>
|
||||||
|
|
||||||
internal class ConflictingJvmDeclarationsImpl(
|
internal class ConflictingJvmDeclarationsImpl(
|
||||||
override val firDiagnostic: FirPsiDiagnostic,
|
override val firDiagnostic: FirPsiDiagnostic,
|
||||||
override val token: ValidityToken,
|
override val token: ValidityToken,
|
||||||
|
|||||||
+4
@@ -1353,6 +1353,10 @@ object DIAGNOSTICS_LIST : DiagnosticList("FirErrors") {
|
|||||||
val MODIFIER_FORM_FOR_NON_BUILT_IN_SUSPEND by error<PsiElement>(PositioningStrategy.REFERENCED_NAME_BY_QUALIFIED)
|
val MODIFIER_FORM_FOR_NON_BUILT_IN_SUSPEND by error<PsiElement>(PositioningStrategy.REFERENCED_NAME_BY_QUALIFIED)
|
||||||
val RETURN_FOR_BUILT_IN_SUSPEND by error<KtReturnExpression>()
|
val RETURN_FOR_BUILT_IN_SUSPEND by error<KtReturnExpression>()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
val LABEL by object : DiagnosticGroup("label") {
|
||||||
|
val REDUNDANT_LABEL_WARNING by warning<KtLabelReferenceExpression>(PositioningStrategy.LABEL)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private val exposedVisibilityDiagnosticInit: DiagnosticBuilder.() -> Unit = {
|
private val exposedVisibilityDiagnosticInit: DiagnosticBuilder.() -> Unit = {
|
||||||
|
|||||||
@@ -66,6 +66,7 @@ import org.jetbrains.kotlin.psi.KtExpressionWithLabel
|
|||||||
import org.jetbrains.kotlin.psi.KtFunction
|
import org.jetbrains.kotlin.psi.KtFunction
|
||||||
import org.jetbrains.kotlin.psi.KtIfExpression
|
import org.jetbrains.kotlin.psi.KtIfExpression
|
||||||
import org.jetbrains.kotlin.psi.KtImportDirective
|
import org.jetbrains.kotlin.psi.KtImportDirective
|
||||||
|
import org.jetbrains.kotlin.psi.KtLabelReferenceExpression
|
||||||
import org.jetbrains.kotlin.psi.KtModifierListOwner
|
import org.jetbrains.kotlin.psi.KtModifierListOwner
|
||||||
import org.jetbrains.kotlin.psi.KtNameReferenceExpression
|
import org.jetbrains.kotlin.psi.KtNameReferenceExpression
|
||||||
import org.jetbrains.kotlin.psi.KtNamedDeclaration
|
import org.jetbrains.kotlin.psi.KtNamedDeclaration
|
||||||
@@ -703,4 +704,7 @@ object FirErrors {
|
|||||||
val MODIFIER_FORM_FOR_NON_BUILT_IN_SUSPEND by error0<PsiElement>(SourceElementPositioningStrategies.REFERENCED_NAME_BY_QUALIFIED)
|
val MODIFIER_FORM_FOR_NON_BUILT_IN_SUSPEND by error0<PsiElement>(SourceElementPositioningStrategies.REFERENCED_NAME_BY_QUALIFIED)
|
||||||
val RETURN_FOR_BUILT_IN_SUSPEND by error0<KtReturnExpression>()
|
val RETURN_FOR_BUILT_IN_SUSPEND by error0<KtReturnExpression>()
|
||||||
|
|
||||||
|
// label
|
||||||
|
val REDUNDANT_LABEL_WARNING by warning0<KtLabelReferenceExpression>(SourceElementPositioningStrategies.LABEL)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
+1
@@ -30,6 +30,7 @@ object CommonDeclarationCheckers : DeclarationCheckers() {
|
|||||||
FirInvalidAndDangerousCharactersChecker,
|
FirInvalidAndDangerousCharactersChecker,
|
||||||
FirAmbiguousAnonymousTypeChecker,
|
FirAmbiguousAnonymousTypeChecker,
|
||||||
FirExplicitApiDeclarationChecker,
|
FirExplicitApiDeclarationChecker,
|
||||||
|
FirRedundantLabelChecker,
|
||||||
)
|
)
|
||||||
|
|
||||||
override val functionCheckers: Set<FirFunctionChecker>
|
override val functionCheckers: Set<FirFunctionChecker>
|
||||||
|
|||||||
+159
@@ -0,0 +1,159 @@
|
|||||||
|
/*
|
||||||
|
* 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.checkers.syntax
|
||||||
|
|
||||||
|
import com.intellij.lang.LighterASTNode
|
||||||
|
import com.intellij.openapi.util.Ref
|
||||||
|
import com.intellij.psi.PsiElement
|
||||||
|
import com.intellij.util.diff.FlyweightCapableTreeStructure
|
||||||
|
import org.jetbrains.kotlin.KtNodeTypes
|
||||||
|
import org.jetbrains.kotlin.descriptors.EffectiveVisibility
|
||||||
|
import org.jetbrains.kotlin.fir.*
|
||||||
|
import org.jetbrains.kotlin.fir.analysis.buildChildSourceElement
|
||||||
|
import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext
|
||||||
|
import org.jetbrains.kotlin.fir.analysis.checkers.getContainingClassSymbol
|
||||||
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.*
|
||||||
|
import org.jetbrains.kotlin.fir.declarations.*
|
||||||
|
import org.jetbrains.kotlin.fir.declarations.utils.effectiveVisibility
|
||||||
|
import org.jetbrains.kotlin.fir.expressions.FirBlock
|
||||||
|
import org.jetbrains.kotlin.fir.symbols.impl.FirRegularClassSymbol
|
||||||
|
import org.jetbrains.kotlin.fir.visitors.FirVisitorVoid
|
||||||
|
import org.jetbrains.kotlin.psi.*
|
||||||
|
|
||||||
|
object FirRedundantLabelChecker : FirDeclarationSyntaxChecker<FirDeclaration, PsiElement>() {
|
||||||
|
override fun checkLightTree(
|
||||||
|
element: FirDeclaration,
|
||||||
|
source: FirLightSourceElement,
|
||||||
|
context: CheckerContext,
|
||||||
|
reporter: DiagnosticReporter
|
||||||
|
) {
|
||||||
|
// Local declarations are already checked when the containing declaration is checked.
|
||||||
|
if (!isRootLabelContainer(element)) return
|
||||||
|
|
||||||
|
val allTraversalRoots = mutableSetOf<FirSourceElement>()
|
||||||
|
|
||||||
|
// First collect all labels in the declaration
|
||||||
|
element.accept(object : FirVisitorVoid() {
|
||||||
|
override fun visitElement(element: FirElement) {
|
||||||
|
element.acceptChildren(this)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun visitBlock(block: FirBlock) {
|
||||||
|
markTraversalRoot(block)
|
||||||
|
super.visitBlock(block)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun visitProperty(property: FirProperty) {
|
||||||
|
markTraversalRoot(property)
|
||||||
|
super.visitProperty(property)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun visitSimpleFunction(simpleFunction: FirSimpleFunction) {
|
||||||
|
markTraversalRoot(simpleFunction)
|
||||||
|
super.visitFunction(simpleFunction)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun visitPropertyAccessor(propertyAccessor: FirPropertyAccessor) {
|
||||||
|
markTraversalRoot(propertyAccessor)
|
||||||
|
super.visitPropertyAccessor(propertyAccessor)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun visitConstructor(constructor: FirConstructor) {
|
||||||
|
markTraversalRoot(constructor)
|
||||||
|
super.visitConstructor(constructor)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun markTraversalRoot(elem: FirElement) {
|
||||||
|
val elemSource = elem.source
|
||||||
|
if (elemSource?.kind is FirRealSourceElementKind) {
|
||||||
|
allTraversalRoots.add(elemSource)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
for (root in allTraversalRoots) {
|
||||||
|
root.treeStructure.reportRedundantLabels(reporter, context, root as FirLightSourceElement, allTraversalRoots)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun FlyweightCapableTreeStructure<LighterASTNode>.reportRedundantLabels(
|
||||||
|
reporter: DiagnosticReporter,
|
||||||
|
context: CheckerContext,
|
||||||
|
source: FirLightSourceElement,
|
||||||
|
allTraversalRoots: Set<FirSourceElement>,
|
||||||
|
isChildNode: Boolean = false,
|
||||||
|
) {
|
||||||
|
if (isChildNode && source in allTraversalRoots) return // Prevent double traversal
|
||||||
|
val node = source.lighterASTNode
|
||||||
|
if (node.tokenType == KtNodeTypes.LABELED_EXPRESSION) {
|
||||||
|
val labelQualifier = findChildByType(node, KtNodeTypes.LABEL_QUALIFIER)
|
||||||
|
if (labelQualifier != null) {
|
||||||
|
findChildByType(labelQualifier, KtNodeTypes.LABEL)?.let { labelNode ->
|
||||||
|
when (unwrapParenthesesLabelsAndAnnotations(node).tokenType) {
|
||||||
|
KtNodeTypes.LAMBDA_EXPRESSION, KtNodeTypes.FOR, KtNodeTypes.WHILE, KtNodeTypes.DO_WHILE, KtNodeTypes.FUN -> {}
|
||||||
|
else -> reporter.reportOn(
|
||||||
|
source.buildChildSourceElement(labelNode),
|
||||||
|
FirErrors.REDUNDANT_LABEL_WARNING,
|
||||||
|
context
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
val childrenRef = Ref.create<Array<LighterASTNode?>>(null)
|
||||||
|
getChildren(node, childrenRef)
|
||||||
|
for (child in childrenRef.get() ?: return) {
|
||||||
|
if (child == null) continue
|
||||||
|
reportRedundantLabels(reporter, context, source.buildChildSourceElement(child), allTraversalRoots, true)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun checkPsi(
|
||||||
|
element: FirDeclaration,
|
||||||
|
source: FirPsiSourceElement,
|
||||||
|
psi: PsiElement,
|
||||||
|
context: CheckerContext,
|
||||||
|
reporter: DiagnosticReporter
|
||||||
|
) {
|
||||||
|
// Local declarations are already checked when the containing declaration is checked.
|
||||||
|
if (!isRootLabelContainer(element)) return
|
||||||
|
|
||||||
|
// First collect all labels in the declaration
|
||||||
|
source.psi.accept(object : KtTreeVisitorVoid() {
|
||||||
|
override fun visitLabeledExpression(expression: KtLabeledExpression) {
|
||||||
|
val labelNameExpression = expression.getTargetLabel()
|
||||||
|
|
||||||
|
if (labelNameExpression != null) {
|
||||||
|
val deparenthesizedBaseExpression = KtPsiUtil.deparenthesize(expression)
|
||||||
|
if (deparenthesizedBaseExpression !is KtLambdaExpression &&
|
||||||
|
deparenthesizedBaseExpression !is KtLoopExpression &&
|
||||||
|
deparenthesizedBaseExpression !is KtNamedFunction
|
||||||
|
) {
|
||||||
|
reporter.reportOn(labelNameExpression.toFirPsiSourceElement(), FirErrors.REDUNDANT_LABEL_WARNING, context)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
super.visitLabeledExpression(expression)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun isRootLabelContainer(element: FirDeclaration): Boolean {
|
||||||
|
if (element.source?.kind is FirFakeSourceElementKind) return false
|
||||||
|
if (element is FirCallableDeclaration && element.effectiveVisibility == EffectiveVisibility.Local) return false
|
||||||
|
return when (element) {
|
||||||
|
is FirAnonymousFunction -> false
|
||||||
|
is FirFunction -> true
|
||||||
|
is FirProperty -> true
|
||||||
|
// Consider class initializer of non local class as root label container.
|
||||||
|
is FirAnonymousInitializer -> {
|
||||||
|
val parentVisibility =
|
||||||
|
(element.getContainingClassSymbol(element.moduleData.session) as? FirRegularClassSymbol)?.effectiveVisibility
|
||||||
|
parentVisibility != null && parentVisibility != EffectiveVisibility.Local
|
||||||
|
}
|
||||||
|
else -> false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
+4
@@ -382,6 +382,7 @@ import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.REDUNDANT_CALL_OF
|
|||||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.REDUNDANT_EXPLICIT_BACKING_FIELD
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.REDUNDANT_EXPLICIT_BACKING_FIELD
|
||||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.REDUNDANT_EXPLICIT_TYPE
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.REDUNDANT_EXPLICIT_TYPE
|
||||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.REDUNDANT_INLINE_SUSPEND_FUNCTION_TYPE
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.REDUNDANT_INLINE_SUSPEND_FUNCTION_TYPE
|
||||||
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.REDUNDANT_LABEL_WARNING
|
||||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.REDUNDANT_MODALITY_MODIFIER
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.REDUNDANT_MODALITY_MODIFIER
|
||||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.REDUNDANT_MODIFIER
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.REDUNDANT_MODIFIER
|
||||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.REDUNDANT_MODIFIER_FOR_TARGET
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.REDUNDANT_MODIFIER_FOR_TARGET
|
||||||
@@ -1760,6 +1761,9 @@ class FirDefaultErrorMessages {
|
|||||||
)
|
)
|
||||||
map.put(RETURN_FOR_BUILT_IN_SUSPEND, "Using implicit label for this lambda is prohibited")
|
map.put(RETURN_FOR_BUILT_IN_SUSPEND, "Using implicit label for this lambda is prohibited")
|
||||||
|
|
||||||
|
// Label
|
||||||
|
map.put(REDUNDANT_LABEL_WARNING, "Label is redundant, because it can not be referenced in either ''break'', ''continue'', or ''return'' expression")
|
||||||
|
|
||||||
// Extended checkers group
|
// Extended checkers group
|
||||||
map.put(REDUNDANT_VISIBILITY_MODIFIER, "Redundant visibility modifier")
|
map.put(REDUNDANT_VISIBILITY_MODIFIER, "Redundant visibility modifier")
|
||||||
map.put(REDUNDANT_MODALITY_MODIFIER, "Redundant modality modifier")
|
map.put(REDUNDANT_MODALITY_MODIFIER, "Redundant modality modifier")
|
||||||
|
|||||||
+3
-4
@@ -518,7 +518,7 @@ object LightTreePositioningStrategies {
|
|||||||
) {
|
) {
|
||||||
val lhs = tree.firstChildExpression(node)
|
val lhs = tree.firstChildExpression(node)
|
||||||
lhs?.let {
|
lhs?.let {
|
||||||
tree.unwrapParenthesesLabelsAndAnnotations(it)?.let { unwrapped ->
|
tree.unwrapParenthesesLabelsAndAnnotations(it).let { unwrapped ->
|
||||||
return markElement(unwrapped, startOffset, endOffset, tree, node)
|
return markElement(unwrapped, startOffset, endOffset, tree, node)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -880,7 +880,7 @@ object LightTreePositioningStrategies {
|
|||||||
tree.firstChildExpression(node)
|
tree.firstChildExpression(node)
|
||||||
}
|
}
|
||||||
lhs?.let {
|
lhs?.let {
|
||||||
tree.unwrapParenthesesLabelsAndAnnotations(it)?.let { unwrapped ->
|
tree.unwrapParenthesesLabelsAndAnnotations(it).let { unwrapped ->
|
||||||
return markElement(unwrapped, startOffset, endOffset, tree, node)
|
return markElement(unwrapped, startOffset, endOffset, tree, node)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1153,8 +1153,7 @@ private fun FlyweightCapableTreeStructure<LighterASTNode>.referenceExpression(
|
|||||||
}
|
}
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
fun FlyweightCapableTreeStructure<LighterASTNode>.unwrapParenthesesLabelsAndAnnotations(node: LighterASTNode): LighterASTNode {
|
||||||
private fun FlyweightCapableTreeStructure<LighterASTNode>.unwrapParenthesesLabelsAndAnnotations(node: LighterASTNode): LighterASTNode? {
|
|
||||||
var unwrapped = node
|
var unwrapped = node
|
||||||
while (true) {
|
while (true) {
|
||||||
unwrapped = when (unwrapped.tokenType) {
|
unwrapped = when (unwrapped.tokenType) {
|
||||||
|
|||||||
@@ -6,12 +6,7 @@
|
|||||||
package org.jetbrains.kotlin.fir.declarations.utils
|
package org.jetbrains.kotlin.fir.declarations.utils
|
||||||
|
|
||||||
import org.jetbrains.kotlin.descriptors.*
|
import org.jetbrains.kotlin.descriptors.*
|
||||||
import org.jetbrains.kotlin.fir.FirRenderer
|
|
||||||
import org.jetbrains.kotlin.fir.declarations.*
|
import org.jetbrains.kotlin.fir.declarations.*
|
||||||
import org.jetbrains.kotlin.fir.declarations.impl.FirResolvedDeclarationStatusImpl
|
|
||||||
import org.jetbrains.kotlin.fir.render
|
|
||||||
import kotlin.contracts.ExperimentalContracts
|
|
||||||
import kotlin.contracts.contract
|
|
||||||
|
|
||||||
inline val FirMemberDeclaration.modality: Modality? get() = status.modality
|
inline val FirMemberDeclaration.modality: Modality? get() = status.modality
|
||||||
inline val FirMemberDeclaration.isAbstract: Boolean get() = status.modality == Modality.ABSTRACT
|
inline val FirMemberDeclaration.isAbstract: Boolean get() = status.modality == Modality.ABSTRACT
|
||||||
@@ -24,9 +19,13 @@ inline val FirMemberDeclaration.isFinal: Boolean
|
|||||||
}
|
}
|
||||||
|
|
||||||
inline val FirMemberDeclaration.visibility: Visibility get() = status.visibility
|
inline val FirMemberDeclaration.visibility: Visibility get() = status.visibility
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the effective visibility. Note that it's assumed that the element or its non-local container has at least resolve phase
|
||||||
|
* [FirResolvePhase.STATUS], in which case, any declarations with unresolved status are effectively local.
|
||||||
|
*/
|
||||||
inline val FirMemberDeclaration.effectiveVisibility: EffectiveVisibility
|
inline val FirMemberDeclaration.effectiveVisibility: EffectiveVisibility
|
||||||
get() = (status as? FirResolvedDeclarationStatus)?.effectiveVisibility
|
get() = (status as? FirResolvedDeclarationStatus)?.effectiveVisibility ?: EffectiveVisibility.Local
|
||||||
?: error("Effective visibility for ${render(FirRenderer.RenderMode.NoBodies)} must be resolved")
|
|
||||||
|
|
||||||
inline val FirMemberDeclaration.allowsToHaveFakeOverride: Boolean
|
inline val FirMemberDeclaration.allowsToHaveFakeOverride: Boolean
|
||||||
get() = !Visibilities.isPrivate(visibility) && visibility != Visibilities.InvisibleFake
|
get() = !Visibilities.isPrivate(visibility) && visibility != Visibilities.InvisibleFake
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ class C {
|
|||||||
|
|
||||||
fun f (a : Boolean, b : Boolean) {
|
fun f (a : Boolean, b : Boolean) {
|
||||||
b@ while (true)
|
b@ while (true)
|
||||||
a@ {
|
<!REDUNDANT_LABEL_WARNING!>a@<!> {
|
||||||
<!NOT_A_LOOP_LABEL!>break@f<!>
|
<!NOT_A_LOOP_LABEL!>break@f<!>
|
||||||
break
|
break
|
||||||
break@b
|
break@b
|
||||||
@@ -12,7 +12,7 @@ class C {
|
|||||||
<!BREAK_OR_CONTINUE_OUTSIDE_A_LOOP!>continue<!>
|
<!BREAK_OR_CONTINUE_OUTSIDE_A_LOOP!>continue<!>
|
||||||
|
|
||||||
b@ while (true)
|
b@ while (true)
|
||||||
a@ {
|
<!REDUNDANT_LABEL_WARNING!>a@<!> {
|
||||||
<!NOT_A_LOOP_LABEL!>continue@f<!>
|
<!NOT_A_LOOP_LABEL!>continue@f<!>
|
||||||
continue
|
continue
|
||||||
continue@b
|
continue@b
|
||||||
|
|||||||
@@ -1,23 +0,0 @@
|
|||||||
// !CHECK_TYPE
|
|
||||||
|
|
||||||
fun test() : Unit {
|
|
||||||
var x : Int? = 0
|
|
||||||
var y : Int = 0
|
|
||||||
|
|
||||||
checkSubtype<Int?>(x)
|
|
||||||
checkSubtype<Int>(y)
|
|
||||||
checkSubtype<Int>(x as Int)
|
|
||||||
checkSubtype<Int>(y <!USELESS_CAST!>as Int<!>)
|
|
||||||
checkSubtype<Int?>(x as Int?)
|
|
||||||
checkSubtype<Int?>(y as Int?)
|
|
||||||
checkSubtype<Int?>(x as? Int)
|
|
||||||
checkSubtype<Int?>(y as? Int)
|
|
||||||
checkSubtype<Int?>(x as? Int?)
|
|
||||||
checkSubtype<Int?>(y as? Int?)
|
|
||||||
|
|
||||||
val s = "" as Any
|
|
||||||
("" as String?)?.length
|
|
||||||
(data@("" as String?))?.length
|
|
||||||
(<!WRONG_ANNOTATION_TARGET!>@MustBeDocumented()<!>( "" as String?))?.length
|
|
||||||
Unit
|
|
||||||
}
|
|
||||||
@@ -1,3 +1,4 @@
|
|||||||
|
// FIR_IDENTICAL
|
||||||
// !CHECK_TYPE
|
// !CHECK_TYPE
|
||||||
|
|
||||||
fun test() : Unit {
|
fun test() : Unit {
|
||||||
|
|||||||
@@ -62,7 +62,7 @@ fun main1() {
|
|||||||
{1}();
|
{1}();
|
||||||
(fun (x : Int) = x)(1)
|
(fun (x : Int) = x)(1)
|
||||||
1.(<!FUNCTION_EXPECTED!>fun Int.(x : Int) = x<!>)(1);
|
1.(<!FUNCTION_EXPECTED!>fun Int.(x : Int) = x<!>)(1);
|
||||||
l@{1}()
|
<!REDUNDANT_LABEL_WARNING!>l@<!>{1}()
|
||||||
1.((<!FUNCTION_EXPECTED!>fun Int.() = 1<!>))()
|
1.((<!FUNCTION_EXPECTED!>fun Int.() = 1<!>))()
|
||||||
1.(<!FUNCTION_EXPECTED!>f()<!>)()
|
1.(<!FUNCTION_EXPECTED!>f()<!>)()
|
||||||
1.<!FUNCTION_EXPECTED!>if(true){f()}else{f()}<!>()
|
1.<!FUNCTION_EXPECTED!>if(true){f()}else{f()}<!>()
|
||||||
|
|||||||
+18
-18
@@ -57,19 +57,19 @@ annotation class Ann
|
|||||||
|
|
||||||
fun canBe(i0: Int, j: Int) {
|
fun canBe(i0: Int, j: Int) {
|
||||||
var i = i0
|
var i = i0
|
||||||
(label@ i) = 34
|
(<!REDUNDANT_LABEL_WARNING!>label@<!> i) = 34
|
||||||
|
|
||||||
(label@ <!VAL_REASSIGNMENT!>j<!>) = 34 //repeat for j
|
(<!REDUNDANT_LABEL_WARNING!>label@<!> <!VAL_REASSIGNMENT!>j<!>) = 34 //repeat for j
|
||||||
|
|
||||||
val a = A()
|
val a = A()
|
||||||
(l@ a.a) = 3894
|
(<!REDUNDANT_LABEL_WARNING!>l@<!> a.a) = 3894
|
||||||
|
|
||||||
@Ann
|
@Ann
|
||||||
l@ (i) = 123
|
<!REDUNDANT_LABEL_WARNING!>l@<!> (i) = 123
|
||||||
}
|
}
|
||||||
|
|
||||||
fun canBe2(j: Int) {
|
fun canBe2(j: Int) {
|
||||||
(label@ <!VAL_REASSIGNMENT!>j<!>) = 34
|
(<!REDUNDANT_LABEL_WARNING!>label@<!> <!VAL_REASSIGNMENT!>j<!>) = 34
|
||||||
}
|
}
|
||||||
|
|
||||||
class A() {
|
class A() {
|
||||||
@@ -79,29 +79,29 @@ class A() {
|
|||||||
class Test() {
|
class Test() {
|
||||||
fun testIllegalValues() {
|
fun testIllegalValues() {
|
||||||
<!VARIABLE_EXPECTED!>1<!> += 23
|
<!VARIABLE_EXPECTED!>1<!> += 23
|
||||||
(l@ <!VARIABLE_EXPECTED!>1<!>) += 23
|
(<!REDUNDANT_LABEL_WARNING!>l@<!> <!VARIABLE_EXPECTED!>1<!>) += 23
|
||||||
|
|
||||||
<!VARIABLE_EXPECTED!>getInt()<!> += 343
|
<!VARIABLE_EXPECTED!>getInt()<!> += 343
|
||||||
(f@ <!VARIABLE_EXPECTED!>getInt()<!>) += 343
|
(<!REDUNDANT_LABEL_WARNING!>f@<!> <!VARIABLE_EXPECTED!>getInt()<!>) += 343
|
||||||
|
|
||||||
<!VARIABLE_EXPECTED!>1<!>++
|
<!VARIABLE_EXPECTED!>1<!>++
|
||||||
(r@ <!VARIABLE_EXPECTED!>1<!>)--
|
(<!REDUNDANT_LABEL_WARNING!>r@<!> <!VARIABLE_EXPECTED!>1<!>)--
|
||||||
|
|
||||||
<!VARIABLE_EXPECTED!>getInt()<!>++
|
<!VARIABLE_EXPECTED!>getInt()<!>++
|
||||||
(m@ <!VARIABLE_EXPECTED!>getInt()<!>)--
|
(<!REDUNDANT_LABEL_WARNING!>m@<!> <!VARIABLE_EXPECTED!>getInt()<!>)--
|
||||||
|
|
||||||
++<!VARIABLE_EXPECTED!>2<!>
|
++<!VARIABLE_EXPECTED!>2<!>
|
||||||
--(r@ <!VARIABLE_EXPECTED!>2<!>)
|
--(<!REDUNDANT_LABEL_WARNING!>r@<!> <!VARIABLE_EXPECTED!>2<!>)
|
||||||
|
|
||||||
this<!UNRESOLVED_REFERENCE!>++<!>
|
this<!UNRESOLVED_REFERENCE!>++<!>
|
||||||
|
|
||||||
var s : String = "r"
|
var s : String = "r"
|
||||||
s += "ss"
|
s += "ss"
|
||||||
s += this
|
s += this
|
||||||
s += (a@ 2)
|
s += (<!REDUNDANT_LABEL_WARNING!>a@<!> 2)
|
||||||
|
|
||||||
@Ann
|
@Ann
|
||||||
l@ (<!VARIABLE_EXPECTED!>1<!>) = 123
|
<!REDUNDANT_LABEL_WARNING!>l@<!> (<!VARIABLE_EXPECTED!>1<!>) = 123
|
||||||
}
|
}
|
||||||
|
|
||||||
fun testIncompleteSyntax() {
|
fun testIncompleteSyntax() {
|
||||||
@@ -114,22 +114,22 @@ class Test() {
|
|||||||
val b: Int = 34
|
val b: Int = 34
|
||||||
|
|
||||||
a += 34
|
a += 34
|
||||||
(l@ a) += 34
|
(<!REDUNDANT_LABEL_WARNING!>l@<!> a) += 34
|
||||||
|
|
||||||
<!VAL_REASSIGNMENT!>b<!> += 34
|
<!VAL_REASSIGNMENT!>b<!> += 34
|
||||||
|
|
||||||
a++
|
a++
|
||||||
(@Ann l@ a)--
|
(@Ann <!REDUNDANT_LABEL_WARNING!>l@<!> a)--
|
||||||
(a)++
|
(a)++
|
||||||
--a
|
--a
|
||||||
++(@Ann l@ a)
|
++(@Ann <!REDUNDANT_LABEL_WARNING!>l@<!> a)
|
||||||
--(a)
|
--(a)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun testVariables1() {
|
fun testVariables1() {
|
||||||
val b: Int = 34
|
val b: Int = 34
|
||||||
|
|
||||||
(l@ <!VAL_REASSIGNMENT!>b<!>) += 34
|
(<!REDUNDANT_LABEL_WARNING!>l@<!> <!VAL_REASSIGNMENT!>b<!>) += 34
|
||||||
//repeat for b
|
//repeat for b
|
||||||
(<!VAL_REASSIGNMENT!>b<!>) += 3
|
(<!VAL_REASSIGNMENT!>b<!>) += 3
|
||||||
}
|
}
|
||||||
@@ -140,12 +140,12 @@ class Test() {
|
|||||||
a[6] += 43
|
a[6] += 43
|
||||||
@Ann
|
@Ann
|
||||||
a[7] = 7
|
a[7] = 7
|
||||||
(@Ann l@ (a))[8] = 8
|
(@Ann <!REDUNDANT_LABEL_WARNING!>l@<!> (a))[8] = 8
|
||||||
|
|
||||||
ab.getArray()[54] = 23
|
ab.getArray()[54] = 23
|
||||||
ab.getArray()[54]++
|
ab.getArray()[54]++
|
||||||
|
|
||||||
(f@ a)[3] = 4
|
(<!REDUNDANT_LABEL_WARNING!>f@<!> a)[3] = 4
|
||||||
|
|
||||||
this<!NO_SET_METHOD!>[54]<!> = 34
|
this<!NO_SET_METHOD!>[54]<!> = 34
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -22,6 +22,6 @@ fun main() {
|
|||||||
<!NO_COMPANION_OBJECT!>System<!> is Int
|
<!NO_COMPANION_OBJECT!>System<!> is Int
|
||||||
<!INVISIBLE_REFERENCE!>System<!>()
|
<!INVISIBLE_REFERENCE!>System<!>()
|
||||||
(<!NO_COMPANION_OBJECT!>System<!>)
|
(<!NO_COMPANION_OBJECT!>System<!>)
|
||||||
foo@ <!NO_COMPANION_OBJECT!>System<!>
|
<!REDUNDANT_LABEL_WARNING!>foo@<!> <!NO_COMPANION_OBJECT!>System<!>
|
||||||
null <!UNRESOLVED_REFERENCE!>in<!> System
|
null <!UNRESOLVED_REFERENCE!>in<!> System
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,8 +5,8 @@
|
|||||||
annotation class yield
|
annotation class yield
|
||||||
|
|
||||||
fun bar(p: Int) {
|
fun bar(p: Int) {
|
||||||
yield@ p
|
<!REDUNDANT_LABEL_WARNING!>yield@<!> p
|
||||||
`yield`@ p
|
<!REDUNDANT_LABEL_WARNING!>`yield`@<!> p
|
||||||
|
|
||||||
@yield() p
|
@yield() p
|
||||||
@`yield`() p
|
@`yield`() p
|
||||||
|
|||||||
+1
-1
@@ -21,7 +21,7 @@ fun <!UNDERSCORE_IS_RESERVED!>__<!>(<!UNDERSCORE_IS_RESERVED!>___<!>: Int, y: <!
|
|||||||
|
|
||||||
fun localFun(<!UNDERSCORE_IS_RESERVED!>_<!>: String) = 1
|
fun localFun(<!UNDERSCORE_IS_RESERVED!>_<!>: String) = 1
|
||||||
|
|
||||||
<!UNDERSCORE_IS_RESERVED!>__<!>@ return if (y != null) <!UNDERSCORE_USAGE_WITHOUT_BACKTICKS!>__<!>(<!UNDERSCORE_USAGE_WITHOUT_BACKTICKS!>____<!>, y) else <!UNDERSCORE_USAGE_WITHOUT_BACKTICKS!>__<!>(`_`, <!UNDERSCORE_USAGE_WITHOUT_BACKTICKS!>______<!>)
|
<!REDUNDANT_LABEL_WARNING!><!UNDERSCORE_IS_RESERVED!>__<!>@<!> return if (y != null) <!UNDERSCORE_USAGE_WITHOUT_BACKTICKS!>__<!>(<!UNDERSCORE_USAGE_WITHOUT_BACKTICKS!>____<!>, y) else <!UNDERSCORE_USAGE_WITHOUT_BACKTICKS!>__<!>(`_`, <!UNDERSCORE_USAGE_WITHOUT_BACKTICKS!>______<!>)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -12,7 +12,7 @@ fun test2() {
|
|||||||
<!UNREACHABLE_CODE!>bar(<!>11, todo()/*comment1*/, <!UNREACHABLE_CODE!>""/*comment2*/)<!>
|
<!UNREACHABLE_CODE!>bar(<!>11, todo()/*comment1*/, <!UNREACHABLE_CODE!>""/*comment2*/)<!>
|
||||||
}
|
}
|
||||||
fun test3() {
|
fun test3() {
|
||||||
<!UNREACHABLE_CODE!>bar(<!>11, <!UNREACHABLE_CODE!>l@(<!>todo()/*comment*/<!UNREACHABLE_CODE!>), "")<!>
|
<!UNREACHABLE_CODE!>bar(<!>11, <!UNREACHABLE_CODE!><!REDUNDANT_LABEL_WARNING!>l@<!>(<!>todo()/*comment*/<!UNREACHABLE_CODE!>), "")<!>
|
||||||
}
|
}
|
||||||
|
|
||||||
fun todo(): Nothing = throw Exception()
|
fun todo(): Nothing = throw Exception()
|
||||||
|
|||||||
Vendored
+1
-1
@@ -19,7 +19,7 @@ class TestObjectLiteral {
|
|||||||
val y = obj
|
val y = obj
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
val obj1: A = l@ ( object: A(obj1) {
|
val obj1: A = <!REDUNDANT_LABEL_WARNING!>l@<!> ( object: A(obj1) {
|
||||||
init {
|
init {
|
||||||
val x = obj1
|
val x = obj1
|
||||||
}
|
}
|
||||||
|
|||||||
+2
-2
@@ -51,12 +51,12 @@ fun testLoopLabelInReturn(xs: List<Int>) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun testValLabelInReturn() {
|
fun testValLabelInReturn() {
|
||||||
L@ val fn = { <!NOT_A_FUNCTION_LABEL!>return@L<!> }
|
<!REDUNDANT_LABEL_WARNING!>L@<!> val fn = { <!NOT_A_FUNCTION_LABEL!>return@L<!> }
|
||||||
fn()
|
fn()
|
||||||
}
|
}
|
||||||
|
|
||||||
fun testHighOrderFunctionCallLabelInReturn() {
|
fun testHighOrderFunctionCallLabelInReturn() {
|
||||||
L@ run {
|
<!REDUNDANT_LABEL_WARNING!>L@<!> run {
|
||||||
<!NOT_A_FUNCTION_LABEL!>return@L<!>
|
<!NOT_A_FUNCTION_LABEL!>return@L<!>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+2
-2
@@ -51,12 +51,12 @@ fun testLoopLabelInReturn(xs: List<Int>) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun testValLabelInReturn() {
|
fun testValLabelInReturn() {
|
||||||
L@ val fn = { <!NOT_A_FUNCTION_LABEL!>return@L<!> }
|
<!REDUNDANT_LABEL_WARNING!>L@<!> val fn = { <!NOT_A_FUNCTION_LABEL!>return@L<!> }
|
||||||
fn()
|
fn()
|
||||||
}
|
}
|
||||||
|
|
||||||
fun testHighOrderFunctionCallLabelInReturn() {
|
fun testHighOrderFunctionCallLabelInReturn() {
|
||||||
L@ run {
|
<!REDUNDANT_LABEL_WARNING!>L@<!> run {
|
||||||
<!NOT_A_FUNCTION_LABEL!>return@L<!>
|
<!NOT_A_FUNCTION_LABEL!>return@L<!>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,39 +0,0 @@
|
|||||||
@Target(AnnotationTarget.EXPRESSION)
|
|
||||||
@Retention(AnnotationRetention.SOURCE)
|
|
||||||
annotation class Ann
|
|
||||||
|
|
||||||
fun testLambdaLabel() = l@ { 42 }
|
|
||||||
|
|
||||||
fun testAnonymousFunctionLabel() = l@ fun() {}
|
|
||||||
|
|
||||||
fun testAnnotatedLambdaLabel() = lambda@ @Ann {}
|
|
||||||
|
|
||||||
fun testParenthesizedLambdaLabel() = lambda@ ( {} )
|
|
||||||
|
|
||||||
fun testLabelBoundToInvokeOperatorExpression() = l@ { 42 }()
|
|
||||||
|
|
||||||
fun testLabelBoundToLambda() = (l@ { 42 })()
|
|
||||||
|
|
||||||
fun testWhileLoopLabel() {
|
|
||||||
L@ while (true) {}
|
|
||||||
}
|
|
||||||
|
|
||||||
fun testDoWhileLoopLabel() {
|
|
||||||
L@ do {} while (true)
|
|
||||||
}
|
|
||||||
|
|
||||||
fun testForLoopLabel(xs: List<Any>) {
|
|
||||||
L@ for (x in xs) {}
|
|
||||||
}
|
|
||||||
|
|
||||||
fun testValLabel() {
|
|
||||||
L@ val fn = {}
|
|
||||||
fn()
|
|
||||||
}
|
|
||||||
|
|
||||||
fun testHighOrderFunctionCallLabel() {
|
|
||||||
L@ run {}
|
|
||||||
}
|
|
||||||
|
|
||||||
fun testAnonymousObjectLabel() =
|
|
||||||
L@ object {}
|
|
||||||
@@ -1,3 +1,4 @@
|
|||||||
|
// FIR_IDENTICAL
|
||||||
@Target(AnnotationTarget.EXPRESSION)
|
@Target(AnnotationTarget.EXPRESSION)
|
||||||
@Retention(AnnotationRetention.SOURCE)
|
@Retention(AnnotationRetention.SOURCE)
|
||||||
annotation class Ann
|
annotation class Ann
|
||||||
|
|||||||
Vendored
-11
@@ -1,11 +0,0 @@
|
|||||||
import kotlin.reflect.KProperty
|
|
||||||
|
|
||||||
class A3 {
|
|
||||||
val a: String by l@ MyProperty()
|
|
||||||
|
|
||||||
class MyProperty<T> {}
|
|
||||||
|
|
||||||
operator fun <T> MyProperty<T>.getValue(thisRef: Any?, desc: KProperty<*>): T {
|
|
||||||
throw Exception("$thisRef $desc")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Vendored
+1
@@ -1,3 +1,4 @@
|
|||||||
|
// FIR_IDENTICAL
|
||||||
import kotlin.reflect.KProperty
|
import kotlin.reflect.KProperty
|
||||||
|
|
||||||
class A3 {
|
class A3 {
|
||||||
|
|||||||
+1
-1
@@ -1,3 +1,3 @@
|
|||||||
fun test() {
|
fun test() {
|
||||||
(d@ val bar = 2)
|
(<!REDUNDANT_LABEL_WARNING!>d@<!> val bar = 2)
|
||||||
}
|
}
|
||||||
+5
-5
@@ -6,19 +6,19 @@ import checkSubtype
|
|||||||
|
|
||||||
fun test(i: Int?) {
|
fun test(i: Int?) {
|
||||||
if (i != null) {
|
if (i != null) {
|
||||||
foo(l1@ i)
|
foo(<!REDUNDANT_LABEL_WARNING!>l1@<!> i)
|
||||||
foo((i))
|
foo((i))
|
||||||
foo(l2@ (i))
|
foo(<!REDUNDANT_LABEL_WARNING!>l2@<!> (i))
|
||||||
foo((l3@ i))
|
foo((<!REDUNDANT_LABEL_WARNING!>l3@<!> i))
|
||||||
}
|
}
|
||||||
|
|
||||||
val a: Int = <!INITIALIZER_TYPE_MISMATCH!>l4@ ""<!>
|
val a: Int = <!INITIALIZER_TYPE_MISMATCH!><!REDUNDANT_LABEL_WARNING!>l4@<!> ""<!>
|
||||||
val b: Int = <!INITIALIZER_TYPE_MISMATCH!>("")<!>
|
val b: Int = <!INITIALIZER_TYPE_MISMATCH!>("")<!>
|
||||||
val c: Int = checkSubtype<Int>(<!ARGUMENT_TYPE_MISMATCH!>""<!>)
|
val c: Int = checkSubtype<Int>(<!ARGUMENT_TYPE_MISMATCH!>""<!>)
|
||||||
val d: Int = <!INITIALIZER_TYPE_MISMATCH!>checkSubtype<Long>(<!ARGUMENT_TYPE_MISMATCH!>""<!>)<!>
|
val d: Int = <!INITIALIZER_TYPE_MISMATCH!>checkSubtype<Long>(<!ARGUMENT_TYPE_MISMATCH!>""<!>)<!>
|
||||||
|
|
||||||
|
|
||||||
foo(l4@ <!ARGUMENT_TYPE_MISMATCH!>""<!>)
|
foo(<!REDUNDANT_LABEL_WARNING!>l4@<!> <!ARGUMENT_TYPE_MISMATCH!>""<!>)
|
||||||
foo((<!ARGUMENT_TYPE_MISMATCH!>""<!>))
|
foo((<!ARGUMENT_TYPE_MISMATCH!>""<!>))
|
||||||
foo(checkSubtype<Int>(<!ARGUMENT_TYPE_MISMATCH!>""<!>))
|
foo(checkSubtype<Int>(<!ARGUMENT_TYPE_MISMATCH!>""<!>))
|
||||||
foo(<!ARGUMENT_TYPE_MISMATCH!>checkSubtype<Long>(<!ARGUMENT_TYPE_MISMATCH!>""<!>)<!>)
|
foo(<!ARGUMENT_TYPE_MISMATCH!>checkSubtype<Long>(<!ARGUMENT_TYPE_MISMATCH!>""<!>)<!>)
|
||||||
|
|||||||
@@ -1,3 +0,0 @@
|
|||||||
fun f(s : String?) : Boolean {
|
|
||||||
return foo@(s?.equals("a"))!!
|
|
||||||
}
|
|
||||||
@@ -1,3 +1,4 @@
|
|||||||
|
// FIR_IDENTICAL
|
||||||
fun f(s : String?) : Boolean {
|
fun f(s : String?) : Boolean {
|
||||||
return <!REDUNDANT_LABEL_WARNING!>foo@<!>(s?.equals("a"))!!
|
return <!REDUNDANT_LABEL_WARNING!>foo@<!>(s?.equals("a"))!!
|
||||||
}
|
}
|
||||||
-22
@@ -1,22 +0,0 @@
|
|||||||
// !LANGUAGE: +ExpectedTypeFromCast
|
|
||||||
|
|
||||||
@Target(AnnotationTarget.EXPRESSION)
|
|
||||||
@Retention(AnnotationRetention.SOURCE)
|
|
||||||
annotation class bar
|
|
||||||
|
|
||||||
fun <T> foo(): T = TODO()
|
|
||||||
|
|
||||||
fun <V> id(value: V) = value
|
|
||||||
|
|
||||||
val par1 = (foo()) as String
|
|
||||||
val par2 = ((foo())) as String
|
|
||||||
|
|
||||||
val par3 = (dd@ (foo())) as String
|
|
||||||
|
|
||||||
val par4 = ( @bar() (foo())) as String
|
|
||||||
|
|
||||||
object X {
|
|
||||||
fun <T> foo(): T = TODO()
|
|
||||||
}
|
|
||||||
|
|
||||||
val par5 = ( @bar() X.foo()) as String
|
|
||||||
+1
@@ -1,3 +1,4 @@
|
|||||||
|
// FIR_IDENTICAL
|
||||||
// !LANGUAGE: +ExpectedTypeFromCast
|
// !LANGUAGE: +ExpectedTypeFromCast
|
||||||
|
|
||||||
@Target(AnnotationTarget.EXPRESSION)
|
@Target(AnnotationTarget.EXPRESSION)
|
||||||
|
|||||||
@@ -1,40 +0,0 @@
|
|||||||
// !DIAGNOSTICS: -UNUSED_EXPRESSION -UNUSED_PARAMETER -UNUSED_VARIABLE
|
|
||||||
|
|
||||||
inline fun foo(bar1: (String.() -> Int) -> Int, bar2: (()->Int) -> Int) {
|
|
||||||
bar1 label@ {
|
|
||||||
this@label.length
|
|
||||||
}
|
|
||||||
|
|
||||||
bar1 {
|
|
||||||
this.length
|
|
||||||
}
|
|
||||||
//unmute after KT-4247 fix
|
|
||||||
//bar1 {
|
|
||||||
// this@bar1.length
|
|
||||||
//}
|
|
||||||
|
|
||||||
bar2 l@ {
|
|
||||||
11
|
|
||||||
}
|
|
||||||
|
|
||||||
bar2 {
|
|
||||||
12
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
inline fun foo2(bar1: (String.() -> Int) -> Int) {
|
|
||||||
l1@ <!USAGE_IS_NOT_INLINABLE!>bar1<!>
|
|
||||||
|
|
||||||
l2@ bar1 {
|
|
||||||
11
|
|
||||||
}
|
|
||||||
|
|
||||||
(l3@ bar1) {
|
|
||||||
11
|
|
||||||
}
|
|
||||||
|
|
||||||
(l5@ (l4@ bar1)) {
|
|
||||||
11
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,3 +1,4 @@
|
|||||||
|
// FIR_IDENTICAL
|
||||||
// !DIAGNOSTICS: -UNUSED_EXPRESSION -UNUSED_PARAMETER -UNUSED_VARIABLE
|
// !DIAGNOSTICS: -UNUSED_EXPRESSION -UNUSED_PARAMETER -UNUSED_VARIABLE
|
||||||
|
|
||||||
inline fun foo(bar1: (String.() -> Int) -> Int, bar2: (()->Int) -> Int) {
|
inline fun foo(bar1: (String.() -> Int) -> Int, bar2: (()->Int) -> Int) {
|
||||||
|
|||||||
@@ -1,27 +0,0 @@
|
|||||||
// !CHECK_TYPE
|
|
||||||
|
|
||||||
inline fun inlineFunWithInvoke(s: (p: Int) -> Unit) {
|
|
||||||
(s)(11)
|
|
||||||
(s).invoke(11)
|
|
||||||
(s) <!INFIX_MODIFIER_REQUIRED!>invoke<!> 11
|
|
||||||
(<!USAGE_IS_NOT_INLINABLE!>s<!>)
|
|
||||||
}
|
|
||||||
|
|
||||||
<!NOTHING_TO_INLINE!>inline<!> fun Function1<Int, Unit>.inlineExt() {
|
|
||||||
(this).invoke(11)
|
|
||||||
(this) <!INFIX_MODIFIER_REQUIRED!>invoke<!> 11
|
|
||||||
(this)(11)
|
|
||||||
(this)
|
|
||||||
}
|
|
||||||
|
|
||||||
inline fun inlineFunWithInvoke2(s: (p: Int) -> Unit) {
|
|
||||||
(((s)))(11)
|
|
||||||
(((s))).invoke(11)
|
|
||||||
(((s))) <!INFIX_MODIFIER_REQUIRED!>invoke<!> 11
|
|
||||||
(((<!USAGE_IS_NOT_INLINABLE!>s<!>)))
|
|
||||||
}
|
|
||||||
|
|
||||||
inline fun propagation(s: (p: Int) -> Unit) {
|
|
||||||
inlineFunWithInvoke((label@ s))
|
|
||||||
inlineFunWithInvoke((label2@ label@ s))
|
|
||||||
}
|
|
||||||
@@ -1,3 +1,4 @@
|
|||||||
|
// FIR_IDENTICAL
|
||||||
// !CHECK_TYPE
|
// !CHECK_TYPE
|
||||||
|
|
||||||
inline fun inlineFunWithInvoke(s: (p: Int) -> Unit) {
|
inline fun inlineFunWithInvoke(s: (p: Int) -> Unit) {
|
||||||
|
|||||||
Vendored
+1
-1
@@ -32,7 +32,7 @@ fun main() {
|
|||||||
val w: Foo? = null
|
val w: Foo? = null
|
||||||
w<!UNSAFE_CALL!>.<!>f = z
|
w<!UNSAFE_CALL!>.<!>f = z
|
||||||
(w<!UNSAFE_CALL!>.<!>f) = z
|
(w<!UNSAFE_CALL!>.<!>f) = z
|
||||||
(label@ w<!UNSAFE_CALL!>.<!>f) = z
|
(<!REDUNDANT_LABEL_WARNING!>label@<!> w<!UNSAFE_CALL!>.<!>f) = z
|
||||||
w!!.f = z
|
w!!.f = z
|
||||||
w.f = z
|
w.f = z
|
||||||
w<!UNNECESSARY_NOT_NULL_ASSERTION!>!!<!>.f = z
|
w<!UNNECESSARY_NOT_NULL_ASSERTION!>!!<!>.f = z
|
||||||
|
|||||||
+2
-2
@@ -8,8 +8,8 @@ fun main() {
|
|||||||
val h : String = v--;
|
val h : String = v--;
|
||||||
val h1 : String = --v;
|
val h1 : String = --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!><!REDUNDANT_LABEL_WARNING!>foo@<!> true<!>;
|
||||||
val k : String = <!INITIALIZER_TYPE_MISMATCH!>foo@ bar@ true<!>;
|
val k : String = <!INITIALIZER_TYPE_MISMATCH!><!REDUNDANT_LABEL_WARNING!>foo@<!> <!REDUNDANT_LABEL_WARNING!>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<!>;
|
||||||
}
|
}
|
||||||
|
|||||||
-20
@@ -1,20 +0,0 @@
|
|||||||
interface Foo<T>
|
|
||||||
|
|
||||||
class Bar {
|
|
||||||
operator fun <T> invoke(): Foo<T> = throw Exception()
|
|
||||||
}
|
|
||||||
|
|
||||||
class A {
|
|
||||||
val bar = Bar()
|
|
||||||
}
|
|
||||||
|
|
||||||
fun fooInt(l: Foo<Int>) = l
|
|
||||||
|
|
||||||
fun test(bar: Bar, a: A) {
|
|
||||||
// no elements with error types
|
|
||||||
fooInt((bar()))
|
|
||||||
fooInt(if (true) bar() else bar())
|
|
||||||
fooInt(label@ bar())
|
|
||||||
fooInt(a.bar())
|
|
||||||
fooInt(((label@ if (true) (a.bar()) else bar())))
|
|
||||||
}
|
|
||||||
+1
@@ -1,3 +1,4 @@
|
|||||||
|
// FIR_IDENTICAL
|
||||||
interface Foo<T>
|
interface Foo<T>
|
||||||
|
|
||||||
class Bar {
|
class Bar {
|
||||||
|
|||||||
@@ -1,23 +0,0 @@
|
|||||||
fun testEquals(x: Int) {
|
|
||||||
if (<!SENSELESS_COMPARISON!>x == null<!>) {}
|
|
||||||
if (<!SENSELESS_COMPARISON!>x == (null)<!>) {}
|
|
||||||
if (<!SENSELESS_COMPARISON!>x == foo@ null<!>) {}
|
|
||||||
}
|
|
||||||
|
|
||||||
fun testEqualsFlipped(x: Int) {
|
|
||||||
if (<!SENSELESS_COMPARISON!>null == x<!>) {}
|
|
||||||
if (<!SENSELESS_COMPARISON!>(null) == x<!>) {}
|
|
||||||
if (<!SENSELESS_COMPARISON!>foo@ null == x<!>) {}
|
|
||||||
}
|
|
||||||
|
|
||||||
fun testNotEquals(x: Int) {
|
|
||||||
if (<!SENSELESS_COMPARISON!>x != null<!>) {}
|
|
||||||
if (<!SENSELESS_COMPARISON!>x != (null)<!>) {}
|
|
||||||
if (<!SENSELESS_COMPARISON!>x != foo@ null<!>) {}
|
|
||||||
}
|
|
||||||
|
|
||||||
fun testNotEqualsFlipped(x: Int) {
|
|
||||||
if (<!SENSELESS_COMPARISON!>null != x<!>) {}
|
|
||||||
if (<!SENSELESS_COMPARISON!>(null) != x<!>) {}
|
|
||||||
if (<!SENSELESS_COMPARISON!>foo@ null != x<!>) {}
|
|
||||||
}
|
|
||||||
@@ -1,3 +1,4 @@
|
|||||||
|
// FIR_IDENTICAL
|
||||||
fun testEquals(x: Int) {
|
fun testEquals(x: Int) {
|
||||||
if (<!SENSELESS_COMPARISON!>x == null<!>) {}
|
if (<!SENSELESS_COMPARISON!>x == null<!>) {}
|
||||||
if (<!SENSELESS_COMPARISON!>x == (null)<!>) {}
|
if (<!SENSELESS_COMPARISON!>x == (null)<!>) {}
|
||||||
|
|||||||
+1
-1
@@ -31,7 +31,7 @@ inline fun case_4(block: () -> Unit) {
|
|||||||
|
|
||||||
// TESTCASE NUMBER: 5
|
// TESTCASE NUMBER: 5
|
||||||
inline fun case_5(block: () -> Unit) {
|
inline fun case_5(block: () -> Unit) {
|
||||||
test@ contract {
|
<!REDUNDANT_LABEL_WARNING!>test@<!> contract {
|
||||||
callsInPlace(block, InvocationKind.EXACTLY_ONCE)
|
callsInPlace(block, InvocationKind.EXACTLY_ONCE)
|
||||||
}
|
}
|
||||||
return block()
|
return block()
|
||||||
|
|||||||
Reference in New Issue
Block a user