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:
Alex Tkachman
2012-09-12 10:31:48 +03:00
parent fb4d6610a8
commit 79c04038fb
7 changed files with 86 additions and 66 deletions
@@ -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());