Include package part name to top level closure names

#KT-4234 Fixed
 #KT-4496 Fixed
This commit is contained in:
Alexander Udalov
2014-09-19 19:27:22 +04:00
parent 7b374b9509
commit c30aa7db84
26 changed files with 93 additions and 74 deletions
@@ -19,7 +19,6 @@ package org.jetbrains.jet.codegen;
import com.intellij.openapi.vfs.StandardFileSystems;
import com.intellij.openapi.vfs.VfsUtilCore;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.util.containers.Stack;
import kotlin.Function1;
import kotlin.KotlinPackage;
import org.jetbrains.annotations.NotNull;
@@ -67,10 +66,6 @@ public class JvmCodegenUtil {
return closure.getCaptureThis() == null && closure.getCaptureReceiverType() == null && closure.getCaptureVariables().isEmpty();
}
public static <T> T peekFromStack(Stack<T> stack) {
return stack.empty() ? null : stack.peek();
}
private static boolean isCallInsideSameClassAsDeclared(@NotNull CallableMemberDescriptor descriptor, @NotNull CodegenContext context) {
boolean isFakeOverride = descriptor.getKind() == CallableMemberDescriptor.Kind.FAKE_OVERRIDE;
boolean isDelegate = descriptor.getKind() == CallableMemberDescriptor.Kind.DELEGATION;
@@ -36,6 +36,7 @@ import org.jetbrains.jet.lang.descriptors.impl.ClassDescriptorImpl;
import org.jetbrains.jet.lang.psi.*;
import org.jetbrains.jet.lang.resolve.BindingContext;
import org.jetbrains.jet.lang.resolve.BindingTrace;
import org.jetbrains.jet.lang.resolve.DescriptorToSourceUtils;
import org.jetbrains.jet.lang.resolve.DescriptorUtils;
import org.jetbrains.jet.lang.resolve.calls.callUtil.CallUtilPackage;
import org.jetbrains.jet.lang.resolve.calls.model.ExpressionValueArgument;
@@ -45,9 +46,7 @@ import org.jetbrains.jet.lang.resolve.constants.CompileTimeConstant;
import org.jetbrains.jet.lang.resolve.constants.EnumValue;
import org.jetbrains.jet.lang.resolve.constants.NullValue;
import org.jetbrains.jet.lang.resolve.java.JvmAbi;
import org.jetbrains.jet.lang.resolve.java.PackageClassUtils;
import org.jetbrains.jet.lang.resolve.kotlin.PackagePartClassUtils;
import org.jetbrains.jet.lang.resolve.name.FqName;
import org.jetbrains.jet.lang.resolve.name.Name;
import org.jetbrains.jet.lang.resolve.scopes.JetScope;
import org.jetbrains.jet.lang.resolve.source.SourcePackage;
@@ -56,7 +55,6 @@ import org.jetbrains.org.objectweb.asm.Type;
import java.util.*;
import static org.jetbrains.jet.codegen.JvmCodegenUtil.peekFromStack;
import static org.jetbrains.jet.codegen.binding.CodegenBinding.*;
import static org.jetbrains.jet.lang.resolve.BindingContext.*;
import static org.jetbrains.jet.lang.resolve.name.SpecialNames.safeIdentifier;
@@ -401,14 +399,12 @@ class CodegenAnnotatingVisitor extends JetVisitorVoid {
return peek + '$' + name;
}
else if (containingDeclaration instanceof PackageFragmentDescriptor) {
FqName qualifiedName = ((PackageFragmentDescriptor) containingDeclaration).getFqName();
String packageClassShortName = PackageClassUtils.getPackageClassName(qualifiedName);
String packageClassName = peek.isEmpty() ? packageClassShortName : peek + "/" + packageClassShortName;
return packageClassName + '$' + name;
}
else {
return null;
JetFile containingFile = DescriptorToSourceUtils.getContainingFile(descriptor);
assert containingFile != null : "File not found for " + descriptor;
return PackagePartClassUtils.getPackagePartInternalName(containingFile) + '$' + name;
}
return null;
}
@Override
@@ -547,7 +543,7 @@ class CodegenAnnotatingVisitor extends JetVisitorVoid {
@NotNull
private String getCurrentTopLevelClassOrPackagePartInternalName(@NotNull JetFile file) {
ListIterator<ClassDescriptorWithState> iterator = classStack.listIterator(classStack.size());
while(iterator.hasPrevious()) {
while (iterator.hasPrevious()) {
ClassDescriptor previous = iterator.previous().getDescriptor();
if (DescriptorUtils.isTopLevelOrInnerClass(previous)) {
return CodegenBinding.getAsmType(bindingContext, previous).getInternalName();
@@ -556,4 +552,8 @@ class CodegenAnnotatingVisitor extends JetVisitorVoid {
return PackagePartClassUtils.getPackagePartInternalName(file);
}
private static <T> T peekFromStack(@NotNull Stack<T> stack) {
return stack.empty() ? null : stack.peek();
}
}
@@ -33,9 +33,7 @@ import org.jetbrains.jet.lang.resolve.BindingTrace;
import org.jetbrains.jet.lang.resolve.DescriptorToSourceUtils;
import org.jetbrains.jet.lang.resolve.java.JvmAbi;
import org.jetbrains.jet.lang.resolve.java.JvmClassName;
import org.jetbrains.jet.lang.resolve.java.PackageClassUtils;
import org.jetbrains.jet.lang.resolve.kotlin.PackagePartClassUtils;
import org.jetbrains.jet.lang.resolve.name.FqName;
import org.jetbrains.jet.lang.resolve.name.Name;
import org.jetbrains.org.objectweb.asm.Type;
@@ -82,14 +80,14 @@ public final class PsiCodegenPredictor {
}
}
else {
FqName packageFqName = declaration.getContainingJetFile().getPackageFqName();
JetFile containingFile = declaration.getContainingJetFile();
if (declaration instanceof JetNamedFunction) {
Name name = ((JetNamedFunction) declaration).getNameAsName();
return name == null ? null : PackageClassUtils.getPackageClassInternalName(packageFqName) + "$" + name.asString();
return name == null ? null : PackagePartClassUtils.getPackagePartInternalName(containingFile) + "$" + name.asString();
}
parentInternalName = AsmUtil.internalNameByFqNameWithoutInnerClasses(packageFqName);
parentInternalName = AsmUtil.internalNameByFqNameWithoutInnerClasses(containingFile.getPackageFqName());
}
if (declaration instanceof JetClassObject) {
@@ -8,6 +8,6 @@ fun foo1() {
}
}
// METHOD : _DefaultPackage$foo1$1.invoke(I)V
// VARIABLE : NAME=this TYPE=L_DefaultPackage$foo1$1; INDEX=0
// METHOD : _DefaultPackage*$foo1$1.invoke(I)V
// VARIABLE : NAME=this TYPE=L_DefaultPackage*$foo1$1; INDEX=0
// VARIABLE : NAME=it TYPE=I INDEX=1
@@ -6,6 +6,6 @@ fun foo() {
}
}
// METHOD : _DefaultPackage$foo$1$1.invoke(I)V
// VARIABLE : NAME=this TYPE=L_DefaultPackage$foo$1$1; INDEX=0
// METHOD : _DefaultPackage*$foo$1$1.invoke(I)V
// VARIABLE : NAME=this TYPE=L_DefaultPackage*$foo$1$1; INDEX=0
// VARIABLE : NAME=it TYPE=I INDEX=1
@@ -4,5 +4,5 @@ fun foo() {
}
}
// METHOD : _DefaultPackage$foo$a$1.invoke()V
// VARIABLE : NAME=this TYPE=L_DefaultPackage$foo$a$1; INDEX=0
// METHOD : _DefaultPackage*$foo$a$1.invoke()V
// VARIABLE : NAME=this TYPE=L_DefaultPackage*$foo$a$1; INDEX=0
@@ -3,5 +3,5 @@ fun foo() {
}
}
// METHOD : _DefaultPackage$foo$1.invoke()V
// VARIABLE : NAME=this TYPE=L_DefaultPackage$foo$1; INDEX=0
// METHOD : _DefaultPackage*$foo$1.invoke()V
// VARIABLE : NAME=this TYPE=L_DefaultPackage*$foo$1; INDEX=0
@@ -8,8 +8,8 @@ fun box(): String {
val enclosingMethod = classInLambda.javaClass.getEnclosingMethod()
if (enclosingMethod?.getName() != "invoke") return "method: $enclosingMethod"
val enclosingClass = classInLambda.javaClass.getEnclosingClass()
if (enclosingClass?.getName() != "_DefaultPackage\$box\$classInLambda\$1") return "enclosing class: $enclosingClass"
val enclosingClass = classInLambda.javaClass.getEnclosingClass()!!.getName()
if (!enclosingClass.startsWith("_DefaultPackage\$") || !enclosingClass.endsWith("\$box\$classInLambda\$1")) return "enclosing class: $enclosingClass"
//KT-5092
//val declaringClass = classInLambda.javaClass.getDeclaringClass()
@@ -7,8 +7,8 @@ fun box(): String {
val enclosingMethod = objectInLambda.javaClass.getEnclosingMethod()
if (enclosingMethod?.getName() != "invoke") return "method: $enclosingMethod"
val enclosingClass = objectInLambda.javaClass.getEnclosingClass()
if (enclosingClass?.getName() != "_DefaultPackage\$box\$objectInLambda\$1") return "enclosing class: $enclosingClass"
val enclosingClass = objectInLambda.javaClass.getEnclosingClass()!!.getName()
if (!enclosingClass.startsWith("_DefaultPackage\$") || !enclosingClass.endsWith("\$box\$objectInLambda\$1")) return "enclosing class: $enclosingClass"
//KT-5092
//val declaringClass = objectInLambda.javaClass.getDeclaringClass()
@@ -7,8 +7,8 @@ fun box(): String {
val enclosingMethod = javaClass.getEnclosingMethod()
if (enclosingMethod?.getName() != "invoke") return "method: $enclosingMethod"
val enclosingClass = javaClass.getEnclosingClass()
if (enclosingClass!!.getName() != "_DefaultPackage\$box\$l$1") return "enclosing class: $enclosingClass"
val enclosingClass = javaClass.getEnclosingClass()!!.getName()
if (!enclosingClass.startsWith("_DefaultPackage\$") || !enclosingClass.contains("\$box\$l\$1")) return "enclosing class: $enclosingClass"
val declaringClass = javaClass.getDeclaringClass()
if (declaringClass != null) return "anonymous function has a declaring class: $declaringClass"
@@ -6,11 +6,13 @@ fun box(): String {
val l = L()
val javaClass = l.a.javaClass
val enclosingMethod = javaClass.getEnclosingConstructor()
if (enclosingMethod?.getName() != "_DefaultPackage\$box\$L") return "ctor: $enclosingMethod"
val enclosingMethod = javaClass.getEnclosingConstructor()!!.getName()
if (!enclosingMethod.startsWith("_DefaultPackage\$") || !enclosingMethod.endsWith("\$box\$L")) return "ctor: $enclosingMethod"
val enclosingClass = javaClass.getEnclosingClass()
if (!enclosingClass!!.getName().startsWith("_DefaultPackage\$box\$L")) return "enclosing class: $enclosingClass"
val enclosingClass = javaClass.getEnclosingClass()!!.getName()
if (!enclosingClass.startsWith("_DefaultPackage\$") || !enclosingClass.endsWith("\$box\$L")) return "enclosing class: $enclosingClass"
if (enclosingMethod != enclosingClass) return "$enclosingClass != $enclosingMethod"
val declaringClass = javaClass.getDeclaringClass()
if (declaringClass != null) return "anonymous function has a declaring class: $declaringClass"
@@ -7,8 +7,8 @@ fun box(): String {
val enclosingMethod = javaClass.getEnclosingMethod()
if (enclosingMethod?.getName() != "invoke") return "method: $enclosingMethod"
val enclosingClass = javaClass.getEnclosingClass()
if (enclosingClass!!.getName() != "_DefaultPackage\$box$1") return "enclosing class: $enclosingClass"
val enclosingClass = javaClass.getEnclosingClass()!!.getName()
if (!enclosingClass.startsWith("_DefaultPackage\$") || !enclosingClass.contains("\$box$1")) return "enclosing class: $enclosingClass"
val declaringClass = javaClass.getDeclaringClass()
if (declaringClass != null) return "anonymous function has a declaring class: $declaringClass"
@@ -9,8 +9,8 @@ fun box(): String {
val enclosingMethod = javaClass.getEnclosingMethod()
if (enclosingMethod?.getName() != "foo") return "method: $enclosingMethod"
val enclosingClass = javaClass.getEnclosingClass()
if (enclosingClass?.getName() != "_DefaultPackage\$box\$C") return "enclosing class: $enclosingClass"
val enclosingClass = javaClass.getEnclosingClass()!!.getName()
if (!enclosingClass.startsWith("_DefaultPackage\$") || !enclosingClass.contains("\$box\$C")) return "enclosing class: $enclosingClass"
val declaringClass = javaClass.getDeclaringClass()
if (declaringClass != null) return "anonymous function has a declaring class: $declaringClass"
@@ -5,11 +5,13 @@ fun box(): String {
}
val javaClass = l.a.javaClass
val enclosingMethod = javaClass.getEnclosingConstructor()
if (enclosingMethod?.getName() != "_DefaultPackage\$box\$l\$1") return "ctor: $enclosingMethod"
val enclosingMethod = javaClass.getEnclosingConstructor()!!.getName()
if (!enclosingMethod.startsWith("_DefaultPackage\$") || !enclosingMethod.endsWith("\$box\$l\$1")) return "ctor: $enclosingMethod"
val enclosingClass = javaClass.getEnclosingClass()
if (!enclosingClass!!.getName().startsWith("_DefaultPackage\$box\$l\$1")) return "enclosing class: $enclosingClass"
val enclosingClass = javaClass.getEnclosingClass()!!.getName()
if (!enclosingClass.startsWith("_DefaultPackage\$") || !enclosingClass.endsWith("\$box\$l\$1")) return "enclosing class: $enclosingClass"
if (enclosingMethod != enclosingClass) return "$enclosingClass != $enclosingMethod"
val declaringClass = javaClass.getDeclaringClass()
if (declaringClass != null) return "anonymous function has a declaring class: $declaringClass"
@@ -0,0 +1,10 @@
// KT-4234
fun box(): String {
class C
val name = javaClass<C>().getSimpleName()
if (name != "box\$C") return "Fail: $name"
return "OK"
}
@@ -17,6 +17,6 @@ fun test() {
(::local)()
}
// 3 GETSTATIC _DefaultPackage\$test\$1\.INSTANCE\$
// 1 GETSTATIC _DefaultPackage\$test\$2\.INSTANCE\$
// 1 GETSTATIC _DefaultPackage\$test\$3\.INSTANCE\$
// 3 GETSTATIC _DefaultPackage\$.+\$test\$1\.INSTANCE\$
// 1 GETSTATIC _DefaultPackage\$.+\$test\$2\.INSTANCE\$
// 1 GETSTATIC _DefaultPackage\$.+\$test\$3\.INSTANCE\$
@@ -102,7 +102,10 @@ public abstract class AbstractCheckLocalVariablesTableTest extends TestCaseWithT
for (LocalVariable expectedVariable : expectedLocalVariables) {
LocalVariable actualVariable = actualLocalVariables.get(index);
assertEquals("Names are different", expectedVariable.name, actualVariable.name);
assertEquals("Types are different for " + expectedVariable.name, expectedVariable.type, actualVariable.type);
assertTrue(
String.format("Type doesn't match regex: name %s, regex %s, type %s", expectedVariable.name, expectedVariable.type, actualVariable.type),
actualVariable.type.matches(expectedVariable.type)
);
assertEquals("Indexes are different", expectedVariable.index, actualVariable.index);
index++;
}
@@ -149,7 +152,7 @@ public abstract class AbstractCheckLocalVariablesTableTest extends TestCaseWithT
expectedLocalVariables.add(new LocalVariable(nameMatcher.group(1),
typeMatcher.group(1),
StringUtil.escapeToRegexp(typeMatcher.group(1)).replace("\\*", ".+"),
Integer.parseInt(indexMatcher.group(1))));
}
}
@@ -1891,6 +1891,12 @@ public class BlackBoxWithStdlibCodegenTestGenerated extends AbstractBlackBoxCode
JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/codegen/boxWithStdlib/reflection/enclosing"), Pattern.compile("^(.+)\\.kt$"), true);
}
@TestMetadata("localClassInTopLevelFunction.kt")
public void testLocalClassInTopLevelFunction() throws Exception {
String fileName = JetTestUtils.navigationMetadata("compiler/testData/codegen/boxWithStdlib/reflection/enclosing/localClassInTopLevelFunction.kt");
doTestWithStdlib(fileName);
}
@TestMetadata("compiler/testData/codegen/boxWithStdlib/reflection/enclosing/insideLambda")
@TestDataPath("$PROJECT_ROOT")
@RunWith(org.jetbrains.jet.JUnit3RunnerWithInners.class)
@@ -25,9 +25,9 @@ fun foo(f: () -> Unit) {
}
// PRINT_FRAME
frame = invoke():11, FrameAnonymousObjectPackage$main$o$1$run$1 {frameAnonymousObject}
this = this = {frameAnonymousObject.FrameAnonymousObjectPackage$main$o$1$run$1@uniqueID}kotlin.Function0<kotlin.Unit>
field = this$0: frameAnonymousObject.FrameAnonymousObjectPackage$main$o$1 = {frameAnonymousObject.FrameAnonymousObjectPackage$main$o$1@uniqueID}
frame = invoke():11, FrameAnonymousObjectPackage$@packagePartHASH$main$o$1$run$1 {frameAnonymousObject}
this = this = {frameAnonymousObject.FrameAnonymousObjectPackage$@packagePartHASH$main$o$1$run$1@uniqueID}kotlin.Function0<kotlin.Unit>
field = this$0: frameAnonymousObject.FrameAnonymousObjectPackage$@packagePartHASH$main$o$1 = {frameAnonymousObject.FrameAnonymousObjectPackage$@packagePartHASH$main$o$1@uniqueID}
field = obProp: int = 1
field = $val1: int = 1
Disconnected from the target VM, address: '!HOST_NAME!:PORT_NAME!', transport: 'socket'
@@ -32,9 +32,9 @@ fun foo(f: () -> Unit) {
// EXPRESSION: val1 + val2
// RESULT: 2: I
frame = invoke():9, FrameInnerLambdaPackage$main$1$1 {frameInnerLambda}
this = this = {frameInnerLambda.FrameInnerLambdaPackage$main$1$1@uniqueID}kotlin.Function0<kotlin.Unit>
field = this$0: frameInnerLambda.FrameInnerLambdaPackage$main$1 = {frameInnerLambda.FrameInnerLambdaPackage$main$1@uniqueID}kotlin.Function0<kotlin.Unit>
frame = invoke():9, FrameInnerLambdaPackage$@packagePartHASH$main$1$1 {frameInnerLambda}
this = this = {frameInnerLambda.FrameInnerLambdaPackage$@packagePartHASH$main$1$1@uniqueID}kotlin.Function0<kotlin.Unit>
field = this$0: frameInnerLambda.FrameInnerLambdaPackage$@packagePartHASH$main$1 = {frameInnerLambda.FrameInnerLambdaPackage$@packagePartHASH$main$1@uniqueID}kotlin.Function0<kotlin.Unit>
field = $val1: int = 1
field = $val2: int = 1
Disconnected from the target VM, address: '!HOST_NAME!:PORT_NAME!', transport: 'socket'
@@ -21,8 +21,8 @@ fun foo(f: () -> Unit) {
// EXPRESSION: val1
// RESULT: 1: I
frame = invoke():7, FrameLambdaPackage$main$1 {frameLambda}
this = this = {frameLambda.FrameLambdaPackage$main$1@uniqueID}kotlin.Function0<kotlin.Unit>
frame = invoke():7, FrameLambdaPackage$@packagePartHASH$main$1 {frameLambda}
this = this = {frameLambda.FrameLambdaPackage$@packagePartHASH$main$1@uniqueID}kotlin.Function0<kotlin.Unit>
field = $val1: int = 1
Disconnected from the target VM, address: '!HOST_NAME!:PORT_NAME!', transport: 'socket'
@@ -21,8 +21,8 @@ fun foo(f: () -> Unit) {
// EXPRESSION: val1
// RESULT: Cannot find local variable: name = val1
frame = invoke():7, FrameLambdaNotUsedPackage$main$1 {frameLambdaNotUsed}
this = this = {frameLambdaNotUsed.FrameLambdaNotUsedPackage$main$1@uniqueID}kotlin.Function0<kotlin.Unit>
frame = invoke():7, FrameLambdaNotUsedPackage$@packagePartHASH$main$1 {frameLambdaNotUsed}
this = this = {frameLambdaNotUsed.FrameLambdaNotUsedPackage$@packagePartHASH$main$1@uniqueID}kotlin.Function0<kotlin.Unit>
local = a: int = 0
Disconnected from the target VM, address: '!HOST_NAME!:PORT_NAME!', transport: 'socket'
@@ -24,8 +24,8 @@ fun foo(f: () -> Unit) {
// EXPRESSION: O.obProp
// RESULT: 1: I
frame = invoke():6, FrameObjectPackage$main$1 {frameObject}
this = this = {frameObject.FrameObjectPackage$main$1@uniqueID}kotlin.Function0<kotlin.Unit>
frame = invoke():6, FrameObjectPackage$@packagePartHASH$main$1 {frameObject}
this = this = {frameObject.FrameObjectPackage$@packagePartHASH$main$1@uniqueID}kotlin.Function0<kotlin.Unit>
Disconnected from the target VM, address: '!HOST_NAME!:PORT_NAME!', transport: 'socket'
Process finished with exit code 0
@@ -17,8 +17,8 @@ fun foo(f: () -> Unit) {
}
// PRINT_FRAME
frame = invoke():7, FrameSharedVarPackage$main$1 {frameSharedVar}
this = this = {frameSharedVar.FrameSharedVarPackage$main$1@uniqueID}kotlin.Function0<kotlin.Unit>
frame = invoke():7, FrameSharedVarPackage$@packagePartHASH$main$1 {frameSharedVar}
this = this = {frameSharedVar.FrameSharedVarPackage$@packagePartHASH$main$1@uniqueID}kotlin.Function0<kotlin.Unit>
field = $var1: kotlin.jvm.internal.Ref$IntRef = {kotlin.jvm.internal.Ref$IntRef@uniqueID}1
field = element: int = 1
Disconnected from the target VM, address: '!HOST_NAME!:PORT_NAME!', transport: 'socket'
@@ -33,6 +33,7 @@ import kotlin.test.fail
import java.util.HashMap
import org.jetbrains.jet.utils.keysToMap
import org.jetbrains.jps.incremental.messages.BuildMessage
import java.util.regex.Pattern
public abstract class AbstractIncrementalJpsTest : JpsBuildTestCase() {
private var testDataDir: File by Delegates.notNull()
@@ -239,19 +240,21 @@ public abstract class AbstractIncrementalJpsTest : JpsBuildTestCase() {
override fun isEnabled(): Boolean = true
override fun logLine(message: String?) {
fun String.replaceHashWithStar(): String {
if (this contains "Package$") {
val lastDollar = this.lastIndexOf('$')
if (lastDollar != -1 && substring(lastDollar + 1).matches("[0-9a-f]{1,8}\\.class")) {
return substring(0, lastDollar) + "$*.class"
}
val matcher = STRIP_PACKAGE_PART_HASH_PATTERN.matcher(this)
if (matcher.find()) {
return matcher.replaceAll("\\$*")
}
return this
}
logBuf.append(message!!.trimLeading(rootPath + "/").replaceHashWithStar()).append('\n')
}
class object {
// We suspect sequences of several consecutive hexadecimal digits to be a package part hash code
val STRIP_PACKAGE_PART_HASH_PATTERN = Pattern.compile("\\$([0-9a-f]{5,8})")
}
}
private abstract class Modification(val path: String) {
@@ -1,6 +1,6 @@
Cleaning output files:
out/production/module/outer/nested/NestedPackage$main$1.class
out/production/module/outer/nested/NestedPackage-nested-*.class
out/production/module/outer/nested/NestedPackage$nested$*$main$1.class
out/production/module/outer/nested/NestedPackage$nested$*.class
out/production/module/outer/nested/NestedPackage.class
End of files
Compiling files: