Introduce KFunctionImpl, KMemberFunctionImpl, KExtensionFunctionImpl

Old 23*3 classes will be dropped, since they have no value.

Simplify JvmFunctionImplTypes significantly because of that
This commit is contained in:
Alexander Udalov
2014-05-16 20:49:00 +04:00
parent ccead8e337
commit 8f7c0f0b65
6 changed files with 129 additions and 113 deletions
@@ -16,7 +16,6 @@
package org.jetbrains.jet.codegen; package org.jetbrains.jet.codegen;
import com.google.common.collect.ImmutableList;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.jet.lang.descriptors.*; import org.jetbrains.jet.lang.descriptors.*;
import org.jetbrains.jet.lang.descriptors.annotations.Annotations; import org.jetbrains.jet.lang.descriptors.annotations.Annotations;
@@ -39,74 +38,55 @@ public class JvmFunctionImplTypes {
private final ClassDescriptor functionImpl; private final ClassDescriptor functionImpl;
private final ClassDescriptor extensionFunctionImpl; private final ClassDescriptor extensionFunctionImpl;
private final ClassDescriptor kFunctionImpl;
private volatile List<KFunctions> kFunctionsList; private final ClassDescriptor kMemberFunctionImpl;
private final ClassDescriptor kExtensionFunctionImpl;
private static class KFunctions {
public final ClassDescriptor kFunctionImpl;
public final ClassDescriptor kMemberFunctionImpl;
public final ClassDescriptor kExtensionFunctionImpl;
public KFunctions(
@NotNull ClassDescriptor kFunctionImpl,
@NotNull ClassDescriptor kMemberFunctionImpl,
@NotNull ClassDescriptor kExtensionFunctionImpl
) {
this.kFunctionImpl = kFunctionImpl;
this.kMemberFunctionImpl = kMemberFunctionImpl;
this.kExtensionFunctionImpl = kExtensionFunctionImpl;
}
}
public JvmFunctionImplTypes(@NotNull ReflectionTypes reflectionTypes) { public JvmFunctionImplTypes(@NotNull ReflectionTypes reflectionTypes) {
this.reflectionTypes = reflectionTypes; this.reflectionTypes = reflectionTypes;
ModuleDescriptor fakeModule = new ModuleDescriptorImpl(Name.special("<fake module for functions impl>"), ModuleDescriptor fakeModule = new ModuleDescriptorImpl(Name.special("<fake module for functions impl>"),
Collections.<ImportPath>emptyList(), JavaToKotlinClassMap.getInstance()); Collections.<ImportPath>emptyList(), JavaToKotlinClassMap.getInstance());
MutablePackageFragmentDescriptor kotlinJvmInternal = PackageFragmentDescriptor kotlinJvmInternal =
new MutablePackageFragmentDescriptor(fakeModule, new FqName("kotlin.jvm.internal")); new MutablePackageFragmentDescriptor(fakeModule, new FqName("kotlin.jvm.internal"));
PackageFragmentDescriptor kotlinReflectJvmInternal =
new MutablePackageFragmentDescriptor(fakeModule, new FqName("kotlin.reflect.jvm.internal"));
MutableClassDescriptor functionImpl = createClass(kotlinJvmInternal, "FunctionImpl"); this.functionImpl = createClass(kotlinJvmInternal, "FunctionImpl", "out R");
TypeParameterDescriptor funR = createTypeParameter(functionImpl, Variance.OUT_VARIANCE, "R", 0); this.extensionFunctionImpl = createClass(kotlinJvmInternal, "ExtensionFunctionImpl", "in T", "out R");
this.kFunctionImpl = createClass(kotlinReflectJvmInternal, "KFunctionImpl", "out R");
MutableClassDescriptor extensionFunctionImpl = createClass(kotlinJvmInternal, "ExtensionFunctionImpl"); this.kExtensionFunctionImpl = createClass(kotlinReflectJvmInternal, "KExtensionFunctionImpl", "in T", "out R");
TypeParameterDescriptor extFunT = createTypeParameter(extensionFunctionImpl, Variance.IN_VARIANCE, "T", 0); this.kMemberFunctionImpl = createClass(kotlinReflectJvmInternal, "KMemberFunctionImpl", "in T", "out R");
TypeParameterDescriptor extFunR = createTypeParameter(extensionFunctionImpl, Variance.OUT_VARIANCE, "R", 1);
this.functionImpl = initializeFunctionImplClass(functionImpl, Arrays.asList(funR));
this.extensionFunctionImpl = initializeFunctionImplClass(extensionFunctionImpl, Arrays.asList(extFunT, extFunR));
} }
@NotNull @NotNull
private List<KFunctions> getKFunctionsImplList() { private static ClassDescriptor createClass(
if (kFunctionsList == null) { @NotNull PackageFragmentDescriptor packageFragment,
MutablePackageFragmentDescriptor packageFragment = new MutablePackageFragmentDescriptor(
DescriptorUtils.getContainingModule(functionImpl), new FqName("kotlin.reflect.jvm.internal")
);
ImmutableList.Builder<KFunctions> builder = ImmutableList.builder();
for (int i = 0; i < KotlinBuiltIns.FUNCTION_TRAIT_COUNT; i++) {
builder.add(new KFunctions(
createKFunctionImpl(packageFragment, "KFunction" + i + "Impl", reflectionTypes.getKFunction(i)),
createKFunctionImpl(packageFragment, "KMemberFunction" + i + "Impl", reflectionTypes.getKMemberFunction(i)),
createKFunctionImpl(packageFragment, "KExtensionFunction" + i + "Impl", reflectionTypes.getKExtensionFunction(i))
));
}
kFunctionsList = builder.build();
}
return kFunctionsList;
}
@NotNull
private static ClassDescriptor createKFunctionImpl(
@NotNull PackageFragmentDescriptor containingDeclaration,
@NotNull String name, @NotNull String name,
@NotNull ClassDescriptor functionInterface @NotNull String... typeParameters
) { ) {
return initializeFunctionImplClass(createClass(containingDeclaration, name), MutableClassDescriptor descriptor = new MutableClassDescriptor(packageFragment, packageFragment.getMemberScope(),
functionInterface.getDefaultType().getConstructor().getParameters()); ClassKind.CLASS, false, Name.identifier(name));
} List<TypeParameterDescriptor> typeParameterDescriptors = new ArrayList<TypeParameterDescriptor>(typeParameters.length);
for (int i = 0; i < typeParameters.length; i++) {
String[] s = typeParameters[i].split(" ");
Variance variance = Variance.valueOf(s[0].toUpperCase() + "_VARIANCE");
String typeParameterName = s[1];
TypeParameterDescriptorImpl typeParameter = TypeParameterDescriptorImpl.createForFurtherModification(
descriptor, Annotations.EMPTY, false, variance, Name.identifier(typeParameterName), i
);
typeParameter.setInitialized();
typeParameterDescriptors.add(typeParameter);
}
descriptor.setModality(Modality.FINAL);
descriptor.setVisibility(Visibilities.PUBLIC);
descriptor.setTypeParameterDescriptors(typeParameterDescriptors);
descriptor.createTypeConstructor();
return descriptor;
}
@NotNull @NotNull
public Collection<JetType> getSupertypesForClosure(@NotNull FunctionDescriptor descriptor) { public Collection<JetType> getSupertypesForClosure(@NotNull FunctionDescriptor descriptor) {
@@ -145,77 +125,48 @@ public class JvmFunctionImplTypes {
} }
@NotNull @NotNull
public JetType getSupertypeForCallableReference(@NotNull FunctionDescriptor descriptor) { public Collection<JetType> getSupertypesForCallableReference(@NotNull FunctionDescriptor descriptor) {
int arity = descriptor.getValueParameters().size();
ReceiverParameterDescriptor receiverParameter = descriptor.getReceiverParameter(); ReceiverParameterDescriptor receiverParameter = descriptor.getReceiverParameter();
ReceiverParameterDescriptor expectedThisObject = descriptor.getExpectedThisObject(); ReceiverParameterDescriptor expectedThisObject = descriptor.getExpectedThisObject();
List<TypeProjection> typeArguments = new ArrayList<TypeProjection>(arity + 2); List<TypeProjection> typeArguments = new ArrayList<TypeProjection>(2);
ClassDescriptor classDescriptor;
JetType receiverType;
if (receiverParameter != null) { if (receiverParameter != null) {
typeArguments.add(new TypeProjectionImpl(receiverParameter.getType())); classDescriptor = kExtensionFunctionImpl;
receiverType = receiverParameter.getType();
typeArguments.add(new TypeProjectionImpl(receiverType));
} }
else if (expectedThisObject != null) { else if (expectedThisObject != null) {
typeArguments.add(new TypeProjectionImpl(expectedThisObject.getType())); classDescriptor = kMemberFunctionImpl;
receiverType = expectedThisObject.getType();
typeArguments.add(new TypeProjectionImpl(receiverType));
} }
else {
for (ValueParameterDescriptor parameter : descriptor.getValueParameters()) { classDescriptor = kFunctionImpl;
typeArguments.add(new TypeProjectionImpl(parameter.getType())); receiverType = null;
} }
//noinspection ConstantConditions //noinspection ConstantConditions
typeArguments.add(new TypeProjectionImpl(descriptor.getReturnType())); typeArguments.add(new TypeProjectionImpl(descriptor.getReturnType()));
ClassDescriptor classDescriptor; JetType kFunctionImplType = new JetTypeImpl(
KFunctions kFunctions = getKFunctionsImplList().get(arity);
if (expectedThisObject != null) {
classDescriptor = kFunctions.kMemberFunctionImpl;
}
else if (receiverParameter != null) {
classDescriptor = kFunctions.kExtensionFunctionImpl;
}
else {
classDescriptor = kFunctions.kFunctionImpl;
}
return new JetTypeImpl(
classDescriptor.getDefaultType().getAnnotations(), classDescriptor.getDefaultType().getAnnotations(),
classDescriptor.getTypeConstructor(), classDescriptor.getTypeConstructor(),
false, false,
typeArguments, typeArguments,
classDescriptor.getMemberScope(typeArguments) classDescriptor.getMemberScope(typeArguments)
); );
}
@NotNull JetType kFunctionType = reflectionTypes.getKFunctionType(
private static MutableClassDescriptor createClass(@NotNull PackageFragmentDescriptor packageFragment, @NotNull String name) { Annotations.EMPTY,
return new MutableClassDescriptor(packageFragment, packageFragment.getMemberScope(), ClassKind.CLASS, false, Name.identifier(name)); receiverType,
} DescriptorUtils.getValueParametersTypes(descriptor.getValueParameters()),
descriptor.getReturnType(),
@NotNull receiverParameter != null
private static TypeParameterDescriptor createTypeParameter(
@NotNull ClassDescriptor classDescriptor,
@NotNull Variance variance,
@NotNull String name,
int index
) {
TypeParameterDescriptorImpl typeParameter = TypeParameterDescriptorImpl.createForFurtherModification(
classDescriptor, Annotations.EMPTY, false, variance, Name.identifier(name), index
); );
typeParameter.setInitialized();
return typeParameter;
}
@NotNull return Arrays.asList(kFunctionImplType, kFunctionType);
private static ClassDescriptor initializeFunctionImplClass(
@NotNull MutableClassDescriptor functionImpl,
@NotNull List<TypeParameterDescriptor> typeParameters
) {
functionImpl.setModality(Modality.FINAL);
functionImpl.setVisibility(Visibilities.PUBLIC);
functionImpl.setTypeParameterDescriptors(typeParameters);
functionImpl.createTypeConstructor();
return functionImpl;
} }
} }
@@ -310,11 +310,11 @@ class CodegenAnnotatingVisitor extends JetVisitorVoid {
ResolvedCall<?> referencedFunction = bindingContext.get(RESOLVED_CALL, expression.getCallableReference()); ResolvedCall<?> referencedFunction = bindingContext.get(RESOLVED_CALL, expression.getCallableReference());
if (referencedFunction == null) return; if (referencedFunction == null) return;
JetType supertype = Collection<JetType> supertypes =
functionImplTypes.getSupertypeForCallableReference((FunctionDescriptor) referencedFunction.getResultingDescriptor()); functionImplTypes.getSupertypesForCallableReference((FunctionDescriptor) referencedFunction.getResultingDescriptor());
String name = inventAnonymousClassName(expression); String name = inventAnonymousClassName(expression);
ClassDescriptor classDescriptor = recordClassForFunction(functionDescriptor, Collections.singleton(supertype)); ClassDescriptor classDescriptor = recordClassForFunction(functionDescriptor, supertypes);
recordClosure(expression, classDescriptor, name); recordClosure(expression, classDescriptor, name);
pushClassDescriptor(classDescriptor); pushClassDescriptor(classDescriptor);
@@ -4,20 +4,20 @@ class A {
fun bar(): String = "" fun bar(): String = ""
} }
fun A.baz() {} fun A.baz(x: Int) {}
fun box(): String { fun box(): String {
val f = "${::foo}" val f = "${::foo}"
if (f != "kotlin.reflect.jvm.internal.KFunction1Impl<java.lang.String, kotlin.Unit>") return "Fail foo: $f" if (f != "kotlin.reflect.KFunction1<java.lang.String, kotlin.Unit>") return "Fail foo: $f"
val nameOfA = (A() as java.lang.Object).getClass().getName() val nameOfA = (A() as java.lang.Object).getClass().getName()
val g = "${A::bar}" val g = "${A::bar}"
if (g != "kotlin.reflect.jvm.internal.KMemberFunction0Impl<$nameOfA, java.lang.String>") return "Fail bar: $g" if (g != "kotlin.reflect.KMemberFunction0<$nameOfA, java.lang.String>") return "Fail bar: $g"
val h = "${A::baz}" val h = "${A::baz}"
if (h != "kotlin.reflect.jvm.internal.KExtensionFunction0Impl<$nameOfA, kotlin.Unit>") return "Fail baz: $h" if (h != "kotlin.reflect.KExtensionFunction1<$nameOfA, java.lang.Integer, kotlin.Unit>") return "Fail baz: $h"
return "OK" return "OK"
} }
@@ -0,0 +1,21 @@
/*
* Copyright 2010-2014 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package kotlin.reflect.jvm.internal
import kotlin.jvm.internal.ExtensionFunctionImpl
public abstract class KExtensionFunctionImpl<in T, out R> : ExtensionFunctionImpl<T, R>()
@@ -0,0 +1,21 @@
/*
* Copyright 2010-2014 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package kotlin.reflect.jvm.internal
import kotlin.jvm.internal.FunctionImpl
public abstract class KFunctionImpl<out R> : FunctionImpl<R>()
@@ -0,0 +1,23 @@
/*
* Copyright 2010-2014 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package kotlin.reflect.jvm.internal
import java.io.Serializable
public abstract class KMemberFunctionImpl<in T, out R> : Serializable {
override fun toString() = "${getClass().getGenericInterfaces()[0]}"
}