From b9d2a1842ade46d08afcaaec30b729930d25660a Mon Sep 17 00:00:00 2001 From: "Denis.Zharkov" Date: Tue, 6 Apr 2021 17:41:32 +0300 Subject: [PATCH] Support definitely-not-null generic T!! types in Parsing and FE1.0 ^KT-26245 In Progress --- .../fir/FirLoadCompiledKotlinGenerated.java | 5 + ...irOldFrontendDiagnosticsTestGenerated.java | 40 ++++ .../converter/DeclarationsConverter.kt | 22 ++ .../kotlin/fir/builder/RawFirBuilder.kt | 7 +- .../jetbrains/kotlin/diagnostics/Errors.java | 2 + .../rendering/DefaultErrorMessages.java | 2 + .../jetbrains/kotlin/resolve/TypeResolver.kt | 66 ++++-- .../src/org/jetbrains/kotlin/KtNodeTypes.java | 1 + .../kotlin/parsing/KotlinParsing.java | 6 + .../kotlin/psi/KtDefinitelyNotNullType.kt | 35 +++ .../org/jetbrains/kotlin/psi/KtVisitor.java | 4 + .../jetbrains/kotlin/psi/KtVisitorVoid.java | 10 + .../stubs/elements/KtStubElementTypes.java | 5 +- .../disabledFeature.fir.kt | 3 + .../disabledFeature.kt | 3 + .../disabledFeature.txt | 4 + .../notApplicable.fir.kt | 12 + .../notApplicable.kt | 12 + .../notApplicable.txt | 16 ++ .../overrides.fir.kt | 36 +++ .../explicitDefinitelyNotNull/overrides.kt | 36 +++ .../explicitDefinitelyNotNull/overrides.txt | 61 +++++ .../overridesJavaAnnotated.fir.kt | 42 ++++ .../overridesJavaAnnotated.kt | 42 ++++ .../overridesJavaAnnotated.txt | 61 +++++ .../explicitDefinitelyNotNull/simple.fir.kt | 14 ++ .../tests/explicitDefinitelyNotNull/simple.kt | 14 ++ .../explicitDefinitelyNotNull/simple.txt | 4 + .../testData/psi/DefinitelyNotNullType.kt | 5 + .../testData/psi/DefinitelyNotNullType.txt | 210 ++++++++++++++++++ .../test/runners/DiagnosticTestGenerated.java | 40 ++++ .../kotlin/parsing/ParsingTestGenerated.java | 5 + .../kotlin/config/LanguageVersionSettings.kt | 5 +- .../jetbrains/kotlin/types/SpecialTypes.kt | 2 +- 34 files changed, 815 insertions(+), 17 deletions(-) create mode 100644 compiler/psi/src/org/jetbrains/kotlin/psi/KtDefinitelyNotNullType.kt create mode 100644 compiler/testData/diagnostics/tests/explicitDefinitelyNotNull/disabledFeature.fir.kt create mode 100644 compiler/testData/diagnostics/tests/explicitDefinitelyNotNull/disabledFeature.kt create mode 100644 compiler/testData/diagnostics/tests/explicitDefinitelyNotNull/disabledFeature.txt create mode 100644 compiler/testData/diagnostics/tests/explicitDefinitelyNotNull/notApplicable.fir.kt create mode 100644 compiler/testData/diagnostics/tests/explicitDefinitelyNotNull/notApplicable.kt create mode 100644 compiler/testData/diagnostics/tests/explicitDefinitelyNotNull/notApplicable.txt create mode 100644 compiler/testData/diagnostics/tests/explicitDefinitelyNotNull/overrides.fir.kt create mode 100644 compiler/testData/diagnostics/tests/explicitDefinitelyNotNull/overrides.kt create mode 100644 compiler/testData/diagnostics/tests/explicitDefinitelyNotNull/overrides.txt create mode 100644 compiler/testData/diagnostics/tests/explicitDefinitelyNotNull/overridesJavaAnnotated.fir.kt create mode 100644 compiler/testData/diagnostics/tests/explicitDefinitelyNotNull/overridesJavaAnnotated.kt create mode 100644 compiler/testData/diagnostics/tests/explicitDefinitelyNotNull/overridesJavaAnnotated.txt create mode 100644 compiler/testData/diagnostics/tests/explicitDefinitelyNotNull/simple.fir.kt create mode 100644 compiler/testData/diagnostics/tests/explicitDefinitelyNotNull/simple.kt create mode 100644 compiler/testData/diagnostics/tests/explicitDefinitelyNotNull/simple.txt create mode 100644 compiler/testData/psi/DefinitelyNotNullType.kt create mode 100644 compiler/testData/psi/DefinitelyNotNullType.txt diff --git a/compiler/fir/analysis-tests/legacy-fir-tests/tests-gen/org/jetbrains/kotlin/fir/FirLoadCompiledKotlinGenerated.java b/compiler/fir/analysis-tests/legacy-fir-tests/tests-gen/org/jetbrains/kotlin/fir/FirLoadCompiledKotlinGenerated.java index a8d4d67ff56..be732663889 100644 --- a/compiler/fir/analysis-tests/legacy-fir-tests/tests-gen/org/jetbrains/kotlin/fir/FirLoadCompiledKotlinGenerated.java +++ b/compiler/fir/analysis-tests/legacy-fir-tests/tests-gen/org/jetbrains/kotlin/fir/FirLoadCompiledKotlinGenerated.java @@ -438,6 +438,11 @@ public class FirLoadCompiledKotlinGenerated extends AbstractFirLoadCompiledKotli runTest("compiler/testData/loadJava/compiledKotlin/annotations/types/ClassLiteralArgument.kt"); } + @TestMetadata("DefinitelyNotNull.kt") + public void testDefinitelyNotNull() throws Exception { + runTest("compiler/testData/loadJava/compiledKotlin/annotations/types/DefinitelyNotNull.kt"); + } + @TestMetadata("ReceiverParameter.kt") public void testReceiverParameter() throws Exception { runTest("compiler/testData/loadJava/compiledKotlin/annotations/types/ReceiverParameter.kt"); diff --git a/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirOldFrontendDiagnosticsTestGenerated.java b/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirOldFrontendDiagnosticsTestGenerated.java index c23e0ef85f3..d20edf07c93 100644 --- a/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirOldFrontendDiagnosticsTestGenerated.java +++ b/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirOldFrontendDiagnosticsTestGenerated.java @@ -9170,6 +9170,46 @@ public class FirOldFrontendDiagnosticsTestGenerated extends AbstractFirDiagnosti } } + @Nested + @TestMetadata("compiler/testData/diagnostics/tests/explicitDefinitelyNotNull") + @TestDataPath("$PROJECT_ROOT") + public class ExplicitDefinitelyNotNull { + @Test + public void testAllFilesPresentInExplicitDefinitelyNotNull() throws Exception { + KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/diagnostics/tests/explicitDefinitelyNotNull"), Pattern.compile("^(.+)\\.kt$"), Pattern.compile("^(.+)\\.fir\\.kts?$"), true); + } + + @Test + @TestMetadata("disabledFeature.kt") + public void testDisabledFeature() throws Exception { + runTest("compiler/testData/diagnostics/tests/explicitDefinitelyNotNull/disabledFeature.kt"); + } + + @Test + @TestMetadata("notApplicable.kt") + public void testNotApplicable() throws Exception { + runTest("compiler/testData/diagnostics/tests/explicitDefinitelyNotNull/notApplicable.kt"); + } + + @Test + @TestMetadata("overrides.kt") + public void testOverrides() throws Exception { + runTest("compiler/testData/diagnostics/tests/explicitDefinitelyNotNull/overrides.kt"); + } + + @Test + @TestMetadata("overridesJavaAnnotated.kt") + public void testOverridesJavaAnnotated() throws Exception { + runTest("compiler/testData/diagnostics/tests/explicitDefinitelyNotNull/overridesJavaAnnotated.kt"); + } + + @Test + @TestMetadata("simple.kt") + public void testSimple() throws Exception { + runTest("compiler/testData/diagnostics/tests/explicitDefinitelyNotNull/simple.kt"); + } + } + @Nested @TestMetadata("compiler/testData/diagnostics/tests/exposed") @TestDataPath("$PROJECT_ROOT") diff --git a/compiler/fir/raw-fir/light-tree2fir/src/org/jetbrains/kotlin/fir/lightTree/converter/DeclarationsConverter.kt b/compiler/fir/raw-fir/light-tree2fir/src/org/jetbrains/kotlin/fir/lightTree/converter/DeclarationsConverter.kt index 883b0c879fe..34d1eda5104 100644 --- a/compiler/fir/raw-fir/light-tree2fir/src/org/jetbrains/kotlin/fir/lightTree/converter/DeclarationsConverter.kt +++ b/compiler/fir/raw-fir/light-tree2fir/src/org/jetbrains/kotlin/fir/lightTree/converter/DeclarationsConverter.kt @@ -1637,6 +1637,7 @@ class DeclarationsConverter( TYPE_REFERENCE -> firType = convertType(it) MODIFIER_LIST -> if (!afterLPar || typeModifiers.hasNoAnnotations()) typeModifiers = convertTypeModifierList(it) USER_TYPE -> firType = convertUserType(it) + DEFINITELY_NOT_NULL_TYPE -> firType = unwrapDefinitelyNotNullableType(it) NULLABLE_TYPE -> firType = convertNullableType(it) FUNCTION_TYPE -> firType = convertFunctionType(it, isSuspend = typeModifiers.hasSuspend) DYNAMIC_TYPE -> firType = buildDynamicTypeRef { @@ -1676,6 +1677,7 @@ class DeclarationsConverter( convertUserType(it, true) FUNCTION_TYPE -> firType = convertFunctionType(it, true) NULLABLE_TYPE -> firType = convertNullableType(it) + DEFINITELY_NOT_NULL_TYPE -> firType = unwrapDefinitelyNotNullableType(it, nullable = true) DYNAMIC_TYPE -> firType = buildDynamicTypeRef { source = nullableType.toFirSourceElement() isMarkedNullable = true @@ -1686,6 +1688,26 @@ class DeclarationsConverter( return firType } + private fun unwrapDefinitelyNotNullableType(definitelyNotNullType: LighterASTNode, nullable: Boolean = false): FirTypeRef { + lateinit var firType: FirTypeRef + // TODO: Support proper DefinitelyNotNullableType + definitelyNotNullType.forEachChildren { + when (it.tokenType) { + USER_TYPE -> firType = + convertUserType(it, nullable) + FUNCTION_TYPE -> firType = convertFunctionType(it, nullable) + NULLABLE_TYPE -> firType = convertNullableType(it) + DEFINITELY_NOT_NULL_TYPE -> firType = unwrapDefinitelyNotNullableType(it, nullable) + DYNAMIC_TYPE -> firType = buildDynamicTypeRef { + source = definitelyNotNullType.toFirSourceElement() + isMarkedNullable = false + } + } + } + + return firType + } + /** * @see org.jetbrains.kotlin.parsing.KotlinParsing.parseUserType */ diff --git a/compiler/fir/raw-fir/psi2fir/src/org/jetbrains/kotlin/fir/builder/RawFirBuilder.kt b/compiler/fir/raw-fir/psi2fir/src/org/jetbrains/kotlin/fir/builder/RawFirBuilder.kt index 3b292b79c95..954ba16a973 100644 --- a/compiler/fir/raw-fir/psi2fir/src/org/jetbrains/kotlin/fir/builder/RawFirBuilder.kt +++ b/compiler/fir/raw-fir/psi2fir/src/org/jetbrains/kotlin/fir/builder/RawFirBuilder.kt @@ -1330,7 +1330,12 @@ open class RawFirBuilder( val isNullable = typeElement is KtNullableType fun KtTypeElement?.unwrapNullable(): KtTypeElement? = - if (this is KtNullableType) this.innerType.unwrapNullable() else this + when (this) { + is KtNullableType -> this.innerType.unwrapNullable() + // TODO: Support explicit definitely not null type + is KtDefinitelyNotNullType -> this.innerType.unwrapNullable() + else -> this + } val firTypeBuilder = when (val unwrappedElement = typeElement.unwrapNullable()) { is KtDynamicType -> FirDynamicTypeRefBuilder().apply { diff --git a/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/Errors.java b/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/Errors.java index ee2d9634df0..f903eb4bbd1 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/Errors.java +++ b/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/Errors.java @@ -156,6 +156,8 @@ public interface Errors { DiagnosticFactory0 PROJECTION_ON_NON_CLASS_TYPE_ARGUMENT = DiagnosticFactory0.create(ERROR, VARIANCE_IN_PROJECTION); DiagnosticFactory2 UPPER_BOUND_VIOLATED = DiagnosticFactory2.create(ERROR); DiagnosticFactory0 REDUNDANT_NULLABLE = DiagnosticFactory0.create(WARNING, NULLABLE_TYPE); + DiagnosticFactory0 DEFINITELY_NOT_NULLABLE_NOT_APPLICABLE = DiagnosticFactory0.create(ERROR); + DiagnosticFactory0 NULLABLE_ON_DEFINITELY_NOT_NULLABLE = DiagnosticFactory0.create(ERROR); DiagnosticFactory2 WRONG_NUMBER_OF_TYPE_ARGUMENTS = DiagnosticFactory2.create(ERROR); DiagnosticFactory1 OUTER_CLASS_ARGUMENTS_REQUIRED = DiagnosticFactory1.create(ERROR); DiagnosticFactory1 TYPE_ARGUMENTS_NOT_ALLOWED = DiagnosticFactory1.create(ERROR); diff --git a/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/rendering/DefaultErrorMessages.java b/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/rendering/DefaultErrorMessages.java index 347f6ef241b..90b2252db63 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/rendering/DefaultErrorMessages.java +++ b/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/rendering/DefaultErrorMessages.java @@ -675,6 +675,8 @@ public class DefaultErrorMessages { MAP.put(NULLABLE_SUPERTYPE, "A supertype cannot be nullable"); MAP.put(DYNAMIC_SUPERTYPE, "A supertype cannot be dynamic"); MAP.put(REDUNDANT_NULLABLE, "Redundant '?'"); + MAP.put(DEFINITELY_NOT_NULLABLE_NOT_APPLICABLE, "'!!' is only applicable to type parameters with nullable upper bounds"); + MAP.put(NULLABLE_ON_DEFINITELY_NOT_NULLABLE, "'!!' type cannot be marked as nullable"); MAP.put(UNSAFE_CALL, "Only safe (?.) or non-null asserted (!!.) calls are allowed on a nullable receiver of type {0}", RENDER_TYPE); MAP.put(UNSAFE_IMPLICIT_INVOKE_CALL, "Reference has a nullable type ''{0}'', use explicit ''?.invoke()'' to make a function-like call instead", RENDER_TYPE); MAP.put(AMBIGUOUS_LABEL, "Ambiguous label"); diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/TypeResolver.kt b/compiler/frontend/src/org/jetbrains/kotlin/resolve/TypeResolver.kt index 57d25263009..a04ca367424 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/TypeResolver.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/TypeResolver.kt @@ -264,21 +264,61 @@ class TypeResolver( } override fun visitNullableType(nullableType: KtNullableType) { - val innerModifierList = nullableType.modifierList - if (innerModifierList != null && outerModifierList != null) { - c.trace.report(MODIFIER_LIST_NOT_ALLOWED.on(innerModifierList)) + val innerType = nullableType.innerType + + val baseType = createTypeFromInner(nullableType, nullableType.modifierList, innerType) + + if (!baseType.isBare && baseType.actualType is DefinitelyNotNullType) { + c.trace.report(NULLABLE_ON_DEFINITELY_NOT_NULLABLE.on(nullableType)) } - val innerAnnotations = composeAnnotations(annotations, resolveTypeAnnotations(c, nullableType)) - - val innerType = nullableType.innerType - val baseType = resolveTypeElement(c, innerAnnotations, outerModifierList ?: innerModifierList, innerType) if (baseType.isNullable || innerType is KtNullableType || innerType is KtDynamicType) { c.trace.report(REDUNDANT_NULLABLE.on(nullableType)) } result = baseType.makeNullable() } + private fun createTypeFromInner( + typeElement: KtTypeElement, + innerModifierList: KtModifierList?, + innerType: KtTypeElement? + ): PossiblyBareType { + if (innerModifierList != null && outerModifierList != null) { + c.trace.report(MODIFIER_LIST_NOT_ALLOWED.on(innerModifierList)) + } + + val innerAnnotations = composeAnnotations(annotations, resolveTypeAnnotations(c, typeElement as KtElementImplStub<*>)) + + return resolveTypeElement(c, innerAnnotations, outerModifierList ?: innerModifierList, innerType) + } + + override fun visitDefinitelyNotNullType(definitelyNotNullType: KtDefinitelyNotNullType) { + val baseType = + createTypeFromInner(definitelyNotNullType, definitelyNotNullType.modifierList, definitelyNotNullType.innerType) + + if (!languageVersionSettings.supportsFeature(LanguageFeature.DefinitelyNotNullTypeParameters)) { + result = baseType + c.trace.report( + UNSUPPORTED_FEATURE.on( + definitelyNotNullType, + LanguageFeature.DefinitelyNotNullTypeParameters to languageVersionSettings + ) + ) + return + } + + val definitelyNotNullKotlinType = + if (!baseType.isBare) DefinitelyNotNullType.makeDefinitelyNotNull(baseType.actualType.unwrap()) else null + + if (definitelyNotNullKotlinType == null) { + result = baseType + c.trace.report(DEFINITELY_NOT_NULLABLE_NOT_APPLICABLE.on(definitelyNotNullType)) + return + } + + result = type(definitelyNotNullKotlinType) + } + override fun visitFunctionType(type: KtFunctionType) { val receiverTypeRef = type.receiverTypeReference val receiverType = if (receiverTypeRef == null) null else resolveType(c.noBareTypes(), receiverTypeRef) @@ -494,8 +534,8 @@ class TypeResolver( } val (collectedArgumentAsTypeProjections, argumentsForOuterClass) = - collectArgumentsForClassifierTypeConstructor(c, classDescriptor, qualifierResolutionResult.qualifierParts) - ?: return createErrorTypeForTypeConstructor(c, projectionFromAllQualifierParts, typeConstructor) + collectArgumentsForClassifierTypeConstructor(c, classDescriptor, qualifierResolutionResult.qualifierParts) + ?: return createErrorTypeForTypeConstructor(c, projectionFromAllQualifierParts, typeConstructor) assert(collectedArgumentAsTypeProjections.size <= parameters.size) { "Collected arguments count should be not greater then parameters count," + @@ -583,11 +623,11 @@ class TypeResolver( val typeAliasQualifierPart = qualifierResolutionResult.qualifierParts.lastOrNull() - ?: return createErrorTypeForTypeConstructor(c, projectionFromAllQualifierParts, typeConstructor) + ?: return createErrorTypeForTypeConstructor(c, projectionFromAllQualifierParts, typeConstructor) val (argumentElementsFromUserType, argumentsForOuterClass) = - collectArgumentsForClassifierTypeConstructor(c, descriptor, qualifierResolutionResult.qualifierParts) - ?: return createErrorTypeForTypeConstructor(c, projectionFromAllQualifierParts, typeConstructor) + collectArgumentsForClassifierTypeConstructor(c, descriptor, qualifierResolutionResult.qualifierParts) + ?: return createErrorTypeForTypeConstructor(c, projectionFromAllQualifierParts, typeConstructor) val argumentsFromUserType = resolveTypeProjections(c, typeConstructor, argumentElementsFromUserType) @@ -803,7 +843,7 @@ class TypeResolver( parameters[result.size].original.containingDeclaration as? ClassDescriptor // If next parameter is captured from the enclosing function, default arguments must be used // (see appendDefaultArgumentsForLocalClassifier) - ?: return Pair(result, null) + ?: return Pair(result, null) val restArguments = c.scope.findImplicitOuterClassArguments(nextParameterOwner) val restParameters = parameters.subList(result.size, parameters.size) diff --git a/compiler/psi/src/org/jetbrains/kotlin/KtNodeTypes.java b/compiler/psi/src/org/jetbrains/kotlin/KtNodeTypes.java index a6d8340ef7e..35e59102d24 100644 --- a/compiler/psi/src/org/jetbrains/kotlin/KtNodeTypes.java +++ b/compiler/psi/src/org/jetbrains/kotlin/KtNodeTypes.java @@ -75,6 +75,7 @@ public interface KtNodeTypes { IElementType FUNCTION_TYPE = KtStubElementTypes.FUNCTION_TYPE; IElementType FUNCTION_TYPE_RECEIVER = KtStubElementTypes.FUNCTION_TYPE_RECEIVER; IElementType NULLABLE_TYPE = KtStubElementTypes.NULLABLE_TYPE; + IElementType DEFINITELY_NOT_NULL_TYPE = KtStubElementTypes.DEFINITELY_NOT_NULL_TYPE; IElementType TYPE_PROJECTION = KtStubElementTypes.TYPE_PROJECTION; IElementType PROPERTY_ACCESSOR = KtStubElementTypes.PROPERTY_ACCESSOR; diff --git a/compiler/psi/src/org/jetbrains/kotlin/parsing/KotlinParsing.java b/compiler/psi/src/org/jetbrains/kotlin/parsing/KotlinParsing.java index 6d0a04eba89..57a44005ade 100644 --- a/compiler/psi/src/org/jetbrains/kotlin/parsing/KotlinParsing.java +++ b/compiler/psi/src/org/jetbrains/kotlin/parsing/KotlinParsing.java @@ -2220,6 +2220,12 @@ public class KotlinParsing extends AbstractKotlinParsing { } userType.done(USER_TYPE); + + if (at(EXCLEXCL)) { + PsiBuilder.Marker definitelyNotNull = userType.precede(); + advance(); // !! + definitelyNotNull.done(DEFINITELY_NOT_NULL_TYPE); + } } private boolean atParenthesizedMutableForPlatformTypes(int offset) { diff --git a/compiler/psi/src/org/jetbrains/kotlin/psi/KtDefinitelyNotNullType.kt b/compiler/psi/src/org/jetbrains/kotlin/psi/KtDefinitelyNotNullType.kt new file mode 100644 index 00000000000..1484e43cad8 --- /dev/null +++ b/compiler/psi/src/org/jetbrains/kotlin/psi/KtDefinitelyNotNullType.kt @@ -0,0 +1,35 @@ +/* + * 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.psi + +import com.intellij.lang.ASTNode +import org.jetbrains.kotlin.psi.stubs.KotlinPlaceHolderStub +import org.jetbrains.kotlin.psi.stubs.elements.KtStubElementTypes + +class KtDefinitelyNotNullType : KtElementImplStub>, KtTypeElement { + constructor(node: ASTNode) : super(node) + constructor(stub: KotlinPlaceHolderStub) : super(stub, KtStubElementTypes.DEFINITELY_NOT_NULL_TYPE) + + override fun getTypeArgumentsAsTypes(): List { + return this.innerType?.typeArgumentsAsTypes ?: emptyList() + } + + override fun accept(visitor: KtVisitor, data: D): R { + return visitor.visitDefinitelyNotNullType(this, data) + } + + @get:IfNotParsed + val innerType: KtTypeElement? + get() = KtStubbedPsiUtil.getStubOrPsiChild(this, KtStubElementTypes.TYPE_ELEMENT_TYPES, KtTypeElement.ARRAY_FACTORY) + + val modifierList: KtModifierList? + get() = getStubOrPsiChild(KtStubElementTypes.MODIFIER_LIST) + + val annotationEntries: List + get() { + return modifierList?.annotationEntries ?: emptyList() + } +} diff --git a/compiler/psi/src/org/jetbrains/kotlin/psi/KtVisitor.java b/compiler/psi/src/org/jetbrains/kotlin/psi/KtVisitor.java index 7f27538ebf6..b2da4ff30f4 100644 --- a/compiler/psi/src/org/jetbrains/kotlin/psi/KtVisitor.java +++ b/compiler/psi/src/org/jetbrains/kotlin/psi/KtVisitor.java @@ -402,6 +402,10 @@ public class KtVisitor extends PsiElementVisitor { return visitTypeElement(nullableType, data); } + public R visitDefinitelyNotNullType(@NotNull KtDefinitelyNotNullType definitelyNotNullType, D data) { + return visitTypeElement(definitelyNotNullType, data); + } + public R visitTypeProjection(@NotNull KtTypeProjection typeProjection, D data) { return visitKtElement(typeProjection, data); } diff --git a/compiler/psi/src/org/jetbrains/kotlin/psi/KtVisitorVoid.java b/compiler/psi/src/org/jetbrains/kotlin/psi/KtVisitorVoid.java index 068635305e5..0ff6bc09f9f 100644 --- a/compiler/psi/src/org/jetbrains/kotlin/psi/KtVisitorVoid.java +++ b/compiler/psi/src/org/jetbrains/kotlin/psi/KtVisitorVoid.java @@ -385,6 +385,10 @@ public class KtVisitorVoid extends KtVisitor { super.visitNullableType(nullableType, null); } + public void visitDefinitelyNotNullType(@NotNull KtDefinitelyNotNullType definitelyNotNullType) { + super.visitDefinitelyNotNullType(definitelyNotNullType, null); + } + public void visitTypeProjection(@NotNull KtTypeProjection typeProjection) { super.visitTypeProjection(typeProjection, null); } @@ -972,6 +976,12 @@ public class KtVisitorVoid extends KtVisitor { return null; } + @Override + public Void visitDefinitelyNotNullType(@NotNull KtDefinitelyNotNullType definitelyNotNullType, Void data) { + visitDefinitelyNotNullType(definitelyNotNullType); + return null; + } + @Override public final Void visitTypeProjection(@NotNull KtTypeProjection typeProjection, Void data) { visitTypeProjection(typeProjection); diff --git a/compiler/psi/src/org/jetbrains/kotlin/psi/stubs/elements/KtStubElementTypes.java b/compiler/psi/src/org/jetbrains/kotlin/psi/stubs/elements/KtStubElementTypes.java index 6e5d61e95ef..92c79d55f1c 100644 --- a/compiler/psi/src/org/jetbrains/kotlin/psi/stubs/elements/KtStubElementTypes.java +++ b/compiler/psi/src/org/jetbrains/kotlin/psi/stubs/elements/KtStubElementTypes.java @@ -79,6 +79,9 @@ public interface KtStubElementTypes { KtPlaceHolderStubElementType NULLABLE_TYPE = new KtPlaceHolderStubElementType<>("NULLABLE_TYPE", KtNullableType.class); + KtPlaceHolderStubElementType DEFINITELY_NOT_NULL_TYPE = + new KtPlaceHolderStubElementType<>("DEFINITELY_NOT_NULL_TYPE", KtDefinitelyNotNullType.class); + KtPlaceHolderStubElementType TYPE_REFERENCE = new KtPlaceHolderStubElementType<>("TYPE_REFERENCE", KtTypeReference.class); @@ -167,7 +170,7 @@ public interface KtStubElementTypes { TokenSet SUPER_TYPE_LIST_ENTRIES = TokenSet.create(DELEGATED_SUPER_TYPE_ENTRY, SUPER_TYPE_CALL_ENTRY, SUPER_TYPE_ENTRY); - TokenSet TYPE_ELEMENT_TYPES = TokenSet.create(USER_TYPE, NULLABLE_TYPE, FUNCTION_TYPE, DYNAMIC_TYPE); + TokenSet TYPE_ELEMENT_TYPES = TokenSet.create(USER_TYPE, NULLABLE_TYPE, FUNCTION_TYPE, DYNAMIC_TYPE, DEFINITELY_NOT_NULL_TYPE); TokenSet INSIDE_DIRECTIVE_EXPRESSIONS = TokenSet.create(REFERENCE_EXPRESSION, DOT_QUALIFIED_EXPRESSION); } diff --git a/compiler/testData/diagnostics/tests/explicitDefinitelyNotNull/disabledFeature.fir.kt b/compiler/testData/diagnostics/tests/explicitDefinitelyNotNull/disabledFeature.fir.kt new file mode 100644 index 00000000000..7d1d1a64cc9 --- /dev/null +++ b/compiler/testData/diagnostics/tests/explicitDefinitelyNotNull/disabledFeature.fir.kt @@ -0,0 +1,3 @@ +// !LANGUAGE: -DefinitelyNotNullTypeParameters + +fun foo(x: T, y: T!!): List? = null diff --git a/compiler/testData/diagnostics/tests/explicitDefinitelyNotNull/disabledFeature.kt b/compiler/testData/diagnostics/tests/explicitDefinitelyNotNull/disabledFeature.kt new file mode 100644 index 00000000000..fa25353f94f --- /dev/null +++ b/compiler/testData/diagnostics/tests/explicitDefinitelyNotNull/disabledFeature.kt @@ -0,0 +1,3 @@ +// !LANGUAGE: -DefinitelyNotNullTypeParameters + +fun foo(x: T, y: T!!): List<T!!>? = null diff --git a/compiler/testData/diagnostics/tests/explicitDefinitelyNotNull/disabledFeature.txt b/compiler/testData/diagnostics/tests/explicitDefinitelyNotNull/disabledFeature.txt new file mode 100644 index 00000000000..5d5fc25c961 --- /dev/null +++ b/compiler/testData/diagnostics/tests/explicitDefinitelyNotNull/disabledFeature.txt @@ -0,0 +1,4 @@ +package + +public fun foo(/*0*/ x: T, /*1*/ y: T): kotlin.collections.List? + diff --git a/compiler/testData/diagnostics/tests/explicitDefinitelyNotNull/notApplicable.fir.kt b/compiler/testData/diagnostics/tests/explicitDefinitelyNotNull/notApplicable.fir.kt new file mode 100644 index 00000000000..c1859acc729 --- /dev/null +++ b/compiler/testData/diagnostics/tests/explicitDefinitelyNotNull/notApplicable.fir.kt @@ -0,0 +1,12 @@ +// !LANGUAGE: +DefinitelyNotNullTypeParameters + +fun foo(x: T!!, y: List!!) {} + +fun bar1(x: F?!!) {} +fun bar2(x: F!!?) {} +fun bar3(x: (F?)!!) {} +fun bar4(x: (F!!)?) {} + +fun bar5(x: F!!!) {} +fun bar6(x: F!!!) {} +fun bar7(x: F!!?!!) {} diff --git a/compiler/testData/diagnostics/tests/explicitDefinitelyNotNull/notApplicable.kt b/compiler/testData/diagnostics/tests/explicitDefinitelyNotNull/notApplicable.kt new file mode 100644 index 00000000000..fd18b966ec3 --- /dev/null +++ b/compiler/testData/diagnostics/tests/explicitDefinitelyNotNull/notApplicable.kt @@ -0,0 +1,12 @@ +// !LANGUAGE: +DefinitelyNotNullTypeParameters + +fun foo(x: T!!, y: List<String!!>!!) {} + +fun bar1(x: F?!!) {} +fun bar2(x: F!!?) {} +fun bar3(x: (F?)!!) {} +fun bar4(x: (F!!)?) {} + +fun bar5(x: F!!!) {} +fun bar6(x: F!!!) {} +fun bar7(x: F!!?!!) {} diff --git a/compiler/testData/diagnostics/tests/explicitDefinitelyNotNull/notApplicable.txt b/compiler/testData/diagnostics/tests/explicitDefinitelyNotNull/notApplicable.txt new file mode 100644 index 00000000000..6bcec699eff --- /dev/null +++ b/compiler/testData/diagnostics/tests/explicitDefinitelyNotNull/notApplicable.txt @@ -0,0 +1,16 @@ +package + +public fun (): kotlin.Unit +public fun (): kotlin.Unit +public fun (): kotlin.Unit +public fun (): kotlin.Unit +public fun (): kotlin.Unit +public fun bar1(/*0*/ x: F?): kotlin.Unit +public fun bar2(/*0*/ x: F?): kotlin.Unit +public fun bar3(/*0*/ x: F?): kotlin.Unit +public fun bar4(/*0*/ x: F?): kotlin.Unit +public fun bar5(/*0*/ x: F!!): kotlin.Unit +public fun bar6(/*0*/ x: F!!): kotlin.Unit +public fun bar7(/*0*/ x: F?): kotlin.Unit +public fun foo(/*0*/ x: T, /*1*/ y: kotlin.collections.List): kotlin.Unit + diff --git a/compiler/testData/diagnostics/tests/explicitDefinitelyNotNull/overrides.fir.kt b/compiler/testData/diagnostics/tests/explicitDefinitelyNotNull/overrides.fir.kt new file mode 100644 index 00000000000..038434b4655 --- /dev/null +++ b/compiler/testData/diagnostics/tests/explicitDefinitelyNotNull/overrides.fir.kt @@ -0,0 +1,36 @@ +// !LANGUAGE: +DefinitelyNotNullTypeParameters + +interface A { + fun foo(x: T): T + fun bar(x: T!!): T!! +} + +interface B : A { + override fun foo(x: T1): T1 + override fun bar(x: T1!!): T1!! +} + +interface C : A { + override fun foo(x: T2!!): T2!! + override fun bar(x: T2): T2 +} + +interface D : A { + override fun foo(x: String?): String? + override fun bar(x: String): String +} + +interface E : A { + override fun foo(x: String): String + override fun bar(x: String): String +} + +interface F : A { + override fun foo(x: String): String + override fun bar(x: String?): String? +} + +interface G : A { + override fun foo(x: T3): T3 + override fun bar(x: T3): T3 +} diff --git a/compiler/testData/diagnostics/tests/explicitDefinitelyNotNull/overrides.kt b/compiler/testData/diagnostics/tests/explicitDefinitelyNotNull/overrides.kt new file mode 100644 index 00000000000..8c61e251032 --- /dev/null +++ b/compiler/testData/diagnostics/tests/explicitDefinitelyNotNull/overrides.kt @@ -0,0 +1,36 @@ +// !LANGUAGE: +DefinitelyNotNullTypeParameters + +interface A { + fun foo(x: T): T + fun bar(x: T!!): T!! +} + +interface B : A { + override fun foo(x: T1): T1 + override fun bar(x: T1!!): T1!! +} + +interface C : A { + override fun foo(x: T2!!): T2!! + override fun bar(x: T2): T2 +} + +interface D : A { + override fun foo(x: String?): String? + override fun bar(x: String): String +} + +interface E : A { + override fun foo(x: String): String + override fun bar(x: String): String +} + +interface F : A { + override fun foo(x: String): String + override fun bar(x: String?): String? +} + +interface G : A { + override fun foo(x: T3): T3 + override fun bar(x: T3): T3 +} diff --git a/compiler/testData/diagnostics/tests/explicitDefinitelyNotNull/overrides.txt b/compiler/testData/diagnostics/tests/explicitDefinitelyNotNull/overrides.txt new file mode 100644 index 00000000000..50b2bc774ec --- /dev/null +++ b/compiler/testData/diagnostics/tests/explicitDefinitelyNotNull/overrides.txt @@ -0,0 +1,61 @@ +package + +public interface A { + public abstract fun bar(/*0*/ x: T!!): T!! + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public abstract fun foo(/*0*/ x: T): T + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String +} + +public interface B : A { + public abstract override /*1*/ fun bar(/*0*/ x: T1!!): T1!! + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public abstract override /*1*/ fun foo(/*0*/ x: T1): T1 + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String +} + +public interface C : A { + public abstract fun bar(/*0*/ x: T2): T2 + public abstract override /*1*/ /*fake_override*/ fun bar(/*0*/ x: T2!!): T2!! + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public abstract override /*1*/ /*fake_override*/ fun foo(/*0*/ x: T2): T2 + public abstract fun foo(/*0*/ x: T2!!): T2!! + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String +} + +public interface D : A { + public abstract override /*1*/ fun bar(/*0*/ x: kotlin.String): kotlin.String + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public abstract override /*1*/ fun foo(/*0*/ x: kotlin.String?): kotlin.String? + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String +} + +public interface E : A { + public abstract override /*1*/ fun bar(/*0*/ x: kotlin.String): kotlin.String + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public abstract override /*1*/ fun foo(/*0*/ x: kotlin.String): kotlin.String + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String +} + +public interface F : A { + public abstract override /*1*/ /*fake_override*/ fun bar(/*0*/ x: kotlin.String): kotlin.String + public abstract fun bar(/*0*/ x: kotlin.String?): kotlin.String? + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public abstract fun foo(/*0*/ x: kotlin.String): kotlin.String + public abstract override /*1*/ /*fake_override*/ fun foo(/*0*/ x: kotlin.String?): kotlin.String? + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String +} + +public interface G : A { + public abstract override /*1*/ fun bar(/*0*/ x: T3): T3 + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public abstract override /*1*/ fun foo(/*0*/ x: T3): T3 + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String +} diff --git a/compiler/testData/diagnostics/tests/explicitDefinitelyNotNull/overridesJavaAnnotated.fir.kt b/compiler/testData/diagnostics/tests/explicitDefinitelyNotNull/overridesJavaAnnotated.fir.kt new file mode 100644 index 00000000000..7eb6f5d041b --- /dev/null +++ b/compiler/testData/diagnostics/tests/explicitDefinitelyNotNull/overridesJavaAnnotated.fir.kt @@ -0,0 +1,42 @@ +// !LANGUAGE: +DefinitelyNotNullTypeParameters +ProhibitUsingNullableTypeParameterAgainstNotNullAnnotated + +// FILE: A.java +import org.jetbrains.annotations.*; + +public interface A { + public T foo(T x) { return x; } + @NotNull + public T bar(@NotNull T x) {} +} + +// FILE: main.kt + +interface B : A { + override fun foo(x: T1): T1 + override fun bar(x: T1!!): T1!! +} + +interface C : A { + override fun foo(x: T2!!): T2!! + override fun bar(x: T2): T2 +} + +interface D : A { + override fun foo(x: String?): String? + override fun bar(x: String): String +} + +interface E : A { + override fun foo(x: String): String + override fun bar(x: String): String +} + +interface F : A { + override fun foo(x: String): String + override fun bar(x: String?): String? +} + +interface G : A { + override fun foo(x: T3): T3 + override fun bar(x: T3): T3 +} diff --git a/compiler/testData/diagnostics/tests/explicitDefinitelyNotNull/overridesJavaAnnotated.kt b/compiler/testData/diagnostics/tests/explicitDefinitelyNotNull/overridesJavaAnnotated.kt new file mode 100644 index 00000000000..339dd4c1b51 --- /dev/null +++ b/compiler/testData/diagnostics/tests/explicitDefinitelyNotNull/overridesJavaAnnotated.kt @@ -0,0 +1,42 @@ +// !LANGUAGE: +DefinitelyNotNullTypeParameters +ProhibitUsingNullableTypeParameterAgainstNotNullAnnotated + +// FILE: A.java +import org.jetbrains.annotations.*; + +public interface A { + public T foo(T x) { return x; } + @NotNull + public T bar(@NotNull T x) {} +} + +// FILE: main.kt + +interface B : A { + override fun foo(x: T1): T1 + override fun bar(x: T1!!): T1!! +} + +interface C : A { + override fun foo(x: T2!!): T2!! + override fun bar(x: T2): T2 +} + +interface D : A { + override fun foo(x: String?): String? + override fun bar(x: String): String +} + +interface E : A { + override fun foo(x: String): String + override fun bar(x: String): String +} + +interface F : A { + override fun foo(x: String): String + override fun bar(x: String?): String? +} + +interface G : A { + override fun foo(x: T3): T3 + override fun bar(x: T3): T3 +} diff --git a/compiler/testData/diagnostics/tests/explicitDefinitelyNotNull/overridesJavaAnnotated.txt b/compiler/testData/diagnostics/tests/explicitDefinitelyNotNull/overridesJavaAnnotated.txt new file mode 100644 index 00000000000..6c3f08fa065 --- /dev/null +++ b/compiler/testData/diagnostics/tests/explicitDefinitelyNotNull/overridesJavaAnnotated.txt @@ -0,0 +1,61 @@ +package + +public interface A { + @org.jetbrains.annotations.NotNull public abstract fun bar(/*0*/ @org.jetbrains.annotations.NotNull x: T!!): T!! + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public abstract fun foo(/*0*/ x: T!): T! + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String +} + +public interface B : A { + public abstract override /*1*/ fun bar(/*0*/ x: T1!!): T1!! + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public abstract override /*1*/ fun foo(/*0*/ x: T1): T1 + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String +} + +public interface C : A { + public abstract fun bar(/*0*/ x: T2): T2 + @org.jetbrains.annotations.NotNull public abstract override /*1*/ /*fake_override*/ fun bar(/*0*/ @org.jetbrains.annotations.NotNull x: T2!!): T2!! + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public abstract override /*1*/ /*fake_override*/ fun foo(/*0*/ x: T2!): T2! + public abstract fun foo(/*0*/ x: T2!!): T2!! + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String +} + +public interface D : A { + public abstract override /*1*/ fun bar(/*0*/ x: kotlin.String): kotlin.String + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public abstract override /*1*/ fun foo(/*0*/ x: kotlin.String?): kotlin.String? + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String +} + +public interface E : A { + public abstract override /*1*/ fun bar(/*0*/ x: kotlin.String): kotlin.String + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public abstract override /*1*/ fun foo(/*0*/ x: kotlin.String): kotlin.String + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String +} + +public interface F : A { + @org.jetbrains.annotations.NotNull public abstract override /*1*/ /*fake_override*/ fun bar(/*0*/ @org.jetbrains.annotations.NotNull x: kotlin.String): kotlin.String + public abstract fun bar(/*0*/ x: kotlin.String?): kotlin.String? + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public abstract fun foo(/*0*/ x: kotlin.String): kotlin.String + public abstract override /*1*/ /*fake_override*/ fun foo(/*0*/ x: kotlin.String?): kotlin.String? + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String +} + +public interface G : A { + public abstract override /*1*/ fun bar(/*0*/ x: T3): T3 + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public abstract override /*1*/ fun foo(/*0*/ x: T3): T3 + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String +} diff --git a/compiler/testData/diagnostics/tests/explicitDefinitelyNotNull/simple.fir.kt b/compiler/testData/diagnostics/tests/explicitDefinitelyNotNull/simple.fir.kt new file mode 100644 index 00000000000..bfd4fbdb084 --- /dev/null +++ b/compiler/testData/diagnostics/tests/explicitDefinitelyNotNull/simple.fir.kt @@ -0,0 +1,14 @@ +// !LANGUAGE: +DefinitelyNotNullTypeParameters + +fun foo(x: T, y: T!!): T!! = x ?: y + +fun main() { + foo("", "").length + foo("", null).length + foo(null, "").length + foo(null, null).length + + foo("", "").length + foo("", null).length + foo(null, "").length +} diff --git a/compiler/testData/diagnostics/tests/explicitDefinitelyNotNull/simple.kt b/compiler/testData/diagnostics/tests/explicitDefinitelyNotNull/simple.kt new file mode 100644 index 00000000000..c4b65706f99 --- /dev/null +++ b/compiler/testData/diagnostics/tests/explicitDefinitelyNotNull/simple.kt @@ -0,0 +1,14 @@ +// !LANGUAGE: +DefinitelyNotNullTypeParameters + +fun foo(x: T, y: T!!): T!! = x ?: y + +fun main() { + foo("", "").length + foo("", null).length + foo(null, "").length + foo(null, null).length + + foo("", "").length + foo("", null).length + foo(null, "").length +} diff --git a/compiler/testData/diagnostics/tests/explicitDefinitelyNotNull/simple.txt b/compiler/testData/diagnostics/tests/explicitDefinitelyNotNull/simple.txt new file mode 100644 index 00000000000..db1673f7a72 --- /dev/null +++ b/compiler/testData/diagnostics/tests/explicitDefinitelyNotNull/simple.txt @@ -0,0 +1,4 @@ +package + +public fun foo(/*0*/ x: T, /*1*/ y: T!!): T!! +public fun main(): kotlin.Unit diff --git a/compiler/testData/psi/DefinitelyNotNullType.kt b/compiler/testData/psi/DefinitelyNotNullType.kt new file mode 100644 index 00000000000..754b38edaf1 --- /dev/null +++ b/compiler/testData/psi/DefinitelyNotNullType.kt @@ -0,0 +1,5 @@ + +fun foo1(x: T!!, y: List, z: T!!.(T!!) -> T!!): T!! {} + +// should be prohibited on type-resolution level +fun foo2(x: T!!?, y: List, z: T!!?.(T!!?) -> T!!?, w: String!!): T!! {} diff --git a/compiler/testData/psi/DefinitelyNotNullType.txt b/compiler/testData/psi/DefinitelyNotNullType.txt new file mode 100644 index 00000000000..e80c6ad4aae --- /dev/null +++ b/compiler/testData/psi/DefinitelyNotNullType.txt @@ -0,0 +1,210 @@ +KtFile: DefinitelyNotNullType.kt + PACKAGE_DIRECTIVE + + IMPORT_LIST + + FUN + PsiElement(fun)('fun') + PsiWhiteSpace(' ') + TYPE_PARAMETER_LIST + PsiElement(LT)('<') + TYPE_PARAMETER + PsiElement(IDENTIFIER)('T') + PsiElement(GT)('>') + PsiWhiteSpace(' ') + PsiElement(IDENTIFIER)('foo1') + VALUE_PARAMETER_LIST + PsiElement(LPAR)('(') + VALUE_PARAMETER + PsiElement(IDENTIFIER)('x') + PsiElement(COLON)(':') + PsiWhiteSpace(' ') + TYPE_REFERENCE + DEFINITELY_NOT_NULL_TYPE + USER_TYPE + REFERENCE_EXPRESSION + PsiElement(IDENTIFIER)('T') + PsiElement(EXCLEXCL)('!!') + PsiElement(COMMA)(',') + PsiWhiteSpace(' ') + VALUE_PARAMETER + PsiElement(IDENTIFIER)('y') + PsiElement(COLON)(':') + PsiWhiteSpace(' ') + TYPE_REFERENCE + USER_TYPE + REFERENCE_EXPRESSION + PsiElement(IDENTIFIER)('List') + TYPE_ARGUMENT_LIST + PsiElement(LT)('<') + TYPE_PROJECTION + TYPE_REFERENCE + DEFINITELY_NOT_NULL_TYPE + USER_TYPE + REFERENCE_EXPRESSION + PsiElement(IDENTIFIER)('T') + PsiElement(EXCLEXCL)('!!') + PsiElement(GT)('>') + PsiElement(COMMA)(',') + PsiWhiteSpace(' ') + VALUE_PARAMETER + PsiElement(IDENTIFIER)('z') + PsiElement(COLON)(':') + PsiWhiteSpace(' ') + TYPE_REFERENCE + FUNCTION_TYPE + FUNCTION_TYPE_RECEIVER + TYPE_REFERENCE + DEFINITELY_NOT_NULL_TYPE + USER_TYPE + REFERENCE_EXPRESSION + PsiElement(IDENTIFIER)('T') + PsiElement(EXCLEXCL)('!!') + PsiElement(DOT)('.') + VALUE_PARAMETER_LIST + PsiElement(LPAR)('(') + VALUE_PARAMETER + TYPE_REFERENCE + DEFINITELY_NOT_NULL_TYPE + USER_TYPE + REFERENCE_EXPRESSION + PsiElement(IDENTIFIER)('T') + PsiElement(EXCLEXCL)('!!') + PsiElement(RPAR)(')') + PsiWhiteSpace(' ') + PsiElement(ARROW)('->') + PsiWhiteSpace(' ') + TYPE_REFERENCE + DEFINITELY_NOT_NULL_TYPE + USER_TYPE + REFERENCE_EXPRESSION + PsiElement(IDENTIFIER)('T') + PsiElement(EXCLEXCL)('!!') + PsiElement(RPAR)(')') + PsiElement(COLON)(':') + PsiWhiteSpace(' ') + TYPE_REFERENCE + DEFINITELY_NOT_NULL_TYPE + USER_TYPE + REFERENCE_EXPRESSION + PsiElement(IDENTIFIER)('T') + PsiElement(EXCLEXCL)('!!') + PsiWhiteSpace(' ') + BLOCK + PsiElement(LBRACE)('{') + PsiElement(RBRACE)('}') + PsiWhiteSpace('\n\n') + FUN + PsiComment(EOL_COMMENT)('// should be prohibited on type-resolution level') + PsiWhiteSpace('\n') + PsiElement(fun)('fun') + PsiWhiteSpace(' ') + TYPE_PARAMETER_LIST + PsiElement(LT)('<') + TYPE_PARAMETER + PsiElement(IDENTIFIER)('T') + PsiElement(GT)('>') + PsiWhiteSpace(' ') + PsiElement(IDENTIFIER)('foo2') + VALUE_PARAMETER_LIST + PsiElement(LPAR)('(') + VALUE_PARAMETER + PsiElement(IDENTIFIER)('x') + PsiElement(COLON)(':') + PsiWhiteSpace(' ') + TYPE_REFERENCE + NULLABLE_TYPE + DEFINITELY_NOT_NULL_TYPE + USER_TYPE + REFERENCE_EXPRESSION + PsiElement(IDENTIFIER)('T') + PsiElement(EXCLEXCL)('!!') + PsiElement(QUEST)('?') + PsiElement(COMMA)(',') + PsiWhiteSpace(' ') + VALUE_PARAMETER + PsiElement(IDENTIFIER)('y') + PsiElement(COLON)(':') + PsiWhiteSpace(' ') + TYPE_REFERENCE + USER_TYPE + REFERENCE_EXPRESSION + PsiElement(IDENTIFIER)('List') + TYPE_ARGUMENT_LIST + PsiElement(LT)('<') + TYPE_PROJECTION + TYPE_REFERENCE + NULLABLE_TYPE + DEFINITELY_NOT_NULL_TYPE + USER_TYPE + REFERENCE_EXPRESSION + PsiElement(IDENTIFIER)('T') + PsiElement(EXCLEXCL)('!!') + PsiElement(QUEST)('?') + PsiElement(GT)('>') + PsiElement(COMMA)(',') + PsiWhiteSpace(' ') + VALUE_PARAMETER + PsiElement(IDENTIFIER)('z') + PsiElement(COLON)(':') + PsiWhiteSpace(' ') + TYPE_REFERENCE + FUNCTION_TYPE + FUNCTION_TYPE_RECEIVER + TYPE_REFERENCE + NULLABLE_TYPE + DEFINITELY_NOT_NULL_TYPE + USER_TYPE + REFERENCE_EXPRESSION + PsiElement(IDENTIFIER)('T') + PsiElement(EXCLEXCL)('!!') + PsiElement(QUEST)('?') + PsiElement(DOT)('.') + VALUE_PARAMETER_LIST + PsiElement(LPAR)('(') + VALUE_PARAMETER + TYPE_REFERENCE + NULLABLE_TYPE + DEFINITELY_NOT_NULL_TYPE + USER_TYPE + REFERENCE_EXPRESSION + PsiElement(IDENTIFIER)('T') + PsiElement(EXCLEXCL)('!!') + PsiElement(QUEST)('?') + PsiElement(RPAR)(')') + PsiWhiteSpace(' ') + PsiElement(ARROW)('->') + PsiWhiteSpace(' ') + TYPE_REFERENCE + NULLABLE_TYPE + DEFINITELY_NOT_NULL_TYPE + USER_TYPE + REFERENCE_EXPRESSION + PsiElement(IDENTIFIER)('T') + PsiElement(EXCLEXCL)('!!') + PsiElement(QUEST)('?') + PsiElement(COMMA)(',') + PsiWhiteSpace(' ') + VALUE_PARAMETER + PsiElement(IDENTIFIER)('w') + PsiElement(COLON)(':') + PsiWhiteSpace(' ') + TYPE_REFERENCE + DEFINITELY_NOT_NULL_TYPE + USER_TYPE + REFERENCE_EXPRESSION + PsiElement(IDENTIFIER)('String') + PsiElement(EXCLEXCL)('!!') + PsiElement(RPAR)(')') + PsiElement(COLON)(':') + PsiWhiteSpace(' ') + TYPE_REFERENCE + DEFINITELY_NOT_NULL_TYPE + USER_TYPE + REFERENCE_EXPRESSION + PsiElement(IDENTIFIER)('T') + PsiElement(EXCLEXCL)('!!') + PsiWhiteSpace(' ') + BLOCK + PsiElement(LBRACE)('{') + PsiElement(RBRACE)('}') \ No newline at end of file diff --git a/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/DiagnosticTestGenerated.java b/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/DiagnosticTestGenerated.java index 6e18e7c6bbb..f61be2267b7 100644 --- a/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/DiagnosticTestGenerated.java +++ b/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/DiagnosticTestGenerated.java @@ -9176,6 +9176,46 @@ public class DiagnosticTestGenerated extends AbstractDiagnosticTest { } } + @Nested + @TestMetadata("compiler/testData/diagnostics/tests/explicitDefinitelyNotNull") + @TestDataPath("$PROJECT_ROOT") + public class ExplicitDefinitelyNotNull { + @Test + public void testAllFilesPresentInExplicitDefinitelyNotNull() throws Exception { + KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/diagnostics/tests/explicitDefinitelyNotNull"), Pattern.compile("^(.*)\\.kts?$"), Pattern.compile("^(.+)\\.fir\\.kts?$"), true); + } + + @Test + @TestMetadata("disabledFeature.kt") + public void testDisabledFeature() throws Exception { + runTest("compiler/testData/diagnostics/tests/explicitDefinitelyNotNull/disabledFeature.kt"); + } + + @Test + @TestMetadata("notApplicable.kt") + public void testNotApplicable() throws Exception { + runTest("compiler/testData/diagnostics/tests/explicitDefinitelyNotNull/notApplicable.kt"); + } + + @Test + @TestMetadata("overrides.kt") + public void testOverrides() throws Exception { + runTest("compiler/testData/diagnostics/tests/explicitDefinitelyNotNull/overrides.kt"); + } + + @Test + @TestMetadata("overridesJavaAnnotated.kt") + public void testOverridesJavaAnnotated() throws Exception { + runTest("compiler/testData/diagnostics/tests/explicitDefinitelyNotNull/overridesJavaAnnotated.kt"); + } + + @Test + @TestMetadata("simple.kt") + public void testSimple() throws Exception { + runTest("compiler/testData/diagnostics/tests/explicitDefinitelyNotNull/simple.kt"); + } + } + @Nested @TestMetadata("compiler/testData/diagnostics/tests/exposed") @TestDataPath("$PROJECT_ROOT") diff --git a/compiler/tests-gen/org/jetbrains/kotlin/parsing/ParsingTestGenerated.java b/compiler/tests-gen/org/jetbrains/kotlin/parsing/ParsingTestGenerated.java index 0bf91c59287..5010f30c5f6 100644 --- a/compiler/tests-gen/org/jetbrains/kotlin/parsing/ParsingTestGenerated.java +++ b/compiler/tests-gen/org/jetbrains/kotlin/parsing/ParsingTestGenerated.java @@ -141,6 +141,11 @@ public class ParsingTestGenerated extends AbstractParsingTest { runTest("compiler/testData/psi/DefaultKeyword.kt"); } + @TestMetadata("DefinitelyNotNullType.kt") + public void testDefinitelyNotNullType() throws Exception { + runTest("compiler/testData/psi/DefinitelyNotNullType.kt"); + } + @TestMetadata("destructuringInLambdas.kt") public void testDestructuringInLambdas() throws Exception { runTest("compiler/testData/psi/destructuringInLambdas.kt"); diff --git a/compiler/util/src/org/jetbrains/kotlin/config/LanguageVersionSettings.kt b/compiler/util/src/org/jetbrains/kotlin/config/LanguageVersionSettings.kt index d00f06ba442..4db40d1334f 100644 --- a/compiler/util/src/org/jetbrains/kotlin/config/LanguageVersionSettings.kt +++ b/compiler/util/src/org/jetbrains/kotlin/config/LanguageVersionSettings.kt @@ -203,7 +203,10 @@ enum class LanguageFeature( InlineClasses(sinceVersion = KOTLIN_1_3, defaultState = State.ENABLED_WITH_WARNING, kind = UNSTABLE_FEATURE), JvmInlineValueClasses(sinceVersion = KOTLIN_1_5, defaultState = State.ENABLED, kind = OTHER), SuspendFunctionsInFunInterfaces(sinceVersion = KOTLIN_1_5, defaultState = State.ENABLED, kind = OTHER), - SamWrapperClassesAreSynthetic(sinceVersion = KOTLIN_1_5, defaultState = State.ENABLED, kind = BUG_FIX) + SamWrapperClassesAreSynthetic(sinceVersion = KOTLIN_1_5, defaultState = State.ENABLED, kind = BUG_FIX), + + // 1.6 + DefinitelyNotNullTypeParameters(sinceVersion = KOTLIN_1_6), ; val presentableName: String diff --git a/core/descriptors/src/org/jetbrains/kotlin/types/SpecialTypes.kt b/core/descriptors/src/org/jetbrains/kotlin/types/SpecialTypes.kt index 9026ca8d7f7..25961ed6c30 100644 --- a/core/descriptors/src/org/jetbrains/kotlin/types/SpecialTypes.kt +++ b/core/descriptors/src/org/jetbrains/kotlin/types/SpecialTypes.kt @@ -97,7 +97,7 @@ class DefinitelyNotNullType private constructor( DefinitelyNotNullTypeMarker { companion object { - internal fun makeDefinitelyNotNull( + fun makeDefinitelyNotNull( type: UnwrappedType, useCorrectedNullabilityForTypeParameters: Boolean = false ): DefinitelyNotNullType? {