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;
import com.google.common.collect.ImmutableList;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.jet.lang.descriptors.*;
import org.jetbrains.jet.lang.descriptors.annotations.Annotations;
@@ -39,74 +38,55 @@ public class JvmFunctionImplTypes {
private final ClassDescriptor functionImpl;
private final ClassDescriptor extensionFunctionImpl;
private volatile List<KFunctions> kFunctionsList;
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;
}
}
private final ClassDescriptor kFunctionImpl;
private final ClassDescriptor kMemberFunctionImpl;
private final ClassDescriptor kExtensionFunctionImpl;
public JvmFunctionImplTypes(@NotNull ReflectionTypes reflectionTypes) {
this.reflectionTypes = reflectionTypes;
ModuleDescriptor fakeModule = new ModuleDescriptorImpl(Name.special("<fake module for functions impl>"),
Collections.<ImportPath>emptyList(), JavaToKotlinClassMap.getInstance());
MutablePackageFragmentDescriptor kotlinJvmInternal =
PackageFragmentDescriptor kotlinJvmInternal =
new MutablePackageFragmentDescriptor(fakeModule, new FqName("kotlin.jvm.internal"));
PackageFragmentDescriptor kotlinReflectJvmInternal =
new MutablePackageFragmentDescriptor(fakeModule, new FqName("kotlin.reflect.jvm.internal"));
MutableClassDescriptor functionImpl = createClass(kotlinJvmInternal, "FunctionImpl");
TypeParameterDescriptor funR = createTypeParameter(functionImpl, Variance.OUT_VARIANCE, "R", 0);
MutableClassDescriptor extensionFunctionImpl = createClass(kotlinJvmInternal, "ExtensionFunctionImpl");
TypeParameterDescriptor extFunT = createTypeParameter(extensionFunctionImpl, Variance.IN_VARIANCE, "T", 0);
TypeParameterDescriptor extFunR = createTypeParameter(extensionFunctionImpl, Variance.OUT_VARIANCE, "R", 1);
this.functionImpl = initializeFunctionImplClass(functionImpl, Arrays.asList(funR));
this.extensionFunctionImpl = initializeFunctionImplClass(extensionFunctionImpl, Arrays.asList(extFunT, extFunR));
this.functionImpl = createClass(kotlinJvmInternal, "FunctionImpl", "out R");
this.extensionFunctionImpl = createClass(kotlinJvmInternal, "ExtensionFunctionImpl", "in T", "out R");
this.kFunctionImpl = createClass(kotlinReflectJvmInternal, "KFunctionImpl", "out R");
this.kExtensionFunctionImpl = createClass(kotlinReflectJvmInternal, "KExtensionFunctionImpl", "in T", "out R");
this.kMemberFunctionImpl = createClass(kotlinReflectJvmInternal, "KMemberFunctionImpl", "in T", "out R");
}
@NotNull
private List<KFunctions> getKFunctionsImplList() {
if (kFunctionsList == null) {
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,
private static ClassDescriptor createClass(
@NotNull PackageFragmentDescriptor packageFragment,
@NotNull String name,
@NotNull ClassDescriptor functionInterface
@NotNull String... typeParameters
) {
return initializeFunctionImplClass(createClass(containingDeclaration, name),
functionInterface.getDefaultType().getConstructor().getParameters());
}
MutableClassDescriptor descriptor = new MutableClassDescriptor(packageFragment, packageFragment.getMemberScope(),
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
public Collection<JetType> getSupertypesForClosure(@NotNull FunctionDescriptor descriptor) {
@@ -145,77 +125,48 @@ public class JvmFunctionImplTypes {
}
@NotNull
public JetType getSupertypeForCallableReference(@NotNull FunctionDescriptor descriptor) {
int arity = descriptor.getValueParameters().size();
public Collection<JetType> getSupertypesForCallableReference(@NotNull FunctionDescriptor descriptor) {
ReceiverParameterDescriptor receiverParameter = descriptor.getReceiverParameter();
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) {
typeArguments.add(new TypeProjectionImpl(receiverParameter.getType()));
classDescriptor = kExtensionFunctionImpl;
receiverType = receiverParameter.getType();
typeArguments.add(new TypeProjectionImpl(receiverType));
}
else if (expectedThisObject != null) {
typeArguments.add(new TypeProjectionImpl(expectedThisObject.getType()));
classDescriptor = kMemberFunctionImpl;
receiverType = expectedThisObject.getType();
typeArguments.add(new TypeProjectionImpl(receiverType));
}
for (ValueParameterDescriptor parameter : descriptor.getValueParameters()) {
typeArguments.add(new TypeProjectionImpl(parameter.getType()));
else {
classDescriptor = kFunctionImpl;
receiverType = null;
}
//noinspection ConstantConditions
typeArguments.add(new TypeProjectionImpl(descriptor.getReturnType()));
ClassDescriptor classDescriptor;
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(
JetType kFunctionImplType = new JetTypeImpl(
classDescriptor.getDefaultType().getAnnotations(),
classDescriptor.getTypeConstructor(),
false,
typeArguments,
classDescriptor.getMemberScope(typeArguments)
);
}
@NotNull
private static MutableClassDescriptor createClass(@NotNull PackageFragmentDescriptor packageFragment, @NotNull String name) {
return new MutableClassDescriptor(packageFragment, packageFragment.getMemberScope(), ClassKind.CLASS, false, Name.identifier(name));
}
@NotNull
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
JetType kFunctionType = reflectionTypes.getKFunctionType(
Annotations.EMPTY,
receiverType,
DescriptorUtils.getValueParametersTypes(descriptor.getValueParameters()),
descriptor.getReturnType(),
receiverParameter != null
);
typeParameter.setInitialized();
return typeParameter;
}
@NotNull
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;
return Arrays.asList(kFunctionImplType, kFunctionType);
}
}
@@ -310,11 +310,11 @@ class CodegenAnnotatingVisitor extends JetVisitorVoid {
ResolvedCall<?> referencedFunction = bindingContext.get(RESOLVED_CALL, expression.getCallableReference());
if (referencedFunction == null) return;
JetType supertype =
functionImplTypes.getSupertypeForCallableReference((FunctionDescriptor) referencedFunction.getResultingDescriptor());
Collection<JetType> supertypes =
functionImplTypes.getSupertypesForCallableReference((FunctionDescriptor) referencedFunction.getResultingDescriptor());
String name = inventAnonymousClassName(expression);
ClassDescriptor classDescriptor = recordClassForFunction(functionDescriptor, Collections.singleton(supertype));
ClassDescriptor classDescriptor = recordClassForFunction(functionDescriptor, supertypes);
recordClosure(expression, classDescriptor, name);
pushClassDescriptor(classDescriptor);
@@ -4,20 +4,20 @@ class A {
fun bar(): String = ""
}
fun A.baz() {}
fun A.baz(x: Int) {}
fun box(): String {
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 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}"
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"
}
@@ -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]}"
}