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:
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
+3
-3
@@ -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]}"
|
||||
}
|
||||
Reference in New Issue
Block a user