From 0fffb9fb17a3b9271794b9db49ac9f311e7fa502 Mon Sep 17 00:00:00 2001 From: Toshiaki Kameyama Date: Wed, 1 Nov 2017 09:05:40 +0300 Subject: [PATCH] Introduce inspection for callables with implicit 'Nothing?' type Inspection is reported only for vars and open callables So #KT-21023 Fixed --- .../ImplicitNullableNothingType.html | 5 +++ idea/src/META-INF/plugin.xml | 9 +++++ .../ImplicitNullableNothingTypeInspection.kt | 35 +++++++++++++++++ .../ImplicitNullableNothingType/.inspection | 1 + .../ImplicitNullableNothingType/final.kt | 5 +++ .../ImplicitNullableNothingType/function.kt | 3 ++ .../function.kt.after | 3 ++ .../ImplicitNullableNothingType/top.kt | 3 ++ .../ImplicitNullableNothingType/val.kt | 3 ++ .../ImplicitNullableNothingType/variable.kt | 1 + .../variable.kt.after | 1 + .../LocalInspectionTestGenerated.java | 39 +++++++++++++++++++ 12 files changed, 108 insertions(+) create mode 100644 idea/resources/inspectionDescriptions/ImplicitNullableNothingType.html create mode 100644 idea/src/org/jetbrains/kotlin/idea/inspections/ImplicitNullableNothingTypeInspection.kt create mode 100644 idea/testData/inspectionsLocal/ImplicitNullableNothingType/.inspection create mode 100644 idea/testData/inspectionsLocal/ImplicitNullableNothingType/final.kt create mode 100644 idea/testData/inspectionsLocal/ImplicitNullableNothingType/function.kt create mode 100644 idea/testData/inspectionsLocal/ImplicitNullableNothingType/function.kt.after create mode 100644 idea/testData/inspectionsLocal/ImplicitNullableNothingType/top.kt create mode 100644 idea/testData/inspectionsLocal/ImplicitNullableNothingType/val.kt create mode 100644 idea/testData/inspectionsLocal/ImplicitNullableNothingType/variable.kt create mode 100644 idea/testData/inspectionsLocal/ImplicitNullableNothingType/variable.kt.after diff --git a/idea/resources/inspectionDescriptions/ImplicitNullableNothingType.html b/idea/resources/inspectionDescriptions/ImplicitNullableNothingType.html new file mode 100644 index 00000000000..7da70cffa19 --- /dev/null +++ b/idea/resources/inspectionDescriptions/ImplicitNullableNothingType.html @@ -0,0 +1,5 @@ + + +This inspection reports variables / functions with implicit `Nothing?` type. + + diff --git a/idea/src/META-INF/plugin.xml b/idea/src/META-INF/plugin.xml index 8eaad0d039c..888b4fcb85d 100644 --- a/idea/src/META-INF/plugin.xml +++ b/idea/src/META-INF/plugin.xml @@ -2642,6 +2642,15 @@ language="kotlin" /> + + diff --git a/idea/src/org/jetbrains/kotlin/idea/inspections/ImplicitNullableNothingTypeInspection.kt b/idea/src/org/jetbrains/kotlin/idea/inspections/ImplicitNullableNothingTypeInspection.kt new file mode 100644 index 00000000000..db5362a07ca --- /dev/null +++ b/idea/src/org/jetbrains/kotlin/idea/inspections/ImplicitNullableNothingTypeInspection.kt @@ -0,0 +1,35 @@ +/* + * Copyright 2010-2017 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.jetbrains.kotlin.idea.inspections + +import org.jetbrains.kotlin.idea.core.getModalityFromDescriptor +import org.jetbrains.kotlin.idea.intentions.SpecifyTypeExplicitlyIntention +import org.jetbrains.kotlin.lexer.KtTokens +import org.jetbrains.kotlin.psi.* +import org.jetbrains.kotlin.types.typeUtil.isNullableNothing + +class ImplicitNullableNothingTypeInspection : IntentionBasedInspection( + intention = SpecifyTypeExplicitlyIntention::class, + additionalChecker = { declaration -> + SpecifyTypeExplicitlyIntention.getTypeForDeclaration(declaration).isNullableNothing() && + (declaration.getModalityFromDescriptor() == KtTokens.OPEN_KEYWORD || + declaration is KtProperty && declaration.isVar) + }, + problemText = "Implicit `Nothing?` type" +) { + override fun inspectionTarget(element: KtCallableDeclaration) = element.nameIdentifier +} diff --git a/idea/testData/inspectionsLocal/ImplicitNullableNothingType/.inspection b/idea/testData/inspectionsLocal/ImplicitNullableNothingType/.inspection new file mode 100644 index 00000000000..63adbb2a955 --- /dev/null +++ b/idea/testData/inspectionsLocal/ImplicitNullableNothingType/.inspection @@ -0,0 +1 @@ +org.jetbrains.kotlin.idea.inspections.ImplicitNullableNothingTypeInspection diff --git a/idea/testData/inspectionsLocal/ImplicitNullableNothingType/final.kt b/idea/testData/inspectionsLocal/ImplicitNullableNothingType/final.kt new file mode 100644 index 00000000000..5d6973d7a7a --- /dev/null +++ b/idea/testData/inspectionsLocal/ImplicitNullableNothingType/final.kt @@ -0,0 +1,5 @@ +// PROBLEM: none + +class My { + fun foo() = null +} \ No newline at end of file diff --git a/idea/testData/inspectionsLocal/ImplicitNullableNothingType/function.kt b/idea/testData/inspectionsLocal/ImplicitNullableNothingType/function.kt new file mode 100644 index 00000000000..49067d35eef --- /dev/null +++ b/idea/testData/inspectionsLocal/ImplicitNullableNothingType/function.kt @@ -0,0 +1,3 @@ +open class My { + open fun foo() = null +} \ No newline at end of file diff --git a/idea/testData/inspectionsLocal/ImplicitNullableNothingType/function.kt.after b/idea/testData/inspectionsLocal/ImplicitNullableNothingType/function.kt.after new file mode 100644 index 00000000000..91320388588 --- /dev/null +++ b/idea/testData/inspectionsLocal/ImplicitNullableNothingType/function.kt.after @@ -0,0 +1,3 @@ +open class My { + open fun foo(): Nothing? = null +} \ No newline at end of file diff --git a/idea/testData/inspectionsLocal/ImplicitNullableNothingType/top.kt b/idea/testData/inspectionsLocal/ImplicitNullableNothingType/top.kt new file mode 100644 index 00000000000..564598b775a --- /dev/null +++ b/idea/testData/inspectionsLocal/ImplicitNullableNothingType/top.kt @@ -0,0 +1,3 @@ +// PROBLEM: none + +fun foo() = null \ No newline at end of file diff --git a/idea/testData/inspectionsLocal/ImplicitNullableNothingType/val.kt b/idea/testData/inspectionsLocal/ImplicitNullableNothingType/val.kt new file mode 100644 index 00000000000..ef9cc666823 --- /dev/null +++ b/idea/testData/inspectionsLocal/ImplicitNullableNothingType/val.kt @@ -0,0 +1,3 @@ +// PROBLEM: none + +val x = null \ No newline at end of file diff --git a/idea/testData/inspectionsLocal/ImplicitNullableNothingType/variable.kt b/idea/testData/inspectionsLocal/ImplicitNullableNothingType/variable.kt new file mode 100644 index 00000000000..fea3df898b7 --- /dev/null +++ b/idea/testData/inspectionsLocal/ImplicitNullableNothingType/variable.kt @@ -0,0 +1 @@ +var x = null \ No newline at end of file diff --git a/idea/testData/inspectionsLocal/ImplicitNullableNothingType/variable.kt.after b/idea/testData/inspectionsLocal/ImplicitNullableNothingType/variable.kt.after new file mode 100644 index 00000000000..18ba9e9adc2 --- /dev/null +++ b/idea/testData/inspectionsLocal/ImplicitNullableNothingType/variable.kt.after @@ -0,0 +1 @@ +var x: Nothing? = null \ No newline at end of file diff --git a/idea/tests/org/jetbrains/kotlin/idea/inspections/LocalInspectionTestGenerated.java b/idea/tests/org/jetbrains/kotlin/idea/inspections/LocalInspectionTestGenerated.java index 5bddd35489e..74b8f23883c 100644 --- a/idea/tests/org/jetbrains/kotlin/idea/inspections/LocalInspectionTestGenerated.java +++ b/idea/tests/org/jetbrains/kotlin/idea/inspections/LocalInspectionTestGenerated.java @@ -582,6 +582,45 @@ public class LocalInspectionTestGenerated extends AbstractLocalInspectionTest { } } + @TestMetadata("idea/testData/inspectionsLocal/ImplicitNullableNothingType") + @TestDataPath("$PROJECT_ROOT") + @RunWith(JUnit3RunnerWithInners.class) + public static class ImplicitNullableNothingType extends AbstractLocalInspectionTest { + public void testAllFilesPresentInImplicitNullableNothingType() throws Exception { + KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("idea/testData/inspectionsLocal/ImplicitNullableNothingType"), Pattern.compile("^([\\w\\-_]+)\\.kt$"), TargetBackend.ANY, true); + } + + @TestMetadata("final.kt") + public void testFinal() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("idea/testData/inspectionsLocal/ImplicitNullableNothingType/final.kt"); + doTest(fileName); + } + + @TestMetadata("function.kt") + public void testFunction() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("idea/testData/inspectionsLocal/ImplicitNullableNothingType/function.kt"); + doTest(fileName); + } + + @TestMetadata("top.kt") + public void testTop() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("idea/testData/inspectionsLocal/ImplicitNullableNothingType/top.kt"); + doTest(fileName); + } + + @TestMetadata("val.kt") + public void testVal() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("idea/testData/inspectionsLocal/ImplicitNullableNothingType/val.kt"); + doTest(fileName); + } + + @TestMetadata("variable.kt") + public void testVariable() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("idea/testData/inspectionsLocal/ImplicitNullableNothingType/variable.kt"); + doTest(fileName); + } + } + @TestMetadata("idea/testData/inspectionsLocal/kdocMissingDocumentation") @TestDataPath("$PROJECT_ROOT") @RunWith(JUnit3RunnerWithInners.class)