IrTypes: generateAnnotationConstructorCall -> ConstantValueGenerator

This commit is contained in:
Dmitry Petrov
2018-05-31 15:07:53 +03:00
parent 3a11767fae
commit a9d0e6d3da
5 changed files with 57 additions and 72 deletions
@@ -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) {
@@ -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>) =