Implicit callable type check refactoring, additional check for property with explicit Nothing type
This commit is contained in:
@@ -727,6 +727,7 @@ public interface Errors {
|
||||
DiagnosticFactory2<KtElement, KotlinType, KotlinType> INCOMPATIBLE_TYPES = DiagnosticFactory2.create(ERROR);
|
||||
|
||||
DiagnosticFactory0<PsiElement> IMPLICIT_NOTHING_RETURN_TYPE = DiagnosticFactory0.create(ERROR);
|
||||
DiagnosticFactory0<PsiElement> IMPLICIT_NOTHING_PROPERTY_TYPE = DiagnosticFactory0.create(WARNING);
|
||||
DiagnosticFactory1<PsiElement, KotlinType> IMPLICIT_INTERSECTION_TYPE = DiagnosticFactory1.create(ERROR);
|
||||
|
||||
// Context tracking
|
||||
|
||||
+1
@@ -527,6 +527,7 @@ public class DefaultErrorMessages {
|
||||
MAP.put(TYPE_MISMATCH_IN_CONDITION, "Condition must be of type kotlin.Boolean, but is of type {0}", RENDER_TYPE);
|
||||
MAP.put(INCOMPATIBLE_TYPES, "Incompatible types: {0} and {1}", RENDER_TYPE, RENDER_TYPE);
|
||||
MAP.put(IMPLICIT_NOTHING_RETURN_TYPE, "''Nothing'' return type needs to be specified explicitly");
|
||||
MAP.put(IMPLICIT_NOTHING_PROPERTY_TYPE, "Deprecated: ''Nothing'' property type needs to be specified explicitly");
|
||||
MAP.put(IMPLICIT_INTERSECTION_TYPE, "Inferred type {0} is an intersection, please specify the required type explicitly", RENDER_TYPE);
|
||||
MAP.put(EXPECTED_CONDITION, "Expected condition of type kotlin.Boolean");
|
||||
|
||||
|
||||
@@ -435,13 +435,7 @@ class DeclarationsChecker(
|
||||
checkTypeParameterConstraints(property)
|
||||
checkPropertyExposedType(property, propertyDescriptor)
|
||||
checkPropertyTypeParametersAreUsedInReceiverType(propertyDescriptor)
|
||||
propertyDescriptor.returnType?.let {
|
||||
if (property.typeReference == null) {
|
||||
if (it.constructor is IntersectionTypeConstructor) {
|
||||
trace.report(IMPLICIT_INTERSECTION_TYPE.on(property.nameIdentifier ?: property, it))
|
||||
}
|
||||
}
|
||||
}
|
||||
checkImplicitCallableType(property, propertyDescriptor)
|
||||
}
|
||||
|
||||
private fun checkPropertyTypeParametersAreUsedInReceiverType(descriptor: PropertyDescriptor) {
|
||||
@@ -656,19 +650,25 @@ class DeclarationsChecker(
|
||||
if (!function.hasBody() && !hasAbstractModifier && !hasExternalModifier) {
|
||||
trace.report(NON_MEMBER_FUNCTION_NO_BODY.on(function, functionDescriptor))
|
||||
}
|
||||
functionDescriptor.returnType?.let {
|
||||
if (!function.hasDeclaredReturnType()) {
|
||||
checkImplicitCallableType(function, functionDescriptor)
|
||||
checkFunctionExposedType(function, functionDescriptor)
|
||||
checkVarargParameters(trace, functionDescriptor)
|
||||
}
|
||||
|
||||
private fun checkImplicitCallableType(declaration: KtCallableDeclaration, descriptor: CallableDescriptor) {
|
||||
descriptor.returnType?.let {
|
||||
if (declaration.typeReference == null) {
|
||||
val target = declaration.nameIdentifier ?: declaration
|
||||
if (it.isNothing()) {
|
||||
trace.report(IMPLICIT_NOTHING_RETURN_TYPE.on(nameIdentifier ?: function))
|
||||
trace.report(
|
||||
(if (declaration is KtProperty) IMPLICIT_NOTHING_PROPERTY_TYPE else IMPLICIT_NOTHING_RETURN_TYPE).on(target)
|
||||
)
|
||||
}
|
||||
if (it.constructor is IntersectionTypeConstructor) {
|
||||
trace.report(IMPLICIT_INTERSECTION_TYPE.on(nameIdentifier ?: function, it))
|
||||
trace.report(IMPLICIT_INTERSECTION_TYPE.on(target, it))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
checkFunctionExposedType(function, functionDescriptor)
|
||||
checkVarargParameters(trace, functionDescriptor)
|
||||
}
|
||||
|
||||
private fun checkFunctionExposedType(function: KtFunction, functionDescriptor: FunctionDescriptor) {
|
||||
|
||||
@@ -5,3 +5,14 @@ fun <!IMPLICIT_NOTHING_RETURN_TYPE!>bar<!>() = null!!
|
||||
fun <!IMPLICIT_NOTHING_RETURN_TYPE!>baz<!>() = bar()
|
||||
|
||||
fun gav(): Any = null!!
|
||||
|
||||
val <!IMPLICIT_NOTHING_PROPERTY_TYPE!>x<!> = null!!
|
||||
|
||||
val y: Nothing = throw Exception()
|
||||
|
||||
fun check() {
|
||||
// Error: KT-10449
|
||||
fun local() = bar()
|
||||
// Unreachable / unused, but not implicit Nothing
|
||||
<!UNREACHABLE_CODE!>val <!UNUSED_VARIABLE!>x<!> =<!> null!!
|
||||
}
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
package
|
||||
|
||||
public val x: kotlin.Nothing
|
||||
public val y: kotlin.Nothing
|
||||
public fun bar(): kotlin.Nothing
|
||||
public fun baz(): kotlin.Nothing
|
||||
public fun check(): kotlin.Unit
|
||||
public fun foo(): kotlin.Nothing
|
||||
public fun gav(): kotlin.Any
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
fun fn(): Nothing = throw java.lang.RuntimeException("oops")
|
||||
|
||||
val x = throw java.lang.RuntimeException("oops")
|
||||
val x: Nothing = throw java.lang.RuntimeException("oops")
|
||||
|
||||
class SomeClass {
|
||||
fun method() {
|
||||
|
||||
Reference in New Issue
Block a user