From e994b718cb48adaa15e6ebdc42b6e923a0e789fa Mon Sep 17 00:00:00 2001 From: Evgeny Gerashchenko Date: Sat, 11 Jan 2014 01:41:45 +0400 Subject: [PATCH] KT-4351 Cannot resolve reference to self in init of class local to function #KT-4351 fixed --- .../jet/lang/resolve/TopDownAnalyzer.java | 6 +++- .../ClosureExpressionsTypingVisitor.java | 3 +- .../ExpressionTypingVisitorForStatements.java | 12 ++------ .../regressions/referenceToSelfInLocal.kt | 18 ++++++++++++ .../tests/inner/referenceToSelfInLocal.kt | 29 +++++++++++++++++++ .../checkers/JetDiagnosticsTestGenerated.java | 5 ++++ ...lackBoxWithStdlibCodegenTestGenerated.java | 5 ++++ 7 files changed, 66 insertions(+), 12 deletions(-) create mode 100644 compiler/testData/codegen/boxWithStdlib/regressions/referenceToSelfInLocal.kt create mode 100644 compiler/testData/diagnostics/tests/inner/referenceToSelfInLocal.kt diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/TopDownAnalyzer.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/TopDownAnalyzer.java index 23023eb003a..c510900d2b4 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/TopDownAnalyzer.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/TopDownAnalyzer.java @@ -20,6 +20,7 @@ import com.google.common.base.Predicates; import com.google.common.collect.Sets; import com.intellij.psi.PsiElement; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; import org.jetbrains.jet.di.InjectorForTopDownAnalyzerBasic; import org.jetbrains.jet.lang.PlatformToKotlinClassMap; import org.jetbrains.jet.lang.descriptors.*; @@ -157,6 +158,7 @@ public class TopDownAnalyzer { } public static void processClassOrObject( + @Nullable final WritableScope scope, @NotNull ExpressionTypingContext context, @NotNull final DeclarationDescriptor containingDeclaration, @NotNull JetClassOrObject object @@ -185,7 +187,9 @@ public class TopDownAnalyzer { @Override public void addClassifierDescriptor(@NotNull MutableClassDescriptorLite classDescriptor) { - + if (scope != null) { + scope.addClassifierDescriptor(classDescriptor); + } } @Override diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/ClosureExpressionsTypingVisitor.java b/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/ClosureExpressionsTypingVisitor.java index 77d001b0407..40f4e9f9c5e 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/ClosureExpressionsTypingVisitor.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/ClosureExpressionsTypingVisitor.java @@ -85,7 +85,8 @@ public class ClosureExpressionsTypingVisitor extends ExpressionTypingVisitor { }; ObservableBindingTrace traceAdapter = new ObservableBindingTrace(temporaryTrace); traceAdapter.addHandler(CLASS, handler); - TopDownAnalyzer.processClassOrObject(context.replaceBindingTrace(traceAdapter).replaceContextDependency(INDEPENDENT), + TopDownAnalyzer.processClassOrObject(null, // don't need to add classifier of object literal to any scope + context.replaceBindingTrace(traceAdapter).replaceContextDependency(INDEPENDENT), context.scope.getContainingDeclaration(), expression.getObjectDeclaration()); diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/ExpressionTypingVisitorForStatements.java b/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/ExpressionTypingVisitorForStatements.java index 543d3d4c687..82589d82241 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/ExpressionTypingVisitorForStatements.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/ExpressionTypingVisitorForStatements.java @@ -85,11 +85,7 @@ public class ExpressionTypingVisitorForStatements extends ExpressionTypingVisito @Override public JetTypeInfo visitObjectDeclaration(@NotNull JetObjectDeclaration declaration, ExpressionTypingContext context) { TopDownAnalyzer.processClassOrObject( - context.replaceScope(scope).replaceContextDependency(INDEPENDENT), scope.getContainingDeclaration(), declaration); - ClassDescriptor classDescriptor = context.trace.getBindingContext().get(BindingContext.CLASS, declaration); - if (classDescriptor != null) { - scope.addClassifierDescriptor(classDescriptor); - } + scope, context.replaceScope(scope).replaceContextDependency(INDEPENDENT), scope.getContainingDeclaration(), declaration); return DataFlowUtils.checkStatementType(declaration, context, context.dataFlowInfo); } @@ -181,11 +177,7 @@ public class ExpressionTypingVisitorForStatements extends ExpressionTypingVisito @Override public JetTypeInfo visitClass(@NotNull JetClass klass, ExpressionTypingContext context) { TopDownAnalyzer.processClassOrObject( - context.replaceScope(scope).replaceContextDependency(INDEPENDENT), scope.getContainingDeclaration(), klass); - ClassDescriptor classDescriptor = context.trace.getBindingContext().get(BindingContext.CLASS, klass); - if (classDescriptor != null) { - scope.addClassifierDescriptor(classDescriptor); - } + scope, context.replaceScope(scope).replaceContextDependency(INDEPENDENT), scope.getContainingDeclaration(), klass); return DataFlowUtils.checkStatementType(klass, context, context.dataFlowInfo); } diff --git a/compiler/testData/codegen/boxWithStdlib/regressions/referenceToSelfInLocal.kt b/compiler/testData/codegen/boxWithStdlib/regressions/referenceToSelfInLocal.kt new file mode 100644 index 00000000000..f0facfa445c --- /dev/null +++ b/compiler/testData/codegen/boxWithStdlib/regressions/referenceToSelfInLocal.kt @@ -0,0 +1,18 @@ +// KT-4351 Cannot resolve reference to self in init of class local to function + +fun box(): String { + var accessedFromConstructor: Class<*>? = null + + class MyClass() { + { + accessedFromConstructor = javaClass() + } + } + + MyClass() + if (accessedFromConstructor!!.getName().endsWith("MyClass")) { + return "OK" + } else { + return accessedFromConstructor.toString() + } +} diff --git a/compiler/testData/diagnostics/tests/inner/referenceToSelfInLocal.kt b/compiler/testData/diagnostics/tests/inner/referenceToSelfInLocal.kt new file mode 100644 index 00000000000..e49bfee8248 --- /dev/null +++ b/compiler/testData/diagnostics/tests/inner/referenceToSelfInLocal.kt @@ -0,0 +1,29 @@ +// KT-4351 Cannot resolve reference to self in init of class local to function + +fun f() { + class MyClass() { + { + val x: MyClass = MyClass() + } + + fun member() { + val x: MyClass = MyClass() + } + } + + object MyObject { + { + val obj: MyObject = MyObject + } + } + + val x: MyClass = MyClass() +} + +val closure = { + class MyClass { + { + val x: MyClass = MyClass() + } + } +} diff --git a/compiler/tests/org/jetbrains/jet/checkers/JetDiagnosticsTestGenerated.java b/compiler/tests/org/jetbrains/jet/checkers/JetDiagnosticsTestGenerated.java index ea29668fff2..169cbba66dd 100644 --- a/compiler/tests/org/jetbrains/jet/checkers/JetDiagnosticsTestGenerated.java +++ b/compiler/tests/org/jetbrains/jet/checkers/JetDiagnosticsTestGenerated.java @@ -4331,6 +4331,11 @@ public class JetDiagnosticsTestGenerated extends AbstractJetDiagnosticsTest { doTest("compiler/testData/diagnostics/tests/inner/outerSuperClassMember.kt"); } + @TestMetadata("referenceToSelfInLocal.kt") + public void testReferenceToSelfInLocal() throws Exception { + doTest("compiler/testData/diagnostics/tests/inner/referenceToSelfInLocal.kt"); + } + @TestMetadata("resolvePackageClassInObjects.kt") public void testResolvePackageClassInObjects() throws Exception { doTest("compiler/testData/diagnostics/tests/inner/resolvePackageClassInObjects.kt"); diff --git a/compiler/tests/org/jetbrains/jet/codegen/generated/BlackBoxWithStdlibCodegenTestGenerated.java b/compiler/tests/org/jetbrains/jet/codegen/generated/BlackBoxWithStdlibCodegenTestGenerated.java index 3b9be0f05df..493792a3c9c 100644 --- a/compiler/tests/org/jetbrains/jet/codegen/generated/BlackBoxWithStdlibCodegenTestGenerated.java +++ b/compiler/tests/org/jetbrains/jet/codegen/generated/BlackBoxWithStdlibCodegenTestGenerated.java @@ -1013,6 +1013,11 @@ public class BlackBoxWithStdlibCodegenTestGenerated extends AbstractBlackBoxCode doTestWithStdlib("compiler/testData/codegen/boxWithStdlib/regressions/kt864.kt"); } + @TestMetadata("referenceToSelfInLocal.kt") + public void testReferenceToSelfInLocal() throws Exception { + doTestWithStdlib("compiler/testData/codegen/boxWithStdlib/regressions/referenceToSelfInLocal.kt"); + } + @TestMetadata("typeCastException.kt") public void testTypeCastException() throws Exception { doTestWithStdlib("compiler/testData/codegen/boxWithStdlib/regressions/typeCastException.kt");