IrTypes: generateAnnotationConstructorCall -> ConstantValueGenerator
This commit is contained in:
@@ -20,15 +20,15 @@ import org.jetbrains.kotlin.ir.declarations.IrFile
|
||||
import org.jetbrains.kotlin.ir.declarations.IrModuleFragment
|
||||
import org.jetbrains.kotlin.ir.declarations.impl.IrFileImpl
|
||||
import org.jetbrains.kotlin.ir.declarations.impl.IrModuleFragmentImpl
|
||||
import org.jetbrains.kotlin.ir.util.ConstantValueGenerator
|
||||
import org.jetbrains.kotlin.ir.util.ExternalDependenciesGenerator
|
||||
import org.jetbrains.kotlin.psi.KtFile
|
||||
import org.jetbrains.kotlin.ir.util.AnnotationGenerator
|
||||
import org.jetbrains.kotlin.resolve.BindingContext
|
||||
import org.jetbrains.kotlin.resolve.lazy.descriptors.findPackageFragmentForFile
|
||||
|
||||
class ModuleGenerator(override val context: GeneratorContext) : Generator {
|
||||
|
||||
private val annotationGenerator = AnnotationGenerator(context.moduleDescriptor, context.symbolTable)
|
||||
private val constantValueGenerator = ConstantValueGenerator(context.moduleDescriptor, context.symbolTable, null)
|
||||
|
||||
fun generateModuleFragment(ktFiles: Collection<KtFile>): IrModuleFragment =
|
||||
generateModuleFragmentWithoutDependencies(ktFiles).also { irModule ->
|
||||
@@ -60,7 +60,7 @@ class ModuleGenerator(override val context: GeneratorContext) : Generator {
|
||||
for (ktAnnotationEntry in ktFile.annotationEntries) {
|
||||
val annotationDescriptor = getOrFail(BindingContext.ANNOTATION, ktAnnotationEntry)
|
||||
irFile.fileAnnotations.add(annotationDescriptor)
|
||||
irFile.annotations.add(annotationGenerator.generateAnnotationConstructorCall(annotationDescriptor))
|
||||
irFile.annotations.add(constantValueGenerator.generateAnnotationConstructorCall(annotationDescriptor))
|
||||
}
|
||||
|
||||
for (ktDeclaration in ktFile.declarations) {
|
||||
|
||||
+1
-1
@@ -222,7 +222,7 @@ class StatementGenerator(
|
||||
)
|
||||
|
||||
fun generateConstantExpression(expression: KtExpression, constant: CompileTimeConstant<*>): IrExpression =
|
||||
ConstantValueGenerator(context.moduleDescriptor, context.symbolTable, null, null).generateConstantValueAsExpression(
|
||||
ConstantValueGenerator(context.moduleDescriptor, context.symbolTable, null).generateConstantValueAsExpression(
|
||||
expression.startOffset,
|
||||
expression.endOffset,
|
||||
constant.toConstantValue(getInferredTypeWithImplicitCastsOrFail(expression))
|
||||
|
||||
@@ -5,33 +5,24 @@
|
||||
|
||||
package org.jetbrains.kotlin.ir.util
|
||||
|
||||
import org.jetbrains.kotlin.descriptors.ClassDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.ModuleDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.PropertySetterDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.annotations.AnnotationDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.annotations.AnnotationUseSiteTarget
|
||||
import org.jetbrains.kotlin.descriptors.annotations.AnnotationWithTarget
|
||||
import org.jetbrains.kotlin.ir.IrElement
|
||||
import org.jetbrains.kotlin.ir.UNDEFINED_OFFSET
|
||||
import org.jetbrains.kotlin.ir.declarations.*
|
||||
import org.jetbrains.kotlin.ir.expressions.IrCall
|
||||
import org.jetbrains.kotlin.ir.expressions.impl.IrCallImpl
|
||||
import org.jetbrains.kotlin.ir.visitors.IrElementVisitorVoid
|
||||
import org.jetbrains.kotlin.ir.visitors.acceptChildrenVoid
|
||||
import org.jetbrains.kotlin.psi.psiUtil.startOffset
|
||||
import org.jetbrains.kotlin.resolve.DescriptorUtils
|
||||
import org.jetbrains.kotlin.resolve.source.PsiSourceElement
|
||||
import org.jetbrains.kotlin.types.KotlinType
|
||||
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
|
||||
|
||||
class AnnotationGenerator(
|
||||
moduleDescriptor: ModuleDescriptor,
|
||||
private val symbolTable: SymbolTable
|
||||
symbolTable: SymbolTable
|
||||
) : IrElementVisitorVoid {
|
||||
|
||||
private val typeTranslator = TypeTranslator(moduleDescriptor, symbolTable)
|
||||
private val scopedTypeParameterResolver = ScopedTypeParametersResolver()
|
||||
private val constantValueGenerator = ConstantValueGenerator(moduleDescriptor, symbolTable, this, scopedTypeParameterResolver)
|
||||
private val constantValueGenerator = ConstantValueGenerator(moduleDescriptor, symbolTable, scopedTypeParameterResolver)
|
||||
|
||||
override fun visitElement(element: IrElement) {
|
||||
element.acceptChildrenVoid(this)
|
||||
@@ -73,57 +64,12 @@ class AnnotationGenerator(
|
||||
|
||||
private fun List<AnnotationWithTarget>.generateAnnotationConstructorCalls(declaration: IrDeclaration) {
|
||||
mapTo(declaration.annotations) {
|
||||
generateAnnotationConstructorCall(it.annotation)
|
||||
constantValueGenerator.generateAnnotationConstructorCall(it.annotation)
|
||||
}
|
||||
}
|
||||
|
||||
private fun KotlinType.toIrType() = typeTranslator.translateType(this)
|
||||
|
||||
fun generateAnnotationConstructorCall(annotationDescriptor: AnnotationDescriptor): IrCall {
|
||||
val annotationType = annotationDescriptor.type
|
||||
val annotationClassDescriptor = annotationType.constructor.declarationDescriptor as? ClassDescriptor
|
||||
?: throw AssertionError("No declaration descriptor for annotation $annotationDescriptor")
|
||||
|
||||
if (annotationClassDescriptor !is ClassDescriptor) {
|
||||
throw AssertionError("Annotation type descriptor is not a class: $annotationClassDescriptor")
|
||||
}
|
||||
|
||||
assert(DescriptorUtils.isAnnotationClass(annotationClassDescriptor)) {
|
||||
"Annotation class expected: $annotationClassDescriptor"
|
||||
}
|
||||
|
||||
val primaryConstructorDescriptor = annotationClassDescriptor.unsubstitutedPrimaryConstructor
|
||||
?: annotationClassDescriptor.constructors.singleOrNull()
|
||||
?: throw AssertionError("No constructor for annotation class $annotationClassDescriptor")
|
||||
val primaryConstructorSymbol = symbolTable.referenceConstructor(primaryConstructorDescriptor)
|
||||
|
||||
val psi = annotationDescriptor.source.safeAs<PsiSourceElement>()?.psi
|
||||
val startOffset = psi?.startOffset ?: UNDEFINED_OFFSET
|
||||
val endOffset = psi?.startOffset ?: UNDEFINED_OFFSET
|
||||
|
||||
val irCall = IrCallImpl(
|
||||
startOffset, endOffset,
|
||||
annotationType.toIrType(),
|
||||
primaryConstructorSymbol, primaryConstructorDescriptor,
|
||||
typeArgumentsCount = 0
|
||||
)
|
||||
|
||||
for (valueParameter in primaryConstructorDescriptor.valueParameters) {
|
||||
val argumentIndex = valueParameter.index
|
||||
val argumentValue = annotationDescriptor.allValueArguments[valueParameter.name] ?: continue
|
||||
val irArgument =
|
||||
constantValueGenerator.generateConstantValueAsExpression(
|
||||
UNDEFINED_OFFSET,
|
||||
UNDEFINED_OFFSET,
|
||||
argumentValue,
|
||||
valueParameter.varargElementType
|
||||
)
|
||||
irCall.putValueArgument(argumentIndex, irArgument)
|
||||
}
|
||||
|
||||
return irCall
|
||||
}
|
||||
|
||||
private fun isAnnotationTargetMatchingDeclaration(target: AnnotationUseSiteTarget?, element: IrElement): Boolean =
|
||||
when (element) {
|
||||
is IrProperty ->
|
||||
|
||||
@@ -8,13 +8,16 @@ package org.jetbrains.kotlin.ir.util
|
||||
import org.jetbrains.kotlin.descriptors.ClassDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.ModuleDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.TypeParameterDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.annotations.AnnotationDescriptor
|
||||
import org.jetbrains.kotlin.incremental.components.NoLookupLocation
|
||||
import org.jetbrains.kotlin.ir.UNDEFINED_OFFSET
|
||||
import org.jetbrains.kotlin.ir.expressions.IrCall
|
||||
import org.jetbrains.kotlin.ir.expressions.IrExpression
|
||||
import org.jetbrains.kotlin.ir.expressions.impl.IrClassReferenceImpl
|
||||
import org.jetbrains.kotlin.ir.expressions.impl.IrConstImpl
|
||||
import org.jetbrains.kotlin.ir.expressions.impl.IrGetEnumValueImpl
|
||||
import org.jetbrains.kotlin.ir.expressions.impl.IrVarargImpl
|
||||
import org.jetbrains.kotlin.ir.expressions.impl.*
|
||||
import org.jetbrains.kotlin.psi.psiUtil.startOffset
|
||||
import org.jetbrains.kotlin.resolve.DescriptorUtils
|
||||
import org.jetbrains.kotlin.resolve.constants.*
|
||||
import org.jetbrains.kotlin.resolve.source.PsiSourceElement
|
||||
import org.jetbrains.kotlin.types.KotlinType
|
||||
import org.jetbrains.kotlin.types.typeUtil.builtIns
|
||||
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
|
||||
@@ -22,7 +25,6 @@ import org.jetbrains.kotlin.utils.addToStdlib.safeAs
|
||||
class ConstantValueGenerator(
|
||||
private val moduleDescriptor: ModuleDescriptor,
|
||||
private val symbolTable: SymbolTable,
|
||||
private val annotationGenerator: AnnotationGenerator?,
|
||||
private val scopedTypeParameterResolver: ScopedTypeParametersResolver?
|
||||
) {
|
||||
|
||||
@@ -81,10 +83,7 @@ class ConstantValueGenerator(
|
||||
)
|
||||
}
|
||||
|
||||
is AnnotationValue -> {
|
||||
if (annotationGenerator == null) throw AssertionError("Unexpected AnnotationValue: $constantValue")
|
||||
annotationGenerator.generateAnnotationConstructorCall(constantValue.value)
|
||||
}
|
||||
is AnnotationValue -> generateAnnotationConstructorCall(constantValue.value)
|
||||
|
||||
is KClassValue -> {
|
||||
val classifierKtType = constantValue.value
|
||||
@@ -107,5 +106,45 @@ class ConstantValueGenerator(
|
||||
}
|
||||
}
|
||||
|
||||
fun generateAnnotationConstructorCall(annotationDescriptor: AnnotationDescriptor): IrCall {
|
||||
val annotationType = annotationDescriptor.type
|
||||
val annotationClassDescriptor = annotationType.constructor.declarationDescriptor as? ClassDescriptor
|
||||
?: throw AssertionError("No declaration descriptor for annotation $annotationDescriptor")
|
||||
|
||||
assert(DescriptorUtils.isAnnotationClass(annotationClassDescriptor)) {
|
||||
"Annotation class expected: $annotationClassDescriptor"
|
||||
}
|
||||
|
||||
val primaryConstructorDescriptor = annotationClassDescriptor.unsubstitutedPrimaryConstructor
|
||||
?: annotationClassDescriptor.constructors.singleOrNull()
|
||||
?: throw AssertionError("No constructor for annotation class $annotationClassDescriptor")
|
||||
val primaryConstructorSymbol = symbolTable.referenceConstructor(primaryConstructorDescriptor)
|
||||
|
||||
val psi = annotationDescriptor.source.safeAs<PsiSourceElement>()?.psi
|
||||
val startOffset = psi?.startOffset ?: UNDEFINED_OFFSET
|
||||
val endOffset = psi?.startOffset ?: UNDEFINED_OFFSET
|
||||
|
||||
val irCall = IrCallImpl(
|
||||
startOffset, endOffset,
|
||||
annotationType.toIrType(),
|
||||
primaryConstructorSymbol, primaryConstructorDescriptor,
|
||||
typeArgumentsCount = 0
|
||||
)
|
||||
|
||||
for (valueParameter in primaryConstructorDescriptor.valueParameters) {
|
||||
val argumentIndex = valueParameter.index
|
||||
val argumentValue = annotationDescriptor.allValueArguments[valueParameter.name] ?: continue
|
||||
val irArgument = generateConstantValueAsExpression(
|
||||
UNDEFINED_OFFSET,
|
||||
UNDEFINED_OFFSET,
|
||||
argumentValue,
|
||||
valueParameter.varargElementType
|
||||
)
|
||||
irCall.putValueArgument(argumentIndex, irArgument)
|
||||
}
|
||||
|
||||
return irCall
|
||||
}
|
||||
|
||||
private fun KotlinType.getArrayElementType() = builtIns.getArrayElementType(this)
|
||||
}
|
||||
@@ -25,8 +25,8 @@ class TypeTranslator(
|
||||
private val symbolTable: SymbolTable
|
||||
) {
|
||||
|
||||
private val annotationGenerator = AnnotationGenerator(moduleDescriptor, symbolTable)
|
||||
private val typeParametersResolver = ScopedTypeParametersResolver()
|
||||
private val constantValueGenerator = ConstantValueGenerator(moduleDescriptor, symbolTable, typeParametersResolver)
|
||||
|
||||
fun enterScope(irElement: IrTypeParametersContainer) {
|
||||
typeParametersResolver.enterTypeParameterScope(irElement)
|
||||
@@ -97,7 +97,7 @@ class TypeTranslator(
|
||||
private fun translateTypeAnnotations(annotations: Annotations): List<IrCall> =
|
||||
annotations.getAllAnnotations().map {
|
||||
// TODO filter out annotation targets
|
||||
annotationGenerator.generateAnnotationConstructorCall(it.annotation)
|
||||
constantValueGenerator.generateAnnotationConstructorCall(it.annotation)
|
||||
}
|
||||
|
||||
private fun translateTypeArguments(arguments: List<TypeProjection>) =
|
||||
|
||||
Reference in New Issue
Block a user