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.IrModuleFragment
|
||||||
import org.jetbrains.kotlin.ir.declarations.impl.IrFileImpl
|
import org.jetbrains.kotlin.ir.declarations.impl.IrFileImpl
|
||||||
import org.jetbrains.kotlin.ir.declarations.impl.IrModuleFragmentImpl
|
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.ir.util.ExternalDependenciesGenerator
|
||||||
import org.jetbrains.kotlin.psi.KtFile
|
import org.jetbrains.kotlin.psi.KtFile
|
||||||
import org.jetbrains.kotlin.ir.util.AnnotationGenerator
|
|
||||||
import org.jetbrains.kotlin.resolve.BindingContext
|
import org.jetbrains.kotlin.resolve.BindingContext
|
||||||
import org.jetbrains.kotlin.resolve.lazy.descriptors.findPackageFragmentForFile
|
import org.jetbrains.kotlin.resolve.lazy.descriptors.findPackageFragmentForFile
|
||||||
|
|
||||||
class ModuleGenerator(override val context: GeneratorContext) : Generator {
|
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 =
|
fun generateModuleFragment(ktFiles: Collection<KtFile>): IrModuleFragment =
|
||||||
generateModuleFragmentWithoutDependencies(ktFiles).also { irModule ->
|
generateModuleFragmentWithoutDependencies(ktFiles).also { irModule ->
|
||||||
@@ -60,7 +60,7 @@ class ModuleGenerator(override val context: GeneratorContext) : Generator {
|
|||||||
for (ktAnnotationEntry in ktFile.annotationEntries) {
|
for (ktAnnotationEntry in ktFile.annotationEntries) {
|
||||||
val annotationDescriptor = getOrFail(BindingContext.ANNOTATION, ktAnnotationEntry)
|
val annotationDescriptor = getOrFail(BindingContext.ANNOTATION, ktAnnotationEntry)
|
||||||
irFile.fileAnnotations.add(annotationDescriptor)
|
irFile.fileAnnotations.add(annotationDescriptor)
|
||||||
irFile.annotations.add(annotationGenerator.generateAnnotationConstructorCall(annotationDescriptor))
|
irFile.annotations.add(constantValueGenerator.generateAnnotationConstructorCall(annotationDescriptor))
|
||||||
}
|
}
|
||||||
|
|
||||||
for (ktDeclaration in ktFile.declarations) {
|
for (ktDeclaration in ktFile.declarations) {
|
||||||
|
|||||||
+1
-1
@@ -222,7 +222,7 @@ class StatementGenerator(
|
|||||||
)
|
)
|
||||||
|
|
||||||
fun generateConstantExpression(expression: KtExpression, constant: CompileTimeConstant<*>): IrExpression =
|
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.startOffset,
|
||||||
expression.endOffset,
|
expression.endOffset,
|
||||||
constant.toConstantValue(getInferredTypeWithImplicitCastsOrFail(expression))
|
constant.toConstantValue(getInferredTypeWithImplicitCastsOrFail(expression))
|
||||||
|
|||||||
@@ -5,33 +5,24 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.ir.util
|
package org.jetbrains.kotlin.ir.util
|
||||||
|
|
||||||
import org.jetbrains.kotlin.descriptors.ClassDescriptor
|
|
||||||
import org.jetbrains.kotlin.descriptors.ModuleDescriptor
|
import org.jetbrains.kotlin.descriptors.ModuleDescriptor
|
||||||
import org.jetbrains.kotlin.descriptors.PropertySetterDescriptor
|
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.AnnotationUseSiteTarget
|
||||||
import org.jetbrains.kotlin.descriptors.annotations.AnnotationWithTarget
|
import org.jetbrains.kotlin.descriptors.annotations.AnnotationWithTarget
|
||||||
import org.jetbrains.kotlin.ir.IrElement
|
import org.jetbrains.kotlin.ir.IrElement
|
||||||
import org.jetbrains.kotlin.ir.UNDEFINED_OFFSET
|
|
||||||
import org.jetbrains.kotlin.ir.declarations.*
|
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.IrElementVisitorVoid
|
||||||
import org.jetbrains.kotlin.ir.visitors.acceptChildrenVoid
|
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.types.KotlinType
|
||||||
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
|
|
||||||
|
|
||||||
class AnnotationGenerator(
|
class AnnotationGenerator(
|
||||||
moduleDescriptor: ModuleDescriptor,
|
moduleDescriptor: ModuleDescriptor,
|
||||||
private val symbolTable: SymbolTable
|
symbolTable: SymbolTable
|
||||||
) : IrElementVisitorVoid {
|
) : IrElementVisitorVoid {
|
||||||
|
|
||||||
private val typeTranslator = TypeTranslator(moduleDescriptor, symbolTable)
|
private val typeTranslator = TypeTranslator(moduleDescriptor, symbolTable)
|
||||||
private val scopedTypeParameterResolver = ScopedTypeParametersResolver()
|
private val scopedTypeParameterResolver = ScopedTypeParametersResolver()
|
||||||
private val constantValueGenerator = ConstantValueGenerator(moduleDescriptor, symbolTable, this, scopedTypeParameterResolver)
|
private val constantValueGenerator = ConstantValueGenerator(moduleDescriptor, symbolTable, scopedTypeParameterResolver)
|
||||||
|
|
||||||
override fun visitElement(element: IrElement) {
|
override fun visitElement(element: IrElement) {
|
||||||
element.acceptChildrenVoid(this)
|
element.acceptChildrenVoid(this)
|
||||||
@@ -73,57 +64,12 @@ class AnnotationGenerator(
|
|||||||
|
|
||||||
private fun List<AnnotationWithTarget>.generateAnnotationConstructorCalls(declaration: IrDeclaration) {
|
private fun List<AnnotationWithTarget>.generateAnnotationConstructorCalls(declaration: IrDeclaration) {
|
||||||
mapTo(declaration.annotations) {
|
mapTo(declaration.annotations) {
|
||||||
generateAnnotationConstructorCall(it.annotation)
|
constantValueGenerator.generateAnnotationConstructorCall(it.annotation)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun KotlinType.toIrType() = typeTranslator.translateType(this)
|
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 =
|
private fun isAnnotationTargetMatchingDeclaration(target: AnnotationUseSiteTarget?, element: IrElement): Boolean =
|
||||||
when (element) {
|
when (element) {
|
||||||
is IrProperty ->
|
is IrProperty ->
|
||||||
|
|||||||
@@ -8,13 +8,16 @@ package org.jetbrains.kotlin.ir.util
|
|||||||
import org.jetbrains.kotlin.descriptors.ClassDescriptor
|
import org.jetbrains.kotlin.descriptors.ClassDescriptor
|
||||||
import org.jetbrains.kotlin.descriptors.ModuleDescriptor
|
import org.jetbrains.kotlin.descriptors.ModuleDescriptor
|
||||||
import org.jetbrains.kotlin.descriptors.TypeParameterDescriptor
|
import org.jetbrains.kotlin.descriptors.TypeParameterDescriptor
|
||||||
|
import org.jetbrains.kotlin.descriptors.annotations.AnnotationDescriptor
|
||||||
import org.jetbrains.kotlin.incremental.components.NoLookupLocation
|
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.IrExpression
|
||||||
import org.jetbrains.kotlin.ir.expressions.impl.IrClassReferenceImpl
|
import org.jetbrains.kotlin.ir.expressions.impl.*
|
||||||
import org.jetbrains.kotlin.ir.expressions.impl.IrConstImpl
|
import org.jetbrains.kotlin.psi.psiUtil.startOffset
|
||||||
import org.jetbrains.kotlin.ir.expressions.impl.IrGetEnumValueImpl
|
import org.jetbrains.kotlin.resolve.DescriptorUtils
|
||||||
import org.jetbrains.kotlin.ir.expressions.impl.IrVarargImpl
|
|
||||||
import org.jetbrains.kotlin.resolve.constants.*
|
import org.jetbrains.kotlin.resolve.constants.*
|
||||||
|
import org.jetbrains.kotlin.resolve.source.PsiSourceElement
|
||||||
import org.jetbrains.kotlin.types.KotlinType
|
import org.jetbrains.kotlin.types.KotlinType
|
||||||
import org.jetbrains.kotlin.types.typeUtil.builtIns
|
import org.jetbrains.kotlin.types.typeUtil.builtIns
|
||||||
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
|
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
|
||||||
@@ -22,7 +25,6 @@ import org.jetbrains.kotlin.utils.addToStdlib.safeAs
|
|||||||
class ConstantValueGenerator(
|
class ConstantValueGenerator(
|
||||||
private val moduleDescriptor: ModuleDescriptor,
|
private val moduleDescriptor: ModuleDescriptor,
|
||||||
private val symbolTable: SymbolTable,
|
private val symbolTable: SymbolTable,
|
||||||
private val annotationGenerator: AnnotationGenerator?,
|
|
||||||
private val scopedTypeParameterResolver: ScopedTypeParametersResolver?
|
private val scopedTypeParameterResolver: ScopedTypeParametersResolver?
|
||||||
) {
|
) {
|
||||||
|
|
||||||
@@ -81,10 +83,7 @@ class ConstantValueGenerator(
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
is AnnotationValue -> {
|
is AnnotationValue -> generateAnnotationConstructorCall(constantValue.value)
|
||||||
if (annotationGenerator == null) throw AssertionError("Unexpected AnnotationValue: $constantValue")
|
|
||||||
annotationGenerator.generateAnnotationConstructorCall(constantValue.value)
|
|
||||||
}
|
|
||||||
|
|
||||||
is KClassValue -> {
|
is KClassValue -> {
|
||||||
val classifierKtType = constantValue.value
|
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)
|
private fun KotlinType.getArrayElementType() = builtIns.getArrayElementType(this)
|
||||||
}
|
}
|
||||||
@@ -25,8 +25,8 @@ class TypeTranslator(
|
|||||||
private val symbolTable: SymbolTable
|
private val symbolTable: SymbolTable
|
||||||
) {
|
) {
|
||||||
|
|
||||||
private val annotationGenerator = AnnotationGenerator(moduleDescriptor, symbolTable)
|
|
||||||
private val typeParametersResolver = ScopedTypeParametersResolver()
|
private val typeParametersResolver = ScopedTypeParametersResolver()
|
||||||
|
private val constantValueGenerator = ConstantValueGenerator(moduleDescriptor, symbolTable, typeParametersResolver)
|
||||||
|
|
||||||
fun enterScope(irElement: IrTypeParametersContainer) {
|
fun enterScope(irElement: IrTypeParametersContainer) {
|
||||||
typeParametersResolver.enterTypeParameterScope(irElement)
|
typeParametersResolver.enterTypeParameterScope(irElement)
|
||||||
@@ -97,7 +97,7 @@ class TypeTranslator(
|
|||||||
private fun translateTypeAnnotations(annotations: Annotations): List<IrCall> =
|
private fun translateTypeAnnotations(annotations: Annotations): List<IrCall> =
|
||||||
annotations.getAllAnnotations().map {
|
annotations.getAllAnnotations().map {
|
||||||
// TODO filter out annotation targets
|
// TODO filter out annotation targets
|
||||||
annotationGenerator.generateAnnotationConstructorCall(it.annotation)
|
constantValueGenerator.generateAnnotationConstructorCall(it.annotation)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun translateTypeArguments(arguments: List<TypeProjection>) =
|
private fun translateTypeArguments(arguments: List<TypeProjection>) =
|
||||||
|
|||||||
Reference in New Issue
Block a user