From 8f7c0f0b65f4a055b6be0e3de68c3f03b1083422 Mon Sep 17 00:00:00 2001 From: Alexander Udalov Date: Fri, 16 May 2014 20:49:00 +0400 Subject: [PATCH] Introduce KFunctionImpl, KMemberFunctionImpl, KExtensionFunctionImpl Old 23*3 classes will be dropped, since they have no value. Simplify JvmFunctionImplTypes significantly because of that --- .../jet/codegen/JvmFunctionImplTypes.java | 163 ++++++------------ .../binding/CodegenAnnotatingVisitor.java | 6 +- .../callableReference/function/toString.kt | 8 +- .../jvm/internal/KExtensionFunctionImpl.kt | 21 +++ .../reflect/jvm/internal/KFunctionImpl.kt | 21 +++ .../jvm/internal/KMemberFunctionImpl.kt | 23 +++ 6 files changed, 129 insertions(+), 113 deletions(-) create mode 100644 core/runtime.jvm/src/kotlin/reflect/jvm/internal/KExtensionFunctionImpl.kt create mode 100644 core/runtime.jvm/src/kotlin/reflect/jvm/internal/KFunctionImpl.kt create mode 100644 core/runtime.jvm/src/kotlin/reflect/jvm/internal/KMemberFunctionImpl.kt diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/JvmFunctionImplTypes.java b/compiler/backend/src/org/jetbrains/jet/codegen/JvmFunctionImplTypes.java index 99c82023d92..c315f11c1c7 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/JvmFunctionImplTypes.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/JvmFunctionImplTypes.java @@ -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 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(""), Collections.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 getKFunctionsImplList() { - if (kFunctionsList == null) { - MutablePackageFragmentDescriptor packageFragment = new MutablePackageFragmentDescriptor( - DescriptorUtils.getContainingModule(functionImpl), new FqName("kotlin.reflect.jvm.internal") - ); - - ImmutableList.Builder 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 typeParameterDescriptors = new ArrayList(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 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 getSupertypesForCallableReference(@NotNull FunctionDescriptor descriptor) { ReceiverParameterDescriptor receiverParameter = descriptor.getReceiverParameter(); ReceiverParameterDescriptor expectedThisObject = descriptor.getExpectedThisObject(); - List typeArguments = new ArrayList(arity + 2); + List typeArguments = new ArrayList(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 typeParameters - ) { - functionImpl.setModality(Modality.FINAL); - functionImpl.setVisibility(Visibilities.PUBLIC); - functionImpl.setTypeParameterDescriptors(typeParameters); - functionImpl.createTypeConstructor(); - - return functionImpl; + return Arrays.asList(kFunctionImplType, kFunctionType); } } diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/binding/CodegenAnnotatingVisitor.java b/compiler/backend/src/org/jetbrains/jet/codegen/binding/CodegenAnnotatingVisitor.java index 9e18d8b1303..b246bf148f7 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/binding/CodegenAnnotatingVisitor.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/binding/CodegenAnnotatingVisitor.java @@ -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 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); diff --git a/compiler/testData/codegen/boxWithStdlib/callableReference/function/toString.kt b/compiler/testData/codegen/boxWithStdlib/callableReference/function/toString.kt index 148ee943a8a..d341c0ec31c 100644 --- a/compiler/testData/codegen/boxWithStdlib/callableReference/function/toString.kt +++ b/compiler/testData/codegen/boxWithStdlib/callableReference/function/toString.kt @@ -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") return "Fail foo: $f" + if (f != "kotlin.reflect.KFunction1") 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" } diff --git a/core/runtime.jvm/src/kotlin/reflect/jvm/internal/KExtensionFunctionImpl.kt b/core/runtime.jvm/src/kotlin/reflect/jvm/internal/KExtensionFunctionImpl.kt new file mode 100644 index 00000000000..929e194890d --- /dev/null +++ b/core/runtime.jvm/src/kotlin/reflect/jvm/internal/KExtensionFunctionImpl.kt @@ -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 : ExtensionFunctionImpl() diff --git a/core/runtime.jvm/src/kotlin/reflect/jvm/internal/KFunctionImpl.kt b/core/runtime.jvm/src/kotlin/reflect/jvm/internal/KFunctionImpl.kt new file mode 100644 index 00000000000..01a034cb22b --- /dev/null +++ b/core/runtime.jvm/src/kotlin/reflect/jvm/internal/KFunctionImpl.kt @@ -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 : FunctionImpl() diff --git a/core/runtime.jvm/src/kotlin/reflect/jvm/internal/KMemberFunctionImpl.kt b/core/runtime.jvm/src/kotlin/reflect/jvm/internal/KMemberFunctionImpl.kt new file mode 100644 index 00000000000..8051e919039 --- /dev/null +++ b/core/runtime.jvm/src/kotlin/reflect/jvm/internal/KMemberFunctionImpl.kt @@ -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 : Serializable { + override fun toString() = "${getClass().getGenericInterfaces()[0]}" +}