Type translation, initial import
This commit is contained in:
@@ -21,7 +21,6 @@ import org.jetbrains.kotlin.ir.IrElement
|
|||||||
import org.jetbrains.kotlin.ir.declarations.IrModuleFragment
|
import org.jetbrains.kotlin.ir.declarations.IrModuleFragment
|
||||||
import org.jetbrains.kotlin.ir.util.patchDeclarationParents
|
import org.jetbrains.kotlin.ir.util.patchDeclarationParents
|
||||||
import org.jetbrains.kotlin.psi.KtFile
|
import org.jetbrains.kotlin.psi.KtFile
|
||||||
import org.jetbrains.kotlin.psi2ir.transformations.AnnotationGenerator
|
|
||||||
import org.jetbrains.kotlin.psi2ir.generators.GeneratorContext
|
import org.jetbrains.kotlin.psi2ir.generators.GeneratorContext
|
||||||
import org.jetbrains.kotlin.psi2ir.generators.ModuleGenerator
|
import org.jetbrains.kotlin.psi2ir.generators.ModuleGenerator
|
||||||
import org.jetbrains.kotlin.psi2ir.transformations.generateAnnotationsForDeclarations
|
import org.jetbrains.kotlin.psi2ir.transformations.generateAnnotationsForDeclarations
|
||||||
|
|||||||
+12
-4
@@ -6,28 +6,36 @@
|
|||||||
package org.jetbrains.kotlin.psi2ir.generators
|
package org.jetbrains.kotlin.psi2ir.generators
|
||||||
|
|
||||||
import org.jetbrains.kotlin.descriptors.ClassDescriptor
|
import org.jetbrains.kotlin.descriptors.ClassDescriptor
|
||||||
|
import org.jetbrains.kotlin.descriptors.ModuleDescriptor
|
||||||
import org.jetbrains.kotlin.incremental.components.NoLookupLocation
|
import org.jetbrains.kotlin.incremental.components.NoLookupLocation
|
||||||
import org.jetbrains.kotlin.ir.expressions.IrExpression
|
import org.jetbrains.kotlin.ir.expressions.IrExpression
|
||||||
import org.jetbrains.kotlin.ir.expressions.impl.IrConstImpl
|
import org.jetbrains.kotlin.ir.expressions.impl.IrConstImpl
|
||||||
import org.jetbrains.kotlin.ir.expressions.impl.IrGetEnumValueImpl
|
import org.jetbrains.kotlin.ir.expressions.impl.IrGetEnumValueImpl
|
||||||
import org.jetbrains.kotlin.ir.expressions.impl.IrVarargImpl
|
import org.jetbrains.kotlin.ir.expressions.impl.IrVarargImpl
|
||||||
|
import org.jetbrains.kotlin.ir.util.SymbolTable
|
||||||
import org.jetbrains.kotlin.psi2ir.transformations.AnnotationGenerator
|
import org.jetbrains.kotlin.psi2ir.transformations.AnnotationGenerator
|
||||||
import org.jetbrains.kotlin.resolve.constants.*
|
import org.jetbrains.kotlin.resolve.constants.*
|
||||||
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
|
||||||
|
|
||||||
class ConstantValueGenerator(
|
class ConstantValueGenerator(
|
||||||
private val context: GeneratorContext,
|
private val moduleDescriptor: ModuleDescriptor,
|
||||||
private val annotationGenerator: AnnotationGenerator? = null
|
private val symbolTable: SymbolTable,
|
||||||
|
private val annotationGenerator: AnnotationGenerator?
|
||||||
) {
|
) {
|
||||||
|
|
||||||
|
constructor(
|
||||||
|
context: GeneratorContext,
|
||||||
|
annotationGenerator: AnnotationGenerator? = null
|
||||||
|
) : this(context.moduleDescriptor, context.symbolTable, annotationGenerator)
|
||||||
|
|
||||||
fun generateConstantValueAsExpression(
|
fun generateConstantValueAsExpression(
|
||||||
startOffset: Int,
|
startOffset: Int,
|
||||||
endOffset: Int,
|
endOffset: Int,
|
||||||
constantValue: ConstantValue<*>,
|
constantValue: ConstantValue<*>,
|
||||||
varargElementType: KotlinType? = null
|
varargElementType: KotlinType? = null
|
||||||
): IrExpression {
|
): IrExpression {
|
||||||
val constantType = constantValue.getType(context.moduleDescriptor)
|
val constantType = constantValue.getType(moduleDescriptor)
|
||||||
|
|
||||||
return when (constantValue) {
|
return when (constantValue) {
|
||||||
is StringValue -> IrConstImpl.string(startOffset, endOffset, constantType, constantValue.value)
|
is StringValue -> IrConstImpl.string(startOffset, endOffset, constantType, constantValue.value)
|
||||||
@@ -63,7 +71,7 @@ class ConstantValueGenerator(
|
|||||||
IrGetEnumValueImpl(
|
IrGetEnumValueImpl(
|
||||||
startOffset, endOffset,
|
startOffset, endOffset,
|
||||||
constantType,
|
constantType,
|
||||||
context.symbolTable.referenceEnumEntry(enumEntryDescriptor)
|
symbolTable.referenceEnumEntry(enumEntryDescriptor)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+12
-4
@@ -6,6 +6,7 @@
|
|||||||
package org.jetbrains.kotlin.psi2ir.transformations
|
package org.jetbrains.kotlin.psi2ir.transformations
|
||||||
|
|
||||||
import org.jetbrains.kotlin.descriptors.ClassDescriptor
|
import org.jetbrains.kotlin.descriptors.ClassDescriptor
|
||||||
|
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.AnnotationDescriptor
|
||||||
import org.jetbrains.kotlin.descriptors.annotations.AnnotationUseSiteTarget
|
import org.jetbrains.kotlin.descriptors.annotations.AnnotationUseSiteTarget
|
||||||
@@ -15,6 +16,7 @@ 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.IrCall
|
||||||
import org.jetbrains.kotlin.ir.expressions.impl.IrCallImpl
|
import org.jetbrains.kotlin.ir.expressions.impl.IrCallImpl
|
||||||
|
import org.jetbrains.kotlin.ir.util.SymbolTable
|
||||||
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.ir.visitors.acceptVoid
|
import org.jetbrains.kotlin.ir.visitors.acceptVoid
|
||||||
@@ -26,12 +28,18 @@ import org.jetbrains.kotlin.resolve.source.PsiSourceElement
|
|||||||
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
|
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
|
||||||
|
|
||||||
fun generateAnnotationsForDeclarations(context: GeneratorContext, irElement: IrElement) {
|
fun generateAnnotationsForDeclarations(context: GeneratorContext, irElement: IrElement) {
|
||||||
irElement.acceptVoid(AnnotationGenerator(context))
|
val annotationGenerator = AnnotationGenerator(context.moduleDescriptor, context.symbolTable)
|
||||||
|
irElement.acceptVoid(annotationGenerator)
|
||||||
}
|
}
|
||||||
|
|
||||||
class AnnotationGenerator(private val context: GeneratorContext) : IrElementVisitorVoid {
|
class AnnotationGenerator(
|
||||||
|
moduleDescriptor: ModuleDescriptor,
|
||||||
|
private val symbolTable: SymbolTable
|
||||||
|
) : IrElementVisitorVoid {
|
||||||
|
|
||||||
private val constantValueGenerator = ConstantValueGenerator(context, this)
|
constructor(context: GeneratorContext) : this(context.moduleDescriptor, context.symbolTable)
|
||||||
|
|
||||||
|
private val constantValueGenerator = ConstantValueGenerator(moduleDescriptor, symbolTable, this)
|
||||||
|
|
||||||
override fun visitElement(element: IrElement) {
|
override fun visitElement(element: IrElement) {
|
||||||
element.acceptChildrenVoid(this)
|
element.acceptChildrenVoid(this)
|
||||||
@@ -82,7 +90,7 @@ class AnnotationGenerator(private val context: GeneratorContext) : IrElementVisi
|
|||||||
val primaryConstructorDescriptor =
|
val primaryConstructorDescriptor =
|
||||||
annotationClassDescriptor.safeAs<ClassDescriptor>()?.unsubstitutedPrimaryConstructor
|
annotationClassDescriptor.safeAs<ClassDescriptor>()?.unsubstitutedPrimaryConstructor
|
||||||
?: throw AssertionError("No primary constructor for annotation class $annotationClassDescriptor")
|
?: throw AssertionError("No primary constructor for annotation class $annotationClassDescriptor")
|
||||||
val primaryConstructorSymbol = context.symbolTable.referenceConstructor(primaryConstructorDescriptor)
|
val primaryConstructorSymbol = symbolTable.referenceConstructor(primaryConstructorDescriptor)
|
||||||
|
|
||||||
val psi = annotationDescriptor.source.safeAs<PsiSourceElement>()?.psi
|
val psi = annotationDescriptor.source.safeAs<PsiSourceElement>()?.psi
|
||||||
val startOffset = psi?.startOffset ?: UNDEFINED_OFFSET
|
val startOffset = psi?.startOffset ?: UNDEFINED_OFFSET
|
||||||
|
|||||||
+9
-24
@@ -34,42 +34,27 @@ import org.jetbrains.kotlin.types.isError
|
|||||||
import org.jetbrains.kotlin.types.isNullabilityFlexible
|
import org.jetbrains.kotlin.types.isNullabilityFlexible
|
||||||
import org.jetbrains.kotlin.types.typeUtil.makeNotNullable
|
import org.jetbrains.kotlin.types.typeUtil.makeNotNullable
|
||||||
import org.jetbrains.kotlin.types.upperIfFlexible
|
import org.jetbrains.kotlin.types.upperIfFlexible
|
||||||
import java.util.*
|
|
||||||
|
|
||||||
fun insertImplicitCasts(builtIns: KotlinBuiltIns, element: IrElement, symbolTable: SymbolTable) {
|
fun insertImplicitCasts(builtIns: KotlinBuiltIns, element: IrElement, symbolTable: SymbolTable) {
|
||||||
element.transformChildren(InsertImplicitCasts(builtIns, symbolTable), null)
|
element.transformChildren(InsertImplicitCasts(builtIns, symbolTable), null)
|
||||||
}
|
}
|
||||||
|
|
||||||
class InsertImplicitCasts(private val builtIns: KotlinBuiltIns, private val symbolTable: SymbolTable) : IrElementTransformerVoid() {
|
class InsertImplicitCasts(private val builtIns: KotlinBuiltIns, private val symbolTable: SymbolTable) : IrElementTransformerVoid() {
|
||||||
private val typeParameterScopes = ArrayDeque<Map<TypeParameterDescriptor, IrTypeParameterSymbol>>()
|
|
||||||
|
private val typeParameterResolver = ScopedTypeParametersResolver()
|
||||||
|
|
||||||
private inline fun <T> runInTypeParameterScope(typeParametersContainer: IrTypeParametersContainer, fn: () -> T): T {
|
private inline fun <T> runInTypeParameterScope(typeParametersContainer: IrTypeParametersContainer, fn: () -> T): T {
|
||||||
enterTypeParameterScope(typeParametersContainer)
|
typeParameterResolver.enterTypeParameterScope(typeParametersContainer)
|
||||||
val result = fn()
|
val result = fn()
|
||||||
leaveTypeParameterScope()
|
typeParameterResolver.leaveTypeParameterScope()
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun enterTypeParameterScope(typeParametersContainer: IrTypeParametersContainer) {
|
private fun resolveScopedTypeParameter(classifier: ClassifierDescriptor): IrTypeParameterSymbol? =
|
||||||
typeParameterScopes.addFirst(
|
if (classifier is TypeParameterDescriptor)
|
||||||
typeParametersContainer.typeParameters.associate {
|
typeParameterResolver.resolveScopedTypeParameter(classifier)
|
||||||
it.descriptor to it.symbol
|
else
|
||||||
}
|
null
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun leaveTypeParameterScope() {
|
|
||||||
typeParameterScopes.removeFirst()
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun resolveScopedTypeParameter(classifier: ClassifierDescriptor): IrTypeParameterSymbol? {
|
|
||||||
if (classifier !is TypeParameterDescriptor) return null
|
|
||||||
for (scope in typeParameterScopes) {
|
|
||||||
val local = scope[classifier]
|
|
||||||
if (local != null) return local
|
|
||||||
}
|
|
||||||
return null
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun visitCallableReference(expression: IrCallableReference): IrExpression =
|
override fun visitCallableReference(expression: IrCallableReference): IrExpression =
|
||||||
expression.transformPostfix {
|
expression.transformPostfix {
|
||||||
|
|||||||
+36
@@ -0,0 +1,36 @@
|
|||||||
|
/*
|
||||||
|
* 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.psi2ir.transformations
|
||||||
|
|
||||||
|
import org.jetbrains.kotlin.descriptors.TypeParameterDescriptor
|
||||||
|
import org.jetbrains.kotlin.ir.declarations.IrTypeParametersContainer
|
||||||
|
import org.jetbrains.kotlin.ir.symbols.IrTypeParameterSymbol
|
||||||
|
import java.util.*
|
||||||
|
|
||||||
|
class ScopedTypeParametersResolver {
|
||||||
|
|
||||||
|
private val typeParameterScopes = ArrayDeque<Map<TypeParameterDescriptor, IrTypeParameterSymbol>>()
|
||||||
|
|
||||||
|
fun enterTypeParameterScope(typeParametersContainer: IrTypeParametersContainer) {
|
||||||
|
typeParameterScopes.addFirst(
|
||||||
|
typeParametersContainer.typeParameters.associate {
|
||||||
|
it.descriptor to it.symbol
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun leaveTypeParameterScope() {
|
||||||
|
typeParameterScopes.removeFirst()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun resolveScopedTypeParameter(typeParameterDescriptor: TypeParameterDescriptor): IrTypeParameterSymbol? {
|
||||||
|
for (scope in typeParameterScopes) {
|
||||||
|
val local = scope[typeParameterDescriptor]
|
||||||
|
if (local != null) return local
|
||||||
|
}
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,128 @@
|
|||||||
|
/*
|
||||||
|
* 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.psi2ir.types
|
||||||
|
|
||||||
|
import org.jetbrains.kotlin.descriptors.ClassDescriptor
|
||||||
|
import org.jetbrains.kotlin.descriptors.ModuleDescriptor
|
||||||
|
import org.jetbrains.kotlin.descriptors.TypeParameterDescriptor
|
||||||
|
import org.jetbrains.kotlin.descriptors.annotations.Annotations
|
||||||
|
import org.jetbrains.kotlin.ir.IrElement
|
||||||
|
import org.jetbrains.kotlin.ir.declarations.IrDeclaration
|
||||||
|
import org.jetbrains.kotlin.ir.declarations.IrTypeParametersContainer
|
||||||
|
import org.jetbrains.kotlin.ir.expressions.IrCall
|
||||||
|
import org.jetbrains.kotlin.ir.expressions.IrExpression
|
||||||
|
import org.jetbrains.kotlin.ir.types.impl.IrTypeImpl
|
||||||
|
import org.jetbrains.kotlin.ir.util.SymbolTable
|
||||||
|
import org.jetbrains.kotlin.ir.visitors.IrElementVisitorVoid
|
||||||
|
import org.jetbrains.kotlin.ir.visitors.acceptChildrenVoid
|
||||||
|
import org.jetbrains.kotlin.ir.visitors.acceptVoid
|
||||||
|
import org.jetbrains.kotlin.psi2ir.generators.GeneratorContext
|
||||||
|
import org.jetbrains.kotlin.psi2ir.transformations.AnnotationGenerator
|
||||||
|
import org.jetbrains.kotlin.psi2ir.transformations.ScopedTypeParametersResolver
|
||||||
|
import org.jetbrains.kotlin.types.*
|
||||||
|
|
||||||
|
class TypeTranslator(
|
||||||
|
moduleDescriptor: ModuleDescriptor,
|
||||||
|
private val symbolTable: SymbolTable
|
||||||
|
) {
|
||||||
|
|
||||||
|
constructor(context: GeneratorContext) : this(context.moduleDescriptor, context.symbolTable)
|
||||||
|
|
||||||
|
private val annotationGenerator = AnnotationGenerator(moduleDescriptor, symbolTable)
|
||||||
|
private val typeParametersResolver = ScopedTypeParametersResolver()
|
||||||
|
|
||||||
|
fun enterScope(irElement: IrTypeParametersContainer) {
|
||||||
|
typeParametersResolver.enterTypeParameterScope(irElement)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun leaveScope() {
|
||||||
|
typeParametersResolver.leaveTypeParameterScope()
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun resolveTypeParameter(typeParameterDescriptor: TypeParameterDescriptor) =
|
||||||
|
typeParametersResolver.resolveScopedTypeParameter(typeParameterDescriptor)
|
||||||
|
?: symbolTable.referenceTypeParameter(typeParameterDescriptor)
|
||||||
|
|
||||||
|
fun translateType(ktType: KotlinType): IrTypeImpl =
|
||||||
|
translateType(ktType, Variance.INVARIANT)
|
||||||
|
|
||||||
|
private fun translateType(ktType: KotlinType, variance: Variance): IrTypeImpl {
|
||||||
|
if (ktType.isFlexible()) {
|
||||||
|
return translateType(ktType.upperIfFlexible(), variance)
|
||||||
|
}
|
||||||
|
|
||||||
|
val ktTypeConstructor = ktType.constructor
|
||||||
|
val ktTypeDescriptor = ktTypeConstructor.declarationDescriptor
|
||||||
|
|
||||||
|
return when (ktTypeDescriptor) {
|
||||||
|
is TypeParameterDescriptor ->
|
||||||
|
IrTypeImpl(
|
||||||
|
resolveTypeParameter(ktTypeDescriptor),
|
||||||
|
ktType.isMarkedNullable,
|
||||||
|
emptyList(),
|
||||||
|
translateTypeAnnotations(ktType.annotations),
|
||||||
|
variance
|
||||||
|
)
|
||||||
|
|
||||||
|
is ClassDescriptor ->
|
||||||
|
IrTypeImpl(
|
||||||
|
symbolTable.referenceClass(ktTypeDescriptor),
|
||||||
|
ktType.isMarkedNullable,
|
||||||
|
translateTypeArguments(ktType.arguments),
|
||||||
|
translateTypeAnnotations(ktType.annotations),
|
||||||
|
variance
|
||||||
|
)
|
||||||
|
|
||||||
|
else ->
|
||||||
|
TODO()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun translateTypeAnnotations(annotations: Annotations): List<IrCall> =
|
||||||
|
annotations.getAllAnnotations().map {
|
||||||
|
// TODO filter out annotation targets
|
||||||
|
annotationGenerator.generateAnnotationConstructorCall(it.annotation)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun translateTypeArguments(arguments: List<TypeProjection>) =
|
||||||
|
arguments.map {
|
||||||
|
// TODO starProjection
|
||||||
|
translateType(it.type, it.projectionKind)
|
||||||
|
}
|
||||||
|
|
||||||
|
private inner class SimpleTranslationVisitor : IrElementVisitorVoid {
|
||||||
|
override fun visitElement(element: IrElement) {
|
||||||
|
element.acceptChildrenVoid(this)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun visitDeclaration(declaration: IrDeclaration) {
|
||||||
|
if (declaration is IrTypeParametersContainer) {
|
||||||
|
enterScope(declaration)
|
||||||
|
}
|
||||||
|
declaration.acceptChildrenVoid(this)
|
||||||
|
if (declaration is IrTypeParametersContainer) {
|
||||||
|
leaveScope()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun visitExpression(expression: IrExpression) {
|
||||||
|
translateType(expression.type)
|
||||||
|
expression.acceptChildrenVoid(this)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
|
||||||
|
fun tryTranslateAllExpressionTypes(
|
||||||
|
element: IrElement,
|
||||||
|
context: GeneratorContext
|
||||||
|
) {
|
||||||
|
element.acceptVoid(TypeTranslator(context).SimpleTranslationVisitor())
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@@ -26,17 +26,16 @@ class IrTypeImpl(
|
|||||||
annotations: List<IrCall>
|
annotations: List<IrCall>
|
||||||
) : this(classifier, hasQuestionMark, arguments, annotations, Variance.INVARIANT)
|
) : this(classifier, hasQuestionMark, arguments, annotations, Variance.INVARIANT)
|
||||||
|
|
||||||
|
constructor(
|
||||||
|
other: IrType,
|
||||||
|
variance: Variance
|
||||||
|
) : this(other.classifier, other.hasQuestionMark, other.arguments, other.annotations, variance)
|
||||||
|
|
||||||
override val type: IrType get() = this
|
override val type: IrType get() = this
|
||||||
}
|
}
|
||||||
|
|
||||||
fun makeTypeProjection(type: IrType, variance: Variance): IrTypeProjection =
|
fun makeTypeProjection(type: IrType, variance: Variance): IrTypeProjection =
|
||||||
if (type !is IrTypeImpl || type.variance != variance)
|
if (type is IrTypeImpl && type.variance == variance)
|
||||||
IrTypeImpl(
|
|
||||||
type.classifier,
|
|
||||||
type.hasQuestionMark,
|
|
||||||
type.arguments,
|
|
||||||
type.annotations,
|
|
||||||
variance
|
|
||||||
)
|
|
||||||
else
|
|
||||||
type
|
type
|
||||||
|
else
|
||||||
|
IrTypeImpl(type, variance)
|
||||||
Reference in New Issue
Block a user