accessor for private constructors #KT-2716 fixed
also on the way done small refactoring of JetTypeMapper - few code duplicates replace by methods - mapToCallableMethod(ConstructorDescriptor) introduced
This commit is contained in:
@@ -19,6 +19,7 @@ package org.jetbrains.jet.codegen;
|
||||
import org.jetbrains.jet.lang.descriptors.*;
|
||||
import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor;
|
||||
import org.jetbrains.jet.lang.resolve.name.Name;
|
||||
import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptor;
|
||||
|
||||
import java.util.Collections;
|
||||
|
||||
@@ -28,13 +29,13 @@ import java.util.Collections;
|
||||
public class AccessorForFunctionDescriptor extends SimpleFunctionDescriptorImpl {
|
||||
public AccessorForFunctionDescriptor(DeclarationDescriptor descriptor, DeclarationDescriptor containingDeclaration, int index) {
|
||||
super(containingDeclaration, Collections.<AnnotationDescriptor>emptyList(),
|
||||
Name.identifier(descriptor.getName() + "$b$" + index),
|
||||
Name.identifier((descriptor instanceof ConstructorDescriptor ? "$init" : descriptor.getName())+ "$b$" + index),
|
||||
Kind.DECLARATION);
|
||||
|
||||
FunctionDescriptor fd = (SimpleFunctionDescriptor) descriptor;
|
||||
FunctionDescriptor fd = (FunctionDescriptor) descriptor;
|
||||
|
||||
initialize(fd.getReceiverParameter().exists() ? fd.getReceiverParameter().getType() : null,
|
||||
fd.getExpectedThisObject(),
|
||||
descriptor instanceof ConstructorDescriptor ? ReceiverDescriptor.NO_RECEIVER : fd.getExpectedThisObject(),
|
||||
Collections.<TypeParameterDescriptor>emptyList(),
|
||||
fd.getValueParameters(),
|
||||
fd.getReturnType(),
|
||||
|
||||
@@ -1086,9 +1086,7 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> implem
|
||||
.getConstructorReferenceExpression());
|
||||
assert superConstructor != null;
|
||||
//noinspection SuspiciousMethodCalls
|
||||
CallableMethod superCallable = typeMapper
|
||||
.mapToCallableMethod(superConstructor,
|
||||
bindingContext.get(CLOSURE, superConstructor.getContainingDeclaration()));
|
||||
CallableMethod superCallable = typeMapper.mapToCallableMethod(superConstructor);
|
||||
Type[] argumentTypes = superCallable.getSignature().getAsmMethod().getArgumentTypes();
|
||||
ResolvedCall resolvedCall = bindingContext.get(BindingContext.RESOLVED_CALL, superCall.getCalleeExpression());
|
||||
assert resolvedCall != null;
|
||||
@@ -1631,14 +1629,20 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> implem
|
||||
throw new CompilationException("Cannot resolve: " + callee.getText(), null, expression);
|
||||
}
|
||||
|
||||
|
||||
DeclarationDescriptor funDescriptor = resolvedCall.getResultingDescriptor();
|
||||
|
||||
if (!(funDescriptor instanceof FunctionDescriptor)) {
|
||||
throw new UnsupportedOperationException("unknown type of callee descriptor: " + funDescriptor);
|
||||
}
|
||||
|
||||
funDescriptor = accessableFunctionDescriptor((FunctionDescriptor) funDescriptor);
|
||||
|
||||
if (funDescriptor instanceof ConstructorDescriptor) {
|
||||
receiver = StackValue.receiver(resolvedCall, receiver, this, null);
|
||||
return generateConstructorCall(expression, (JetSimpleNameExpression) callee, receiver);
|
||||
}
|
||||
|
||||
if (funDescriptor instanceof FunctionDescriptor) {
|
||||
else {
|
||||
Call call = bindingContext.get(CALL, expression.getCalleeExpression());
|
||||
if (resolvedCall instanceof VariableAsFunctionResolvedCall) {
|
||||
VariableAsFunctionResolvedCall variableAsFunctionResolvedCall = (VariableAsFunctionResolvedCall) resolvedCall;
|
||||
@@ -1649,9 +1653,6 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> implem
|
||||
return invokeFunction(call, receiver, resolvedCall);
|
||||
}
|
||||
}
|
||||
else {
|
||||
throw new UnsupportedOperationException("unknown type of callee descriptor: " + funDescriptor);
|
||||
}
|
||||
}
|
||||
|
||||
private PropertyDescriptor accessablePropertyDescriptor(PropertyDescriptor propertyDescriptor) {
|
||||
@@ -2920,9 +2921,7 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> implem
|
||||
|
||||
final ClassDescriptor classDescriptor = ((ConstructorDescriptor) constructorDescriptor).getContainingDeclaration();
|
||||
|
||||
CallableMethod method = typeMapper
|
||||
.mapToCallableMethod((ConstructorDescriptor) constructorDescriptor,
|
||||
bindingContext.get(CLOSURE, classDescriptor));
|
||||
CallableMethod method = typeMapper.mapToCallableMethod((ConstructorDescriptor) constructorDescriptor);
|
||||
|
||||
receiver.put(receiver.type, v);
|
||||
|
||||
|
||||
@@ -446,7 +446,10 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
||||
FunctionDescriptor original = (FunctionDescriptor) entry.getKey();
|
||||
|
||||
Method method = typeMapper.mapSignature(bridge.getName(), bridge).getAsmMethod();
|
||||
Method originalMethod = typeMapper.mapSignature(original.getName(), original).getAsmMethod();
|
||||
final boolean isConstructor = original instanceof ConstructorDescriptor;
|
||||
Method originalMethod = isConstructor ?
|
||||
typeMapper.mapToCallableMethod((ConstructorDescriptor) original).getSignature().getAsmMethod() :
|
||||
typeMapper.mapSignature(original.getName(), original).getAsmMethod();
|
||||
Type[] argTypes = method.getArgumentTypes();
|
||||
|
||||
String owner = typeMapper.getOwner(original, OwnerKind.IMPLEMENTATION).getInternalName();
|
||||
@@ -460,8 +463,16 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
||||
|
||||
InstructionAdapter iv = new InstructionAdapter(mv);
|
||||
|
||||
iv.load(0, OBJECT_TYPE);
|
||||
for (int i = 1, reg = 1; i < argTypes.length; i++) {
|
||||
if (isConstructor) {
|
||||
iv.anew(method.getReturnType());
|
||||
iv.dup();
|
||||
}
|
||||
else {
|
||||
// todo: note that for now we never have access bridges for namespace methods, if at some point we do...
|
||||
iv.load(0, OBJECT_TYPE);
|
||||
}
|
||||
|
||||
for (int i = isConstructor ? 0 : 1, reg = isConstructor ? 0 : 1; i < argTypes.length; i++) {
|
||||
Type argType = argTypes[i];
|
||||
iv.load(reg, argType);
|
||||
//noinspection AssignmentToForLoopParameter
|
||||
@@ -1108,8 +1119,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
||||
|
||||
//noinspection SuspiciousMethodCalls
|
||||
final CalculatedClosure closureForSuper = bindingContext.get(CLOSURE, superConstructor.getContainingDeclaration());
|
||||
CallableMethod superCallable = typeMapper.mapToCallableMethod(superConstructor,
|
||||
closureForSuper);
|
||||
CallableMethod superCallable = typeMapper.mapToCallableMethod(superConstructor, closureForSuper);
|
||||
|
||||
if (closureForSuper != null && closureForSuper.getCaptureThis() != null) {
|
||||
iv.load(frameMap.getOuterThisIndex(), OBJECT_TYPE);
|
||||
@@ -1214,8 +1224,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
||||
.get(BindingContext.REFERENCE_TARGET, superCall.getCalleeExpression().getConstructorReferenceExpression());
|
||||
assert constructorDescriptor != null;
|
||||
//noinspection SuspiciousMethodCalls
|
||||
CallableMethod method = typeMapper.mapToCallableMethod(constructorDescriptor, bindingContext
|
||||
.get(CLOSURE, constructorDescriptor.getContainingDeclaration()));
|
||||
CallableMethod method = typeMapper.mapToCallableMethod(constructorDescriptor);
|
||||
codegen.invokeMethodWithArguments(method, superCall, StackValue.none());
|
||||
}
|
||||
else {
|
||||
|
||||
@@ -227,14 +227,14 @@ public abstract class CodegenContext {
|
||||
return accessor;
|
||||
}
|
||||
|
||||
if (descriptor instanceof SimpleFunctionDescriptor) {
|
||||
if (descriptor instanceof SimpleFunctionDescriptor || descriptor instanceof ConstructorDescriptor) {
|
||||
accessor = new AccessorForFunctionDescriptor(descriptor, contextDescriptor, accessors.size());
|
||||
}
|
||||
else if (descriptor instanceof PropertyDescriptor) {
|
||||
accessor = new AccessorForPropertyDescriptor((PropertyDescriptor) descriptor, contextDescriptor, accessors.size());
|
||||
}
|
||||
else {
|
||||
throw new UnsupportedOperationException();
|
||||
throw new UnsupportedOperationException("Do not know how to create accessor for descriptor " + descriptor);
|
||||
}
|
||||
accessors.put(descriptor, accessor);
|
||||
return accessor;
|
||||
|
||||
@@ -23,6 +23,7 @@ import org.jetbrains.asm4.Type;
|
||||
import org.jetbrains.jet.codegen.*;
|
||||
import org.jetbrains.jet.codegen.binding.BindingTraceAware;
|
||||
import org.jetbrains.jet.codegen.binding.CalculatedClosure;
|
||||
import org.jetbrains.jet.codegen.binding.CodegenBinding;
|
||||
import org.jetbrains.jet.codegen.context.EnclosedValueDescriptor;
|
||||
import org.jetbrains.jet.codegen.signature.*;
|
||||
import org.jetbrains.jet.lang.descriptors.*;
|
||||
@@ -474,11 +475,7 @@ public class JetTypeMapper extends BindingTraceAware {
|
||||
|
||||
signatureVisitor.writeParametersStart();
|
||||
|
||||
if (isAccessor(f)) {
|
||||
signatureVisitor.writeParameterType(JvmMethodParameterKind.THIS);
|
||||
mapType(((ClassifierDescriptor) f.getContainingDeclaration()).getDefaultType(), signatureVisitor, JetTypeMapperMode.VALUE);
|
||||
signatureVisitor.writeParameterTypeEnd();
|
||||
}
|
||||
writeThisForAccessorIfNeeded(f, signatureVisitor);
|
||||
|
||||
if (kind == OwnerKind.TRAIT_IMPL) {
|
||||
ClassDescriptor containingDeclaration = (ClassDescriptor) f.getContainingDeclaration();
|
||||
@@ -501,9 +498,7 @@ public class JetTypeMapper extends BindingTraceAware {
|
||||
}
|
||||
|
||||
for (ValueParameterDescriptor parameter : parameters) {
|
||||
signatureVisitor.writeParameterType(JvmMethodParameterKind.VALUE);
|
||||
mapType(parameter.getType(), signatureVisitor, JetTypeMapperMode.VALUE);
|
||||
signatureVisitor.writeParameterTypeEnd();
|
||||
writeParameter(signatureVisitor, parameter.getType());
|
||||
}
|
||||
|
||||
signatureVisitor.writeParametersEnd();
|
||||
@@ -521,6 +516,14 @@ public class JetTypeMapper extends BindingTraceAware {
|
||||
return signatureVisitor.makeJvmMethodSignature(f.getName().getName());
|
||||
}
|
||||
|
||||
private void writeThisForAccessorIfNeeded(FunctionDescriptor f, BothSignatureWriter signatureVisitor) {
|
||||
if (isAccessor(f) && f.getExpectedThisObject().exists()) {
|
||||
signatureVisitor.writeParameterType(JvmMethodParameterKind.THIS);
|
||||
mapType(((ClassifierDescriptor) f.getContainingDeclaration()).getDefaultType(), signatureVisitor, JetTypeMapperMode.VALUE);
|
||||
signatureVisitor.writeParameterTypeEnd();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void writeFormalTypeParameters(List<TypeParameterDescriptor> typeParameters, BothSignatureWriter signatureVisitor) {
|
||||
if (signatureVisitor == null) {
|
||||
@@ -585,22 +588,12 @@ public class JetTypeMapper extends BindingTraceAware {
|
||||
|
||||
signatureWriter.writeParametersStart();
|
||||
|
||||
if (isAccessor(f)) {
|
||||
signatureWriter.writeParameterType(JvmMethodParameterKind.THIS);
|
||||
mapType(((ClassifierDescriptor) f.getContainingDeclaration()).getDefaultType(), signatureWriter, JetTypeMapperMode.VALUE);
|
||||
signatureWriter.writeParameterTypeEnd();
|
||||
}
|
||||
writeThisForAccessorIfNeeded(f, signatureWriter);
|
||||
|
||||
final List<ValueParameterDescriptor> parameters = f.getValueParameters();
|
||||
if (receiver.exists()) {
|
||||
signatureWriter.writeParameterType(JvmMethodParameterKind.RECEIVER);
|
||||
mapType(receiver.getType(), signatureWriter, JetTypeMapperMode.VALUE);
|
||||
signatureWriter.writeParameterTypeEnd();
|
||||
}
|
||||
writeReceiverIfNeeded(receiver, signatureWriter);
|
||||
for (ValueParameterDescriptor parameter : parameters) {
|
||||
signatureWriter.writeParameterType(JvmMethodParameterKind.VALUE);
|
||||
mapType(parameter.getType(), signatureWriter, JetTypeMapperMode.VALUE);
|
||||
signatureWriter.writeParameterTypeEnd();
|
||||
writeParameter(signatureWriter, parameter.getType());
|
||||
}
|
||||
|
||||
signatureWriter.writeParametersEnd();
|
||||
@@ -614,6 +607,14 @@ public class JetTypeMapper extends BindingTraceAware {
|
||||
return signatureWriter.makeJvmMethodSignature(name.getName());
|
||||
}
|
||||
|
||||
private void writeReceiverIfNeeded(ReceiverDescriptor receiver, BothSignatureWriter signatureWriter) {
|
||||
if (receiver.exists()) {
|
||||
signatureWriter.writeParameterType(JvmMethodParameterKind.RECEIVER);
|
||||
mapType(receiver.getType(), signatureWriter, JetTypeMapperMode.VALUE);
|
||||
signatureWriter.writeParameterTypeEnd();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public JvmPropertyAccessorSignature mapGetterSignature(PropertyDescriptor descriptor, OwnerKind kind) {
|
||||
final DeclarationDescriptor parentDescriptor = descriptor.getContainingDeclaration();
|
||||
@@ -643,11 +644,7 @@ public class JetTypeMapper extends BindingTraceAware {
|
||||
}
|
||||
}
|
||||
|
||||
if (descriptor.getReceiverParameter().exists()) {
|
||||
signatureWriter.writeParameterType(JvmMethodParameterKind.RECEIVER);
|
||||
mapType(descriptor.getReceiverParameter().getType(), signatureWriter, JetTypeMapperMode.VALUE);
|
||||
signatureWriter.writeParameterTypeEnd();
|
||||
}
|
||||
writeReceiverIfNeeded(descriptor.getReceiverParameter(), signatureWriter);
|
||||
|
||||
signatureWriter.writeParametersEnd();
|
||||
|
||||
@@ -689,15 +686,9 @@ public class JetTypeMapper extends BindingTraceAware {
|
||||
}
|
||||
}
|
||||
|
||||
if (descriptor.getReceiverParameter().exists()) {
|
||||
signatureWriter.writeParameterType(JvmMethodParameterKind.RECEIVER);
|
||||
mapType(descriptor.getReceiverParameter().getType(), signatureWriter, JetTypeMapperMode.VALUE);
|
||||
signatureWriter.writeParameterTypeEnd();
|
||||
}
|
||||
writeReceiverIfNeeded(descriptor.getReceiverParameter(), signatureWriter);
|
||||
|
||||
signatureWriter.writeParameterType(JvmMethodParameterKind.VALUE);
|
||||
mapType(outType, signatureWriter, JetTypeMapperMode.VALUE);
|
||||
signatureWriter.writeParameterTypeEnd();
|
||||
writeParameter(signatureWriter, outType);
|
||||
|
||||
signatureWriter.writeParametersEnd();
|
||||
|
||||
@@ -708,6 +699,12 @@ public class JetTypeMapper extends BindingTraceAware {
|
||||
jvmMethodSignature.getKotlinParameterType(jvmMethodSignature.getParameterCount() - 1));
|
||||
}
|
||||
|
||||
private void writeParameter(BothSignatureWriter signatureWriter, JetType outType) {
|
||||
signatureWriter.writeParameterType(JvmMethodParameterKind.VALUE);
|
||||
mapType(outType, signatureWriter, JetTypeMapperMode.VALUE);
|
||||
signatureWriter.writeParameterTypeEnd();
|
||||
}
|
||||
|
||||
private JvmMethodSignature mapConstructorSignature(ConstructorDescriptor descriptor, CalculatedClosure closure) {
|
||||
|
||||
BothSignatureWriter signatureWriter = new BothSignatureWriter(BothSignatureWriter.Mode.METHOD, true);
|
||||
@@ -766,9 +763,7 @@ public class JetTypeMapper extends BindingTraceAware {
|
||||
|
||||
if (isObjectLiteral(bindingContext, descriptor.getContainingDeclaration())) {
|
||||
//noinspection SuspiciousMethodCalls
|
||||
CallableMethod superCallable = mapToCallableMethod(superConstructor,
|
||||
bindingContext.get(CLOSURE,
|
||||
superConstructor.getContainingDeclaration()));
|
||||
CallableMethod superCallable = mapToCallableMethod(superConstructor);
|
||||
final List<JvmMethodParameterSignature> types = superCallable.getSignature().getKotlinParameterTypes();
|
||||
if (types != null) {
|
||||
for (JvmMethodParameterSignature type : types) {
|
||||
@@ -783,9 +778,7 @@ public class JetTypeMapper extends BindingTraceAware {
|
||||
}
|
||||
|
||||
for (ValueParameterDescriptor parameter : descriptor.getOriginal().getValueParameters()) {
|
||||
signatureWriter.writeParameterType(JvmMethodParameterKind.VALUE);
|
||||
mapType(parameter.getType(), signatureWriter, JetTypeMapperMode.VALUE);
|
||||
signatureWriter.writeParameterTypeEnd();
|
||||
writeParameter(signatureWriter, parameter.getType());
|
||||
}
|
||||
|
||||
signatureWriter.writeParametersEnd();
|
||||
@@ -812,9 +805,7 @@ public class JetTypeMapper extends BindingTraceAware {
|
||||
}
|
||||
|
||||
for (ValueParameterDescriptor valueParameter : script.getValueParameters()) {
|
||||
signatureWriter.writeParameterType(JvmMethodParameterKind.VALUE);
|
||||
mapType(valueParameter.getType(), signatureWriter, JetTypeMapperMode.VALUE);
|
||||
signatureWriter.writeParameterTypeEnd();
|
||||
writeParameter(signatureWriter, valueParameter.getType());
|
||||
}
|
||||
|
||||
signatureWriter.writeParametersEnd();
|
||||
@@ -824,6 +815,10 @@ public class JetTypeMapper extends BindingTraceAware {
|
||||
return signatureWriter.makeJvmMethodSignature("<init>");
|
||||
}
|
||||
|
||||
public CallableMethod mapToCallableMethod(ConstructorDescriptor descriptor) {
|
||||
return mapToCallableMethod(descriptor, bindingContext.get(CodegenBinding.CLOSURE, descriptor.getContainingDeclaration()));
|
||||
}
|
||||
|
||||
public CallableMethod mapToCallableMethod(ConstructorDescriptor descriptor, CalculatedClosure closure) {
|
||||
final JvmMethodSignature method = mapConstructorSignature(descriptor, closure);
|
||||
JetType defaultType = descriptor.getContainingDeclaration().getDefaultType();
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
package someTest
|
||||
|
||||
public class Some private(val v: String) {
|
||||
class object {
|
||||
public fun init(v: String): Some {
|
||||
return Some(v)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun box() = Some.init("OK").v
|
||||
@@ -32,6 +32,11 @@ public class FunctionGenTest extends CodegenTestCase {
|
||||
createEnvironmentWithMockJdkAndIdeaAnnotations(ConfigurationKind.JDK_ONLY);
|
||||
}
|
||||
|
||||
public void testKt2716() throws Exception {
|
||||
blackBoxFile("regressions/kt2716.kt");
|
||||
// System.out.println(generateToText());
|
||||
}
|
||||
|
||||
public void testDefaultArgs() throws Exception {
|
||||
blackBoxFile("functions/defaultargs.jet");
|
||||
// System.out.println(generateToText());
|
||||
|
||||
Reference in New Issue
Block a user