fixed INACCESSIBLE_OUTER_CLASS_EXPRESSION check
for extension lambda (with implicit this) in nested class
This commit is contained in:
@@ -39,7 +39,6 @@ import org.jetbrains.jet.lang.resolve.scopes.WritableScopeImpl;
|
||||
import org.jetbrains.jet.lang.types.*;
|
||||
import org.jetbrains.jet.lang.types.checker.JetTypeChecker;
|
||||
import org.jetbrains.jet.lang.types.expressions.ExpressionTypingServices;
|
||||
import org.jetbrains.jet.lang.types.lang.InlineStrategy;
|
||||
import org.jetbrains.jet.lang.types.lang.KotlinBuiltIns;
|
||||
import org.jetbrains.jet.lexer.JetKeywordToken;
|
||||
import org.jetbrains.jet.lexer.JetTokens;
|
||||
@@ -1310,36 +1309,22 @@ public class DescriptorResolver {
|
||||
@NotNull PsiElement reportErrorsOn,
|
||||
@NotNull ClassDescriptor target
|
||||
) {
|
||||
return checkHasOuterClassInstance(scope, trace, reportErrorsOn, target, true);
|
||||
}
|
||||
ClassDescriptor classDescriptor = getContainingClass(scope);
|
||||
|
||||
public static boolean checkHasOuterClassInstance(
|
||||
@NotNull JetScope scope,
|
||||
@NotNull BindingTrace trace,
|
||||
@NotNull PsiElement reportErrorsOn,
|
||||
@NotNull ClassDescriptor target,
|
||||
boolean doSuperClassCheck
|
||||
) {
|
||||
DeclarationDescriptor descriptor = getContainingClass(scope);
|
||||
if (!isInsideOuterClassOrItsSubclass(classDescriptor, target)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
while (descriptor != null) {
|
||||
if (descriptor instanceof ClassDescriptor) {
|
||||
ClassDescriptor classDescriptor = (ClassDescriptor) descriptor;
|
||||
|
||||
if (classDescriptor == target) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (doSuperClassCheck && isSubclass(classDescriptor, target)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (isStaticNestedClass(classDescriptor)) {
|
||||
trace.report(INACCESSIBLE_OUTER_CLASS_EXPRESSION.on(reportErrorsOn, classDescriptor));
|
||||
return false;
|
||||
}
|
||||
while (classDescriptor != null) {
|
||||
if (isSubclass(classDescriptor, target)) {
|
||||
return true;
|
||||
}
|
||||
descriptor = descriptor.getContainingDeclaration();
|
||||
|
||||
if (isStaticNestedClass(classDescriptor)) {
|
||||
trace.report(INACCESSIBLE_OUTER_CLASS_EXPRESSION.on(reportErrorsOn, classDescriptor));
|
||||
return false;
|
||||
}
|
||||
classDescriptor = getParentOfType(classDescriptor, ClassDescriptor.class, true);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -135,8 +135,7 @@ public class TypeResolver {
|
||||
|
||||
DeclarationDescriptor containing = typeParameterDescriptor.getContainingDeclaration();
|
||||
if (containing instanceof ClassDescriptor) {
|
||||
// Type parameter can't be inherited from member of parent class, so we can skip subclass check
|
||||
DescriptorResolver.checkHasOuterClassInstance(c.scope, c.trace, referenceExpression, (ClassDescriptor) containing, false);
|
||||
DescriptorResolver.checkHasOuterClassInstance(c.scope, c.trace, referenceExpression, (ClassDescriptor) containing);
|
||||
}
|
||||
}
|
||||
else if (classifierDescriptor instanceof ClassDescriptor) {
|
||||
|
||||
@@ -0,0 +1,27 @@
|
||||
package f
|
||||
|
||||
object A {
|
||||
class LoginFormPage() : Request({
|
||||
val failed = session.get("LOGIN_FAILED")
|
||||
})
|
||||
}
|
||||
|
||||
class B {
|
||||
class object {
|
||||
class LoginFormPage() : Request({
|
||||
val failed = session.get("LOGIN_FAILED")
|
||||
})
|
||||
}
|
||||
|
||||
class C {
|
||||
class LoginFormPage() : Request({
|
||||
val failed = session.get("LOGIN_FAILED")
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
open class Request(private val handler: ActionContext.() -> Unit) {}
|
||||
|
||||
trait ActionContext {
|
||||
val session : Map<String, String>
|
||||
}
|
||||
@@ -4216,6 +4216,11 @@ public class JetDiagnosticsTestGenerated extends AbstractDiagnosticsTestWithEage
|
||||
doTest("compiler/testData/diagnostics/tests/inner/extensionFun.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("extensionLambdaInsideNestedClass.kt")
|
||||
public void testExtensionLambdaInsideNestedClass() throws Exception {
|
||||
doTest("compiler/testData/diagnostics/tests/inner/extensionLambdaInsideNestedClass.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("illegalModifier.kt")
|
||||
public void testIllegalModifier() throws Exception {
|
||||
doTest("compiler/testData/diagnostics/tests/inner/illegalModifier.kt");
|
||||
|
||||
@@ -421,6 +421,14 @@ public class DescriptorUtils {
|
||||
return parameterTypes;
|
||||
}
|
||||
|
||||
public static boolean isInsideOuterClassOrItsSubclass(@Nullable DeclarationDescriptor nested, @NotNull ClassDescriptor outer) {
|
||||
if (nested == null) return false;
|
||||
|
||||
if (nested instanceof ClassDescriptor && isSubclass((ClassDescriptor) nested, outer)) return true;
|
||||
|
||||
return isInsideOuterClassOrItsSubclass(nested.getContainingDeclaration(), outer);
|
||||
}
|
||||
|
||||
public static boolean isConstructorOfStaticNestedClass(@Nullable CallableDescriptor descriptor) {
|
||||
return descriptor instanceof ConstructorDescriptor && isStaticNestedClass(descriptor.getContainingDeclaration());
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user