KT-1547 Wrong layout of closure classes
#KT-1547 fixed
This commit is contained in:
+37
-18
@@ -17,6 +17,8 @@
|
||||
package org.jetbrains.jet.codegen.binding;
|
||||
|
||||
import com.intellij.util.containers.Stack;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.jet.lang.descriptors.*;
|
||||
import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor;
|
||||
import org.jetbrains.jet.lang.descriptors.impl.ClassDescriptorImpl;
|
||||
@@ -243,7 +245,17 @@ class CodegenAnnotatingVisitor extends JetVisitorVoid {
|
||||
|
||||
@Override
|
||||
public void visitProperty(JetProperty property) {
|
||||
nameStack.push(peekFromStack(nameStack) + '$' + property.getName());
|
||||
DeclarationDescriptor propertyDescriptor = bindingContext.get(DECLARATION_TO_DESCRIPTOR, property);
|
||||
// working around a problem with shallow analysis
|
||||
if (propertyDescriptor == null) return;
|
||||
|
||||
String nameForClassOrNamespaceMember = getNameForClassOrNamespaceMember(propertyDescriptor);
|
||||
if (nameForClassOrNamespaceMember != null) {
|
||||
nameStack.push(nameForClassOrNamespaceMember);
|
||||
}
|
||||
else {
|
||||
nameStack.push(peekFromStack(nameStack) + '$' + property.getName());
|
||||
}
|
||||
super.visitProperty(property);
|
||||
nameStack.pop();
|
||||
}
|
||||
@@ -254,23 +266,10 @@ class CodegenAnnotatingVisitor extends JetVisitorVoid {
|
||||
(FunctionDescriptor) bindingContext.get(DECLARATION_TO_DESCRIPTOR, function);
|
||||
// working around a problem with shallow analysis
|
||||
if (functionDescriptor == null) return;
|
||||
DeclarationDescriptor containingDeclaration = functionDescriptor.getContainingDeclaration();
|
||||
if (containingDeclaration instanceof ClassDescriptor) {
|
||||
nameStack.push(peekFromStack(nameStack) + '$' + function.getName());
|
||||
super.visitNamedFunction(function);
|
||||
nameStack.pop();
|
||||
}
|
||||
else if (containingDeclaration instanceof NamespaceDescriptor) {
|
||||
String peek = peekFromStack(nameStack);
|
||||
FqName qualifiedName = ((NamespaceDescriptor) containingDeclaration).getFqName();
|
||||
String packageClassName = PackageClassUtils.getPackageClassName(qualifiedName);
|
||||
if (peek.isEmpty()) {
|
||||
peek = packageClassName;
|
||||
}
|
||||
else {
|
||||
peek += "/" + packageClassName;
|
||||
}
|
||||
nameStack.push(peek + '$' + function.getName());
|
||||
|
||||
String nameForClassOrNamespaceMember = getNameForClassOrNamespaceMember(functionDescriptor);
|
||||
if (nameForClassOrNamespaceMember != null) {
|
||||
nameStack.push(nameForClassOrNamespaceMember);
|
||||
super.visitNamedFunction(function);
|
||||
nameStack.pop();
|
||||
}
|
||||
@@ -286,4 +285,24 @@ class CodegenAnnotatingVisitor extends JetVisitorVoid {
|
||||
classStack.pop();
|
||||
}
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private String getNameForClassOrNamespaceMember(@NotNull DeclarationDescriptor descriptor) {
|
||||
DeclarationDescriptor containingDeclaration = descriptor.getContainingDeclaration();
|
||||
|
||||
String peek = peekFromStack(nameStack);
|
||||
String name = descriptor.getName().getName();
|
||||
if (containingDeclaration instanceof ClassDescriptor) {
|
||||
return peek + '$' + name;
|
||||
}
|
||||
else if (containingDeclaration instanceof NamespaceDescriptor) {
|
||||
FqName qualifiedName = ((NamespaceDescriptor) containingDeclaration).getFqName();
|
||||
String packageClassShortName = PackageClassUtils.getPackageClassName(qualifiedName);
|
||||
String packageClassName = peek.isEmpty() ? packageClassShortName : peek + "/" + packageClassShortName;
|
||||
return packageClassName + '$' + name;
|
||||
}
|
||||
else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
package test
|
||||
|
||||
val p = { "OK" }()
|
||||
|
||||
val getter: String
|
||||
get() = { "OK" }()
|
||||
|
||||
fun f() = { "OK" }()
|
||||
|
||||
val obj = object : Function0<String>() {
|
||||
override fun invoke() = "OK"
|
||||
}
|
||||
|
||||
fun box(): String {
|
||||
if (p != "OK") return "FAIL"
|
||||
if (getter != "OK") return "FAIL"
|
||||
if (f() != "OK") return "FAIL"
|
||||
if (obj() != "OK") return "FAIL"
|
||||
|
||||
return "OK"
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
val p = { "OK" }()
|
||||
|
||||
val getter: String
|
||||
get() = { "OK" }()
|
||||
|
||||
fun f() = { "OK" }()
|
||||
|
||||
val obj = object : Function0<String>() {
|
||||
override fun invoke() = "OK"
|
||||
}
|
||||
|
||||
fun box(): String {
|
||||
if (p != "OK") return "FAIL"
|
||||
if (getter != "OK") return "FAIL"
|
||||
if (f() != "OK") return "FAIL"
|
||||
if (obj() != "OK") return "FAIL"
|
||||
|
||||
return "OK"
|
||||
}
|
||||
@@ -65,7 +65,7 @@ public class OuterClassGenTest extends CodegenTestCase {
|
||||
|
||||
public void testObjectLiteralInPackageClass() throws Exception {
|
||||
OuterClassInfo expectedInfo = new OuterClassInfo("foo/FooPackage$src$outerClassInfo$", null, null);
|
||||
doCustomTest("foo$packageObjectLiteral$1", expectedInfo);
|
||||
doCustomTest("foo.FooPackage$packageObjectLiteral$1", expectedInfo);
|
||||
}
|
||||
|
||||
public void testLocalClassInTopLevelFunction() throws Exception {
|
||||
|
||||
@@ -921,6 +921,16 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest {
|
||||
doTest("compiler/testData/codegen/box/closures/closureInsideConstrucor.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("closureOnTopLevel1.kt")
|
||||
public void testClosureOnTopLevel1() throws Exception {
|
||||
doTest("compiler/testData/codegen/box/closures/closureOnTopLevel1.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("closureOnTopLevel2.kt")
|
||||
public void testClosureOnTopLevel2() throws Exception {
|
||||
doTest("compiler/testData/codegen/box/closures/closureOnTopLevel2.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("closureWithParameter.kt")
|
||||
public void testClosureWithParameter() throws Exception {
|
||||
doTest("compiler/testData/codegen/box/closures/closureWithParameter.kt");
|
||||
|
||||
Reference in New Issue
Block a user