Fix supressing no body errors for external functions

This commit is contained in:
Alexey Tsvetkov
2015-10-16 22:05:10 +03:00
parent 1e2256207c
commit 7a1b6ed13f
4 changed files with 10 additions and 15 deletions
@@ -16,10 +16,7 @@
package org.jetbrains.kotlin.load.kotlin.nativeDeclarations package org.jetbrains.kotlin.load.kotlin.nativeDeclarations
import org.jetbrains.kotlin.descriptors.CallableMemberDescriptor import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.descriptors.ConstructorDescriptor
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
import org.jetbrains.kotlin.descriptors.Modality
import org.jetbrains.kotlin.diagnostics.DiagnosticSink import org.jetbrains.kotlin.diagnostics.DiagnosticSink
import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.psi.JetDeclaration import org.jetbrains.kotlin.psi.JetDeclaration
@@ -33,15 +30,13 @@ import org.jetbrains.kotlin.resolve.inline.InlineUtil
import org.jetbrains.kotlin.resolve.jvm.diagnostics.ErrorsJvm import org.jetbrains.kotlin.resolve.jvm.diagnostics.ErrorsJvm
private val NATIVE_ANNOTATION_CLASS_NAME = FqName("kotlin.jvm.native") private val NATIVE_ANNOTATION_CLASS_NAME = FqName("kotlin.jvm.native")
private val EXTERNAL_ANNOTATION_CLASS_NAME = FqName("kotlin.external")
public fun DeclarationDescriptor.hasNativeAnnotation(): Boolean { public fun DeclarationDescriptor.hasNativeAnnotation(): Boolean {
return getAnnotations().findAnnotation(EXTERNAL_ANNOTATION_CLASS_NAME) != null return this is FunctionDescriptor && this.isExternal
|| this is PropertyAccessorDescriptor && this.isExternal
|| annotations.findAnnotation(NATIVE_ANNOTATION_CLASS_NAME) != null || annotations.findAnnotation(NATIVE_ANNOTATION_CLASS_NAME) != null
} }
public class SuppressNoBodyErrorsForExternalDeclarations : SuppressDiagnosticsByAnnotations(FUNCTION_NO_BODY_ERRORS, EXTERNAL_ANNOTATION_CLASS_NAME)
public class SuppressNoBodyErrorsForNativeDeclarations : SuppressDiagnosticsByAnnotations(FUNCTION_NO_BODY_ERRORS, NATIVE_ANNOTATION_CLASS_NAME) public class SuppressNoBodyErrorsForNativeDeclarations : SuppressDiagnosticsByAnnotations(FUNCTION_NO_BODY_ERRORS, NATIVE_ANNOTATION_CLASS_NAME)
public class NativeFunChecker : DeclarationChecker { public class NativeFunChecker : DeclarationChecker {
@@ -25,7 +25,6 @@ import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import org.jetbrains.kotlin.builtins.KotlinBuiltIns; import org.jetbrains.kotlin.builtins.KotlinBuiltIns;
import org.jetbrains.kotlin.descriptors.*; import org.jetbrains.kotlin.descriptors.*;
import org.jetbrains.kotlin.diagnostics.DiagnosticFactory1;
import org.jetbrains.kotlin.diagnostics.DiagnosticFactory0; import org.jetbrains.kotlin.diagnostics.DiagnosticFactory0;
import org.jetbrains.kotlin.diagnostics.Errors; import org.jetbrains.kotlin.diagnostics.Errors;
import org.jetbrains.kotlin.lexer.JetModifierKeywordToken; import org.jetbrains.kotlin.lexer.JetModifierKeywordToken;
@@ -714,6 +713,8 @@ public class DeclarationsChecker {
DeclarationDescriptor containingDescriptor = functionDescriptor.getContainingDeclaration(); DeclarationDescriptor containingDescriptor = functionDescriptor.getContainingDeclaration();
boolean hasAbstractModifier = function.hasModifier(JetTokens.ABSTRACT_KEYWORD); boolean hasAbstractModifier = function.hasModifier(JetTokens.ABSTRACT_KEYWORD);
boolean hasExternalModifier = function.hasModifier(JetTokens.EXTERNAL_KEYWORD);
if (containingDescriptor instanceof ClassDescriptor) { if (containingDescriptor instanceof ClassDescriptor) {
ClassDescriptor classDescriptor = (ClassDescriptor) containingDescriptor; ClassDescriptor classDescriptor = (ClassDescriptor) containingDescriptor;
boolean inTrait = classDescriptor.getKind() == ClassKind.INTERFACE; boolean inTrait = classDescriptor.getKind() == ClassKind.INTERFACE;
@@ -728,19 +729,19 @@ public class DeclarationsChecker {
trace.report(ABSTRACT_FUNCTION_WITH_BODY.on(function, functionDescriptor)); trace.report(ABSTRACT_FUNCTION_WITH_BODY.on(function, functionDescriptor));
} }
if (!hasBody && inTrait) { if (!hasBody && inTrait) {
if (function.hasModifier(JetTokens.FINAL_KEYWORD)) { if (function.hasModifier(JetTokens.FINAL_KEYWORD) && !hasExternalModifier) {
trace.report(FINAL_FUNCTION_WITH_NO_BODY.on(function, functionDescriptor)); trace.report(FINAL_FUNCTION_WITH_NO_BODY.on(function, functionDescriptor));
} }
if (function.hasModifier(JetTokens.PRIVATE_KEYWORD)) { if (function.hasModifier(JetTokens.PRIVATE_KEYWORD)) {
trace.report(PRIVATE_FUNCTION_WITH_NO_BODY.on(function, functionDescriptor)); trace.report(PRIVATE_FUNCTION_WITH_NO_BODY.on(function, functionDescriptor));
} }
} }
if (!hasBody && !hasAbstractModifier && !inTrait) { if (!hasBody && !hasAbstractModifier && !hasExternalModifier && !inTrait) {
trace.report(NON_ABSTRACT_FUNCTION_WITH_NO_BODY.on(function, functionDescriptor)); trace.report(NON_ABSTRACT_FUNCTION_WITH_NO_BODY.on(function, functionDescriptor));
} }
return; return;
} }
if (!function.hasBody() && !hasAbstractModifier) { if (!function.hasBody() && !hasAbstractModifier && !hasExternalModifier) {
trace.report(NON_MEMBER_FUNCTION_NO_BODY.on(function, functionDescriptor)); trace.report(NON_MEMBER_FUNCTION_NO_BODY.on(function, functionDescriptor));
} }
if (TypeUtilsKt.isNothing(functionDescriptor.getReturnType()) && !function.hasDeclaredReturnType()) { if (TypeUtilsKt.isNothing(functionDescriptor.getReturnType()) && !function.hasDeclaredReturnType()) {
@@ -25,6 +25,7 @@ import org.jetbrains.kotlin.descriptors.impl.AnonymousFunctionDescriptor
import org.jetbrains.kotlin.descriptors.impl.SimpleFunctionDescriptorImpl import org.jetbrains.kotlin.descriptors.impl.SimpleFunctionDescriptorImpl
import org.jetbrains.kotlin.diagnostics.DiagnosticUtils import org.jetbrains.kotlin.diagnostics.DiagnosticUtils
import org.jetbrains.kotlin.diagnostics.Errors.* import org.jetbrains.kotlin.diagnostics.Errors.*
import org.jetbrains.kotlin.lexer.JetTokens
import org.jetbrains.kotlin.psi.* import org.jetbrains.kotlin.psi.*
import org.jetbrains.kotlin.psi.psiUtil.getAnnotationEntries import org.jetbrains.kotlin.psi.psiUtil.getAnnotationEntries
import org.jetbrains.kotlin.resolve.* import org.jetbrains.kotlin.resolve.*
@@ -38,7 +39,6 @@ import org.jetbrains.kotlin.types.TypeUtils
import org.jetbrains.kotlin.types.TypeUtils.CANT_INFER_FUNCTION_PARAM_TYPE import org.jetbrains.kotlin.types.TypeUtils.CANT_INFER_FUNCTION_PARAM_TYPE
import org.jetbrains.kotlin.types.TypeUtils.NO_EXPECTED_TYPE import org.jetbrains.kotlin.types.TypeUtils.NO_EXPECTED_TYPE
import org.jetbrains.kotlin.types.TypeUtils.noExpectedType import org.jetbrains.kotlin.types.TypeUtils.noExpectedType
import org.jetbrains.kotlin.types.checker.JetTypeChecker
import org.jetbrains.kotlin.types.expressions.CoercionStrategy.COERCION_TO_UNIT import org.jetbrains.kotlin.types.expressions.CoercionStrategy.COERCION_TO_UNIT
import org.jetbrains.kotlin.types.expressions.typeInfoFactory.createTypeInfo import org.jetbrains.kotlin.types.expressions.typeInfoFactory.createTypeInfo
import org.jetbrains.kotlin.utils.addIfNotNull import org.jetbrains.kotlin.utils.addIfNotNull
@@ -104,7 +104,7 @@ public class FunctionsTypingVisitor(facade: ExpressionTypingInternals) : Express
components.modifiersChecker.withTrace(context.trace).checkModifiersForLocalDeclaration(function, functionDescriptor) components.modifiersChecker.withTrace(context.trace).checkModifiersForLocalDeclaration(function, functionDescriptor)
components.identifierChecker.checkDeclaration(function, context.trace) components.identifierChecker.checkDeclaration(function, context.trace)
if (!function.hasBody()) { if (!function.hasBody() && !function.hasModifier(JetTokens.EXTERNAL_KEYWORD)) {
context.trace.report(NON_MEMBER_FUNCTION_NO_BODY.on(function, functionDescriptor)) context.trace.report(NON_MEMBER_FUNCTION_NO_BODY.on(function, functionDescriptor))
} }
@@ -4,7 +4,6 @@
<extensions defaultExtensionNs="org.jetbrains.kotlin"> <extensions defaultExtensionNs="org.jetbrains.kotlin">
<defaultErrorMessages implementation="org.jetbrains.kotlin.resolve.jvm.diagnostics.DefaultErrorMessagesJvm"/> <defaultErrorMessages implementation="org.jetbrains.kotlin.resolve.jvm.diagnostics.DefaultErrorMessagesJvm"/>
<suppressStringProvider implementation="org.jetbrains.kotlin.load.kotlin.nativeDeclarations.SuppressNoBodyErrorsForExternalDeclarations"/>
<suppressStringProvider implementation="org.jetbrains.kotlin.load.kotlin.nativeDeclarations.SuppressNoBodyErrorsForNativeDeclarations"/> <suppressStringProvider implementation="org.jetbrains.kotlin.load.kotlin.nativeDeclarations.SuppressNoBodyErrorsForNativeDeclarations"/>
<classBuilderInterceptorExtension implementation="org.jetbrains.kotlin.annotation.AnnotationCollectorExtension"/> <classBuilderInterceptorExtension implementation="org.jetbrains.kotlin.annotation.AnnotationCollectorExtension"/>