fix KT-249/KT-255
This commit is contained in:
@@ -851,7 +851,7 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
|
||||
DeclarationDescriptor funDescriptor = resolveCalleeDescriptor(expression);
|
||||
|
||||
if (funDescriptor instanceof ConstructorDescriptor) {
|
||||
return generateConstructorCall(expression, (JetSimpleNameExpression) callee);
|
||||
return generateConstructorCall(expression, (JetSimpleNameExpression) callee, receiver);
|
||||
}
|
||||
else if (funDescriptor instanceof FunctionDescriptor) {
|
||||
final FunctionDescriptor fd = (FunctionDescriptor) funDescriptor;
|
||||
@@ -1471,7 +1471,7 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
|
||||
return StackValue.none();
|
||||
}
|
||||
|
||||
private StackValue generateConstructorCall(JetCallExpression expression, JetSimpleNameExpression constructorReference) {
|
||||
private StackValue generateConstructorCall(JetCallExpression expression, JetSimpleNameExpression constructorReference, StackValue receiver) {
|
||||
DeclarationDescriptor constructorDescriptor = bindingContext.get(BindingContext.REFERENCE_TARGET, constructorReference);
|
||||
final PsiElement declaration = bindingContext.get(BindingContext.DESCRIPTOR_TO_DECLARATION, constructorDescriptor);
|
||||
Type type;
|
||||
@@ -1486,11 +1486,26 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
|
||||
else {
|
||||
ClassDescriptor classDecl = (ClassDescriptor) constructorDescriptor.getContainingDeclaration();
|
||||
|
||||
receiver.put(receiver.type, v);
|
||||
v.anew(type);
|
||||
v.dup();
|
||||
|
||||
// TODO typechecker must verify that we're the outer class of the instance being created
|
||||
pushOuterClassArguments(classDecl);
|
||||
if (classDecl.getContainingDeclaration() instanceof ClassDescriptor) {
|
||||
if(!receiver.type.equals(Type.VOID_TYPE)) {
|
||||
// class object is in receiver
|
||||
v.dupX1();
|
||||
v.swap();
|
||||
}
|
||||
else {
|
||||
// this$0 need to be put on stack
|
||||
v.dup();
|
||||
v.load(0, JetTypeMapper.jetImplementationType(classDecl));
|
||||
}
|
||||
}
|
||||
else {
|
||||
// regular case
|
||||
v.dup();
|
||||
}
|
||||
|
||||
CallableMethod method = typeMapper.mapToCallableMethod((ConstructorDescriptor) constructorDescriptor, OwnerKind.IMPLEMENTATION);
|
||||
invokeMethodWithArguments(method, expression);
|
||||
@@ -1513,12 +1528,6 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
|
||||
generateTypeInfo(typeArgument);
|
||||
}
|
||||
|
||||
private void pushOuterClassArguments(ClassDescriptor classDecl) {
|
||||
if (classDecl.getContainingDeclaration() instanceof ClassDescriptor) {
|
||||
v.load(0, JetTypeMapper.jetImplementationType(classDecl));
|
||||
}
|
||||
}
|
||||
|
||||
private Type generateJavaConstructorCall(JetCallExpression expression, PsiMethod constructor) {
|
||||
PsiClass javaClass = constructor.getContainingClass();
|
||||
Type type = JetTypeMapper.psiClassType(javaClass);
|
||||
|
||||
@@ -147,7 +147,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
||||
}
|
||||
|
||||
protected void generatePrimaryConstructor() {
|
||||
ConstructorDescriptor constructorDescriptor = state.getBindingContext().get(BindingContext.CONSTRUCTOR, (JetElement) myClass);
|
||||
ConstructorDescriptor constructorDescriptor = state.getBindingContext().get(BindingContext.CONSTRUCTOR, myClass);
|
||||
if (constructorDescriptor == null && !(myClass instanceof JetObjectDeclaration) && !isEnum(myClass)) return;
|
||||
|
||||
Method method;
|
||||
@@ -193,10 +193,9 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
||||
iv.invokespecial(superClass, "<init>", /* TODO super constructor descriptor */"()V");
|
||||
}
|
||||
|
||||
final DeclarationDescriptor outerDescriptor = getOuterClassDescriptor();
|
||||
if (outerDescriptor instanceof ClassDescriptor) {
|
||||
final ClassDescriptor outerClassDescriptor = (ClassDescriptor) outerDescriptor;
|
||||
final Type type = JetTypeMapper.jetImplementationType(outerClassDescriptor);
|
||||
final ClassDescriptor outerDescriptor = getOuterClassDescriptor();
|
||||
if (outerDescriptor != null && !outerDescriptor.isObject()) {
|
||||
final Type type = JetTypeMapper.jetImplementationType(outerDescriptor);
|
||||
String interfaceDesc = type.getDescriptor();
|
||||
final String fieldName = "this$0";
|
||||
v.visitField(Opcodes.ACC_PRIVATE | Opcodes.ACC_FINAL, fieldName, interfaceDesc, null, null);
|
||||
@@ -216,7 +215,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
||||
HashSet<FunctionDescriptor> overridden = new HashSet<FunctionDescriptor>();
|
||||
for (JetDeclaration declaration : myClass.getDeclarations()) {
|
||||
if (declaration instanceof JetFunction) {
|
||||
overridden.addAll(state.getBindingContext().get(BindingContext.FUNCTION, (JetNamedFunction) declaration).getOverriddenFunctions());
|
||||
overridden.addAll(state.getBindingContext().get(BindingContext.FUNCTION, declaration).getOverriddenFunctions());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -410,8 +409,8 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
||||
protected void generateInitializers(ExpressionCodegen codegen, InstructionAdapter iv) {
|
||||
for (JetDeclaration declaration : myClass.getDeclarations()) {
|
||||
if (declaration instanceof JetProperty) {
|
||||
final PropertyDescriptor propertyDescriptor = (PropertyDescriptor) state.getBindingContext().get(BindingContext.VARIABLE, (JetProperty) declaration);
|
||||
if ((boolean) state.getBindingContext().get(BindingContext.BACKING_FIELD_REQUIRED, propertyDescriptor)) {
|
||||
final PropertyDescriptor propertyDescriptor = (PropertyDescriptor) state.getBindingContext().get(BindingContext.VARIABLE, declaration);
|
||||
if (state.getBindingContext().get(BindingContext.BACKING_FIELD_REQUIRED, propertyDescriptor)) {
|
||||
final JetExpression initializer = ((JetProperty) declaration).getInitializer();
|
||||
if (initializer != null) {
|
||||
iv.load(0, JetTypeMapper.TYPE_OBJECT);
|
||||
@@ -436,7 +435,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
||||
propertyCodegen.gen((JetProperty) declaration);
|
||||
}
|
||||
else if (declaration instanceof JetFunction) {
|
||||
if (!overriden.contains(state.getBindingContext().get(BindingContext.FUNCTION, (JetNamedFunction) declaration))) {
|
||||
if (!overriden.contains(state.getBindingContext().get(BindingContext.FUNCTION, declaration))) {
|
||||
functionCodegen.gen((JetNamedFunction) declaration);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,7 +22,7 @@ public class JetObjectDeclaration extends JetNamedDeclaration implements JetClas
|
||||
@Override
|
||||
public String getName() {
|
||||
JetObjectDeclarationName nameAsDeclaration = getNameAsDeclaration();
|
||||
return nameAsDeclaration == null ? "<Anonymous>" : nameAsDeclaration.getName();
|
||||
return nameAsDeclaration == null ? "ClassObj" : nameAsDeclaration.getName();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -0,0 +1,35 @@
|
||||
namespace x
|
||||
|
||||
class Outer(val name: String) {
|
||||
class Inner() {
|
||||
val me = name
|
||||
|
||||
class object {
|
||||
fun bar() = "bar"
|
||||
}
|
||||
}
|
||||
|
||||
class object {
|
||||
class StaticInner() {
|
||||
class object {
|
||||
fun f() = "oo"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun box (): String {
|
||||
val inner = Outer("mama").Inner() //verify error
|
||||
if(inner.me != "mama")
|
||||
return "fail"
|
||||
|
||||
val outer = Outer ("papa")
|
||||
val inner2 = outer.Inner ()
|
||||
if(inner2.me != "papa")
|
||||
return "fail"
|
||||
|
||||
if(Outer.StaticInner.f() != "oo" )
|
||||
return "fail"
|
||||
|
||||
return "OK"
|
||||
}
|
||||
@@ -168,4 +168,8 @@ public class ClassGenTest extends CodegenTestCase {
|
||||
final Method rgbMethod = colorClass.getMethod("getRgb");
|
||||
assertEquals(0xFF0000, rgbMethod.invoke(redValue));
|
||||
}
|
||||
|
||||
public void testKt249() throws Exception {
|
||||
blackBoxFile("regressions/kt249.jet");
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user