Leverage existing psi2ir function declaration generator in plugin

This seems to be the only reasonable way to provide function declarations with
_correctly_ substituted type parameters without rewriting logic from scratch;
correctly scoped type parameters in IR are now required in serialization
plugin by all backends.

Also fix some missing upper bounds.
This commit is contained in:
Leonid Startsev
2020-03-04 16:55:15 +03:00
parent fc22cfa896
commit a2c24e696f
8 changed files with 98 additions and 53 deletions
@@ -62,7 +62,7 @@ class Psi2IrTranslator(
symbolTable: SymbolTable = SymbolTable(signaturer),
extensions: GeneratorExtensions = GeneratorExtensions()
): GeneratorContext =
GeneratorContext(configuration, moduleDescriptor, bindingContext, languageVersionSettings, symbolTable, extensions, signaturer)
createGeneratorContext(configuration, moduleDescriptor, bindingContext, languageVersionSettings, symbolTable, extensions, signaturer)
fun generateModuleFragment(
context: GeneratorContext,
@@ -1,17 +1,6 @@
/*
* Copyright 2010-2016 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.
* Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors.
* 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.psi2ir.generators
@@ -24,12 +13,41 @@ import org.jetbrains.kotlin.descriptors.NotFoundClasses
import org.jetbrains.kotlin.ir.builders.IrGeneratorContext
import org.jetbrains.kotlin.ir.descriptors.IrBuiltIns
import org.jetbrains.kotlin.ir.expressions.IrMemberAccessExpression
import org.jetbrains.kotlin.ir.util.*
import org.jetbrains.kotlin.ir.util.ConstantValueGenerator
import org.jetbrains.kotlin.ir.util.IdSignatureComposer
import org.jetbrains.kotlin.ir.util.SymbolTable
import org.jetbrains.kotlin.ir.util.TypeTranslator
import org.jetbrains.kotlin.psi2ir.Psi2IrConfiguration
import org.jetbrains.kotlin.psi2ir.PsiSourceManager
import org.jetbrains.kotlin.resolve.BindingContext
import org.jetbrains.kotlin.storage.LockBasedStorageManager
fun createGeneratorContext(
configuration: Psi2IrConfiguration,
moduleDescriptor: ModuleDescriptor,
bindingContext: BindingContext,
languageVersionSettings: LanguageVersionSettings,
symbolTable: SymbolTable,
extensions: GeneratorExtensions,
signaturer: IdSignatureComposer
): GeneratorContext {
val typeTranslator = TypeTranslator(symbolTable, languageVersionSettings, builtIns = moduleDescriptor.builtIns)
val constantValueGenerator = ConstantValueGenerator(moduleDescriptor, symbolTable)
typeTranslator.constantValueGenerator = constantValueGenerator
constantValueGenerator.typeTranslator = typeTranslator
return GeneratorContext(
configuration,
moduleDescriptor,
bindingContext,
languageVersionSettings,
symbolTable,
extensions,
typeTranslator,
constantValueGenerator,
IrBuiltIns(moduleDescriptor.builtIns, typeTranslator, signaturer, symbolTable)
)
}
class GeneratorContext(
val configuration: Psi2IrConfiguration,
val moduleDescriptor: ModuleDescriptor,
@@ -37,20 +55,13 @@ class GeneratorContext(
val languageVersionSettings: LanguageVersionSettings,
val symbolTable: SymbolTable,
val extensions: GeneratorExtensions,
signaturer: IdSignatureComposer
val typeTranslator: TypeTranslator,
val constantValueGenerator: ConstantValueGenerator,
override val irBuiltIns: IrBuiltIns
) : IrGeneratorContext() {
val constantValueGenerator: ConstantValueGenerator = ConstantValueGenerator(moduleDescriptor, symbolTable)
val typeTranslator: TypeTranslator = TypeTranslator(symbolTable, languageVersionSettings, builtIns = moduleDescriptor.builtIns)
val callToSubstitutedDescriptorMap = mutableMapOf<IrMemberAccessExpression, CallableDescriptor>()
init {
typeTranslator.constantValueGenerator = constantValueGenerator
constantValueGenerator.typeTranslator = typeTranslator
}
override val irBuiltIns: IrBuiltIns = IrBuiltIns(moduleDescriptor.builtIns, typeTranslator, signaturer, symbolTable)
val sourceManager = PsiSourceManager()
// TODO: inject a correct StorageManager instance, or store NotFoundClasses inside ModuleDescriptor
@@ -47,6 +47,7 @@ import org.jetbrains.kotlin.psi.KtFile
import org.jetbrains.kotlin.psi2ir.Psi2IrConfiguration
import org.jetbrains.kotlin.psi2ir.Psi2IrTranslator
import org.jetbrains.kotlin.psi2ir.generators.GeneratorContext
import org.jetbrains.kotlin.psi2ir.generators.createGeneratorContext
import org.jetbrains.kotlin.psi2ir.generators.GeneratorExtensions
import org.jetbrains.kotlin.resolve.BindingContext
import org.jetbrains.kotlin.resolve.BindingContextUtils
@@ -241,7 +242,7 @@ private fun runAnalysisAndPreparePsi2Ir(depsDescriptors: ModulesStructure): Gene
val mangler = JsManglerDesc
val signaturer = IdSignatureDescriptor(mangler)
return GeneratorContext(
return createGeneratorContext(
Psi2IrConfiguration(),
analysisResult.moduleDescriptor,
analysisResult.bindingContext,
@@ -13,6 +13,7 @@ dependencies {
compileOnly(project(":compiler:frontend"))
compileOnly(project(":compiler:backend"))
compileOnly(project(":compiler:ir.backend.common"))
compileOnly(project(":compiler:ir.psi2ir"))
compileOnly(project(":js:js.frontend"))
compileOnly(project(":js:js.translator"))
@@ -1,5 +1,5 @@
/*
* Copyright 2010-2018 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
@@ -26,6 +26,11 @@ import org.jetbrains.kotlin.ir.types.typeWith
import org.jetbrains.kotlin.ir.util.*
import org.jetbrains.kotlin.js.resolve.diagnostics.findPsi
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.psi2ir.Psi2IrConfiguration
import org.jetbrains.kotlin.psi2ir.generators.DeclarationGenerator
import org.jetbrains.kotlin.psi2ir.generators.FunctionGenerator
import org.jetbrains.kotlin.psi2ir.generators.GeneratorContext
import org.jetbrains.kotlin.psi2ir.generators.GeneratorExtensions
import org.jetbrains.kotlin.resolve.descriptorUtil.classId
import org.jetbrains.kotlin.types.*
import org.jetbrains.kotlin.types.typeUtil.isTypeParameter
@@ -50,6 +55,24 @@ interface IrBuilderExtension {
}
}
private fun createFunctionGenerator(): FunctionGenerator = with(compilerContext) {
return FunctionGenerator(
DeclarationGenerator(
GeneratorContext(
Psi2IrConfiguration(),
moduleDescriptor,
bindingContext,
languageVersionSettings,
symbolTable,
GeneratorExtensions(),
typeTranslator,
typeTranslator.constantValueGenerator,
irBuiltIns
)
)
)
}
fun IrClass.contributeFunction(
descriptor: FunctionDescriptor,
declareNew: Boolean = true,
@@ -59,9 +82,16 @@ interface IrBuilderExtension {
descriptor
) else compilerContext.symbolTable.referenceSimpleFunction(descriptor).owner
f.parent = this
f.returnType = descriptor.returnType!!.toIrType()
if (declareNew) f.createParameterDeclarations(this.thisReceiver!!)
f.body = DeclarationIrBuilder(compilerContext, f.symbol, this.startOffset, this.endOffset).irBlockBody(this.startOffset, this.endOffset) { bodyGen(f) }
if (declareNew) {
f.buildWithScope {
createFunctionGenerator().generateFunctionParameterDeclarationsAndReturnType(f, null, null)
}
}
f.body = DeclarationIrBuilder(compilerContext, f.symbol, this.startOffset, this.endOffset).irBlockBody(
this.startOffset,
this.endOffset
) { bodyGen(f) }
this.addMember(f)
}
@@ -347,7 +377,7 @@ interface IrBuilderExtension {
SERIALIZABLE_PLUGIN_ORIGIN,
this,
type.toIrType(),
null
(this as? ValueParameterDescriptor)?.varargElementType?.toIrType()
).also {
it.parent = this@createParameterDeclarations
}
@@ -372,6 +402,7 @@ interface IrBuilderExtension {
it
).also { typeParameter ->
typeParameter.parent = this
typeParameter.superTypes.addAll(it.upperBounds.map { it.toIrType() })
}
}
}
@@ -1,3 +1,8 @@
/*
* Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors.
* 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.kotlinx.serialization.compiler.backend.ir
import org.jetbrains.kotlin.descriptors.*
@@ -111,21 +116,23 @@ class SerializableCompanionIrGenerator(
&& it.returnType != null && isKSerializer(it.returnType)
} ?: return
irClass.contributeFunction(serialFactoryDescriptor) { factory ->
val kSerializerStarType = factory.returnType
val array = factory.valueParameters.first()
val argsSize = serializableDescriptor.declaredTypeParameters.size
val arrayGet =
compilerContext.builtIns.array.getFuncDesc("get").single()
val arrayGetSymbol = compilerContext.symbolTable.referenceFunction(arrayGet)
val outAnyNullable = makeTypeProjection(compilerContext.irBuiltIns.anyNType, Variance.OUT_VARIANCE).type
val serializers: List<IrExpression> = (0 until argsSize).map { irInvoke(irGet(array), arrayGetSymbol, irInt(it)) }
val serializers: List<IrExpression> = (0 until argsSize).map {
irInvoke(irGet(array), arrayGetSymbol, irInt(it), typeHint = kSerializerStarType)
}
val serializerCall = compilerContext.symbolTable.referenceSimpleFunction(getterDescriptor)
val call = irInvoke(
IrGetValueImpl(startOffset, endOffset, factory.dispatchReceiverParameter!!.symbol),
serializerCall,
List(argsSize) { outAnyNullable },
serializers
List(argsSize) { compilerContext.irBuiltIns.anyNType },
serializers,
returnTypeHint = kSerializerStarType
)
+irReturn(call)
patchSerializableClassWithMarkerAnnotation(companionDescriptor)
@@ -1,5 +1,5 @@
/*
* Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
@@ -7,13 +7,13 @@ package org.jetbrains.kotlinx.serialization.compiler.backend.ir
import org.jetbrains.kotlin.descriptors.ClassDescriptor
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
import org.jetbrains.kotlin.incremental.components.NoLookupLocation
import org.jetbrains.kotlin.ir.builders.*
import org.jetbrains.kotlin.ir.declarations.IrClass
import org.jetbrains.kotlin.ir.declarations.IrVariable
import org.jetbrains.kotlin.ir.expressions.IrExpression
import org.jetbrains.kotlin.ir.expressions.impl.IrGetValueImpl
import org.jetbrains.kotlin.ir.symbols.IrFunctionSymbol
import org.jetbrains.kotlin.ir.util.defaultType
import org.jetbrains.kotlin.ir.util.functions
import org.jetbrains.kotlin.ir.util.properties
import org.jetbrains.kotlin.ir.util.referenceFunction
@@ -61,7 +61,12 @@ class SerializerForEnumsGenerator(
compilerContext.builtIns.array.getFuncDesc("get").single()
val arrayGetSymbol = compilerContext.symbolTable.referenceFunction(arrayGet)
val getValueByOrdinal =
irInvoke(getValues, arrayGetSymbol, irInvoke(irGet(loadFunc.valueParameters[0]), decode, serialDescGetter))
irInvoke(
getValues,
arrayGetSymbol,
irInvoke(irGet(loadFunc.valueParameters[0]), decode, serialDescGetter),
typeHint = serializableIrClass.defaultType
)
+irReturn(getValueByOrdinal)
}
@@ -1,17 +1,6 @@
/*
* Copyright 2010-2017 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.
* Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors.
* 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.kotlinx.serialization.compiler.resolve
@@ -460,7 +449,7 @@ object KSerializerDescriptorResolver {
declaresDefaultValue = false,
isCrossinline = false,
isNoinline = false,
varargElementType = serializerClass.defaultType,
varargElementType = kSerializerStarType,
source = f.source
)