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);
|
DeclarationDescriptor funDescriptor = resolveCalleeDescriptor(expression);
|
||||||
|
|
||||||
if (funDescriptor instanceof ConstructorDescriptor) {
|
if (funDescriptor instanceof ConstructorDescriptor) {
|
||||||
return generateConstructorCall(expression, (JetSimpleNameExpression) callee);
|
return generateConstructorCall(expression, (JetSimpleNameExpression) callee, receiver);
|
||||||
}
|
}
|
||||||
else if (funDescriptor instanceof FunctionDescriptor) {
|
else if (funDescriptor instanceof FunctionDescriptor) {
|
||||||
final FunctionDescriptor fd = (FunctionDescriptor) funDescriptor;
|
final FunctionDescriptor fd = (FunctionDescriptor) funDescriptor;
|
||||||
@@ -1471,7 +1471,7 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
|
|||||||
return StackValue.none();
|
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);
|
DeclarationDescriptor constructorDescriptor = bindingContext.get(BindingContext.REFERENCE_TARGET, constructorReference);
|
||||||
final PsiElement declaration = bindingContext.get(BindingContext.DESCRIPTOR_TO_DECLARATION, constructorDescriptor);
|
final PsiElement declaration = bindingContext.get(BindingContext.DESCRIPTOR_TO_DECLARATION, constructorDescriptor);
|
||||||
Type type;
|
Type type;
|
||||||
@@ -1486,11 +1486,26 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
|
|||||||
else {
|
else {
|
||||||
ClassDescriptor classDecl = (ClassDescriptor) constructorDescriptor.getContainingDeclaration();
|
ClassDescriptor classDecl = (ClassDescriptor) constructorDescriptor.getContainingDeclaration();
|
||||||
|
|
||||||
|
receiver.put(receiver.type, v);
|
||||||
v.anew(type);
|
v.anew(type);
|
||||||
v.dup();
|
|
||||||
|
|
||||||
// TODO typechecker must verify that we're the outer class of the instance being created
|
// 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);
|
CallableMethod method = typeMapper.mapToCallableMethod((ConstructorDescriptor) constructorDescriptor, OwnerKind.IMPLEMENTATION);
|
||||||
invokeMethodWithArguments(method, expression);
|
invokeMethodWithArguments(method, expression);
|
||||||
@@ -1513,12 +1528,6 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
|
|||||||
generateTypeInfo(typeArgument);
|
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) {
|
private Type generateJavaConstructorCall(JetCallExpression expression, PsiMethod constructor) {
|
||||||
PsiClass javaClass = constructor.getContainingClass();
|
PsiClass javaClass = constructor.getContainingClass();
|
||||||
Type type = JetTypeMapper.psiClassType(javaClass);
|
Type type = JetTypeMapper.psiClassType(javaClass);
|
||||||
|
|||||||
@@ -147,7 +147,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected void generatePrimaryConstructor() {
|
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;
|
if (constructorDescriptor == null && !(myClass instanceof JetObjectDeclaration) && !isEnum(myClass)) return;
|
||||||
|
|
||||||
Method method;
|
Method method;
|
||||||
@@ -193,10 +193,9 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
|||||||
iv.invokespecial(superClass, "<init>", /* TODO super constructor descriptor */"()V");
|
iv.invokespecial(superClass, "<init>", /* TODO super constructor descriptor */"()V");
|
||||||
}
|
}
|
||||||
|
|
||||||
final DeclarationDescriptor outerDescriptor = getOuterClassDescriptor();
|
final ClassDescriptor outerDescriptor = getOuterClassDescriptor();
|
||||||
if (outerDescriptor instanceof ClassDescriptor) {
|
if (outerDescriptor != null && !outerDescriptor.isObject()) {
|
||||||
final ClassDescriptor outerClassDescriptor = (ClassDescriptor) outerDescriptor;
|
final Type type = JetTypeMapper.jetImplementationType(outerDescriptor);
|
||||||
final Type type = JetTypeMapper.jetImplementationType(outerClassDescriptor);
|
|
||||||
String interfaceDesc = type.getDescriptor();
|
String interfaceDesc = type.getDescriptor();
|
||||||
final String fieldName = "this$0";
|
final String fieldName = "this$0";
|
||||||
v.visitField(Opcodes.ACC_PRIVATE | Opcodes.ACC_FINAL, fieldName, interfaceDesc, null, null);
|
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>();
|
HashSet<FunctionDescriptor> overridden = new HashSet<FunctionDescriptor>();
|
||||||
for (JetDeclaration declaration : myClass.getDeclarations()) {
|
for (JetDeclaration declaration : myClass.getDeclarations()) {
|
||||||
if (declaration instanceof JetFunction) {
|
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) {
|
protected void generateInitializers(ExpressionCodegen codegen, InstructionAdapter iv) {
|
||||||
for (JetDeclaration declaration : myClass.getDeclarations()) {
|
for (JetDeclaration declaration : myClass.getDeclarations()) {
|
||||||
if (declaration instanceof JetProperty) {
|
if (declaration instanceof JetProperty) {
|
||||||
final PropertyDescriptor propertyDescriptor = (PropertyDescriptor) state.getBindingContext().get(BindingContext.VARIABLE, (JetProperty) declaration);
|
final PropertyDescriptor propertyDescriptor = (PropertyDescriptor) state.getBindingContext().get(BindingContext.VARIABLE, declaration);
|
||||||
if ((boolean) state.getBindingContext().get(BindingContext.BACKING_FIELD_REQUIRED, propertyDescriptor)) {
|
if (state.getBindingContext().get(BindingContext.BACKING_FIELD_REQUIRED, propertyDescriptor)) {
|
||||||
final JetExpression initializer = ((JetProperty) declaration).getInitializer();
|
final JetExpression initializer = ((JetProperty) declaration).getInitializer();
|
||||||
if (initializer != null) {
|
if (initializer != null) {
|
||||||
iv.load(0, JetTypeMapper.TYPE_OBJECT);
|
iv.load(0, JetTypeMapper.TYPE_OBJECT);
|
||||||
@@ -436,7 +435,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
|||||||
propertyCodegen.gen((JetProperty) declaration);
|
propertyCodegen.gen((JetProperty) declaration);
|
||||||
}
|
}
|
||||||
else if (declaration instanceof JetFunction) {
|
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);
|
functionCodegen.gen((JetNamedFunction) declaration);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ public class JetObjectDeclaration extends JetNamedDeclaration implements JetClas
|
|||||||
@Override
|
@Override
|
||||||
public String getName() {
|
public String getName() {
|
||||||
JetObjectDeclarationName nameAsDeclaration = getNameAsDeclaration();
|
JetObjectDeclarationName nameAsDeclaration = getNameAsDeclaration();
|
||||||
return nameAsDeclaration == null ? "<Anonymous>" : nameAsDeclaration.getName();
|
return nameAsDeclaration == null ? "ClassObj" : nameAsDeclaration.getName();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@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");
|
final Method rgbMethod = colorClass.getMethod("getRgb");
|
||||||
assertEquals(0xFF0000, rgbMethod.invoke(redValue));
|
assertEquals(0xFF0000, rgbMethod.invoke(redValue));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void testKt249() throws Exception {
|
||||||
|
blackBoxFile("regressions/kt249.jet");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user