From 4141e0a8dfb5fa25a942407536100210496e9da4 Mon Sep 17 00:00:00 2001 From: Alexander Udalov Date: Thu, 16 Apr 2015 17:58:18 +0300 Subject: [PATCH] Introduce fictitious numbered Function class descriptors --- .../kotlin/codegen/JvmRuntimeTypes.java | 29 ++- .../codegen/inline/InlineCodegenUtil.java | 2 +- .../kotlin/codegen/state/JetTypeMapper.java | 5 +- .../box/functions/functionNtoString.kt | 12 +- .../functionLiteralGenericSignature.kt | 12 +- .../adapters/inheritedOverriddenAdapter.java | 2 +- .../MethodWithFunctionTypes.java | 6 +- .../MethodWithFunctionTypes.txt | 2 +- .../AdapterDoesntOverrideDeclaration.java | 2 +- .../InheritedAdapterAndDeclaration.java | 2 +- .../InheritedOverriddenAdapter.java | 2 +- .../OverriddenAmbiguousAdapters.java | 2 +- .../kotlin/codegen/OuterClassGenTest.java | 4 +- .../builtins/BuiltInsSerializerTest.kt | 12 +- .../DeserializationComponentsForJava.kt | 3 +- .../kotlin/platform/JavaToKotlinClassMap.java | 22 ++- .../kotlin/builtins/KotlinBuiltIns.java | 2 + .../builtInsPackageFragmentProvider.kt | 9 +- .../BuiltInFictitiousFunctionClassFactory.kt | 77 ++++++++ .../functions/FunctionClassDescriptor.kt | 162 +++++++++++++++ .../builtins/functions/FunctionClassScope.kt | 85 ++++++++ .../functions/FunctionInvokeDescriptor.kt | 92 +++++++++ .../ClassDescriptorFactory.kt} | 13 +- .../deserialization/ClassDeserializer.kt | 13 +- .../serialization/deserialization/context.kt | 9 +- .../src/kotlin/jvm/internal/FunctionImpl.java | 185 ++++++++++++++++++ .../generators/builtins/functionImpl.kt | 80 ++++++++ .../generators/builtins/generateBuiltIns.kt | 12 +- .../textBuilder/DeserializerForDecompiler.kt | 3 +- ...tlinJavaScriptDeserializerForDecompiler.kt | 3 +- .../after/a/X.java | 5 +- ...kotlinJavascriptPackageFragmentProvider.kt | 8 +- 32 files changed, 807 insertions(+), 70 deletions(-) create mode 100644 core/descriptors/src/org/jetbrains/kotlin/builtins/functions/BuiltInFictitiousFunctionClassFactory.kt create mode 100644 core/descriptors/src/org/jetbrains/kotlin/builtins/functions/FunctionClassDescriptor.kt create mode 100644 core/descriptors/src/org/jetbrains/kotlin/builtins/functions/FunctionClassScope.kt create mode 100644 core/descriptors/src/org/jetbrains/kotlin/builtins/functions/FunctionInvokeDescriptor.kt rename core/{runtime.jvm/src/kotlin/jvm/internal/FunctionImpl.kt => deserialization/src/org/jetbrains/kotlin/serialization/deserialization/ClassDescriptorFactory.kt} (60%) create mode 100644 core/runtime.jvm/src/kotlin/jvm/internal/FunctionImpl.java create mode 100644 generators/src/org/jetbrains/kotlin/generators/builtins/functionImpl.kt diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/JvmRuntimeTypes.java b/compiler/backend/src/org/jetbrains/kotlin/codegen/JvmRuntimeTypes.java index 83e2b343e0a..d647a08e795 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/JvmRuntimeTypes.java +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/JvmRuntimeTypes.java @@ -28,11 +28,12 @@ import org.jetbrains.kotlin.name.Name; import org.jetbrains.kotlin.resolve.jvm.TopDownAnalyzerFacadeForJVM; import org.jetbrains.kotlin.storage.LockBasedStorageManager; import org.jetbrains.kotlin.types.JetType; +import org.jetbrains.kotlin.types.JetTypeImpl; +import org.jetbrains.kotlin.types.TypeProjection; +import org.jetbrains.kotlin.types.TypeProjectionImpl; import org.jetbrains.kotlin.types.expressions.ExpressionTypingUtils; -import java.util.Arrays; -import java.util.Collection; -import java.util.Collections; +import java.util.*; import static org.jetbrains.kotlin.resolve.descriptorUtil.DescriptorUtilPackage.getBuiltIns; @@ -94,30 +95,40 @@ public class JvmRuntimeTypes { ReceiverParameterDescriptor extensionReceiver = descriptor.getExtensionReceiverParameter(); ReceiverParameterDescriptor dispatchReceiver = descriptor.getDispatchReceiverParameter(); + List typeArguments = new ArrayList(2); + + ClassDescriptor kFunctionClass; ClassDescriptor functionImplClass; JetType receiverType; if (extensionReceiver != null) { functionImplClass = extensionFunctionImpl; receiverType = extensionReceiver.getType(); + kFunctionClass = reflectionTypes.getkExtensionFunction(); + typeArguments.add(new TypeProjectionImpl(receiverType)); } else if (dispatchReceiver != null) { functionImplClass = memberFunctionImpl; receiverType = dispatchReceiver.getType(); + kFunctionClass = reflectionTypes.getkMemberFunction(); + typeArguments.add(new TypeProjectionImpl(receiverType)); } else { functionImplClass = functionImpl; receiverType = null; + kFunctionClass = reflectionTypes.getkFunction(); } JetType functionImplType = functionImplClass.getDefaultType(); //noinspection ConstantConditions - JetType kFunctionType = reflectionTypes.getKFunctionType( - Annotations.EMPTY, - receiverType, - ExpressionTypingUtils.getValueParametersTypes(descriptor.getValueParameters()), - descriptor.getReturnType(), - extensionReceiver != null + typeArguments.add(new TypeProjectionImpl(descriptor.getReturnType())); + + JetType kFunctionType = new JetTypeImpl( + kFunctionClass.getDefaultType().getAnnotations(), + kFunctionClass.getTypeConstructor(), + false, + typeArguments, + kFunctionClass.getMemberScope(typeArguments) ); return Arrays.asList(functionImplType, kFunctionType); diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/InlineCodegenUtil.java b/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/InlineCodegenUtil.java index 28992048dcd..83a0617e85b 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/InlineCodegenUtil.java +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/InlineCodegenUtil.java @@ -256,7 +256,7 @@ public class InlineCodegenUtil { return false; } - for (String prefix : Arrays.asList("kotlin/Function", "kotlin/ExtensionFunction")) { + for (String prefix : Arrays.asList("kotlin/jvm/functions/Function", "kotlin/ExtensionFunction")) { if (owner.startsWith(prefix)) { String suffix = owner.substring(prefix.length()); if (isInteger(suffix)) { diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/state/JetTypeMapper.java b/compiler/backend/src/org/jetbrains/kotlin/codegen/state/JetTypeMapper.java index 85d64e0a06f..e50cebb4a34 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/state/JetTypeMapper.java +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/state/JetTypeMapper.java @@ -22,6 +22,7 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.kotlin.builtins.KotlinBuiltIns; import org.jetbrains.kotlin.builtins.PrimitiveType; +import org.jetbrains.kotlin.builtins.functions.FunctionClassDescriptor; import org.jetbrains.kotlin.codegen.*; import org.jetbrains.kotlin.codegen.binding.CodegenBinding; import org.jetbrains.kotlin.codegen.binding.MutableClosure; @@ -595,7 +596,9 @@ public class JetTypeMapper { signature = mapSignature(functionDescriptor.getOriginal()); - ClassDescriptor receiver = currentIsInterface && !originalIsInterface ? declarationOwner : currentOwner; + ClassDescriptor receiver = (currentIsInterface && !originalIsInterface) || currentOwner instanceof FunctionClassDescriptor + ? declarationOwner + : currentOwner; owner = mapClass(receiver); thisClass = owner; } diff --git a/compiler/testData/codegen/box/functions/functionNtoString.kt b/compiler/testData/codegen/box/functions/functionNtoString.kt index 1add172e443..fdd06bbbd18 100644 --- a/compiler/testData/codegen/box/functions/functionNtoString.kt +++ b/compiler/testData/codegen/box/functions/functionNtoString.kt @@ -6,13 +6,13 @@ fun check(expected: String, obj: Any?) { fun box(): String { - check("kotlin.Function0") + check("kotlin.jvm.functions.Function0") { -> } - check("kotlin.Function0") - { -> 42 } - check("kotlin.Function1", + check("kotlin.jvm.functions.Function0") + { -> 42 } + check("kotlin.jvm.functions.Function1", fun (s: String) = 42.toLong()) - check("kotlin.Function2") + check("kotlin.jvm.functions.Function2") { x: Int, y: Int -> } check("kotlin.ExtensionFunction0", @@ -25,4 +25,4 @@ fun box(): String { fun Int.(x: Int, y: Int) {}) return "OK" -} \ No newline at end of file +} diff --git a/compiler/testData/codegen/box/reflection/functionLiteralGenericSignature.kt b/compiler/testData/codegen/box/reflection/functionLiteralGenericSignature.kt index 167fb492450..60ee90aa2e6 100644 --- a/compiler/testData/codegen/box/reflection/functionLiteralGenericSignature.kt +++ b/compiler/testData/codegen/box/reflection/functionLiteralGenericSignature.kt @@ -19,12 +19,12 @@ val extensionFun = fun Any.() {} val extensionWithArgFun = fun Long.(x: Any): Date = Date() fun box(): String { - assertGenericSuper("kotlin.Function0", unitFun) - assertGenericSuper("kotlin.Function0", intFun) - assertGenericSuper("kotlin.Function1", stringParamFun) - assertGenericSuper("kotlin.Function1, java.util.List>", listFun) - assertGenericSuper("kotlin.Function1, java.util.List>", mutableListFun) - assertGenericSuper("kotlin.Function1, kotlin.Unit>", funWithIn) + assertGenericSuper("kotlin.jvm.functions.Function0", unitFun) + assertGenericSuper("kotlin.jvm.functions.Function0", intFun) + assertGenericSuper("kotlin.jvm.functions.Function1", stringParamFun) + assertGenericSuper("kotlin.jvm.functions.Function1, java.util.List>", listFun) + assertGenericSuper("kotlin.jvm.functions.Function1, java.util.List>", mutableListFun) + assertGenericSuper("kotlin.jvm.functions.Function1, kotlin.Unit>", funWithIn) assertGenericSuper("kotlin.ExtensionFunction0", extensionFun) assertGenericSuper("kotlin.ExtensionFunction1", extensionWithArgFun) diff --git a/compiler/testData/codegen/boxAgainstJava/sam/adapters/inheritedOverriddenAdapter.java b/compiler/testData/codegen/boxAgainstJava/sam/adapters/inheritedOverriddenAdapter.java index a5b02a1a406..4489ca4cf5e 100644 --- a/compiler/testData/codegen/boxAgainstJava/sam/adapters/inheritedOverriddenAdapter.java +++ b/compiler/testData/codegen/boxAgainstJava/sam/adapters/inheritedOverriddenAdapter.java @@ -7,7 +7,7 @@ class Super { } class Sub extends Super { - void foo(kotlin.Function0 r) { + void foo(kotlin.jvm.functions.Function0 r) { lastCalled = "sub"; } } diff --git a/compiler/testData/loadJava/compiledJava/kotlinSignature/MethodWithFunctionTypes.java b/compiler/testData/loadJava/compiledJava/kotlinSignature/MethodWithFunctionTypes.java index 0c63b4abb02..ae4162d2726 100644 --- a/compiler/testData/loadJava/compiledJava/kotlinSignature/MethodWithFunctionTypes.java +++ b/compiler/testData/loadJava/compiledJava/kotlinSignature/MethodWithFunctionTypes.java @@ -4,11 +4,11 @@ import java.lang.String; import java.lang.UnsupportedOperationException; import java.util.*; import jet.runtime.typeinfo.KotlinSignature; -import kotlin.*; +import kotlin.jvm.functions.*; public class MethodWithFunctionTypes { - @KotlinSignature("fun foo(f : (String?) -> String) : (String.() -> String?)?") - public ExtensionFunction0 foo(Function1 f) { + @KotlinSignature("fun foo(f : (String?) -> String) : (() -> String?)?") + public Function0 foo(Function1 f) { throw new UnsupportedOperationException(); } } diff --git a/compiler/testData/loadJava/compiledJava/kotlinSignature/MethodWithFunctionTypes.txt b/compiler/testData/loadJava/compiledJava/kotlinSignature/MethodWithFunctionTypes.txt index bbadf981ea0..3e2866e6261 100644 --- a/compiler/testData/loadJava/compiledJava/kotlinSignature/MethodWithFunctionTypes.txt +++ b/compiler/testData/loadJava/compiledJava/kotlinSignature/MethodWithFunctionTypes.txt @@ -2,5 +2,5 @@ package test public open class MethodWithFunctionTypes { public constructor MethodWithFunctionTypes() - public open fun foo(/*0*/ f: ((kotlin.String!) -> kotlin.String!)!): (kotlin.String!.() -> kotlin.String!)! + public open fun foo(/*0*/ f: ((kotlin.String!) -> kotlin.String!)!): (() -> kotlin.String!)! } diff --git a/compiler/testData/loadJava/compiledJava/sam/adapters/inheritance/AdapterDoesntOverrideDeclaration.java b/compiler/testData/loadJava/compiledJava/sam/adapters/inheritance/AdapterDoesntOverrideDeclaration.java index 0b6a153d6ea..68786d142a5 100644 --- a/compiler/testData/loadJava/compiledJava/sam/adapters/inheritance/AdapterDoesntOverrideDeclaration.java +++ b/compiler/testData/loadJava/compiledJava/sam/adapters/inheritance/AdapterDoesntOverrideDeclaration.java @@ -2,7 +2,7 @@ package test; public interface AdapterDoesntOverrideDeclaration { public interface Super { - void foo(kotlin.Function0 r); + void foo(kotlin.jvm.functions.Function0 r); } public interface Sub extends Super { diff --git a/compiler/testData/loadJava/compiledJava/sam/adapters/inheritance/InheritedAdapterAndDeclaration.java b/compiler/testData/loadJava/compiledJava/sam/adapters/inheritance/InheritedAdapterAndDeclaration.java index 943dfaf160e..330ebd7a6fc 100644 --- a/compiler/testData/loadJava/compiledJava/sam/adapters/inheritance/InheritedAdapterAndDeclaration.java +++ b/compiler/testData/loadJava/compiledJava/sam/adapters/inheritance/InheritedAdapterAndDeclaration.java @@ -3,7 +3,7 @@ package test; public interface InheritedAdapterAndDeclaration { public interface Super { void foo(Runnable r); - void foo(kotlin.Function0 r); + void foo(kotlin.jvm.functions.Function0 r); } public interface Sub extends Super { diff --git a/compiler/testData/loadJava/compiledJava/sam/adapters/inheritance/InheritedOverriddenAdapter.java b/compiler/testData/loadJava/compiledJava/sam/adapters/inheritance/InheritedOverriddenAdapter.java index 7096030a1e6..15e197be571 100644 --- a/compiler/testData/loadJava/compiledJava/sam/adapters/inheritance/InheritedOverriddenAdapter.java +++ b/compiler/testData/loadJava/compiledJava/sam/adapters/inheritance/InheritedOverriddenAdapter.java @@ -7,7 +7,7 @@ public interface InheritedOverriddenAdapter { } public class Sub extends Super { - public void foo(kotlin.Function0 r) { + public void foo(kotlin.jvm.functions.Function0 r) { } } } diff --git a/compiler/testData/loadJava/compiledJava/sam/adapters/inheritance/OverriddenAmbiguousAdapters.java b/compiler/testData/loadJava/compiledJava/sam/adapters/inheritance/OverriddenAmbiguousAdapters.java index 2006e77772a..9a9391e9343 100644 --- a/compiler/testData/loadJava/compiledJava/sam/adapters/inheritance/OverriddenAmbiguousAdapters.java +++ b/compiler/testData/loadJava/compiledJava/sam/adapters/inheritance/OverriddenAmbiguousAdapters.java @@ -9,6 +9,6 @@ public interface OverriddenAmbiguousAdapters { } public interface Sub extends Super { - void foo(kotlin.Function0 r); + void foo(kotlin.jvm.functions.Function0 r); } } diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/OuterClassGenTest.java b/compiler/tests/org/jetbrains/kotlin/codegen/OuterClassGenTest.java index cd9fafa88d9..7e38ba3670e 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/OuterClassGenTest.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/OuterClassGenTest.java @@ -91,7 +91,7 @@ public class OuterClassGenTest extends CodegenTestCase { } public void testLocalObjectInInlineFunction() throws Exception { - OuterClassInfo expectedInfo = new OuterClassInfo("foo/Foo", "inlineFoo", "(Lkotlin/Function0;)V"); + OuterClassInfo expectedInfo = new OuterClassInfo("foo/Foo", "inlineFoo", "(Lkotlin/jvm/functions/Function0;)V"); doCustomTest("foo/Foo\\$inlineFoo\\$localObject\\$1", expectedInfo, "inlineObject"); } @@ -116,7 +116,7 @@ public class OuterClassGenTest extends CodegenTestCase { } public void testLambdaInInlineFunction() throws Exception { - OuterClassInfo expectedInfo = new OuterClassInfo("foo/Foo", "inlineFoo", "(Lkotlin/Function0;)V"); + OuterClassInfo expectedInfo = new OuterClassInfo("foo/Foo", "inlineFoo", "(Lkotlin/jvm/functions/Function0;)V"); doCustomTest("foo/Foo\\$inlineFoo\\$1", expectedInfo, "inlineLambda"); } diff --git a/compiler/tests/org/jetbrains/kotlin/serialization/builtins/BuiltInsSerializerTest.kt b/compiler/tests/org/jetbrains/kotlin/serialization/builtins/BuiltInsSerializerTest.kt index 7a1c58200b6..2367372294a 100644 --- a/compiler/tests/org/jetbrains/kotlin/serialization/builtins/BuiltInsSerializerTest.kt +++ b/compiler/tests/org/jetbrains/kotlin/serialization/builtins/BuiltInsSerializerTest.kt @@ -20,6 +20,7 @@ import org.jetbrains.kotlin.builtins.KotlinBuiltIns import org.jetbrains.kotlin.builtins.createBuiltInPackageFragmentProvider import org.jetbrains.kotlin.codegen.forTestCompile.ForTestCompileRuntime import org.jetbrains.kotlin.jvm.compiler.LoadDescriptorUtil.TEST_PACKAGE_FQNAME +import org.jetbrains.kotlin.serialization.deserialization.ClassDescriptorFactory import org.jetbrains.kotlin.storage.LockBasedStorageManager import org.jetbrains.kotlin.test.JetTestUtils import org.jetbrains.kotlin.test.TestCaseWithTmpdir @@ -39,11 +40,12 @@ public class BuiltInsSerializerTest : TestCaseWithTmpdir() { val module = JetTestUtils.createEmptyModule("") - val packageFragmentProvider = - createBuiltInPackageFragmentProvider(LockBasedStorageManager(), module, setOf(TEST_PACKAGE_FQNAME)) { - val file = File(tmpdir, it) - if (file.exists()) FileInputStream(file) else null - } + val packageFragmentProvider = createBuiltInPackageFragmentProvider( + LockBasedStorageManager(), module, setOf(TEST_PACKAGE_FQNAME), ClassDescriptorFactory.EMPTY + ) { + val file = File(tmpdir, it) + if (file.exists()) FileInputStream(file) else null + } module.initialize(packageFragmentProvider) module.addDependencyOnModule(module) diff --git a/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/kotlin/DeserializationComponentsForJava.kt b/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/kotlin/DeserializationComponentsForJava.kt index 5f65ed25db5..8a8360394d8 100644 --- a/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/kotlin/DeserializationComponentsForJava.kt +++ b/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/kotlin/DeserializationComponentsForJava.kt @@ -18,6 +18,7 @@ package org.jetbrains.kotlin.load.kotlin import org.jetbrains.kotlin.descriptors.ModuleDescriptor import org.jetbrains.kotlin.load.java.lazy.LazyJavaPackageFragmentProvider +import org.jetbrains.kotlin.serialization.deserialization.ClassDescriptorFactory import org.jetbrains.kotlin.serialization.deserialization.DeserializationComponents import org.jetbrains.kotlin.serialization.deserialization.LocalClassResolverImpl import org.jetbrains.kotlin.storage.StorageManager @@ -37,7 +38,7 @@ public class DeserializationComponentsForJava( val localClassResolver = LocalClassResolverImpl() components = DeserializationComponents( storageManager, moduleDescriptor, classDataFinder, annotationAndConstantLoader, packageFragmentProvider, - localClassResolver, JavaFlexibleTypeCapabilitiesDeserializer + localClassResolver, JavaFlexibleTypeCapabilitiesDeserializer, ClassDescriptorFactory.EMPTY ) localClassResolver.setDeserializationComponents(components) } diff --git a/core/descriptor.loader.java/src/org/jetbrains/kotlin/platform/JavaToKotlinClassMap.java b/core/descriptor.loader.java/src/org/jetbrains/kotlin/platform/JavaToKotlinClassMap.java index e64f49d1413..bb5b80e799f 100644 --- a/core/descriptor.loader.java/src/org/jetbrains/kotlin/platform/JavaToKotlinClassMap.java +++ b/core/descriptor.loader.java/src/org/jetbrains/kotlin/platform/JavaToKotlinClassMap.java @@ -73,6 +73,19 @@ public class JavaToKotlinClassMap implements PlatformToKotlinClassMap { add(ClassId.topLevel(new FqName("kotlin.jvm.internal." + descriptor.getName().asString() + "CompanionObject")), companion); } + // TODO: support also functions with >= 23 parameters + for (int i = 0; i < 23; i++) { + add(ClassId.topLevel(new FqName("kotlin.jvm.functions.Function" + i)), builtIns.getFunction(i)); + + for (String kFun : Arrays.asList( + "kotlin.reflect.KFunction", + "kotlin.reflect.KMemberFunction", + "kotlin.reflect.KExtensionFunction" + )) { + addKotlinToJava(ClassId.topLevel(new FqName(kFun)), new FqNameUnsafe(kFun + i)); + } + } + addJavaToKotlin(classId(Deprecated.class), builtIns.getDeprecatedAnnotation()); addKotlinToJava(classId(Void.class), builtIns.getNothing()); @@ -87,6 +100,7 @@ public class JavaToKotlinClassMap implements PlatformToKotlinClassMap { * java.util.List -> kotlin.List * java.util.Map.Entry -> kotlin.Map.Entry * java.lang.Void -> null + * kotlin.jvm.functions.Function3 -> kotlin.Function3 */ @Nullable public ClassDescriptor mapJavaToKotlin(@NotNull FqName fqName) { @@ -100,6 +114,8 @@ public class JavaToKotlinClassMap implements PlatformToKotlinClassMap { * kotlin.Int.Companion -> kotlin.jvm.internal.IntCompanionObject * kotlin.Nothing -> java.lang.Void * kotlin.IntArray -> null + * kotlin.Function3 -> kotlin.jvm.functions.Function3 + * kotlin.reflect.KFunction3 -> kotlin.reflect.KFunction */ @Nullable public ClassId mapKotlinToJava(@NotNull FqNameUnsafe kotlinFqName) { @@ -134,7 +150,11 @@ public class JavaToKotlinClassMap implements PlatformToKotlinClassMap { } private void addKotlinToJava(@NotNull ClassId javaClassId, @NotNull ClassDescriptor kotlinDescriptor) { - kotlinToJava.put(DescriptorUtils.getFqName(kotlinDescriptor), javaClassId); + addKotlinToJava(javaClassId, DescriptorUtils.getFqName(kotlinDescriptor)); + } + + private void addKotlinToJava(@NotNull ClassId javaClassId, @NotNull FqNameUnsafe kotlinFqName) { + kotlinToJava.put(kotlinFqName, javaClassId); } @NotNull diff --git a/core/descriptors/src/org/jetbrains/kotlin/builtins/KotlinBuiltIns.java b/core/descriptors/src/org/jetbrains/kotlin/builtins/KotlinBuiltIns.java index 09578f0b80f..8368dd3fd3c 100644 --- a/core/descriptors/src/org/jetbrains/kotlin/builtins/KotlinBuiltIns.java +++ b/core/descriptors/src/org/jetbrains/kotlin/builtins/KotlinBuiltIns.java @@ -21,6 +21,7 @@ import kotlin.*; import kotlin.KotlinPackage; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import org.jetbrains.kotlin.builtins.functions.BuiltInFictitiousFunctionClassFactory; import org.jetbrains.kotlin.descriptors.*; import org.jetbrains.kotlin.descriptors.annotations.AnnotationDescriptor; import org.jetbrains.kotlin.descriptors.annotations.Annotations; @@ -116,6 +117,7 @@ public class KotlinBuiltIns { PackageFragmentProvider packageFragmentProvider = BuiltinsPackage.createBuiltInPackageFragmentProvider( storageManager, builtInsModule, setOf(BUILT_INS_PACKAGE_FQ_NAME, BuiltinsPackage.getKOTLIN_REFLECT_FQ_NAME()), + new BuiltInFictitiousFunctionClassFactory(storageManager, builtInsModule), new Function1() { @Override public InputStream invoke(String path) { diff --git a/core/descriptors/src/org/jetbrains/kotlin/builtins/builtInsPackageFragmentProvider.kt b/core/descriptors/src/org/jetbrains/kotlin/builtins/builtInsPackageFragmentProvider.kt index 62d0f0355bf..91dccc07adf 100644 --- a/core/descriptors/src/org/jetbrains/kotlin/builtins/builtInsPackageFragmentProvider.kt +++ b/core/descriptors/src/org/jetbrains/kotlin/builtins/builtInsPackageFragmentProvider.kt @@ -20,10 +20,7 @@ import org.jetbrains.kotlin.descriptors.ModuleDescriptor import org.jetbrains.kotlin.descriptors.PackageFragmentProvider import org.jetbrains.kotlin.descriptors.PackageFragmentProviderImpl import org.jetbrains.kotlin.name.FqName -import org.jetbrains.kotlin.serialization.deserialization.DeserializationComponents -import org.jetbrains.kotlin.serialization.deserialization.FlexibleTypeCapabilitiesDeserializer -import org.jetbrains.kotlin.serialization.deserialization.LocalClassResolverImpl -import org.jetbrains.kotlin.serialization.deserialization.ResourceLoadingClassDataFinder +import org.jetbrains.kotlin.serialization.deserialization.* import org.jetbrains.kotlin.storage.StorageManager import java.io.InputStream @@ -31,6 +28,7 @@ public fun createBuiltInPackageFragmentProvider( storageManager: StorageManager, module: ModuleDescriptor, packageFqNames: Set, + classDescriptorFactory: ClassDescriptorFactory, loadResource: (String) -> InputStream? ): PackageFragmentProvider { val packageFragments = packageFqNames.map { fqName -> @@ -47,7 +45,8 @@ public fun createBuiltInPackageFragmentProvider( BuiltInsAnnotationAndConstantLoader(module), provider, localClassResolver, - FlexibleTypeCapabilitiesDeserializer.ThrowException + FlexibleTypeCapabilitiesDeserializer.ThrowException, + classDescriptorFactory ) localClassResolver.setDeserializationComponents(components) diff --git a/core/descriptors/src/org/jetbrains/kotlin/builtins/functions/BuiltInFictitiousFunctionClassFactory.kt b/core/descriptors/src/org/jetbrains/kotlin/builtins/functions/BuiltInFictitiousFunctionClassFactory.kt new file mode 100644 index 00000000000..d0e2ddf8522 --- /dev/null +++ b/core/descriptors/src/org/jetbrains/kotlin/builtins/functions/BuiltInFictitiousFunctionClassFactory.kt @@ -0,0 +1,77 @@ +/* + * Copyright 2010-2015 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 org.jetbrains.kotlin.builtins.functions + +import org.jetbrains.kotlin.builtins.KOTLIN_REFLECT_FQ_NAME +import org.jetbrains.kotlin.builtins.KotlinBuiltIns.BUILT_INS_PACKAGE_FQ_NAME +import org.jetbrains.kotlin.builtins.functions.FunctionClassDescriptor.Kind +import org.jetbrains.kotlin.builtins.functions.FunctionClassDescriptor.Kinds +import org.jetbrains.kotlin.descriptors.ClassDescriptor +import org.jetbrains.kotlin.descriptors.ModuleDescriptor +import org.jetbrains.kotlin.name.ClassId +import org.jetbrains.kotlin.serialization.deserialization.ClassDescriptorFactory +import org.jetbrains.kotlin.storage.StorageManager + +/** + * Produces descriptors representing the fictitious classes for function types, such as kotlin.Function1 or kotlin.reflect.KMemberFunction0. + */ +public class BuiltInFictitiousFunctionClassFactory( + private val storageManager: StorageManager, + private val module: ModuleDescriptor +) : ClassDescriptorFactory { + + private data class KindWithArity(val kind: Kind, val arity: Int) + + private fun parseClassName(className: String, allowedKinds: Set): KindWithArity? { + for (kind in allowedKinds) { + val prefix = kind.classNamePrefix + if (!className.startsWith(prefix)) continue + + val arity = try { + className.substring(prefix.length()).toInt() + } + catch (e: NumberFormatException) { continue } + + // TODO: validate arity, should be <= 255 for functions, <= 254 for members/extensions + return KindWithArity(kind, arity) + } + + return null + } + + override fun createClass(classId: ClassId): ClassDescriptor? { + if (classId.isLocal() || classId.isNestedClass()) return null + + val className = classId.getRelativeClassName().asString() + if ("Function" !in className) return null // An optimization + + val packageFqName = classId.getPackageFqName() + + val allowedKinds = when (packageFqName) { + BUILT_INS_PACKAGE_FQ_NAME -> Kinds.Functions + KOTLIN_REFLECT_FQ_NAME -> Kinds.KFunctions + else -> return null + } + + val kindWithArity = parseClassName(className, allowedKinds) ?: return null + val (kind, arity) = kindWithArity // KT-5100 + + val containingPackageFragment = module.getPackage(packageFqName)!!.getFragments().single() + + return FunctionClassDescriptor(storageManager, containingPackageFragment, kind, arity) + } +} diff --git a/core/descriptors/src/org/jetbrains/kotlin/builtins/functions/FunctionClassDescriptor.kt b/core/descriptors/src/org/jetbrains/kotlin/builtins/functions/FunctionClassDescriptor.kt new file mode 100644 index 00000000000..9161f5aac8a --- /dev/null +++ b/core/descriptors/src/org/jetbrains/kotlin/builtins/functions/FunctionClassDescriptor.kt @@ -0,0 +1,162 @@ +/* + * Copyright 2010-2015 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 org.jetbrains.kotlin.builtins.functions + +import org.jetbrains.kotlin.builtins.KotlinBuiltIns.BUILT_INS_PACKAGE_FQ_NAME +import org.jetbrains.kotlin.builtins.functions.FunctionClassDescriptor.Kind +import org.jetbrains.kotlin.descriptors.* +import org.jetbrains.kotlin.descriptors.annotations.Annotations +import org.jetbrains.kotlin.descriptors.impl.AbstractClassDescriptor +import org.jetbrains.kotlin.descriptors.impl.TypeParameterDescriptorImpl +import org.jetbrains.kotlin.name.Name +import org.jetbrains.kotlin.resolve.scopes.StaticScopeForKotlinClass +import org.jetbrains.kotlin.storage.StorageManager +import org.jetbrains.kotlin.types.* +import org.jetbrains.kotlin.utils.toReadOnlyList +import java.util.ArrayList +import java.util.EnumSet + +/** + * A [ClassDescriptor] representing the fictitious class for a function type, such as kotlin.Function1 or kotlin.reflect.KMemberFunction0. + * + * Classes which are represented by this descriptor include (with supertypes): + * + * Function1 : Function + * KFunction1 : Function1, KFunction + * KMemberFunction1 : Function2, KMemberFunction + * KExtensionFunction1 : Function2, KExtensionFunction + * (TODO) KMemberExtensionFunction1 : Function3, KMemberExtensionFunction + */ +public class FunctionClassDescriptor( + private val storageManager: StorageManager, + private val containingDeclaration: PackageFragmentDescriptor, + val functionKind: Kind, + val arity: Int +) : AbstractClassDescriptor(storageManager, functionKind.numberedClassName(arity)) { + + public enum class Kind(val classNamePrefix: String) { + Function("Function"), + KFunction("KFunction"), + KMemberFunction("KMemberFunction"), + KExtensionFunction("KExtensionFunction"); + // TODO: KMemberExtensionFunction + + fun numberedClassName(arity: Int) = Name.identifier("$classNamePrefix$arity") + val hasDispatchReceiver: Boolean get() = this == KMemberFunction + val hasExtensionReceiver: Boolean get() = this == KExtensionFunction + } + + public object Kinds { + val Functions = EnumSet.of(Kind.Function) + val KFunctions = EnumSet.of(Kind.KFunction, Kind.KMemberFunction, Kind.KExtensionFunction) + } + + private val staticScope = StaticScopeForKotlinClass(this) + private val typeConstructor = FunctionTypeConstructor() + private val memberScope = FunctionClassScope(storageManager, this) + + override fun getContainingDeclaration() = containingDeclaration + + override fun getStaticScope() = staticScope + + override fun getTypeConstructor(): TypeConstructor = typeConstructor + + override fun getScopeForMemberLookup() = memberScope + + override fun getCompanionObjectDescriptor() = null + override fun getConstructors() = emptyList() + override fun getKind() = ClassKind.INTERFACE + override fun getModality() = Modality.ABSTRACT + override fun getUnsubstitutedPrimaryConstructor() = null + override fun getVisibility() = Visibilities.PUBLIC + override fun isCompanionObject() = false + override fun isInner() = false + override fun getAnnotations() = Annotations.EMPTY + override fun getSource() = SourceElement.NO_SOURCE + + private inner class FunctionTypeConstructor : AbstractClassTypeConstructor() { + private val parameters = storageManager.createLazyValue { + val result = ArrayList() + + fun typeParameter(variance: Variance, name: String) { + result.add(TypeParameterDescriptorImpl.createWithDefaultBound( + this@FunctionClassDescriptor, Annotations.EMPTY, false, variance, Name.identifier(name), result.size() + )) + } + + if (functionKind.hasDispatchReceiver) { + typeParameter(Variance.IN_VARIANCE, "T") + } + if (functionKind.hasExtensionReceiver) { + typeParameter(Variance.IN_VARIANCE, "E") + } + + (1..arity).map { i -> + typeParameter(Variance.IN_VARIANCE, "P$i") + } + + typeParameter(Variance.OUT_VARIANCE, "R") + + result.toReadOnlyList() + } + + private val supertypes = storageManager.createLazyValue { + val result = ArrayList(2) + + fun add(packageFragment: PackageFragmentDescriptor, name: Name, annotations: Annotations) { + val descriptor = packageFragment.getMemberScope().getClassifier(name) as? ClassDescriptor + ?: error("Class $name not found in $packageFragment") + + // Substitute K type parameters of the super class with our last K type parameters + val typeConstructor = descriptor.getTypeConstructor() + val superParameters = typeConstructor.getParameters() + val arguments = getParameters().takeLast(superParameters.size()).map { TypeProjectionImpl(it.getDefaultType()) } + + result.add(JetTypeImpl(annotations, typeConstructor, false, arguments, descriptor.getMemberScope(arguments))) + } + + // Add unnumbered base class, e.g. KMemberFunction for KMemberFunction5, or Function for Function0 + add(containingDeclaration, Name.identifier(functionKind.classNamePrefix), Annotations.EMPTY) + + // For K*Functions, add corresponding numbered Function class, e.g. Function2 for KMemberFunction1 + if (functionKind in Kinds.KFunctions) { + var functionArity = arity + if (functionKind.hasDispatchReceiver) functionArity++ + if (functionKind.hasExtensionReceiver) functionArity++ + + val module = containingDeclaration.getContainingDeclaration() + val kotlinPackageFragment = module.getPackage(BUILT_INS_PACKAGE_FQ_NAME)!!.getFragments().single() + add(kotlinPackageFragment, Kind.Function.numberedClassName(functionArity), Annotations.EMPTY) + } + + result.toReadOnlyList() + } + + override fun getParameters() = parameters() + + override fun getSupertypes(): Collection = supertypes() + + override fun getDeclarationDescriptor() = this@FunctionClassDescriptor + override fun isDenotable() = true + override fun isFinal() = false + override fun getAnnotations() = Annotations.EMPTY + + override fun toString() = getDeclarationDescriptor().toString() + } + + override fun toString() = getName().asString() +} diff --git a/core/descriptors/src/org/jetbrains/kotlin/builtins/functions/FunctionClassScope.kt b/core/descriptors/src/org/jetbrains/kotlin/builtins/functions/FunctionClassScope.kt new file mode 100644 index 00000000000..13b68e0d240 --- /dev/null +++ b/core/descriptors/src/org/jetbrains/kotlin/builtins/functions/FunctionClassScope.kt @@ -0,0 +1,85 @@ +/* + * Copyright 2010-2015 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 org.jetbrains.kotlin.builtins.functions + +import org.jetbrains.kotlin.descriptors.CallableMemberDescriptor +import org.jetbrains.kotlin.descriptors.DeclarationDescriptor +import org.jetbrains.kotlin.descriptors.FunctionDescriptor +import org.jetbrains.kotlin.name.Name +import org.jetbrains.kotlin.resolve.OverridingUtil +import org.jetbrains.kotlin.resolve.scopes.DescriptorKindFilter +import org.jetbrains.kotlin.resolve.scopes.JetScopeImpl +import org.jetbrains.kotlin.storage.StorageManager +import org.jetbrains.kotlin.utils.Printer +import org.jetbrains.kotlin.utils.toReadOnlyList +import java.util.ArrayList + +class FunctionClassScope( + private val storageManager: StorageManager, + private val functionClass: FunctionClassDescriptor +) : JetScopeImpl() { + private val allFunctions = storageManager.createLazyValue { + if (functionClass.functionKind == FunctionClassDescriptor.Kind.Function) { + val invoke = FunctionInvokeDescriptor.create(functionClass) + (listOf(invoke) + createFakeOverrides(invoke)).toReadOnlyList() + } + else { + createFakeOverrides(null).toReadOnlyList() + } + } + + override fun getContainingDeclaration() = functionClass + + override fun getDescriptors(kindFilter: DescriptorKindFilter, nameFilter: (Name) -> Boolean): Collection { + if (!kindFilter.acceptsKinds(DescriptorKindFilter.FUNCTIONS_MASK)) return listOf() + return allFunctions() + } + + override fun getFunctions(name: Name): Collection { + return allFunctions().filter { it.getName() == name } + } + + private fun createFakeOverrides(invoke: FunctionDescriptor?): List { + val result = ArrayList(3) + val allSuperDescriptors = functionClass.getTypeConstructor().getSupertypes().flatMap { it.getMemberScope().getAllDescriptors() } + for ((name, descriptors) in allSuperDescriptors.groupBy { it.getName() }) { + @suppress("UNCHECKED_CAST") + OverridingUtil.generateOverridesInFunctionGroup( + name, + /* membersFromSupertypes = */ descriptors as Collection, + /* membersFromCurrent = */ if (name == invoke?.getName()) listOf(invoke) else listOf(), + functionClass, + object : OverridingUtil.DescriptorSink { + override fun addToScope(fakeOverride: CallableMemberDescriptor) { + OverridingUtil.resolveUnknownVisibilityForMember(fakeOverride, null) + result.add(fakeOverride as FunctionDescriptor) + } + + override fun conflict(fromSuper: CallableMemberDescriptor, fromCurrent: CallableMemberDescriptor) { + error("Conflict in scope of ${getContainingDeclaration()}: $fromSuper vs $fromCurrent") + } + } + ) + } + + return result + } + + override fun printScopeStructure(p: Printer) { + p.println("Scope of function class $functionClass") + } +} diff --git a/core/descriptors/src/org/jetbrains/kotlin/builtins/functions/FunctionInvokeDescriptor.kt b/core/descriptors/src/org/jetbrains/kotlin/builtins/functions/FunctionInvokeDescriptor.kt new file mode 100644 index 00000000000..939e2c68c6d --- /dev/null +++ b/core/descriptors/src/org/jetbrains/kotlin/builtins/functions/FunctionInvokeDescriptor.kt @@ -0,0 +1,92 @@ +/* + * Copyright 2010-2015 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 org.jetbrains.kotlin.builtins.functions + +import org.jetbrains.kotlin.descriptors.* +import org.jetbrains.kotlin.descriptors.annotations.Annotations +import org.jetbrains.kotlin.descriptors.impl.SimpleFunctionDescriptorImpl +import org.jetbrains.kotlin.descriptors.impl.ValueParameterDescriptorImpl +import org.jetbrains.kotlin.name.Name +import org.jetbrains.kotlin.types.Variance + +// TODO: make parameter names synthetic / non-stable +public class FunctionInvokeDescriptor private constructor( + private val container: DeclarationDescriptor, + private val original: FunctionInvokeDescriptor?, + private val callableKind: CallableMemberDescriptor.Kind +) : SimpleFunctionDescriptorImpl( + container, + original, + Annotations.EMPTY, + Name.identifier("invoke"), + callableKind, + SourceElement.NO_SOURCE +) { + override fun createSubstitutedCopy( + newOwner: DeclarationDescriptor, + original: FunctionDescriptor?, + kind: CallableMemberDescriptor.Kind + ): FunctionInvokeDescriptor { + return FunctionInvokeDescriptor(newOwner, original as FunctionInvokeDescriptor?, kind) + } + + companion object Factory { + fun create(functionClass: FunctionClassDescriptor): FunctionInvokeDescriptor { + val typeParameters = functionClass.getTypeConstructor().getParameters() + + val result = FunctionInvokeDescriptor(functionClass, null, CallableMemberDescriptor.Kind.DECLARATION) + result.initialize( + null, + functionClass.getThisAsReceiverParameter(), + listOf(), + typeParameters.takeWhile { it.getVariance() == Variance.IN_VARIANCE } + .withIndex() + .map { createValueParameter(result, it.index, it.value) }, + typeParameters.last().getDefaultType(), + Modality.ABSTRACT, + Visibilities.PUBLIC + ) + return result + } + + private fun createValueParameter( + containingDeclaration: FunctionInvokeDescriptor, + index: Int, + typeParameter: TypeParameterDescriptor + ): ValueParameterDescriptor { + val typeParameterName = typeParameter.getName().asString() + val name = when (typeParameterName) { + "T" -> "instance" + "E" -> "receiver" + else -> { + // Type parameter "P1" -> value parameter "p1", "P2" -> "p2", etc. + typeParameterName.toLowerCase() + } + } + + return ValueParameterDescriptorImpl( + containingDeclaration, null, index, + Annotations.EMPTY, + Name.identifier(name), + typeParameter.getDefaultType(), + /* declaresDefaultValue = */ false, + /* varargElementType = */ null, + SourceElement.NO_SOURCE + ) + } + } +} diff --git a/core/runtime.jvm/src/kotlin/jvm/internal/FunctionImpl.kt b/core/deserialization/src/org/jetbrains/kotlin/serialization/deserialization/ClassDescriptorFactory.kt similarity index 60% rename from core/runtime.jvm/src/kotlin/jvm/internal/FunctionImpl.kt rename to core/deserialization/src/org/jetbrains/kotlin/serialization/deserialization/ClassDescriptorFactory.kt index 0600f3db645..594fa389c45 100644 --- a/core/runtime.jvm/src/kotlin/jvm/internal/FunctionImpl.kt +++ b/core/deserialization/src/org/jetbrains/kotlin/serialization/deserialization/ClassDescriptorFactory.kt @@ -14,10 +14,15 @@ * limitations under the License. */ -package kotlin.jvm.internal +package org.jetbrains.kotlin.serialization.deserialization -import java.io.Serializable +import org.jetbrains.kotlin.descriptors.ClassDescriptor +import org.jetbrains.kotlin.name.ClassId -public abstract class FunctionImpl : Serializable { - override fun toString() = "${(this as Object).getClass().getGenericInterfaces()[0]}" +public interface ClassDescriptorFactory { + public fun createClass(classId: ClassId): ClassDescriptor? + + public object EMPTY : ClassDescriptorFactory { + override fun createClass(classId: ClassId): ClassDescriptor? = null + } } diff --git a/core/deserialization/src/org/jetbrains/kotlin/serialization/deserialization/ClassDeserializer.kt b/core/deserialization/src/org/jetbrains/kotlin/serialization/deserialization/ClassDeserializer.kt index edec8bfe9bb..f26af6d8b5b 100644 --- a/core/deserialization/src/org/jetbrains/kotlin/serialization/deserialization/ClassDeserializer.kt +++ b/core/deserialization/src/org/jetbrains/kotlin/serialization/deserialization/ClassDeserializer.kt @@ -16,23 +16,26 @@ package org.jetbrains.kotlin.serialization.deserialization -import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedClassDescriptor +import org.jetbrains.kotlin.descriptors.ClassDescriptor import org.jetbrains.kotlin.name.ClassId import org.jetbrains.kotlin.serialization.ClassData +import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedClassDescriptor public class ClassDeserializer(private val components: DeserializationComponents) { - private val classes: (ClassKey) -> DeserializedClassDescriptor? = + private val classes: (ClassKey) -> ClassDescriptor? = components.storageManager.createMemoizedFunctionWithNullableValues { key -> createClass(key) } // Additional ClassData parameter is needed to avoid calling ClassDataFinder#findClassData() if it is already computed at call site - public fun deserializeClass(classId: ClassId, classData: ClassData? = null): DeserializedClassDescriptor? = + public fun deserializeClass(classId: ClassId, classData: ClassData? = null): ClassDescriptor? = classes(ClassKey(classId, classData)) - private fun createClass(key: ClassKey): DeserializedClassDescriptor? { + private fun createClass(key: ClassKey): ClassDescriptor? { val classId = key.classId + components.fictitiousClassDescriptorFactory.createClass(classId)?.let { return it } + val classData = key.classData ?: components.classDataFinder.findClassData(classId) ?: return null val outerContext = if (classId.isNestedClass()) { - deserializeClass(classId.getOuterClassId())?.c ?: return null + (deserializeClass(classId.getOuterClassId()) as? DeserializedClassDescriptor)?.c ?: return null } else { val fragments = components.packageFragmentProvider.getPackageFragments(classId.getPackageFqName()) diff --git a/core/deserialization/src/org/jetbrains/kotlin/serialization/deserialization/context.kt b/core/deserialization/src/org/jetbrains/kotlin/serialization/deserialization/context.kt index cfa9ca5f7be..002cf06197e 100644 --- a/core/deserialization/src/org/jetbrains/kotlin/serialization/deserialization/context.kt +++ b/core/deserialization/src/org/jetbrains/kotlin/serialization/deserialization/context.kt @@ -16,12 +16,12 @@ package org.jetbrains.kotlin.serialization.deserialization -import org.jetbrains.kotlin.storage.StorageManager -import org.jetbrains.kotlin.serialization.ProtoBuf import org.jetbrains.kotlin.descriptors.* +import org.jetbrains.kotlin.descriptors.annotations.AnnotationDescriptor import org.jetbrains.kotlin.name.ClassId import org.jetbrains.kotlin.resolve.constants.CompileTimeConstant -import org.jetbrains.kotlin.descriptors.annotations.AnnotationDescriptor +import org.jetbrains.kotlin.serialization.ProtoBuf +import org.jetbrains.kotlin.storage.StorageManager public class DeserializationComponents( public val storageManager: StorageManager, @@ -30,7 +30,8 @@ public class DeserializationComponents( public val annotationAndConstantLoader: AnnotationAndConstantLoader>, public val packageFragmentProvider: PackageFragmentProvider, public val localClassResolver: LocalClassResolver, - public val flexibleTypeCapabilitiesDeserializer: FlexibleTypeCapabilitiesDeserializer + public val flexibleTypeCapabilitiesDeserializer: FlexibleTypeCapabilitiesDeserializer, + public val fictitiousClassDescriptorFactory: ClassDescriptorFactory ) { public val classDeserializer: ClassDeserializer = ClassDeserializer(this) diff --git a/core/runtime.jvm/src/kotlin/jvm/internal/FunctionImpl.java b/core/runtime.jvm/src/kotlin/jvm/internal/FunctionImpl.java new file mode 100644 index 00000000000..da76b499617 --- /dev/null +++ b/core/runtime.jvm/src/kotlin/jvm/internal/FunctionImpl.java @@ -0,0 +1,185 @@ +/* + * Copyright 2010-2015 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. + */ + +// Auto-generated file. DO NOT EDIT! + +package kotlin.jvm.internal; + +import kotlin.Function; +import kotlin.jvm.functions.*; + +import java.io.Serializable; + +public abstract class FunctionImpl + implements Function, Serializable, + Function0, Function1, Function2, Function3, Function4, Function5, Function6, Function7, Function8, Function9, + Function10, Function11, Function12, Function13, Function14, Function15, Function16, Function17, Function18, Function19, + Function20, Function21, Function22 { + + public abstract int getArity(); + + public Object invokeVararg(Object... p) { + throw new UnsupportedOperationException(); + } + + private void checkArity(int expected) { + if (getArity() != expected) { + throwWrongArity(expected); + } + } + + private void throwWrongArity(int expected) { + throw new IllegalStateException("Wrong function arity, expected: " + expected + ", actual: " + getArity()); + } + + @Override + public Object invoke() { + checkArity(0); + return invokeVararg(); + } + + @Override + public Object invoke(Object p1) { + checkArity(1); + return invokeVararg(p1); + } + + @Override + public Object invoke(Object p1, Object p2) { + checkArity(2); + return invokeVararg(p1, p2); + } + + @Override + public Object invoke(Object p1, Object p2, Object p3) { + checkArity(3); + return invokeVararg(p1, p2, p3); + } + + @Override + public Object invoke(Object p1, Object p2, Object p3, Object p4) { + checkArity(4); + return invokeVararg(p1, p2, p3, p4); + } + + @Override + public Object invoke(Object p1, Object p2, Object p3, Object p4, Object p5) { + checkArity(5); + return invokeVararg(p1, p2, p3, p4, p5); + } + + @Override + public Object invoke(Object p1, Object p2, Object p3, Object p4, Object p5, Object p6) { + checkArity(6); + return invokeVararg(p1, p2, p3, p4, p5, p6); + } + + @Override + public Object invoke(Object p1, Object p2, Object p3, Object p4, Object p5, Object p6, Object p7) { + checkArity(7); + return invokeVararg(p1, p2, p3, p4, p5, p6, p7); + } + + @Override + public Object invoke(Object p1, Object p2, Object p3, Object p4, Object p5, Object p6, Object p7, Object p8) { + checkArity(8); + return invokeVararg(p1, p2, p3, p4, p5, p6, p7, p8); + } + + @Override + public Object invoke(Object p1, Object p2, Object p3, Object p4, Object p5, Object p6, Object p7, Object p8, Object p9) { + checkArity(9); + return invokeVararg(p1, p2, p3, p4, p5, p6, p7, p8, p9); + } + + @Override + public Object invoke(Object p1, Object p2, Object p3, Object p4, Object p5, Object p6, Object p7, Object p8, Object p9, Object p10) { + checkArity(10); + return invokeVararg(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10); + } + + @Override + public Object invoke(Object p1, Object p2, Object p3, Object p4, Object p5, Object p6, Object p7, Object p8, Object p9, Object p10, Object p11) { + checkArity(11); + return invokeVararg(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11); + } + + @Override + public Object invoke(Object p1, Object p2, Object p3, Object p4, Object p5, Object p6, Object p7, Object p8, Object p9, Object p10, Object p11, Object p12) { + checkArity(12); + return invokeVararg(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12); + } + + @Override + public Object invoke(Object p1, Object p2, Object p3, Object p4, Object p5, Object p6, Object p7, Object p8, Object p9, Object p10, Object p11, Object p12, Object p13) { + checkArity(13); + return invokeVararg(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13); + } + + @Override + public Object invoke(Object p1, Object p2, Object p3, Object p4, Object p5, Object p6, Object p7, Object p8, Object p9, Object p10, Object p11, Object p12, Object p13, Object p14) { + checkArity(14); + return invokeVararg(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14); + } + + @Override + public Object invoke(Object p1, Object p2, Object p3, Object p4, Object p5, Object p6, Object p7, Object p8, Object p9, Object p10, Object p11, Object p12, Object p13, Object p14, Object p15) { + checkArity(15); + return invokeVararg(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15); + } + + @Override + public Object invoke(Object p1, Object p2, Object p3, Object p4, Object p5, Object p6, Object p7, Object p8, Object p9, Object p10, Object p11, Object p12, Object p13, Object p14, Object p15, Object p16) { + checkArity(16); + return invokeVararg(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15, p16); + } + + @Override + public Object invoke(Object p1, Object p2, Object p3, Object p4, Object p5, Object p6, Object p7, Object p8, Object p9, Object p10, Object p11, Object p12, Object p13, Object p14, Object p15, Object p16, Object p17) { + checkArity(17); + return invokeVararg(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15, p16, p17); + } + + @Override + public Object invoke(Object p1, Object p2, Object p3, Object p4, Object p5, Object p6, Object p7, Object p8, Object p9, Object p10, Object p11, Object p12, Object p13, Object p14, Object p15, Object p16, Object p17, Object p18) { + checkArity(18); + return invokeVararg(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15, p16, p17, p18); + } + + @Override + public Object invoke(Object p1, Object p2, Object p3, Object p4, Object p5, Object p6, Object p7, Object p8, Object p9, Object p10, Object p11, Object p12, Object p13, Object p14, Object p15, Object p16, Object p17, Object p18, Object p19) { + checkArity(19); + return invokeVararg(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15, p16, p17, p18, p19); + } + + @Override + public Object invoke(Object p1, Object p2, Object p3, Object p4, Object p5, Object p6, Object p7, Object p8, Object p9, Object p10, Object p11, Object p12, Object p13, Object p14, Object p15, Object p16, Object p17, Object p18, Object p19, Object p20) { + checkArity(20); + return invokeVararg(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15, p16, p17, p18, p19, p20); + } + + @Override + public Object invoke(Object p1, Object p2, Object p3, Object p4, Object p5, Object p6, Object p7, Object p8, Object p9, Object p10, Object p11, Object p12, Object p13, Object p14, Object p15, Object p16, Object p17, Object p18, Object p19, Object p20, Object p21) { + checkArity(21); + return invokeVararg(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15, p16, p17, p18, p19, p20, p21); + } + + @Override + public Object invoke(Object p1, Object p2, Object p3, Object p4, Object p5, Object p6, Object p7, Object p8, Object p9, Object p10, Object p11, Object p12, Object p13, Object p14, Object p15, Object p16, Object p17, Object p18, Object p19, Object p20, Object p21, Object p22) { + checkArity(22); + return invokeVararg(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15, p16, p17, p18, p19, p20, p21, p22); + } +} diff --git a/generators/src/org/jetbrains/kotlin/generators/builtins/functionImpl.kt b/generators/src/org/jetbrains/kotlin/generators/builtins/functionImpl.kt new file mode 100644 index 00000000000..5c216ff3cb4 --- /dev/null +++ b/generators/src/org/jetbrains/kotlin/generators/builtins/functionImpl.kt @@ -0,0 +1,80 @@ +/* + * Copyright 2010-2015 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 org.jetbrains.kotlin.generators.builtins.functionImpl + +import org.jetbrains.kotlin.generators.builtins.functions.MAX_PARAM_COUNT +import org.jetbrains.kotlin.generators.builtins.generateBuiltIns.BuiltInsSourceGenerator +import org.jetbrains.kotlin.generators.builtins.generateBuiltIns.BuiltInsSourceGenerator.Language +import java.io.PrintWriter + +class GenerateFunctionImpl(out: PrintWriter) : BuiltInsSourceGenerator(out) { + override fun getPackage() = "kotlin.jvm.internal" + + override val language = Language.JAVA + + override fun generateBody() { + val n = MAX_PARAM_COUNT + + out.print("""import kotlin.Function; +import kotlin.jvm.functions.*; + +import java.io.Serializable; + +public abstract class FunctionImpl + implements Function, Serializable,""") + + for (i in 0..n) { + if (i % 10 == 0) { + // Insert newline sometimes to avoid very long lines + out.println() + out.print(" ") + } + out.print("Function$i") + if (i < n) out.print(", ") + } + + out.println(" {") + + out.println(""" + public abstract int getArity(); + + public Object invokeVararg(Object... p) { + throw new UnsupportedOperationException(); + } + + private void checkArity(int expected) { + if (getArity() != expected) { + throwWrongArity(expected); + } + } + + private void throwWrongArity(int expected) { + throw new IllegalStateException("Wrong function arity, expected: " + expected + ", actual: " + getArity()); + }""") + + for (i in 0..n) { + out.println() + out.println(" @Override") + out.println(" public Object invoke(" + (1..i).joinToString { "Object p$it" } + ") {") + out.println(" checkArity($i);") + out.println(" return invokeVararg(" + (1..i).joinToString { "p$it" } + ");") + out.println(" }") + } + + out.println("}") + } +} diff --git a/generators/src/org/jetbrains/kotlin/generators/builtins/generateBuiltIns.kt b/generators/src/org/jetbrains/kotlin/generators/builtins/generateBuiltIns.kt index d93cb433828..a001e133092 100644 --- a/generators/src/org/jetbrains/kotlin/generators/builtins/generateBuiltIns.kt +++ b/generators/src/org/jetbrains/kotlin/generators/builtins/generateBuiltIns.kt @@ -18,6 +18,7 @@ package org.jetbrains.kotlin.generators.builtins.generateBuiltIns import org.jetbrains.kotlin.generators.builtins.arrayIterators.GenerateArrayIterators import org.jetbrains.kotlin.generators.builtins.arrays.GenerateArrays +import org.jetbrains.kotlin.generators.builtins.functionImpl.GenerateFunctionImpl import org.jetbrains.kotlin.generators.builtins.functions.FunctionKind import org.jetbrains.kotlin.generators.builtins.functions.GenerateFunctions import org.jetbrains.kotlin.generators.builtins.iterators.GenerateIterators @@ -40,13 +41,21 @@ abstract class BuiltInsSourceGenerator(val out: PrintWriter) { protected open fun getPackage(): String = "kotlin" + protected open val language: Language = Language.KOTLIN + + enum class Language { + KOTLIN + JAVA + } + final fun generate() { out.println(File("license/LICENSE.txt").readText()) // Don't include generator class name in the message: these are built-in sources, // and we don't want to scare users with any internal information about our project out.println("// Auto-generated file. DO NOT EDIT!") out.println() - out.println("package ${getPackage()}") + out.print("package ${getPackage()}") + if (language == Language.KOTLIN) out.println() else out.println(";") out.println() generateBody() @@ -63,6 +72,7 @@ fun generateBuiltIns(generate: (File, (PrintWriter) -> BuiltInsSourceGenerator) generate(File(dir, kind.fileName)) { GenerateFunctions(it, kind) } } + generate(File(RUNTIME_JVM_DIR, "kotlin/jvm/internal/FunctionImpl.java")) { GenerateFunctionImpl(it) } generate(File(BUILT_INS_NATIVE_DIR, "kotlin/Arrays.kt")) { GenerateArrays(it) } generate(File(BUILT_INS_NATIVE_DIR, "kotlin/Primitives.kt")) { GeneratePrimitives(it) } generate(File(BUILT_INS_SRC_DIR, "kotlin/Iterators.kt")) { GenerateIterators(it) } diff --git a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/decompiler/textBuilder/DeserializerForDecompiler.kt b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/decompiler/textBuilder/DeserializerForDecompiler.kt index b2ccdc47099..45bde4c59ee 100644 --- a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/decompiler/textBuilder/DeserializerForDecompiler.kt +++ b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/decompiler/textBuilder/DeserializerForDecompiler.kt @@ -24,6 +24,7 @@ import org.jetbrains.kotlin.load.kotlin.JavaFlexibleTypeCapabilitiesDeserializer import org.jetbrains.kotlin.load.kotlin.KotlinBinaryClassCache import org.jetbrains.kotlin.load.kotlin.PackageClassUtils import org.jetbrains.kotlin.name.FqName +import org.jetbrains.kotlin.serialization.deserialization.ClassDescriptorFactory import org.jetbrains.kotlin.serialization.deserialization.DeserializationComponents import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedPackageMemberScope import org.jetbrains.kotlin.serialization.jvm.JvmProtoBufUtil @@ -49,7 +50,7 @@ public class DeserializerForDecompiler( override val deserializationComponents: DeserializationComponents = DeserializationComponents( storageManager, moduleDescriptor, classDataFinder, annotationAndConstantLoader, packageFragmentProvider, - ResolveEverythingToKotlinAnyLocalClassResolver, JavaFlexibleTypeCapabilitiesDeserializer + ResolveEverythingToKotlinAnyLocalClassResolver, JavaFlexibleTypeCapabilitiesDeserializer, ClassDescriptorFactory.EMPTY ) override fun resolveDeclarationsInPackage(packageFqName: FqName): Collection { diff --git a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/decompiler/textBuilder/KotlinJavaScriptDeserializerForDecompiler.kt b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/decompiler/textBuilder/KotlinJavaScriptDeserializerForDecompiler.kt index 36d367516ea..363b34a88eb 100644 --- a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/decompiler/textBuilder/KotlinJavaScriptDeserializerForDecompiler.kt +++ b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/decompiler/textBuilder/KotlinJavaScriptDeserializerForDecompiler.kt @@ -22,6 +22,7 @@ import org.jetbrains.kotlin.descriptors.DeclarationDescriptor import org.jetbrains.kotlin.idea.decompiler.navigation.JsMetaFileUtils import org.jetbrains.kotlin.load.kotlin.PackageClassUtils import org.jetbrains.kotlin.name.FqName +import org.jetbrains.kotlin.serialization.deserialization.ClassDescriptorFactory import org.jetbrains.kotlin.serialization.deserialization.DeserializationComponents import org.jetbrains.kotlin.serialization.deserialization.FlexibleTypeCapabilitiesDeserializer import org.jetbrains.kotlin.serialization.deserialization.NameResolver @@ -51,7 +52,7 @@ public class KotlinJavaScriptDeserializerForDecompiler( override val deserializationComponents = DeserializationComponents( storageManager, moduleDescriptor, classDataFinder, annotationAndConstantLoader, packageFragmentProvider, - ResolveEverythingToKotlinAnyLocalClassResolver, FlexibleTypeCapabilitiesDeserializer.Dynamic + ResolveEverythingToKotlinAnyLocalClassResolver, FlexibleTypeCapabilitiesDeserializer.Dynamic, ClassDescriptorFactory.EMPTY ) override fun resolveDeclarationsInPackage(packageFqName: FqName): Collection { diff --git a/idea/testData/refactoring/move/java/moveClass/moveInnerToTop/moveNestedClassToTopLevelInTheSamePackageAndAddOuterInstanceWithLambda/after/a/X.java b/idea/testData/refactoring/move/java/moveClass/moveInnerToTop/moveNestedClassToTopLevelInTheSamePackageAndAddOuterInstanceWithLambda/after/a/X.java index 96eb0e128f2..1209b9aa3d4 100644 --- a/idea/testData/refactoring/move/java/moveClass/moveInnerToTop/moveNestedClassToTopLevelInTheSamePackageAndAddOuterInstanceWithLambda/after/a/X.java +++ b/idea/testData/refactoring/move/java/moveClass/moveInnerToTop/moveNestedClassToTopLevelInTheSamePackageAndAddOuterInstanceWithLambda/after/a/X.java @@ -1,7 +1,6 @@ package a; -import kotlin.jvm.functions.*; -import kotlin.*; +import kotlin.jvm.functions.Function0; public class X { private A outer; @@ -10,4 +9,4 @@ public class X { this.outer = outer; System.out.println(f.invoke()); } -} +} \ No newline at end of file diff --git a/js/js.serializer/src/org/jetbrains/kotlin/serialization/js/kotlinJavascriptPackageFragmentProvider.kt b/js/js.serializer/src/org/jetbrains/kotlin/serialization/js/kotlinJavascriptPackageFragmentProvider.kt index aecdc917e55..5362c855cab 100644 --- a/js/js.serializer/src/org/jetbrains/kotlin/serialization/js/kotlinJavascriptPackageFragmentProvider.kt +++ b/js/js.serializer/src/org/jetbrains/kotlin/serialization/js/kotlinJavascriptPackageFragmentProvider.kt @@ -20,10 +20,7 @@ import org.jetbrains.kotlin.descriptors.ModuleDescriptor import org.jetbrains.kotlin.descriptors.PackageFragmentProvider import org.jetbrains.kotlin.descriptors.PackageFragmentProviderImpl import org.jetbrains.kotlin.name.FqName -import org.jetbrains.kotlin.serialization.deserialization.DeserializationComponents -import org.jetbrains.kotlin.serialization.deserialization.FlexibleTypeCapabilitiesDeserializer -import org.jetbrains.kotlin.serialization.deserialization.LocalClassResolverImpl -import org.jetbrains.kotlin.serialization.deserialization.ResourceLoadingClassDataFinder +import org.jetbrains.kotlin.serialization.deserialization.* import org.jetbrains.kotlin.storage.StorageManager import java.io.InputStream @@ -47,7 +44,8 @@ public fun createKotlinJavascriptPackageFragmentProvider( KotlinJavascriptAnnotationAndConstantLoader(module), provider, localClassResolver, - FlexibleTypeCapabilitiesDeserializer.Dynamic + FlexibleTypeCapabilitiesDeserializer.Dynamic, + ClassDescriptorFactory.EMPTY ) localClassResolver.setDeserializationComponents(components)