[JS IR BE] Load builtins from code to runtime

Bypass builtins deserialization mechanism in legacy JS backend and load
bultins direcly as kotlin code.

This way we won't have separated IR declarations for Enum, Char, Long

Some "native" builtins are implemented in libraries/stdlib/js/irRuntime/builtins/
Other builtins are moved by MoveExternalDeclarationsToSeparatePlace and
used only in compile-time
This commit is contained in:
Svyatoslav Kuzmich
2019-01-24 18:44:59 +03:00
parent 7e263fd68e
commit 8c89ffbe2d
19 changed files with 1506 additions and 127 deletions
@@ -0,0 +1,8 @@
/*
* Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
* that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlin.builtins
interface FunctionInterfacePackageFragment : BuiltInsPackageFragment
@@ -17,6 +17,7 @@
package org.jetbrains.kotlin.builtins.functions
import org.jetbrains.kotlin.builtins.BuiltInsPackageFragment
import org.jetbrains.kotlin.builtins.FunctionInterfacePackageFragment
import org.jetbrains.kotlin.builtins.functions.FunctionClassDescriptor.Kind
import org.jetbrains.kotlin.descriptors.ClassDescriptor
import org.jetbrains.kotlin.descriptors.ModuleDescriptor
@@ -81,7 +82,12 @@ class BuiltInFictitiousFunctionClassFactory(
val packageFqName = classId.packageFqName
val (kind, arity) = parseClassName(className, packageFqName) ?: return null
val containingPackageFragment = module.getPackage(packageFqName).fragments.filterIsInstance<BuiltInsPackageFragment>().first()
val builtInsFragments = module.getPackage(packageFqName).fragments.filterIsInstance<BuiltInsPackageFragment>()
// JS IR backend uses separate FunctionInterfacePackageFragment for function interfaces
val containingPackageFragment =
builtInsFragments.filterIsInstance<FunctionInterfacePackageFragment>().firstOrNull() ?: builtInsFragments.first()
return FunctionClassDescriptor(storageManager, containingPackageFragment, kind, arity)
}
@@ -5,14 +5,13 @@
package org.jetbrains.kotlin.builtins.functions
import org.jetbrains.kotlin.builtins.BuiltInsPackageFragment
import org.jetbrains.kotlin.builtins.KOTLIN_REFLECT_FQ_NAME
import org.jetbrains.kotlin.builtins.KotlinBuiltIns.BUILT_INS_PACKAGE_FQ_NAME
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.incremental.components.NoLookupLocation
import org.jetbrains.kotlin.name.ClassId
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.resolve.DescriptorUtils.COROUTINES_PACKAGE_FQ_NAME_RELEASE
@@ -108,9 +107,9 @@ class FunctionClassDescriptor(
override fun computeSupertypes(): Collection<KotlinType> {
val result = ArrayList<KotlinType>(2)
fun add(packageFragment: PackageFragmentDescriptor, name: Name) {
val descriptor = packageFragment.getMemberScope().getContributedClassifier(name, NoLookupLocation.FROM_BUILTINS) as? ClassDescriptor
?: error("Class $name not found in $packageFragment")
fun add(id: ClassId) {
val moduleDescriptor = containingDeclaration.containingDeclaration
val descriptor = moduleDescriptor.findClassAcrossModuleDependencies(id) ?: error("Built-in class $id not found")
val typeConstructor = descriptor.typeConstructor
@@ -124,20 +123,21 @@ class FunctionClassDescriptor(
when (functionKind) {
Kind.SuspendFunction -> // SuspendFunction$N<...> <: Function
add(getBuiltInPackage(BUILT_INS_PACKAGE_FQ_NAME), Name.identifier("Function"))
add(functionClassId)
Kind.KSuspendFunction -> // KSuspendFunction$N<...> <: KFunction
add(containingDeclaration, Name.identifier("KFunction"))
else -> // Add unnumbered base class, e.g. Function for Function{n}, KFunction for KFunction{n}
add(containingDeclaration, Name.identifier(functionKind.classNamePrefix))
add(kFunctionClassId)
Kind.Function -> // Function$N <: Function
add(functionClassId)
Kind.KFunction -> // KFunction$N <: KFunction
add(kFunctionClassId)
}
// For K{Suspend}Function{n}, add corresponding numbered {Suspend}Function{n} class, e.g. {Suspend}Function2 for K{Suspend}Function2
when (functionKind) {
Kind.KFunction -> add(getBuiltInPackage(BUILT_INS_PACKAGE_FQ_NAME), Kind.Function.numberedClassName(arity))
Kind.KSuspendFunction -> add(
getBuiltInPackage(COROUTINES_PACKAGE_FQ_NAME_RELEASE),
Kind.SuspendFunction.numberedClassName(arity)
)
Kind.KFunction ->
add(ClassId(BUILT_INS_PACKAGE_FQ_NAME, Kind.Function.numberedClassName(arity)))
Kind.KSuspendFunction ->
add(ClassId(COROUTINES_PACKAGE_FQ_NAME_RELEASE, Kind.SuspendFunction.numberedClassName(arity)))
else -> {
}
}
@@ -145,11 +145,6 @@ class FunctionClassDescriptor(
return result.toList()
}
private fun getBuiltInPackage(fqName: FqName): BuiltInsPackageFragment {
val packageView = containingDeclaration.containingDeclaration.getPackage(fqName)
return packageView.fragments.filterIsInstance<BuiltInsPackageFragment>().first()
}
override fun getParameters() = this@FunctionClassDescriptor.parameters
override fun getDeclarationDescriptor() = this@FunctionClassDescriptor
@@ -162,4 +157,9 @@ class FunctionClassDescriptor(
}
override fun toString() = name.asString()
companion object {
val functionClassId = ClassId(BUILT_INS_PACKAGE_FQ_NAME, Name.identifier("Function"))
val kFunctionClassId = ClassId(KOTLIN_REFLECT_FQ_NAME, Name.identifier("KFunction"))
}
}
@@ -0,0 +1,83 @@
/*
* Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
* that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlin.builtins.functions
import org.jetbrains.kotlin.builtins.FunctionInterfacePackageFragment
import org.jetbrains.kotlin.builtins.KOTLIN_REFLECT_FQ_NAME
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.descriptors.deserialization.ClassDescriptorFactory
import org.jetbrains.kotlin.descriptors.impl.PackageFragmentDescriptorImpl
import org.jetbrains.kotlin.incremental.components.LookupLocation
import org.jetbrains.kotlin.name.ClassId
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.resolve.DescriptorUtils.COROUTINES_PACKAGE_FQ_NAME_RELEASE
import org.jetbrains.kotlin.resolve.scopes.DescriptorKindFilter
import org.jetbrains.kotlin.resolve.scopes.MemberScopeImpl
import org.jetbrains.kotlin.storage.StorageManager
import org.jetbrains.kotlin.utils.Printer
class FunctionInterfaceMemberScope(
private val classDescriptorFactory: ClassDescriptorFactory,
val packageName: FqName
) : MemberScopeImpl() {
override fun getContributedDescriptors(
kindFilter: DescriptorKindFilter,
nameFilter: (Name) -> Boolean
) =
classDescriptorFactory.getAllContributedClassesIfPossible(packageName)
override fun getContributedVariables(name: Name, location: LookupLocation): Collection<PropertyDescriptor> =
emptyList()
override fun getContributedFunctions(name: Name, location: LookupLocation): Collection<SimpleFunctionDescriptor> =
emptyList()
override fun getFunctionNames(): Set<Name> =
emptySet()
override fun getVariableNames(): Set<Name> =
emptySet()
override fun getClassifierNames(): Set<Name>? = null
override fun printScopeStructure(p: Printer) {
TODO()
}
override fun getContributedClassifier(name: Name, location: LookupLocation): ClassifierDescriptor? = when {
classDescriptorFactory.shouldCreateClass(packageName, name) ->
classDescriptorFactory.createClass(ClassId.topLevel(packageName.child(name)))
else -> null
}
}
class FunctionInterfacePackageFragmentImpl(
classDescriptorFactory: ClassDescriptorFactory,
module: ModuleDescriptor,
name: FqName
) : FunctionInterfacePackageFragment,
PackageFragmentDescriptorImpl(module, name) {
private val memberScope = FunctionInterfaceMemberScope(classDescriptorFactory, fqName)
override fun getMemberScope() = memberScope
}
fun functionInterfacePackageFragmentProvider(
storageManager: StorageManager,
module: ModuleDescriptor
): PackageFragmentProvider {
val classFactory = BuiltInFictitiousFunctionClassFactory(storageManager, module)
val fragments = listOf(
KOTLIN_REFLECT_FQ_NAME,
KotlinBuiltIns.BUILT_INS_PACKAGE_FQ_NAME,
COROUTINES_PACKAGE_FQ_NAME_RELEASE
).map { fqName ->
FunctionInterfacePackageFragmentImpl(classFactory, module, fqName)
}
return PackageFragmentProviderImpl(fragments)
}