diff --git a/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/JavaSymbolProvider.kt b/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/JavaSymbolProvider.kt index 321f98b9c02..8e84583464e 100644 --- a/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/JavaSymbolProvider.kt +++ b/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/JavaSymbolProvider.kt @@ -11,8 +11,11 @@ import org.jetbrains.kotlin.fir.FirSession import org.jetbrains.kotlin.fir.declarations.FirNamedFunction import org.jetbrains.kotlin.fir.declarations.impl.* import org.jetbrains.kotlin.fir.expressions.FirAnnotationCall +import org.jetbrains.kotlin.fir.expressions.FirArrayOfCall import org.jetbrains.kotlin.fir.expressions.FirExpression import org.jetbrains.kotlin.fir.expressions.impl.* +import org.jetbrains.kotlin.fir.references.FirErrorNamedReference +import org.jetbrains.kotlin.fir.references.FirResolvedCallableReferenceImpl import org.jetbrains.kotlin.fir.resolve.AbstractFirSymbolProvider import org.jetbrains.kotlin.fir.resolve.FirSymbolProvider import org.jetbrains.kotlin.fir.service @@ -61,23 +64,75 @@ class JavaSymbolProvider( } } + // TODO: use kind here + private fun List.createArrayOfCall(@Suppress("UNUSED_PARAMETER") kind: IrConstKind): FirArrayOfCall { + return FirArrayOfCallImpl(session, null).apply { + for (element in this@createArrayOfCall) { + arguments += element.createConstant() + } + } + } + + private fun Any?.createConstant(): FirExpression { + return when (this) { + is Byte -> FirConstExpressionImpl(session, null, IrConstKind.Byte, this) + is Short -> FirConstExpressionImpl(session, null, IrConstKind.Short, this) + is Int -> FirConstExpressionImpl(session, null, IrConstKind.Int, this) + is Long -> FirConstExpressionImpl(session, null, IrConstKind.Long, this) + is Char -> FirConstExpressionImpl(session, null, IrConstKind.Char, this) + is Float -> FirConstExpressionImpl(session, null, IrConstKind.Float, this) + is Double -> FirConstExpressionImpl(session, null, IrConstKind.Double, this) + is Boolean -> FirConstExpressionImpl(session, null, IrConstKind.Boolean, this) + is String -> FirConstExpressionImpl(session, null, IrConstKind.String, this) + null -> FirConstExpressionImpl(session, null, IrConstKind.Null, null) + + else -> FirErrorExpressionImpl(session, null, "Unknown value in JavaLiteralAnnotationArgument: $this") + } + } + private fun JavaAnnotationArgument.toFirExpression(): FirExpression { // TODO: this.name return when (this) { - is JavaLiteralAnnotationArgument -> when (value) { - null -> FirConstExpressionImpl(session, null, IrConstKind.Null, null) - else -> FirErrorExpressionImpl(session, null, "Unknown value in JavaLiteralAnnotationArgument: $value") + is JavaLiteralAnnotationArgument -> { + val value = value + when (value) { + is ByteArray -> value.toList().createArrayOfCall(IrConstKind.Byte) + is ShortArray -> value.toList().createArrayOfCall(IrConstKind.Short) + is IntArray -> value.toList().createArrayOfCall(IrConstKind.Int) + is LongArray -> value.toList().createArrayOfCall(IrConstKind.Long) + is CharArray -> value.toList().createArrayOfCall(IrConstKind.Char) + is FloatArray -> value.toList().createArrayOfCall(IrConstKind.Float) + is DoubleArray -> value.toList().createArrayOfCall(IrConstKind.Double) + is BooleanArray -> value.toList().createArrayOfCall(IrConstKind.Boolean) + else -> value.createConstant() + } } is JavaArrayAnnotationArgument -> FirArrayOfCallImpl(session, null).apply { for (element in getElements()) { arguments += element.toFirExpression() } } - // TODO - //is JavaEnumValueAnnotationArgument -> {} + is JavaEnumValueAnnotationArgument -> { + FirFunctionCallImpl(session, null).apply { + val classId = this@toFirExpression.enumClassId + val entryName = this@toFirExpression.entryName + val calleeReference = if (classId != null && entryName != null) { + val callableSymbol = session.service().getCallableSymbols( + CallableId(classId.packageFqName, classId.relativeClassName, entryName) + ).firstOrNull() + callableSymbol?.let { + FirResolvedCallableReferenceImpl(session, null, entryName, it) + } + } else { + null + } + this.calleeReference = calleeReference + ?: FirErrorNamedReference(session, null, "Strange Java enum value: ${this@toFirExpression}") + } + } is JavaClassObjectAnnotationArgument -> FirGetClassCallImpl(session, null).apply { - // TODO - //arguments += getReferencedType().toFirType() + val referencedType = getReferencedType() + arguments += FirClassReferenceExpressionImpl(session, null, referencedType.toFirResolvedTypeRef()) } is JavaAnnotationAsAnnotationArgument -> getAnnotation().toFirAnnotationCall() else -> FirErrorExpressionImpl(session, null, "Unknown JavaAnnotationArgument: ${this::class.java}") diff --git a/compiler/fir/tree/src/org/jetbrains/kotlin/fir/FirRenderer.kt b/compiler/fir/tree/src/org/jetbrains/kotlin/fir/FirRenderer.kt index 3621bc622be..ae7d6db906e 100644 --- a/compiler/fir/tree/src/org/jetbrains/kotlin/fir/FirRenderer.kt +++ b/compiler/fir/tree/src/org/jetbrains/kotlin/fir/FirRenderer.kt @@ -841,6 +841,14 @@ class FirRenderer(builder: StringBuilder) : FirVisitorVoid() { visitCall(getClassCall) } + override fun visitClassReferenceExpression(classReferenceExpression: FirClassReferenceExpression) { + classReferenceExpression.annotations.renderAnnotations() + print("") + print("(") + classReferenceExpression.typeRef.accept(this) + print(")") + } + override fun visitArrayOfCall(arrayOfCall: FirArrayOfCall) { arrayOfCall.annotations.renderAnnotations() print("") diff --git a/compiler/fir/tree/src/org/jetbrains/kotlin/fir/expressions/FirClassReferenceExpression.kt b/compiler/fir/tree/src/org/jetbrains/kotlin/fir/expressions/FirClassReferenceExpression.kt new file mode 100644 index 00000000000..5178475dd49 --- /dev/null +++ b/compiler/fir/tree/src/org/jetbrains/kotlin/fir/expressions/FirClassReferenceExpression.kt @@ -0,0 +1,16 @@ +/* + * Copyright 2010-2019 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.fir.expressions + +import org.jetbrains.kotlin.fir.types.FirTypeRef +import org.jetbrains.kotlin.fir.visitors.FirVisitor + +interface FirClassReferenceExpression : FirExpression { + val typeRef: FirTypeRef + + override fun accept(visitor: FirVisitor, data: D): R = + visitor.visitClassReferenceExpression(this, data) +} \ No newline at end of file diff --git a/compiler/fir/tree/src/org/jetbrains/kotlin/fir/expressions/impl/FirClassReferenceExpressionImpl.kt b/compiler/fir/tree/src/org/jetbrains/kotlin/fir/expressions/impl/FirClassReferenceExpressionImpl.kt new file mode 100644 index 00000000000..cbf70281097 --- /dev/null +++ b/compiler/fir/tree/src/org/jetbrains/kotlin/fir/expressions/impl/FirClassReferenceExpressionImpl.kt @@ -0,0 +1,25 @@ +/* + * Copyright 2010-2019 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.fir.expressions.impl + +import com.intellij.psi.PsiElement +import org.jetbrains.kotlin.fir.FirElement +import org.jetbrains.kotlin.fir.FirSession +import org.jetbrains.kotlin.fir.expressions.FirClassReferenceExpression +import org.jetbrains.kotlin.fir.transformSingle +import org.jetbrains.kotlin.fir.types.FirTypeRef +import org.jetbrains.kotlin.fir.visitors.FirTransformer + +class FirClassReferenceExpressionImpl( + session: FirSession, + psi: PsiElement?, + override var typeRef: FirTypeRef +) : FirAbstractExpression(session, psi), FirClassReferenceExpression { + override fun transformChildren(transformer: FirTransformer, data: D): FirElement { + typeRef = typeRef.transformSingle(transformer, data) + return super.transformChildren(transformer, data) + } +} \ No newline at end of file diff --git a/compiler/fir/tree/visitors/org/jetbrains/kotlin/fir/visitors/FirTransformerGenerated.kt b/compiler/fir/tree/visitors/org/jetbrains/kotlin/fir/visitors/FirTransformerGenerated.kt index a2644112e5f..f72d212c5d9 100644 --- a/compiler/fir/tree/visitors/org/jetbrains/kotlin/fir/visitors/FirTransformerGenerated.kt +++ b/compiler/fir/tree/visitors/org/jetbrains/kotlin/fir/visitors/FirTransformerGenerated.kt @@ -220,6 +220,10 @@ abstract class FirTransformer : FirVisitor { + return transformExpression(classReferenceExpression, data) + } + open fun transformConstExpression(constExpression: FirConstExpression, data: D): CompositeTransformResult { return transformExpression(constExpression, data) } @@ -416,6 +420,10 @@ abstract class FirTransformer : FirVisitor { + return transformClassReferenceExpression(classReferenceExpression, data) + } + final override fun visitComponentCall(componentCall: FirComponentCall, data: D): CompositeTransformResult { return transformComponentCall(componentCall, data) } diff --git a/compiler/fir/tree/visitors/org/jetbrains/kotlin/fir/visitors/FirVisitorGenerated.kt b/compiler/fir/tree/visitors/org/jetbrains/kotlin/fir/visitors/FirVisitorGenerated.kt index 3c3cf9dbb4f..2199e64f554 100644 --- a/compiler/fir/tree/visitors/org/jetbrains/kotlin/fir/visitors/FirVisitorGenerated.kt +++ b/compiler/fir/tree/visitors/org/jetbrains/kotlin/fir/visitors/FirVisitorGenerated.kt @@ -220,6 +220,10 @@ abstract class FirVisitor { return visitOperatorCall(typeOperatorCall, data) } + open fun visitClassReferenceExpression(classReferenceExpression: FirClassReferenceExpression, data: D): R { + return visitExpression(classReferenceExpression, data) + } + open fun visitConstExpression(constExpression: FirConstExpression, data: D): R { return visitExpression(constExpression, data) } diff --git a/compiler/fir/tree/visitors/org/jetbrains/kotlin/fir/visitors/FirVisitorVoidGenerated.kt b/compiler/fir/tree/visitors/org/jetbrains/kotlin/fir/visitors/FirVisitorVoidGenerated.kt index b6af4d21cad..fae50b79e8c 100644 --- a/compiler/fir/tree/visitors/org/jetbrains/kotlin/fir/visitors/FirVisitorVoidGenerated.kt +++ b/compiler/fir/tree/visitors/org/jetbrains/kotlin/fir/visitors/FirVisitorVoidGenerated.kt @@ -220,6 +220,10 @@ abstract class FirVisitorVoid : FirVisitor() { visitOperatorCall(typeOperatorCall, null) } + open fun visitClassReferenceExpression(classReferenceExpression: FirClassReferenceExpression) { + visitExpression(classReferenceExpression, null) + } + open fun visitConstExpression(constExpression: FirConstExpression) { visitExpression(constExpression, null) } @@ -416,6 +420,10 @@ abstract class FirVisitorVoid : FirVisitor() { visitClass(klass) } + final override fun visitClassReferenceExpression(classReferenceExpression: FirClassReferenceExpression, data: Nothing?) { + visitClassReferenceExpression(classReferenceExpression) + } + final override fun visitComponentCall(componentCall: FirComponentCall, data: Nothing?) { visitComponentCall(componentCall) }