Add separate FirJava elements (class, method, parameter, type reference)

Related to KT-29218
This commit is contained in:
Mikhail Glukhikh
2019-02-22 13:38:44 +03:00
parent 109f1938f6
commit 060bd1b464
9 changed files with 134 additions and 34 deletions
@@ -9,11 +9,16 @@ import com.intellij.openapi.project.Project
import com.intellij.psi.search.GlobalSearchScope
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.declarations.impl.FirModifiableClass
import org.jetbrains.kotlin.fir.declarations.impl.FirTypeParameterImpl
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.java.declarations.FirJavaClass
import org.jetbrains.kotlin.fir.java.declarations.FirJavaMethod
import org.jetbrains.kotlin.fir.java.declarations.FirJavaValueParameter
import org.jetbrains.kotlin.fir.java.types.FirJavaTypeRef
import org.jetbrains.kotlin.fir.references.FirErrorNamedReference
import org.jetbrains.kotlin.fir.references.FirResolvedCallableReferenceImpl
import org.jetbrains.kotlin.fir.resolve.AbstractFirSymbolProvider
@@ -91,8 +96,7 @@ class JavaSymbolProvider(
// TODO: this.name
return when (this) {
is JavaLiteralAnnotationArgument -> {
val value = value
when (value) {
when (val value = value) {
is ByteArray -> value.toList().createArrayOfCall(IrConstKind.Byte)
is ShortArray -> value.toList().createArrayOfCall(IrConstKind.Short)
is IntArray -> value.toList().createArrayOfCall(IrConstKind.Int)
@@ -136,23 +140,17 @@ class JavaSymbolProvider(
}
}
private fun flexibleType(create: (isNullable: Boolean) -> ConeLookupTagBasedType): ConeFlexibleType {
return ConeFlexibleType(create(false), create(true))
}
private fun JavaClassifierType.toFirResolvedTypeRef(): FirResolvedTypeRef {
val coneType = when (val classifier = classifier) {
is JavaClass -> {
val symbol = ConeClassLikeLookupTagImpl(classifier.classId!!)
flexibleType { isNullable ->
ConeClassTypeImpl(symbol, typeArguments.map { it.toConeProjection() }.toTypedArray(), isNullable)
}
val lookupTag = ConeClassLikeLookupTagImpl(classifier.classId!!)
ConeClassTypeImpl(lookupTag, typeArguments.map { it.toConeProjection() }.toTypedArray(), isNullable = false)
}
is JavaTypeParameter -> {
// TODO: it's unclear how to identify type parameter by the symbol
// TODO: some type parameter cache (provider?)
val symbol = createTypeParameterSymbol(classifier.name)
flexibleType { isNullable -> ConeTypeParameterTypeImpl(symbol, isNullable) }
ConeTypeParameterTypeImpl(symbol, isNullable = false)
}
else -> ConeClassErrorType(reason = "Unexpected classifier: $classifier")
}
@@ -162,6 +160,11 @@ class JavaSymbolProvider(
)
}
private fun JavaType.toFirJavaTypeRef(): FirJavaTypeRef {
val annotations = (this as? JavaClassifierType)?.annotations.orEmpty()
return FirJavaTypeRef(session, annotations = annotations.map { it.toFirAnnotationCall() }, type = this)
}
private fun JavaType.toFirResolvedTypeRef(): FirResolvedTypeRef {
if (this is JavaClassifierType) return toFirResolvedTypeRef()
return FirResolvedTypeRefImpl(
@@ -204,23 +207,19 @@ class JavaSymbolProvider(
val methodName = javaMethod.name
val methodId = CallableId(callableId.packageName, callableId.className, methodName)
val methodSymbol = FirFunctionSymbol(methodId)
val memberFunction = FirMemberFunctionImpl(
session, null, methodSymbol, methodName,
val memberFunction = FirJavaMethod(
session, methodSymbol, methodName,
javaMethod.visibility, javaMethod.modality,
isExpect = false, isActual = false, isOverride = false,
isOperator = true, isInfix = false, isInline = false,
isTailRec = false, isExternal = false, isSuspend = false,
receiverTypeRef = null, returnTypeRef = javaMethod.returnType.toFirResolvedTypeRef()
returnTypeRef = javaMethod.returnType.toFirJavaTypeRef()
).apply {
for (typeParameter in javaMethod.typeParameters) {
typeParameters += createTypeParameterSymbol(typeParameter.name).fir
}
addAnnotationsFrom(javaMethod)
for (valueParameter in javaMethod.valueParameters) {
valueParameters += FirValueParameterImpl(
session, null, valueParameter.name ?: Name.special("<anonymous Java parameter>"),
returnTypeRef = valueParameter.type.toFirResolvedTypeRef(),
defaultValue = null, isCrossinline = false, isNoinline = false,
valueParameters += FirJavaValueParameter(
session, valueParameter.name ?: Name.special("<anonymous Java parameter>"),
returnTypeRef = valueParameter.type.toFirJavaTypeRef(),
isVararg = valueParameter.isVararg
)
}
@@ -252,13 +251,10 @@ class JavaSymbolProvider(
}
}) { firSymbol, foundClass ->
foundClass?.let { javaClass ->
FirClassImpl(
session, null, firSymbol as FirClassSymbol, javaClass.name,
FirJavaClass(
session, firSymbol as FirClassSymbol, javaClass.name,
javaClass.visibility, javaClass.modality,
isExpect = false, isActual = false,
classKind = javaClass.classKind,
isInner = !javaClass.isStatic, isCompanion = false,
isData = false, isInline = false
javaClass.classKind, javaClass.isStatic
).apply {
for (typeParameter in javaClass.typeParameters) {
typeParameters += createTypeParameterSymbol(typeParameter.name).fir
@@ -0,0 +1,30 @@
/*
* 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.java.declarations
import com.intellij.psi.PsiElement
import org.jetbrains.kotlin.descriptors.ClassKind
import org.jetbrains.kotlin.descriptors.Modality
import org.jetbrains.kotlin.descriptors.Visibility
import org.jetbrains.kotlin.fir.FirSession
import org.jetbrains.kotlin.fir.declarations.impl.FirClassImpl
import org.jetbrains.kotlin.fir.symbols.impl.FirClassSymbol
import org.jetbrains.kotlin.name.Name
class FirJavaClass(
session: FirSession,
symbol: FirClassSymbol,
name: Name,
visibility: Visibility,
modality: Modality?,
classKind: ClassKind,
isStatic: Boolean
) : FirClassImpl(
session, psi = null, symbol = symbol, name = name,
visibility = visibility, modality = modality,
isExpect = false, isActual = false, classKind = classKind, isInner = !isStatic,
isCompanion = false, isData = false, isInline = false
)
@@ -0,0 +1,32 @@
/*
* 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.java.declarations
import org.jetbrains.kotlin.descriptors.Modality
import org.jetbrains.kotlin.descriptors.Visibility
import org.jetbrains.kotlin.fir.FirSession
import org.jetbrains.kotlin.fir.declarations.impl.FirMemberFunctionImpl
import org.jetbrains.kotlin.fir.java.types.FirJavaTypeRef
import org.jetbrains.kotlin.fir.symbols.impl.FirFunctionSymbol
import org.jetbrains.kotlin.fir.types.FirTypeRef
import org.jetbrains.kotlin.name.Name
class FirJavaMethod(
session: FirSession,
symbol: FirFunctionSymbol,
name: Name,
visibility: Visibility,
modality: Modality?,
returnTypeRef: FirJavaTypeRef
) : FirMemberFunctionImpl(
session, null, symbol, name,
visibility, modality,
false, isActual = false,
isOverride = false, // TODO: really it's unknown whether Java methods are overrides or not
isOperator = true, // All Java methods with name that allows to use it in operator form are considered operators
isInfix = false, isInline = false, isTailRec = false, isExternal = false, isSuspend = false,
receiverTypeRef = null, returnTypeRef = returnTypeRef
)
@@ -0,0 +1,21 @@
/*
* 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.java.declarations
import org.jetbrains.kotlin.fir.FirSession
import org.jetbrains.kotlin.fir.declarations.impl.FirValueParameterImpl
import org.jetbrains.kotlin.fir.java.types.FirJavaTypeRef
import org.jetbrains.kotlin.name.Name
class FirJavaValueParameter(
session: FirSession,
name: Name,
returnTypeRef: FirJavaTypeRef,
isVararg: Boolean
) : FirValueParameterImpl(
session, psi = null, name = name, returnTypeRef = returnTypeRef,
defaultValue = null, isCrossinline = false, isNoinline = false, isVararg = isVararg
)
@@ -0,0 +1,21 @@
/*
* 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.java.types
import org.jetbrains.kotlin.fir.FirSession
import org.jetbrains.kotlin.fir.expressions.FirAnnotationCall
import org.jetbrains.kotlin.fir.types.impl.FirUserTypeRefImpl
import org.jetbrains.kotlin.load.java.structure.JavaType
class FirJavaTypeRef(
session: FirSession,
annotations: List<FirAnnotationCall>,
val type: JavaType
) : FirUserTypeRefImpl(session, psi = null,isMarkedNullable = false) {
init {
this.annotations += annotations
}
}