[FIR] Add REDUNDANT_NULLABLE diagnostics

This commit is contained in:
Ivan Kochurkin
2021-11-19 16:21:51 +03:00
committed by TeamCityServer
parent 4caf3c5e83
commit 51b73bb6ae
37 changed files with 233 additions and 87 deletions
@@ -1891,6 +1891,12 @@ internal val KT_DIAGNOSTIC_CONVERTER = KtDiagnosticConverterBuilder.buildConvert
token,
)
}
add(FirErrors.REDUNDANT_NULLABLE) { firDiagnostic ->
RedundantNullableImpl(
firDiagnostic as KtPsiDiagnostic,
token,
)
}
add(FirErrors.EXTENSION_IN_CLASS_REFERENCE_NOT_ALLOWED) { firDiagnostic ->
ExtensionInClassReferenceNotAllowedImpl(
firSymbolBuilder.callableBuilder.buildCallableSymbol(firDiagnostic.a.fir),
@@ -1348,6 +1348,10 @@ sealed class KtFirDiagnostic<PSI : PsiElement> : KtDiagnosticWithPsi<PSI> {
abstract val isCastToNotNull: Boolean
}
abstract class RedundantNullable : KtFirDiagnostic<KtTypeReference>() {
override val diagnosticClass get() = RedundantNullable::class
}
abstract class ExtensionInClassReferenceNotAllowed : KtFirDiagnostic<KtExpression>() {
override val diagnosticClass get() = ExtensionInClassReferenceNotAllowed::class
abstract val referencedDeclaration: KtCallableSymbol
@@ -1617,6 +1617,11 @@ internal class SmartcastImpossibleImpl(
override val token: ValidityToken,
) : KtFirDiagnostic.SmartcastImpossible(), KtAbstractFirDiagnostic<KtExpression>
internal class RedundantNullableImpl(
override val firDiagnostic: KtPsiDiagnostic,
override val token: ValidityToken,
) : KtFirDiagnostic.RedundantNullable(), KtAbstractFirDiagnostic<KtTypeReference>
internal class ExtensionInClassReferenceNotAllowedImpl(
override val referencedDeclaration: KtCallableSymbol,
override val firDiagnostic: KtPsiDiagnostic,
@@ -90,7 +90,7 @@ private object CheckersFactory {
}
private fun createTypeCheckers(useExtendedCheckers: Boolean): TypeCheckers? =
if (useExtendedCheckers) null else CommonTypeCheckers
if (useExtendedCheckers) ExtendedTypeCheckers else CommonTypeCheckers
@OptIn(ExperimentalStdlibApi::class)
@@ -655,6 +655,8 @@ object DIAGNOSTICS_LIST : DiagnosticList("FirErrors") {
parameter<String>("description")
parameter<Boolean>("isCastToNotNull")
}
val REDUNDANT_NULLABLE by warning<KtTypeReference>(PositioningStrategy.REDUNDANT_NULLABLE)
}
val REFLECTION by object : DiagnosticGroup("Reflection") {
@@ -111,6 +111,7 @@ enum class PositioningStrategy(private val strategy: String? = null) {
PROPERTY_DELEGATE,
IMPORT_ALIAS,
DECLARATION_START_TO_NAME,
REDUNDANT_NULLABLE,
;
@@ -395,6 +395,7 @@ object FirErrors {
val TYPE_VARIANCE_CONFLICT by error4<PsiElement, FirTypeParameterSymbol, Variance, Variance, ConeKotlinType>(SourceElementPositioningStrategies.DECLARATION_SIGNATURE_OR_DEFAULT)
val TYPE_VARIANCE_CONFLICT_IN_EXPANDED_TYPE by error4<PsiElement, FirTypeParameterSymbol, Variance, Variance, ConeKotlinType>(SourceElementPositioningStrategies.DECLARATION_SIGNATURE_OR_DEFAULT)
val SMARTCAST_IMPOSSIBLE by error4<KtExpression, ConeKotlinType, FirExpression, String, Boolean>()
val REDUNDANT_NULLABLE by warning0<KtTypeReference>(SourceElementPositioningStrategies.REDUNDANT_NULLABLE)
// Reflection
val EXTENSION_IN_CLASS_REFERENCE_NOT_ALLOWED by error1<KtExpression, FirCallableSymbol<*>>(SourceElementPositioningStrategies.REFERENCE_BY_QUALIFIED)
@@ -12,6 +12,6 @@ object CommonTypeCheckers : TypeCheckers() {
FirTypeAnnotationChecker,
FirSuspendModifierChecker,
FirDeprecatedTypeChecker,
FirOptInUsageTypeRefChecker,
FirOptInUsageTypeRefChecker
)
}
@@ -0,0 +1,15 @@
/*
* 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
import org.jetbrains.kotlin.fir.analysis.checkers.extended.RedundantNullableChecker
import org.jetbrains.kotlin.fir.analysis.checkers.type.*
object ExtendedTypeCheckers : TypeCheckers() {
override val typeRefCheckers: Set<FirTypeRefChecker> = setOf(
RedundantNullableChecker
)
}
@@ -6,13 +6,11 @@
package org.jetbrains.kotlin.fir.analysis.checkers
import com.intellij.lang.LighterASTNode
import com.intellij.openapi.util.Ref
import com.intellij.psi.PsiElement
import com.intellij.psi.PsiNameIdentifierOwner
import com.intellij.psi.impl.source.tree.LeafPsiElement
import org.jetbrains.kotlin.KtLightSourceElement
import org.jetbrains.kotlin.KtPsiSourceElement
import org.jetbrains.kotlin.KtSourceElement
import org.jetbrains.kotlin.KtNodeTypes
import org.jetbrains.kotlin.*
import org.jetbrains.kotlin.fir.FirElement
import org.jetbrains.kotlin.diagnostics.getAncestors
import org.jetbrains.kotlin.diagnostics.nameIdentifier
@@ -40,6 +38,8 @@ interface SourceNavigator {
fun FirValueParameterSymbol.isCatchElementParameter(): Boolean
fun FirTypeRef.isRedundantNullable(): Boolean
companion object {
private val lightTreeInstance = LightTreeSourceNavigator()
@@ -90,6 +90,19 @@ open class LightTreeSourceNavigator : SourceNavigator {
return source?.getParentOfParent()?.tokenType == KtNodeTypes.CATCH
}
override fun FirTypeRef.isRedundantNullable(): Boolean {
val source = source ?: return false
val ref = Ref<Array<LighterASTNode?>>()
val firstChild = getNullableChild(source, source.lighterASTNode, ref) ?: return false
return getNullableChild(source, firstChild, ref) != null
}
private fun getNullableChild(source: KtSourceElement, node: LighterASTNode, ref: Ref<Array<LighterASTNode?>>): LighterASTNode? {
source.treeStructure.getChildren(node, ref)
val firstChild = ref.get().firstOrNull() ?: return null
return if (firstChild.tokenType != KtNodeTypes.NULLABLE_TYPE) null else firstChild
}
private fun KtSourceElement?.getParentOfParent(): LighterASTNode? {
val source = this ?: return null
var parent = source.treeStructure.getParent(source.lighterASTNode)
@@ -131,4 +144,11 @@ object PsiSourceNavigator : LightTreeSourceNavigator() {
override fun FirValueParameterSymbol.isCatchElementParameter(): Boolean {
return source?.psi<PsiElement>()?.parent?.parent is KtCatchClause
}
override fun FirTypeRef.isRedundantNullable(): Boolean {
val source = source ?: return false
val typeReference = (source.psi as? KtTypeReference) ?: return false
val typeElement = typeReference.typeElement as? KtNullableType ?: return false
return typeElement.innerType is KtNullableType
}
}
@@ -0,0 +1,41 @@
/*
* 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.extended
import org.jetbrains.kotlin.diagnostics.DiagnosticReporter
import org.jetbrains.kotlin.diagnostics.reportOn
import org.jetbrains.kotlin.fir.analysis.checkers.SourceNavigator
import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext
import org.jetbrains.kotlin.fir.analysis.checkers.toClassLikeSymbol
import org.jetbrains.kotlin.fir.analysis.checkers.type.FirTypeRefChecker
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.REDUNDANT_NULLABLE
import org.jetbrains.kotlin.fir.symbols.impl.FirTypeAliasSymbol
import org.jetbrains.kotlin.fir.types.*
object RedundantNullableChecker : FirTypeRefChecker() {
override fun check(typeRef: FirTypeRef, context: CheckerContext, reporter: DiagnosticReporter) {
if (typeRef !is FirResolvedTypeRef || typeRef.isMarkedNullable != true) return
var symbol = typeRef.toClassLikeSymbol(context.session)
if (symbol is FirTypeAliasSymbol) {
while (symbol is FirTypeAliasSymbol) {
val resolvedExpandedTypeRef = symbol.resolvedExpandedTypeRef
if (resolvedExpandedTypeRef.type.isMarkedNullable) {
reporter.reportOn(typeRef.source, REDUNDANT_NULLABLE, context)
break
} else {
symbol = resolvedExpandedTypeRef.toClassLikeSymbol(context.session)
}
}
} else {
with(SourceNavigator.forElement(typeRef)) {
if (typeRef.isRedundantNullable()) {
reporter.reportOn(typeRef.source, REDUNDANT_NULLABLE, context)
}
}
}
}
}
@@ -236,14 +236,7 @@ import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.INFIX_MODIFIER_RE
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.INITIALIZATION_BEFORE_DECLARATION
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.INITIALIZER_REQUIRED_FOR_DESTRUCTURING_DECLARATION
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.INITIALIZER_TYPE_MISMATCH
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.VALUE_CLASS_CANNOT_BE_RECURSIVE
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.VALUE_CLASS_CANNOT_EXTEND_CLASSES
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.VALUE_CLASS_CANNOT_IMPLEMENT_INTERFACE_BY_DELEGATION
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.VALUE_CLASS_CONSTRUCTOR_NOT_FINAL_READ_ONLY_PARAMETER
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.INLINE_CLASS_CONSTRUCTOR_WRONG_PARAMETERS_SIZE
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.VALUE_CLASS_HAS_INAPPLICABLE_PARAMETER_TYPE
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.VALUE_CLASS_NOT_FINAL
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.VALUE_CLASS_NOT_TOP_LEVEL
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.INLINE_PROPERTY_WITH_BACKING_FIELD
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.INLINE_SUSPEND_FUNCTION_TYPE_UNSUPPORTED
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.INNER_CLASS_INSIDE_VALUE_CLASS
@@ -394,6 +387,7 @@ import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.REDUNDANT_LABEL_W
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_FOR_TARGET
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.REDUNDANT_NULLABLE
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.REDUNDANT_OPEN_IN_INTERFACE
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.REDUNDANT_PROJECTION
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.REDUNDANT_RETURN_UNIT_TYPE
@@ -501,6 +495,13 @@ import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.USELESS_ELVIS_RIG
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.USELESS_IS_CHECK
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.USELESS_VARARG_ON_PARAMETER
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.VALUE_CLASS_CANNOT_BE_CLONEABLE
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.VALUE_CLASS_CANNOT_BE_RECURSIVE
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.VALUE_CLASS_CANNOT_EXTEND_CLASSES
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.VALUE_CLASS_CANNOT_IMPLEMENT_INTERFACE_BY_DELEGATION
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.VALUE_CLASS_CONSTRUCTOR_NOT_FINAL_READ_ONLY_PARAMETER
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.VALUE_CLASS_HAS_INAPPLICABLE_PARAMETER_TYPE
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.VALUE_CLASS_NOT_FINAL
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.VALUE_CLASS_NOT_TOP_LEVEL
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.VALUE_PARAMETER_WITH_NO_TYPE_ANNOTATION
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.VAL_OR_VAR_ON_CATCH_PARAMETER
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.VAL_OR_VAR_ON_FUN_PARAMETER
@@ -622,6 +623,7 @@ object FirErrorsDefaultMessages : BaseDiagnosticRendererFactory() {
map.put(SUPERTYPE_IS_EXTENSION_FUNCTION_TYPE, "Extension function type is not allowed as supertypes")
map.put(SINGLETON_IN_SUPERTYPE, "Cannot inherit from a singleton")
map.put(NULLABLE_SUPERTYPE, "A supertype cannot be nullable")
map.put(REDUNDANT_NULLABLE, "Redundant '?'")
map.put(MANY_CLASSES_IN_SUPERTYPE_LIST, "Only one class may appear in a supertype list")
map.put(SUPERTYPE_APPEARS_TWICE, "A supertype appears twice")
map.put(CLASS_IN_SUPERTYPE_FOR_ENUM, "Enum class cannot inherit from classes")
@@ -19,6 +19,7 @@ fun FirSessionFactory.FirSessionConfigurator.registerCommonCheckers() {
fun FirSessionFactory.FirSessionConfigurator.registerExtendedCommonCheckers() {
useCheckers(ExtendedExpressionCheckers)
useCheckers(ExtendedDeclarationCheckers)
useCheckers(ExtendedTypeCheckers)
}
fun FirSessionFactory.FirSessionConfigurator.registerJvmCheckers() {
@@ -62,20 +62,20 @@ fun FirExpression.isStableSmartcast(): Boolean {
return this is FirExpressionWithSmartcast && this.isStable
}
private val FirTypeRef.classLikeTypeOrNull: ConeClassLikeType?
private val FirTypeRef.lookupTagBasedOrNull: ConeLookupTagBasedType?
get() = when (this) {
is FirImplicitBuiltinTypeRef -> type
is FirResolvedTypeRef -> type as? ConeClassLikeType
is FirResolvedTypeRef -> type as? ConeLookupTagBasedType
else -> null
}
private fun FirTypeRef.isBuiltinType(classId: ClassId, isNullable: Boolean): Boolean {
val type = this.classLikeTypeOrNull ?: return false
return type.lookupTag.classId == classId && type.isNullable == isNullable
val type = this.lookupTagBasedOrNull ?: return false
return (type as? ConeClassLikeType)?.lookupTag?.classId == classId && type.isNullable == isNullable
}
val FirTypeRef.isMarkedNullable: Boolean?
get() = classLikeTypeOrNull?.isMarkedNullable
get() = if (this is FirTypeRefWithNullability) this.isMarkedNullable else lookupTagBasedOrNull?.isMarkedNullable
val FirFunctionTypeRef.parametersCount: Int
get() = if (receiverTypeRef != null)
@@ -14,7 +14,6 @@ import com.intellij.util.diff.FlyweightCapableTreeStructure
import org.jetbrains.kotlin.KtNodeType
import org.jetbrains.kotlin.KtNodeTypes
import org.jetbrains.kotlin.KtSourceElement
import org.jetbrains.kotlin.diagnostics.PositioningStrategies
import org.jetbrains.kotlin.lexer.KtTokens
import org.jetbrains.kotlin.lexer.KtTokens.MODALITY_MODIFIERS
import org.jetbrains.kotlin.lexer.KtTokens.VISIBILITY_MODIFIERS
@@ -827,6 +826,40 @@ object LightTreePositioningStrategies {
}
}
val REDUNDANT_NULLABLE: LightTreePositioningStrategy = object : LightTreePositioningStrategy() {
override fun mark(
node: LighterASTNode,
startOffset: Int,
endOffset: Int,
tree: FlyweightCapableTreeStructure<LighterASTNode>
): List<TextRange> {
val ref = Ref<Array<LighterASTNode?>>()
var child: LighterASTNode? = node
var lastQuest: LighterASTNode? = null
var prevQuest: LighterASTNode? = null
var quest: LighterASTNode? = null
while (child != null) {
child = getNullableChild(tree, child, ref)
prevQuest = quest
quest = ref.get().elementAtOrNull(1)
if (lastQuest == null) {
lastQuest = quest
}
}
return markRange(prevQuest ?: lastQuest ?: node, lastQuest ?: node, startOffset, endOffset, tree, node)
}
private fun getNullableChild(
tree: FlyweightCapableTreeStructure<LighterASTNode>,
node: LighterASTNode,
ref: Ref<Array<LighterASTNode?>>
): LighterASTNode? {
tree.getChildren(node, ref)
val firstChild = ref.get().firstOrNull() ?: return null
return if (firstChild.tokenType != KtNodeTypes.NULLABLE_TYPE) null else firstChild
}
}
val QUESTION_MARK_BY_TYPE: LightTreePositioningStrategy = object : LightTreePositioningStrategy() {
override fun mark(
node: LighterASTNode,
@@ -1154,6 +1187,7 @@ private fun FlyweightCapableTreeStructure<LighterASTNode>.referenceExpression(
}
return result
}
fun FlyweightCapableTreeStructure<LighterASTNode>.unwrapParenthesesLabelsAndAnnotations(node: LighterASTNode): LighterASTNode {
var unwrapped = node
while (true) {
@@ -5,6 +5,7 @@
package org.jetbrains.kotlin.diagnostics
import com.intellij.lang.ASTNode
import com.intellij.openapi.util.TextRange
import com.intellij.psi.*
import com.intellij.psi.tree.TokenSet
@@ -549,6 +550,30 @@ object PositioningStrategies {
}
}
@JvmField
val REDUNDANT_NULLABLE: PositioningStrategy<KtTypeReference> = object : PositioningStrategy<KtTypeReference>() {
override fun mark(element: KtTypeReference): List<TextRange> {
var typeElement = element.typeElement
var question: ASTNode? = null
var prevQuestion: ASTNode? = null
var lastQuestion: ASTNode? = null
while (typeElement is KtNullableType) {
prevQuestion = question
question = typeElement.questionMarkNode
if (lastQuestion == null) {
lastQuestion = question
}
typeElement = typeElement.innerType
}
if (lastQuestion != null) {
return markRange((prevQuestion ?: lastQuestion).psi, lastQuestion.psi)
}
return super.mark(element)
}
}
@JvmField
val NULLABLE_TYPE: PositioningStrategy<KtNullableType> = object : PositioningStrategy<KtNullableType>() {
override fun mark(element: KtNullableType): List<TextRange> {
@@ -248,6 +248,11 @@ object SourceElementPositioningStrategies {
PositioningStrategies.NAME_IDENTIFIER
)
val REDUNDANT_NULLABLE = SourceElementPositioningStrategy(
LightTreePositioningStrategies.REDUNDANT_NULLABLE,
PositioningStrategies.REDUNDANT_NULLABLE
)
val QUESTION_MARK_BY_TYPE = SourceElementPositioningStrategy(
LightTreePositioningStrategies.QUESTION_MARK_BY_TYPE,
PositioningStrategies.QUESTION_MARK_BY_TYPE
@@ -1,6 +1,7 @@
// WITH_EXTENDED_CHECKERS
interface A<T> {}
interface B<T> {}
interface C<T> {}
interface D<T> {}
interface Test : A<<!PROJECTION_IN_IMMEDIATE_ARGUMENT_TO_SUPERTYPE!>in<!> Int>, B<<!PROJECTION_IN_IMMEDIATE_ARGUMENT_TO_SUPERTYPE!>out<!> Int>, C<<!PROJECTION_IN_IMMEDIATE_ARGUMENT_TO_SUPERTYPE!>*<!>>??<!NULLABLE_SUPERTYPE!>?<!>, D<Int> {}
interface Test : A<<!PROJECTION_IN_IMMEDIATE_ARGUMENT_TO_SUPERTYPE!>in<!> Int>, B<<!PROJECTION_IN_IMMEDIATE_ARGUMENT_TO_SUPERTYPE!>out<!> Int>, C<<!PROJECTION_IN_IMMEDIATE_ARGUMENT_TO_SUPERTYPE!>*<!>>?<!REDUNDANT_NULLABLE!>?<!NULLABLE_SUPERTYPE!>?<!><!>, D<Int> {}
@@ -1,4 +0,0 @@
interface B<T>
class G<T>: B<T>
fun f(b: B<String>?) = b is G??
@@ -1,3 +1,5 @@
// FIR_IDENTICAL
// WITH_EXTENDED_CHECKERS
interface B<T>
class G<T>: B<T>
@@ -1,13 +0,0 @@
fun <NN: Any, NNN: NN> nonMisleadingNullable(
nn: NN?,
nnn: NNN?
) {}
fun <T, N: T, INDIRECT: N> misleadingNullableSimple(
t: T?,
t2: T?,
n: N?,
ind: INDIRECT?
) {}
fun <T> interactionWithRedundant(t: T??) {}
@@ -1,3 +1,5 @@
// FIR_IDENTICAL
// WITH_EXTENDED_CHECKERS
fun <NN: Any, NNN: NN> nonMisleadingNullable(
nn: NN?,
nnn: NNN?
@@ -1,9 +1,10 @@
// WITH_EXTENDED_CHECKERS
class Generic<T>
fun redundantNullable(
i: Int??,
three: Int???,
gOut: Generic<Int>??,
gIn: Generic<Int??>
i: Int?<!REDUNDANT_NULLABLE!>?<!>,
three: Int?<!REDUNDANT_NULLABLE!>??<!>,
gOut: Generic<Int>?<!REDUNDANT_NULLABLE!>?<!>,
gIn: Generic<Int?<!REDUNDANT_NULLABLE!>?<!>>
) {
}
@@ -1,9 +1,10 @@
// WITH_EXTENDED_CHECKERS
interface A
interface X: A?<!NULLABLE_SUPERTYPE!>?<!> {
interface X: A?<!NULLABLE_SUPERTYPE, REDUNDANT_NULLABLE!>?<!> {
}
fun <T> interaction(t: T) {
if (t == null) {}
}
}
@@ -1,19 +0,0 @@
@Target(AnnotationTarget.TYPE)
annotation class Ann
typealias TString = String
typealias TNString = TString?
typealias TNAString = @Ann TString?
val test1: TNString = TODO()
val test2: TNAString = TODO()
val test3: List<TNString> = TODO()
val test4: List<TNAString> = TODO()
val test5: List<TNString?> = TODO()
val test6: () -> List<TNString> = TODO()
fun test(x: TNString) {
x<!UNSAFE_CALL!>.<!>hashCode()
}
@@ -1,3 +1,5 @@
// FIR_IDENTICAL
// WITH_EXTENDED_CHECKERS
@Target(AnnotationTarget.TYPE)
annotation class Ann
@@ -1,6 +1,7 @@
// !LANGUAGE: +NewInference
// !DIAGNOSTICS: -UNUSED_EXPRESSION
// !DIAGNOSTICS: -UNUSED_EXPRESSION -UNUSED_VARIABLE
// SKIP_TXT
// WITH_EXTENDED_CHECKERS
// TESTCASE NUMBER: 1
fun case_1(x: Any?) {
@@ -108,7 +109,7 @@ fun case_8(x: TypealiasNullableString) {
}
// TESTCASE NUMBER: 9
fun case_9(x: TypealiasNullableString?) {
fun case_9(x: TypealiasNullableString<!REDUNDANT_NULLABLE!>?<!>) {
if (<!SENSELESS_COMPARISON!>x === null === null<!>) {
} else if (<!USELESS_IS_CHECK!>false is Boolean<!>) {
@@ -138,7 +139,7 @@ fun case_10() {
}
// TESTCASE NUMBER: 11
fun case_11(x: TypealiasNullableStringIndirect?, y: TypealiasNullableStringIndirect) {
fun case_11(x: TypealiasNullableStringIndirect<!REDUNDANT_NULLABLE!>?<!>, y: TypealiasNullableStringIndirect) {
val t: TypealiasNullableStringIndirect = null
if (<!EQUALITY_NOT_APPLICABLE!>x == null is Boolean<!>) {
@@ -1,6 +1,7 @@
// !LANGUAGE: +NewInference
// !DIAGNOSTICS: -UNUSED_EXPRESSION
// !DIAGNOSTICS: -UNUSED_EXPRESSION -UNREACHABLE_CODE
// SKIP_TXT
// WITH_EXTENDED_CHECKERS
// TESTCASE NUMBER: 1
fun case_1(x: Nothing?) {
@@ -68,7 +69,7 @@ fun case_8(x: Nothing?) {
// TESTCASE NUMBER: 9
fun case_9(x: Nothing?) {
if (!!(<!USELESS_IS_CHECK!>x !is TypealiasNullableStringIndirect?<!>)) else {
if (!!(<!USELESS_IS_CHECK!>x !is TypealiasNullableStringIndirect<!REDUNDANT_NULLABLE!>?<!><!>)) else {
<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Nothing?")!>x<!>
<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Nothing?")!>x<!>?.<!UNRESOLVED_REFERENCE!>length<!>
}
@@ -1,6 +1,7 @@
// !LANGUAGE: +NewInference
// !DIAGNOSTICS: -UNUSED_EXPRESSION
// SKIP_TXT
// WITH_EXTENDED_CHECKERS
// TESTCASE NUMBER: 1
fun case_1(x: Any?) {
@@ -70,8 +71,8 @@ fun case_8(x: Any?) {
// TESTCASE NUMBER: 9
fun case_9(x: Any?) {
if (!!!(x !is TypealiasNullableStringIndirect?)) else {
if (!(x !is TypealiasNullableStringIndirect?)) else {
if (!!!(x !is TypealiasNullableStringIndirect<!REDUNDANT_NULLABLE!>?<!>)) else {
if (!(x !is TypealiasNullableStringIndirect<!REDUNDANT_NULLABLE!>?<!>)) else {
<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Any?")!>x<!>
<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Any?")!>x<!>?.<!UNRESOLVED_REFERENCE!>get<!>(0)
}
@@ -1,6 +1,7 @@
// !LANGUAGE: +NewInference
// !DIAGNOSTICS: -UNUSED_EXPRESSION
// SKIP_TXT
// TODO: https://youtrack.jetbrains.com/issue/KT-49862
/*
* KOTLIN DIAGNOSTICS NOT LINKED SPEC TEST (POSITIVE)
@@ -1,6 +1,7 @@
// !LANGUAGE: +NewInference
// !DIAGNOSTICS: -UNUSED_EXPRESSION
// SKIP_TXT
// WITH_EXTENDED_CHECKERS
// TESTCASE NUMBER: 1
fun case_1(x: Any?) {
@@ -68,7 +69,7 @@ fun case_8(x: Any?) {
// TESTCASE NUMBER: 9
fun case_9(x: Any?) {
if (!!(x !is TypealiasNullableStringIndirect?)) else {
if (!!(x !is TypealiasNullableStringIndirect<!REDUNDANT_NULLABLE!>?<!>)) else {
<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Any? & TypealiasNullableStringIndirect?")!>x<!>
<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Any? & TypealiasNullableStringIndirect?")!>x<!>?.get(0)
}
@@ -1,6 +1,7 @@
// !LANGUAGE: +NewInference
// !DIAGNOSTICS: -UNUSED_EXPRESSION
// SKIP_TXT
// WITH_EXTENDED_CHECKERS
// TESTCASE NUMBER: 1
fun case_1(x: Any?) {
@@ -80,7 +81,7 @@ fun case_8(x: Any?) {
* ISSUES: KT-28329
*/
fun case_9(x: Any?) {
if (true && true && !!(x !is TypealiasNullableStringIndirect?) && true && true && true && true) else {
if (true && true && !!(x !is TypealiasNullableStringIndirect<!REDUNDANT_NULLABLE!>?<!>) && true && true && true && true) else {
<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Any?")!>x<!>
<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Any?")!>x<!>?.<!UNRESOLVED_REFERENCE!>get<!>(0)
}
@@ -1,6 +1,7 @@
// !LANGUAGE: +NewInference
// !DIAGNOSTICS: -UNUSED_EXPRESSION
// SKIP_TXT
// WITH_EXTENDED_CHECKERS
// TESTCASE NUMBER: 1
fun case_1(x: Any?) {
@@ -84,7 +85,7 @@ fun case_8(x: Any?) {
* ISSUES: KT-28329
*/
fun case_9(x: Any?) {
if (!!(x !is TypealiasNullableStringIndirect?) !== false === true) else {
if (!!(x !is TypealiasNullableStringIndirect<!REDUNDANT_NULLABLE!>?<!>) !== false === true) else {
<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Any? & TypealiasNullableStringIndirect?")!>x<!>
<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Any? & TypealiasNullableStringIndirect?")!>x<!>?.get(0)
}
@@ -1,6 +1,7 @@
// !LANGUAGE: +NewInference
// !DIAGNOSTICS: -UNUSED_EXPRESSION
// SKIP_TXT
// WITH_EXTENDED_CHECKERS
// TESTCASE NUMBER: 1
fun case_1(x: Any?) {
@@ -84,8 +85,8 @@ fun case_8(x: Any?) {
// TESTCASE NUMBER: 9
fun case_9(x: Any?) {
if (!!!(x !is TypealiasNullableStringIndirect?)) else {
if (!!(x !is TypealiasNullableStringIndirect?)) else {
if (!!!(x !is TypealiasNullableStringIndirect<!REDUNDANT_NULLABLE!>?<!>)) else {
if (!!(x !is TypealiasNullableStringIndirect<!REDUNDANT_NULLABLE!>?<!>)) else {
<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Any? & TypealiasNullableStringIndirect?")!>x<!>
<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Any? & TypealiasNullableStringIndirect?")!>x<!>?.get(0)
}
@@ -1,6 +1,7 @@
// !LANGUAGE: +NewInference
// !DIAGNOSTICS: -UNUSED_EXPRESSION
// !DIAGNOSTICS: -UNUSED_EXPRESSION -UNUSED_VARIABLE
// SKIP_TXT
// WITH_EXTENDED_CHECKERS
// FILE: other_package.kt
@@ -76,7 +77,7 @@ fun case_8(x: TypealiasNullableString) {
* UNEXPECTED BEHAVIOUR
* ISSUES: KT-28329
*/
fun case_9(x: TypealiasNullableString?) {
fun case_9(x: TypealiasNullableString<!REDUNDANT_NULLABLE!>?<!>) {
if (true && true && true && true && x !== null) {
} else if (false) {
@@ -96,7 +97,7 @@ fun case_10() {
}
// TESTCASE NUMBER: 11
fun case_11(x: TypealiasNullableString?, y: TypealiasNullableString) {
fun case_11(x: TypealiasNullableString<!REDUNDANT_NULLABLE!>?<!>, y: TypealiasNullableString) {
val z: TypealiasNullableString = null
if (x != null) {
@@ -1,7 +1,8 @@
// FIR_IGNORE
// !LANGUAGE: +NewInference
// !DIAGNOSTICS: -UNUSED_EXPRESSION
// !DIAGNOSTICS: -UNUSED_EXPRESSION -UNUSED_VARIABLE -UNREACHABLE_CODE -CAN_BE_VAL
// SKIP_TXT
// WITH_EXTENDED_CHECKERS
// FILE: other_types.kt
@@ -153,7 +154,7 @@ fun case_8(x: TypealiasNullableString) {
}
// TESTCASE NUMBER: 9
fun case_9(x: TypealiasNullableString?, y: Nothing?) {
fun case_9(x: TypealiasNullableString<!REDUNDANT_NULLABLE!>?<!>, y: Nothing?) {
if (x === y) {
} else if (false) {
@@ -192,7 +193,7 @@ fun case_10() {
}
// TESTCASE NUMBER: 11
fun case_11(x: TypealiasNullableString?, y: TypealiasNullableString) {
fun case_11(x: TypealiasNullableString<!REDUNDANT_NULLABLE!>?<!>, y: TypealiasNullableString) {
val z = null
val u: TypealiasNullableString = null
val v = null
@@ -253,7 +254,7 @@ fun case_13(x: EmptyClass12_48?, z: Nothing?) =
// TESTCASE NUMBER: 14
class Case14 {
val x: TypealiasNullableString?
val x: TypealiasNullableString<!REDUNDANT_NULLABLE!>?<!>
init {
x = TypealiasNullableString()
}
@@ -800,7 +801,7 @@ fun case_43(x: TypealiasNullableString) {
* UNEXPECTED BEHAVIOUR
* ISSUES: KT-28329
*/
fun case_44(x: TypealiasNullableString?, z1: Nothing?) {
fun case_44(x: TypealiasNullableString<!REDUNDANT_NULLABLE!>?<!>, z1: Nothing?) {
if (true && true && true && true && x !== z1) {
} else if (false) {
@@ -831,7 +832,7 @@ fun case_45() {
}
// TESTCASE NUMBER: 46
fun case_46(x: TypealiasNullableString?, y: TypealiasNullableString) {
fun case_46(x: TypealiasNullableString<!REDUNDANT_NULLABLE!>?<!>, y: TypealiasNullableString) {
val t: TypealiasNullableString = null
var z: Nothing? = null
@@ -879,7 +880,7 @@ fun case_48(x: EmptyClass12_48?, z: Nothing?) =
// TESTCASE NUMBER: 49
class Case49 {
val x: TypealiasNullableString?
val x: TypealiasNullableString<!REDUNDANT_NULLABLE!>?<!>
init {
x = TypealiasNullableString()
}
@@ -1,6 +1,7 @@
// !LANGUAGE: +NewInference
// !DIAGNOSTICS: -UNUSED_EXPRESSION
// !DIAGNOSTICS: -UNUSED_EXPRESSION -UNUSED_VARIABLE -UNREACHABLE_CODE -CAN_BE_VAL
// SKIP_TXT
// WITH_EXTENDED_CHECKERS
// FILE: other_package.kt
@@ -146,7 +147,7 @@ fun case_8(x: TypealiasString) {
}
// TESTCASE NUMBER: 9
fun case_9(x: TypealiasNullableString?) {
fun case_9(x: TypealiasNullableString<!REDUNDANT_NULLABLE!>?<!>) {
if (x === null && <!SENSELESS_COMPARISON!>x === null<!> || <!SENSELESS_COMPARISON!>x === null<!>) {
} else if (<!SENSELESS_COMPARISON!>x === null<!> || <!SENSELESS_COMPARISON!>x === null<!>) {
@@ -185,7 +186,7 @@ fun case_10() {
}
// TESTCASE NUMBER: 11
fun case_11(x: TypealiasNullableString?, y: TypealiasNullableString) {
fun case_11(x: TypealiasNullableString<!REDUNDANT_NULLABLE!>?<!>, y: TypealiasNullableString) {
val t: TypealiasNullableString = null
if (x == null) {