Implicit callable type check refactoring, additional check for property with explicit Nothing type

This commit is contained in:
Mikhail Glukhikh
2015-12-22 20:25:26 +03:00
parent 6b8b39a7bd
commit 15746cbf56
6 changed files with 31 additions and 15 deletions
@@ -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
@@ -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) {
+11
View File
@@ -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,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() {