Error diagnostic for private classes in inline functions; Fix for KT-7545: IllegalAccessError when accessing private nested class through inlined function from different package
#KT-7545 Fixed
This commit is contained in:
@@ -32,7 +32,6 @@ import org.jetbrains.kotlin.resolve.calls.inference.InferenceErrorData;
|
||||
import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall;
|
||||
import org.jetbrains.kotlin.resolve.varianceChecker.VarianceChecker.VarianceConflictDiagnosticData;
|
||||
import org.jetbrains.kotlin.types.KotlinType;
|
||||
import org.jetbrains.kotlin.types.TypeProjection;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.Modifier;
|
||||
@@ -774,6 +773,7 @@ public interface Errors {
|
||||
|
||||
//Inline and inlinable parameters
|
||||
DiagnosticFactory2<KtElement, DeclarationDescriptor, DeclarationDescriptor> INVISIBLE_MEMBER_FROM_INLINE = DiagnosticFactory2.create(ERROR, CALL_ELEMENT);
|
||||
DiagnosticFactory2<KtElement, DeclarationDescriptor, DeclarationDescriptor> PRIVATE_CLASS_MEMBER_FROM_INLINE = DiagnosticFactory2.create(ERROR, CALL_ELEMENT);
|
||||
DiagnosticFactory1<KtElement, KtElement> NON_LOCAL_RETURN_NOT_ALLOWED = DiagnosticFactory1.create(ERROR, CALL_ELEMENT);
|
||||
DiagnosticFactory2<KtElement, KtNamedDeclaration, DeclarationDescriptor> NOT_YET_SUPPORTED_IN_INLINE = DiagnosticFactory2.create(ERROR);
|
||||
DiagnosticFactory1<PsiElement, DeclarationDescriptor> NOTHING_TO_INLINE = DiagnosticFactory1.create(WARNING);
|
||||
|
||||
+2
@@ -733,6 +733,8 @@ public class DefaultErrorMessages {
|
||||
|
||||
//Inline
|
||||
MAP.put(INVISIBLE_MEMBER_FROM_INLINE, "Public-API inline function cannot access non-public-API ''{0}''", SHORT_NAMES_IN_TYPES, SHORT_NAMES_IN_TYPES);
|
||||
MAP.put(PRIVATE_CLASS_MEMBER_FROM_INLINE, "Non-private inline function cannot access members of private classes: ''{0}''", SHORT_NAMES_IN_TYPES, SHORT_NAMES_IN_TYPES);
|
||||
|
||||
MAP.put(NOT_YET_SUPPORTED_IN_INLINE, "''{0}'' construction is not yet supported in inline functions", ELEMENT_TEXT, SHORT_NAMES_IN_TYPES);
|
||||
MAP.put(DECLARATION_CANT_BE_INLINED, "''inline'' modifier is not allowed on virtual members. Only private or final members can be inlined");
|
||||
MAP.put(NOTHING_TO_INLINE, "Expected performance impact of inlining ''{0}'' can be insignificant. Inlining works best for functions with lambda parameters", SHORT_NAMES_IN_TYPES);
|
||||
|
||||
+17
-2
@@ -93,7 +93,7 @@ class InlineChecker implements CallChecker {
|
||||
}
|
||||
}
|
||||
|
||||
checkVisibility(targetDescriptor, expression, context);
|
||||
checkVisibilityAndAccess(targetDescriptor, expression, context);
|
||||
checkRecursion(context, targetDescriptor, expression);
|
||||
}
|
||||
|
||||
@@ -238,11 +238,26 @@ class InlineChecker implements CallChecker {
|
||||
return isInvoke || InlineUtil.isInline(descriptor);
|
||||
}
|
||||
|
||||
private void checkVisibility(@NotNull CallableDescriptor declarationDescriptor, @NotNull KtElement expression, @NotNull BasicCallResolutionContext context){
|
||||
private void checkVisibilityAndAccess(@NotNull CallableDescriptor declarationDescriptor, @NotNull KtElement expression, @NotNull BasicCallResolutionContext context){
|
||||
boolean declarationDescriptorIsPublicApi = DescriptorUtilsKt.isEffectivelyPublicApi(declarationDescriptor) || isDefinedInInlineFunction(declarationDescriptor);
|
||||
if (isEffectivelyPublicApiFunction && !declarationDescriptorIsPublicApi && declarationDescriptor.getVisibility() != Visibilities.LOCAL) {
|
||||
context.trace.report(Errors.INVISIBLE_MEMBER_FROM_INLINE.on(expression, declarationDescriptor, descriptor));
|
||||
}
|
||||
else {
|
||||
checkPrivateClassMemberAccess(declarationDescriptor, expression, context);
|
||||
}
|
||||
}
|
||||
|
||||
private void checkPrivateClassMemberAccess(
|
||||
@NotNull DeclarationDescriptor declarationDescriptor,
|
||||
@NotNull KtElement expression,
|
||||
@NotNull BasicCallResolutionContext context
|
||||
) {
|
||||
if (!Visibilities.isPrivate(descriptor.getVisibility())) {
|
||||
if (DescriptorUtilsKt.isInsidePrivateClass(declarationDescriptor)) {
|
||||
context.trace.report(Errors.PRIVATE_CLASS_MEMBER_FROM_INLINE.on(expression, declarationDescriptor, descriptor));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private boolean isDefinedInInlineFunction(@NotNull DeclarationDescriptorWithVisibility startDescriptor) {
|
||||
|
||||
Reference in New Issue
Block a user