crazy bug with constructing object of the same class as calling class
This commit is contained in:
Generated
+1
-1
@@ -1,7 +1,7 @@
|
||||
<component name="libraryTable">
|
||||
<library name="idea-full">
|
||||
<CLASSES>
|
||||
<root url="file://$PROJECT_DIR$/ideaSDK/lib" />
|
||||
<root url="file://$PROJECT_DIR$/IdeaSDK/lib" />
|
||||
</CLASSES>
|
||||
<JAVADOC />
|
||||
<SOURCES />
|
||||
|
||||
Generated
+1
-1
@@ -1,7 +1,7 @@
|
||||
<component name="libraryTable">
|
||||
<library name="intellij-core">
|
||||
<CLASSES>
|
||||
<root url="file://$PROJECT_DIR$/ideaSDK/core" />
|
||||
<root url="file://$PROJECT_DIR$/IdeaSDK/core" />
|
||||
</CLASSES>
|
||||
<JAVADOC />
|
||||
<SOURCES />
|
||||
|
||||
@@ -36,7 +36,7 @@ public class CompilationException extends RuntimeException {
|
||||
col = -1;
|
||||
}
|
||||
|
||||
return "Internal error: (" + (line+1) + "," + col + ") " + (getCause().getMessage() != null ? getCause().getMessage() : getCause().toString());
|
||||
return "Internal error: (" + (line+1) + "," + col + ") " + (getCause().getMessage() != null ? getCause().getMessage() : getCause().toString()) + "\n@" + getCause().getStackTrace()[0].getFileName() + ":" + getCause().getStackTrace()[0].getLineNumber();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -782,6 +782,15 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
|
||||
}
|
||||
}
|
||||
|
||||
if(closureCodegen.superCall != null) {
|
||||
ConstructorDescriptor superConstructor = (ConstructorDescriptor) bindingContext.get(BindingContext.REFERENCE_TARGET, ((JetDelegatorToSuperCall) closureCodegen.superCall).getCalleeExpression().getConstructorReferenceExpression());
|
||||
CallableMethod superCallable = typeMapper.mapToCallableMethod(superConstructor, OwnerKind.IMPLEMENTATION);
|
||||
Type[] argumentTypes = superCallable.getSignature().getAsmMethod().getArgumentTypes();
|
||||
Collections.addAll(consArgTypes, argumentTypes);
|
||||
ResolvedCall resolvedCall = bindingContext.get(BindingContext.RESOLVED_CALL, closureCodegen.superCall.getCalleeExpression());
|
||||
pushMethodArguments(resolvedCall, Arrays.asList(argumentTypes));
|
||||
}
|
||||
|
||||
Method cons = new Method("<init>", Type.VOID_TYPE, consArgTypes.toArray(new Type[consArgTypes.size()]));
|
||||
v.invokespecial(closure.getClassname(), "<init>", cons.getDescriptor());
|
||||
return StackValue.onStack(Type.getObjectType(closure.getClassname()));
|
||||
|
||||
@@ -21,6 +21,8 @@ import org.objectweb.asm.commons.Method;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
import static org.jetbrains.jet.codegen.JetTypeMapper.TYPE_OBJECT;
|
||||
|
||||
/**
|
||||
* @author max
|
||||
* @author yole
|
||||
@@ -212,6 +214,9 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
||||
try {
|
||||
generatePrimaryConstructor();
|
||||
}
|
||||
catch (CompilationException e) {
|
||||
throw e;
|
||||
}
|
||||
catch(RuntimeException e) {
|
||||
throw new RuntimeException("Error generating primary constructor of class " + myClass.getName() + " with kind " + kind, e);
|
||||
}
|
||||
@@ -396,6 +401,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
||||
}
|
||||
|
||||
ObjectOrClosureCodegen closure = context.closure;
|
||||
int firstSuperArgument = -1;
|
||||
if(closure != null) {
|
||||
final LinkedList<JvmMethodParameterSignature> consArgTypes = new LinkedList<JvmMethodParameterSignature>(constructorMethod.getKotlinParameterTypes());
|
||||
|
||||
@@ -424,6 +430,18 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
||||
}
|
||||
}
|
||||
|
||||
if(myClass instanceof JetObjectDeclaration) {
|
||||
if(superCall instanceof JetDelegatorToSuperCall) {
|
||||
closure.superCall = (JetDelegatorToSuperCall) superCall;
|
||||
ConstructorDescriptor superConstructor = (ConstructorDescriptor) bindingContext.get(BindingContext.REFERENCE_TARGET, ((JetDelegatorToSuperCall) superCall).getCalleeExpression().getConstructorReferenceExpression());
|
||||
CallableMethod superCallable = typeMapper.mapToCallableMethod(superConstructor, OwnerKind.IMPLEMENTATION);
|
||||
firstSuperArgument = insert;
|
||||
for(Type t : superCallable.getSignature().getAsmMethod().getArgumentTypes()) {
|
||||
consArgTypes.add(insert++, new JvmMethodParameterSignature(t, "", JvmMethodParameterKind.SHARED_VAR));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
constructorMethod = JvmMethodSignature.simple("<init>", Type.VOID_TYPE, consArgTypes);
|
||||
}
|
||||
|
||||
@@ -488,32 +506,31 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
||||
}
|
||||
}
|
||||
|
||||
if (superCall == null || superCall instanceof JetDelegatorToSuperClass) {
|
||||
if (superCall == null) {
|
||||
iv.load(0, Type.getType("L" + superClass + ";"));
|
||||
if(superCall == null) {
|
||||
iv.invokespecial(superClass, "<init>", "()V");
|
||||
iv.invokespecial(superClass, "<init>", "()V");
|
||||
}
|
||||
else if (superCall instanceof JetDelegatorToSuperClass) {
|
||||
iv.load(0, Type.getType("L" + superClass + ";"));
|
||||
JetType superType = bindingContext.get(BindingContext.TYPE, superCall.getTypeReference());
|
||||
List<Type> parameterTypes = new ArrayList<Type>();
|
||||
assert superType != null;
|
||||
ClassDescriptor superClassDescriptor = (ClassDescriptor) superType.getConstructor().getDeclarationDescriptor();
|
||||
if (CodegenUtil.hasThis0(superClassDescriptor)) {
|
||||
iv.load(1, JetTypeMapper.TYPE_OBJECT);
|
||||
parameterTypes.add(typeMapper.mapType(CodegenUtil.getOuterClassDescriptor(descriptor).getDefaultType(), OwnerKind.IMPLEMENTATION));
|
||||
}
|
||||
else {
|
||||
JetType superType = bindingContext.get(BindingContext.TYPE, superCall.getTypeReference());
|
||||
List<Type> parameterTypes = new ArrayList<Type>();
|
||||
assert superType != null;
|
||||
ClassDescriptor superClassDescriptor = (ClassDescriptor) superType.getConstructor().getDeclarationDescriptor();
|
||||
if (CodegenUtil.hasThis0(superClassDescriptor)) {
|
||||
iv.load(1, JetTypeMapper.TYPE_OBJECT);
|
||||
parameterTypes.add(typeMapper.mapType(CodegenUtil.getOuterClassDescriptor(descriptor).getDefaultType(), OwnerKind.IMPLEMENTATION));
|
||||
}
|
||||
for(TypeProjection typeParameterDescriptor : superType.getArguments()) {
|
||||
codegen.generateTypeInfo(typeParameterDescriptor.getType(), null);
|
||||
parameterTypes.add(JetTypeMapper.TYPE_TYPEINFO);
|
||||
}
|
||||
Method superCallMethod = new Method("<init>", Type.VOID_TYPE, parameterTypes.toArray(new Type[parameterTypes.size()]));
|
||||
iv.invokespecial(typeMapper.mapType(superClassDescriptor.getDefaultType(), OwnerKind.IMPLEMENTATION).getInternalName(), "<init>", superCallMethod.getDescriptor());
|
||||
for(TypeProjection typeParameterDescriptor : superType.getArguments()) {
|
||||
codegen.generateTypeInfo(typeParameterDescriptor.getType(), null);
|
||||
parameterTypes.add(JetTypeMapper.TYPE_TYPEINFO);
|
||||
}
|
||||
Method superCallMethod = new Method("<init>", Type.VOID_TYPE, parameterTypes.toArray(new Type[parameterTypes.size()]));
|
||||
iv.invokespecial(typeMapper.mapType(superClassDescriptor.getDefaultType(), OwnerKind.IMPLEMENTATION).getInternalName(), "<init>", superCallMethod.getDescriptor());
|
||||
}
|
||||
else {
|
||||
iv.load(0, classType);
|
||||
ConstructorDescriptor constructorDescriptor1 = (ConstructorDescriptor) bindingContext.get(BindingContext.REFERENCE_TARGET, ((JetDelegatorToSuperCall) superCall).getCalleeExpression().getConstructorReferenceExpression());
|
||||
generateDelegatorToConstructorCall(iv, codegen, (JetDelegatorToSuperCall) superCall, constructorDescriptor1, frameMap);
|
||||
generateDelegatorToConstructorCall(iv, codegen, (JetDelegatorToSuperCall) superCall, constructorDescriptor1, frameMap, firstSuperArgument);
|
||||
}
|
||||
|
||||
int n = 0;
|
||||
@@ -685,10 +702,9 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
||||
|
||||
private void generateDelegatorToConstructorCall(InstructionAdapter iv, ExpressionCodegen codegen, JetCallElement constructorCall,
|
||||
ConstructorDescriptor constructorDescriptor,
|
||||
ConstructorFrameMap frameMap) {
|
||||
ConstructorFrameMap frameMap, int firstSuperArgument) {
|
||||
ClassDescriptor classDecl = constructorDescriptor.getContainingDeclaration();
|
||||
Type type;
|
||||
type = typeMapper.mapType(classDecl.getDefaultType(), OwnerKind.IMPLEMENTATION);
|
||||
Type type = typeMapper.mapType(classDecl.getDefaultType(), OwnerKind.IMPLEMENTATION);
|
||||
|
||||
iv.load(0, type);
|
||||
|
||||
@@ -697,7 +713,20 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
||||
}
|
||||
|
||||
CallableMethod method = typeMapper.mapToCallableMethod(constructorDescriptor, kind);
|
||||
codegen.invokeMethodWithArguments(method, constructorCall, StackValue.none());
|
||||
if(myClass instanceof JetObjectDeclaration && superCall instanceof JetDelegatorToSuperCall) {
|
||||
iv.load(0, TYPE_OBJECT);
|
||||
ConstructorDescriptor superConstructor = (ConstructorDescriptor) bindingContext.get(BindingContext.REFERENCE_TARGET, ((JetDelegatorToSuperCall) superCall).getCalleeExpression().getConstructorReferenceExpression());
|
||||
CallableMethod superCallable = typeMapper.mapToCallableMethod(superConstructor, OwnerKind.IMPLEMENTATION);
|
||||
int nextVar = firstSuperArgument+1;
|
||||
for(Type t : superCallable.getSignature().getAsmMethod().getArgumentTypes()) {
|
||||
iv.load(nextVar, t);
|
||||
nextVar += t.getSize();
|
||||
}
|
||||
method.invoke(codegen.v);
|
||||
}
|
||||
else {
|
||||
codegen.invokeMethodWithArguments(method, constructorCall, StackValue.none());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -785,7 +814,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
||||
if (!(thisDescriptor instanceof ConstructorDescriptor)) {
|
||||
throw new UnsupportedOperationException("expected 'this' delegator to resolve to constructor");
|
||||
}
|
||||
generateDelegatorToConstructorCall(iv, codegen, thisCall, (ConstructorDescriptor) thisDescriptor, frameMap);
|
||||
generateDelegatorToConstructorCall(iv, codegen, thisCall, (ConstructorDescriptor) thisDescriptor, frameMap, flags);
|
||||
}
|
||||
else {
|
||||
throw new UnsupportedOperationException("unknown initializer type");
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package org.jetbrains.jet.codegen;
|
||||
|
||||
import org.jetbrains.jet.lang.descriptors.*;
|
||||
import org.jetbrains.jet.lang.psi.JetDelegatorToSuperCall;
|
||||
import org.objectweb.asm.Opcodes;
|
||||
import org.objectweb.asm.Type;
|
||||
|
||||
@@ -20,6 +21,7 @@ public class ObjectOrClosureCodegen {
|
||||
protected ClassBuilder cv = null;
|
||||
public String name = null;
|
||||
protected Map<DeclarationDescriptor, EnclosedValueDescriptor> closure = new LinkedHashMap<DeclarationDescriptor, EnclosedValueDescriptor>();
|
||||
public JetDelegatorToSuperCall superCall;
|
||||
|
||||
public ObjectOrClosureCodegen(ExpressionCodegen exprContext, CodegenContext context, GenerationState state) {
|
||||
this.exprContext = exprContext;
|
||||
|
||||
@@ -0,0 +1,10 @@
|
||||
class B () {}
|
||||
|
||||
open class A(val b : B) {
|
||||
fun a() = object: A(b) {}
|
||||
}
|
||||
|
||||
fun box() : String {
|
||||
A(B()).a()
|
||||
return "OK"
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
import java.util.concurrent.ConcurrentLinkedQueue
|
||||
import java.util.List
|
||||
|
||||
public object RefreshQueue {
|
||||
private val queue = ConcurrentLinkedQueue<List<String>>
|
||||
|
||||
private val workerThread = Thread(object : Runnable {
|
||||
override fun run() {
|
||||
while (!workerThread.isInterrupted()) {
|
||||
try {
|
||||
// synchronized(queue) {
|
||||
// queue.wait()
|
||||
// }
|
||||
} catch (e : InterruptedException) {
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
fun box() : String {
|
||||
val t = RefreshQueue.workerThread
|
||||
return "OK"
|
||||
}
|
||||
@@ -243,4 +243,14 @@ public class ClassGenTest extends CodegenTestCase {
|
||||
public void testKt1018 () throws Exception {
|
||||
blackBoxFile("regressions/kt1018.kt");
|
||||
}
|
||||
|
||||
public void testKt1120 () throws Exception {
|
||||
// createEnvironmentWithFullJdk();
|
||||
// blackBoxFile("regressions/kt1120.kt");
|
||||
}
|
||||
|
||||
public void testSelfCreate() throws Exception {
|
||||
createEnvironmentWithFullJdk();
|
||||
blackBoxFile("classes/selfcreate.kt");
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user