New J2K: add support of method reference conversion
This commit is contained in:
@@ -68,10 +68,8 @@ object ConversionsRunner {
|
|||||||
+LabeledStatementConversion()
|
+LabeledStatementConversion()
|
||||||
+TypeParametersNullabilityConversion()
|
+TypeParametersNullabilityConversion()
|
||||||
+ArrayOperationsConversion(context)
|
+ArrayOperationsConversion(context)
|
||||||
+BuiltinMembersConversion(context)
|
|
||||||
+EqualsOperatorConversion(context)
|
+EqualsOperatorConversion(context)
|
||||||
+TypeMappingConversion(context)
|
+TypeMappingConversion(context)
|
||||||
+ImplicitCastsConversion(context)
|
|
||||||
+InternalDeclarationConversion(context)
|
+InternalDeclarationConversion(context)
|
||||||
|
|
||||||
//Kotlin --> Kotlin conversions
|
//Kotlin --> Kotlin conversions
|
||||||
@@ -80,6 +78,10 @@ object ConversionsRunner {
|
|||||||
+StaticsToCompanionExtractConversion()
|
+StaticsToCompanionExtractConversion()
|
||||||
+InterfaceWithFieldConversion()
|
+InterfaceWithFieldConversion()
|
||||||
+ClassToObjectPromotionConversion(context)
|
+ClassToObjectPromotionConversion(context)
|
||||||
|
+MethodReferenceToLambdaConversion(context)
|
||||||
|
+BuiltinMembersConversion(context)
|
||||||
|
+ImplicitCastsConversion(context)
|
||||||
|
|
||||||
+CollectImportsConversion(context)
|
+CollectImportsConversion(context)
|
||||||
+SortClassMembersConversion()
|
+SortClassMembersConversion()
|
||||||
+AddElementsInfoConversion(context)
|
+AddElementsInfoConversion(context)
|
||||||
|
|||||||
@@ -16,6 +16,7 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.nj2k
|
package org.jetbrains.kotlin.nj2k
|
||||||
|
|
||||||
|
import com.intellij.codeInsight.daemon.impl.quickfix.AddTypeArgumentsFix
|
||||||
import com.intellij.lang.jvm.JvmAnnotatedElement
|
import com.intellij.lang.jvm.JvmAnnotatedElement
|
||||||
import com.intellij.lang.jvm.JvmModifier
|
import com.intellij.lang.jvm.JvmModifier
|
||||||
import com.intellij.psi.*
|
import com.intellij.psi.*
|
||||||
@@ -27,12 +28,11 @@ import com.intellij.psi.impl.source.tree.java.PsiClassObjectAccessExpressionImpl
|
|||||||
import com.intellij.psi.impl.source.tree.java.PsiLabeledStatementImpl
|
import com.intellij.psi.impl.source.tree.java.PsiLabeledStatementImpl
|
||||||
import com.intellij.psi.impl.source.tree.java.PsiLiteralExpressionImpl
|
import com.intellij.psi.impl.source.tree.java.PsiLiteralExpressionImpl
|
||||||
import com.intellij.psi.impl.source.tree.java.PsiNewExpressionImpl
|
import com.intellij.psi.impl.source.tree.java.PsiNewExpressionImpl
|
||||||
|
import com.intellij.psi.infos.MethodCandidateInfo
|
||||||
import com.intellij.psi.javadoc.PsiDocComment
|
import com.intellij.psi.javadoc.PsiDocComment
|
||||||
import com.intellij.psi.search.searches.ReferencesSearch
|
import com.intellij.psi.search.searches.ReferencesSearch
|
||||||
import com.intellij.psi.tree.IElementType
|
import com.intellij.psi.tree.IElementType
|
||||||
import com.intellij.psi.util.InheritanceUtil
|
|
||||||
import com.intellij.psi.util.PsiTreeUtil
|
import com.intellij.psi.util.PsiTreeUtil
|
||||||
import com.intellij.psi.util.PsiUtil
|
|
||||||
import org.jetbrains.kotlin.asJava.classes.KtLightClassForFacade
|
import org.jetbrains.kotlin.asJava.classes.KtLightClassForFacade
|
||||||
import org.jetbrains.kotlin.asJava.elements.KtLightField
|
import org.jetbrains.kotlin.asJava.elements.KtLightField
|
||||||
import org.jetbrains.kotlin.asJava.elements.KtLightMethod
|
import org.jetbrains.kotlin.asJava.elements.KtLightMethod
|
||||||
@@ -49,7 +49,6 @@ import org.jetbrains.kotlin.nj2k.tree.impl.*
|
|||||||
import org.jetbrains.kotlin.psi.*
|
import org.jetbrains.kotlin.psi.*
|
||||||
import org.jetbrains.kotlin.psi.psiUtil.getStrictParentOfType
|
import org.jetbrains.kotlin.psi.psiUtil.getStrictParentOfType
|
||||||
import org.jetbrains.kotlin.psi.psiUtil.isExtensionDeclaration
|
import org.jetbrains.kotlin.psi.psiUtil.isExtensionDeclaration
|
||||||
import org.jetbrains.kotlin.psi.psiUtil.parentsWithSelf
|
|
||||||
import org.jetbrains.kotlin.utils.addToStdlib.cast
|
import org.jetbrains.kotlin.utils.addToStdlib.cast
|
||||||
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
|
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
|
||||||
|
|
||||||
@@ -265,21 +264,32 @@ class JavaToJKTreeBuilder constructor(
|
|||||||
else -> JKBlockStatementImpl(JKBodyStubImpl)
|
else -> JKBlockStatementImpl(JKBodyStubImpl)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
with(declarationMapper) { parameterList.parameters.map { it.toJK() } }
|
with(declarationMapper) { parameterList.parameters.map { it.toJK() } },
|
||||||
|
functionalType()
|
||||||
).also {
|
).also {
|
||||||
it.assignNonCodeElements(this)
|
it.assignNonCodeElements(this)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun JKExpression.qualified(qualifier: JKExpression?) =
|
private fun PsiMethodCallExpression.getExplicitTypeArguments(): PsiReferenceParameterList {
|
||||||
if (qualifier != null && qualifier !is JKStubExpression) {
|
if (typeArguments.isNotEmpty()) return typeArgumentList
|
||||||
JKQualifiedExpressionImpl(qualifier, JKJavaQualifierImpl.DOT, this)
|
|
||||||
} else this
|
val resolveResult = resolveMethodGenerics()
|
||||||
|
if (resolveResult is MethodCandidateInfo && resolveResult.isApplicable) {
|
||||||
|
val method = resolveResult.element
|
||||||
|
if (method.isConstructor || !method.hasTypeParameters()) return typeArgumentList
|
||||||
|
}
|
||||||
|
|
||||||
|
return AddTypeArgumentsFix.addTypeArguments(this, null)
|
||||||
|
?.safeAs<PsiMethodCallExpression>()
|
||||||
|
?.typeArgumentList
|
||||||
|
?: typeArgumentList
|
||||||
|
}
|
||||||
|
|
||||||
//TODO mostly copied from old j2k, refactor
|
//TODO mostly copied from old j2k, refactor
|
||||||
fun PsiMethodCallExpression.toJK(): JKExpression {
|
fun PsiMethodCallExpression.toJK(): JKExpression {
|
||||||
val arguments = argumentList
|
val arguments = argumentList
|
||||||
val typeArguments = typeArgumentList.toJK()
|
val typeArguments = getExplicitTypeArguments().toJK()
|
||||||
val qualifier = methodExpression.qualifierExpression?.toJK()
|
val qualifier = methodExpression.qualifierExpression?.toJK()
|
||||||
val target = methodExpression.resolve()
|
val target = methodExpression.resolve()
|
||||||
val symbol = target?.let {
|
val symbol = target?.let {
|
||||||
@@ -367,7 +377,30 @@ class JavaToJKTreeBuilder constructor(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun PsiFunctionalExpression.functionalType(): JKTypeElement =
|
||||||
|
functionalInterfaceType?.toJK(symbolProvider)?.takeIf { type ->
|
||||||
|
type.safeAs<JKClassType>()?.classReference is JKMultiverseClassSymbol
|
||||||
|
}?.asTypeElement() ?: JKTypeElementImpl(JKNoTypeImpl)
|
||||||
|
|
||||||
|
fun PsiMethodReferenceExpression.toJK(): JKMethodReferenceExpression {
|
||||||
|
val symbol = symbolProvider.provideSymbol<JKNamedSymbol>(this).let { symbol ->
|
||||||
|
when {
|
||||||
|
symbol.isUnresolved() && isConstructor -> JKUnresolvedClassSymbol(qualifier?.text ?: text)
|
||||||
|
symbol.isUnresolved() && !isConstructor -> JKUnresolvedMethod(referenceName ?: text)
|
||||||
|
else -> symbol
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return JKMethodReferenceExpressionImpl(
|
||||||
|
qualifierExpression?.toJK() ?: JKStubExpressionImpl(),
|
||||||
|
symbol,
|
||||||
|
functionalType(),
|
||||||
|
isConstructor
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
fun PsiReferenceExpression.toJK(): JKExpression {
|
fun PsiReferenceExpression.toJK(): JKExpression {
|
||||||
|
if (this is PsiMethodReferenceExpression) return toJK()
|
||||||
val target = resolve()
|
val target = resolve()
|
||||||
if (target is KtLightClassForFacade
|
if (target is KtLightClassForFacade
|
||||||
|| target is KtLightClassForDecompiledDeclaration
|
|| target is KtLightClassForDecompiledDeclaration
|
||||||
|
|||||||
@@ -702,7 +702,7 @@ class NewCodeBuilder(context: NewJ2kConverterContext) {
|
|||||||
}
|
}
|
||||||
renderClassSymbol(javaNewExpression.classSymbol, javaNewExpression)
|
renderClassSymbol(javaNewExpression.classSymbol, javaNewExpression)
|
||||||
javaNewExpression.typeArgumentList.accept(this)
|
javaNewExpression.typeArgumentList.accept(this)
|
||||||
if (!javaNewExpression.classSymbol.isInterface()) {
|
if (!javaNewExpression.classSymbol.isInterface() || javaNewExpression.arguments.arguments.isNotEmpty()) {
|
||||||
printer.par(ROUND) {
|
printer.par(ROUND) {
|
||||||
javaNewExpression.arguments.accept(this)
|
javaNewExpression.arguments.accept(this)
|
||||||
}
|
}
|
||||||
@@ -775,6 +775,18 @@ class NewCodeBuilder(context: NewJ2kConverterContext) {
|
|||||||
printer.printWithNoIndent(packageAccessExpression.identifier.name.escaped())
|
printer.printWithNoIndent(packageAccessExpression.identifier.name.escaped())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun visitMethodReferenceExpressionRaw(methodReferenceExpression: JKMethodReferenceExpression) {
|
||||||
|
methodReferenceExpression.qualifier.accept(this)
|
||||||
|
printer.printWithNoIndent("::")
|
||||||
|
val needFqName = methodReferenceExpression.qualifier is JKStubExpression
|
||||||
|
val displayName =
|
||||||
|
if (needFqName) methodReferenceExpression.identifier.getDisplayName()
|
||||||
|
else methodReferenceExpression.identifier.name
|
||||||
|
|
||||||
|
printer.printWithNoIndent(displayName.escapedAsQualifiedName())
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
override fun visitDelegationConstructorCallRaw(delegationConstructorCall: JKDelegationConstructorCall) {
|
override fun visitDelegationConstructorCallRaw(delegationConstructorCall: JKDelegationConstructorCall) {
|
||||||
delegationConstructorCall.expression.accept(this)
|
delegationConstructorCall.expression.accept(this)
|
||||||
printer.par {
|
printer.par {
|
||||||
@@ -839,24 +851,35 @@ class NewCodeBuilder(context: NewJ2kConverterContext) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun visitLambdaExpressionRaw(lambdaExpression: JKLambdaExpression) {
|
override fun visitLambdaExpressionRaw(lambdaExpression: JKLambdaExpression) {
|
||||||
printer.par(CURVED) {
|
val printLambda = {
|
||||||
if (lambdaExpression.statement.statements.size > 1)
|
printer.par(CURVED) {
|
||||||
printer.println()
|
if (lambdaExpression.statement.statements.size > 1)
|
||||||
lambdaExpression.parameters.firstOrNull()?.accept(this)
|
printer.println()
|
||||||
lambdaExpression.parameters.asSequence().drop(1).forEach { printer.printWithNoIndent(", "); it.accept(this) }
|
lambdaExpression.parameters.firstOrNull()?.accept(this)
|
||||||
if (lambdaExpression.parameters.isNotEmpty()) {
|
lambdaExpression.parameters.asSequence().drop(1).forEach { printer.printWithNoIndent(", "); it.accept(this) }
|
||||||
printer.printWithNoIndent(" -> ")
|
if (lambdaExpression.parameters.isNotEmpty()) {
|
||||||
}
|
printer.printWithNoIndent(" -> ")
|
||||||
|
}
|
||||||
|
|
||||||
val statement = lambdaExpression.statement
|
val statement = lambdaExpression.statement
|
||||||
if (statement is JKBlockStatement) {
|
if (statement is JKBlockStatement) {
|
||||||
renderList(statement.block.statements, { printer.println() }) { it.accept(this) }
|
renderList(statement.block.statements, { printer.println() }) { it.accept(this) }
|
||||||
} else {
|
} else {
|
||||||
statement.accept(this)
|
statement.accept(this)
|
||||||
|
}
|
||||||
|
if (lambdaExpression.statement.statements.size > 1)
|
||||||
|
printer.println()
|
||||||
}
|
}
|
||||||
if (lambdaExpression.statement.statements.size > 1)
|
|
||||||
printer.println()
|
|
||||||
}
|
}
|
||||||
|
if (lambdaExpression.functionalType.present()) {
|
||||||
|
renderType(lambdaExpression.functionalType.type, lambdaExpression)
|
||||||
|
printer.printWithNoIndent(" ")
|
||||||
|
printer.par(ROUND, printLambda)
|
||||||
|
} else {
|
||||||
|
printLambda()
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun visitBlockStatementRaw(blockStatement: JKBlockStatement) {
|
override fun visitBlockStatementRaw(blockStatement: JKBlockStatement) {
|
||||||
|
|||||||
@@ -0,0 +1,88 @@
|
|||||||
|
/*
|
||||||
|
* 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.nj2k.conversions
|
||||||
|
|
||||||
|
import org.jetbrains.kotlin.nj2k.NewJ2kConverterContext
|
||||||
|
import org.jetbrains.kotlin.nj2k.nullIfStubExpression
|
||||||
|
import org.jetbrains.kotlin.nj2k.qualified
|
||||||
|
import org.jetbrains.kotlin.nj2k.tree.*
|
||||||
|
import org.jetbrains.kotlin.nj2k.tree.impl.*
|
||||||
|
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
|
||||||
|
|
||||||
|
|
||||||
|
class MethodReferenceToLambdaConversion(private val context: NewJ2kConverterContext) : RecursiveApplicableConversionBase() {
|
||||||
|
override fun applyToElement(element: JKTreeElement): JKTreeElement {
|
||||||
|
if (element !is JKMethodReferenceExpression) return recurse(element)
|
||||||
|
val symbol = element.identifier
|
||||||
|
|
||||||
|
val parameters =
|
||||||
|
if (symbol is JKMethodSymbol) {
|
||||||
|
(symbol.parameterNames ?: return recurse(element)).zip(
|
||||||
|
symbol.parameterTypes ?: return recurse(element)
|
||||||
|
) { name, type ->
|
||||||
|
JKParameterImpl(
|
||||||
|
JKTypeElementImpl(type),
|
||||||
|
JKNameIdentifierImpl(name),
|
||||||
|
isVarArgs = false
|
||||||
|
)
|
||||||
|
}
|
||||||
|
} else emptyList()
|
||||||
|
|
||||||
|
val receiverParameter = element.qualifier
|
||||||
|
.nullIfStubExpression()
|
||||||
|
?.safeAs<JKClassAccessExpression>()
|
||||||
|
?.takeIf { symbol.safeAs<JKMethodSymbol>()?.isStatic == false && !element.isConstructorCall }
|
||||||
|
?.let { classAccessExpression ->
|
||||||
|
JKParameterImpl(
|
||||||
|
JKTypeElementImpl(JKClassTypeImpl(classAccessExpression.identifier)),
|
||||||
|
JKNameIdentifierImpl(RECEIVER_NAME),
|
||||||
|
isVarArgs = false
|
||||||
|
)
|
||||||
|
}
|
||||||
|
val arguments = parameters.map { parameter ->
|
||||||
|
val parameterSymbol = context.symbolProvider.provideUniverseSymbol(parameter)
|
||||||
|
JKArgumentImpl(JKFieldAccessExpressionImpl(parameterSymbol))
|
||||||
|
}
|
||||||
|
val callExpression =
|
||||||
|
when (symbol) {
|
||||||
|
is JKMethodSymbol ->
|
||||||
|
JKKtCallExpressionImpl(
|
||||||
|
symbol,
|
||||||
|
JKArgumentListImpl(arguments)
|
||||||
|
)
|
||||||
|
is JKClassSymbol -> JKJavaNewExpressionImpl(symbol, JKArgumentListImpl(), JKTypeArgumentListImpl())
|
||||||
|
is JKUnresolvedSymbol -> return recurse(element)
|
||||||
|
else -> error("Symbol should be either method symbol or class symbol, but it is ${symbol::class}")
|
||||||
|
}
|
||||||
|
val qualifier = when {
|
||||||
|
receiverParameter != null ->
|
||||||
|
JKFieldAccessExpressionImpl(context.symbolProvider.provideUniverseSymbol(receiverParameter))
|
||||||
|
element.isConstructorCall -> element.qualifier.safeAs<JKQualifiedExpression>()?.let { it::receiver.detached() }
|
||||||
|
else -> element::qualifier.detached().nullIfStubExpression()
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
val lambda = JKLambdaExpressionImpl(
|
||||||
|
JKExpressionStatementImpl(callExpression.qualified(qualifier)),
|
||||||
|
listOfNotNull(receiverParameter) + parameters,
|
||||||
|
element::functionalType.detached(),
|
||||||
|
JKTypeElementImpl(
|
||||||
|
when (symbol) {
|
||||||
|
is JKMethodSymbol -> symbol.returnType ?: JKNoTypeImpl
|
||||||
|
is JKClassSymbol -> JKClassTypeImpl(symbol)
|
||||||
|
is JKUnresolvedSymbol -> return recurse(element)
|
||||||
|
else -> error("Symbol should be either method symbol or class symbol, but it is ${symbol::class}")
|
||||||
|
}
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
return recurse(lambda)
|
||||||
|
}
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
private const val RECEIVER_NAME = "obj" //name taken from old j2k
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -597,3 +597,11 @@ fun JKAnnotation.isVarargsArgument(index: Int): Boolean {
|
|||||||
fun JKExpression.asStatement(): JKExpressionStatement =
|
fun JKExpression.asStatement(): JKExpressionStatement =
|
||||||
JKExpressionStatementImpl(this)
|
JKExpressionStatementImpl(this)
|
||||||
|
|
||||||
|
inline fun <T : JKExpression> T.nullIfStubExpression(): T? =
|
||||||
|
if (this is JKStubExpression) null
|
||||||
|
else this
|
||||||
|
|
||||||
|
inline fun JKExpression.qualified(qualifier: JKExpression?) =
|
||||||
|
if (qualifier != null && qualifier !is JKStubExpression) {
|
||||||
|
JKQualifiedExpressionImpl(qualifier, JKJavaQualifierImpl.DOT, this)
|
||||||
|
} else this
|
||||||
@@ -391,11 +391,14 @@ class JKClassAccessExpressionImpl(override var identifier: JKClassSymbol) : JKCl
|
|||||||
class JKLambdaExpressionImpl(
|
class JKLambdaExpressionImpl(
|
||||||
statement: JKStatement,
|
statement: JKStatement,
|
||||||
parameters: List<JKParameter>,
|
parameters: List<JKParameter>,
|
||||||
|
functionalType: JKTypeElement = JKTypeElementImpl(JKNoTypeImpl),
|
||||||
returnType: JKTypeElement = JKTypeElementImpl(JKContextType)//TODO use function type
|
returnType: JKTypeElement = JKTypeElementImpl(JKContextType)//TODO use function type
|
||||||
) : JKLambdaExpression, JKBranchElementBase(), PsiOwner by PsiOwnerImpl() {
|
) : JKLambdaExpression, JKBranchElementBase(), PsiOwner by PsiOwnerImpl() {
|
||||||
override var statement by child(statement)
|
override var statement by child(statement)
|
||||||
override val returnType by child(returnType)
|
override val returnType by child(returnType)
|
||||||
override var parameters by children(parameters)
|
override var parameters by children(parameters)
|
||||||
|
override var functionalType by child(functionalType)
|
||||||
|
|
||||||
override fun <R, D> accept(visitor: JKVisitor<R, D>, data: D): R = visitor.visitLambdaExpression(this, data)
|
override fun <R, D> accept(visitor: JKVisitor<R, D>, data: D): R = visitor.visitLambdaExpression(this, data)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -635,3 +638,16 @@ class JKVisibilityModifierElementImpl(override var visibility: Visibility) : JKV
|
|||||||
class JKExtraModifierElementImpl(override var extraModifier: ExtraModifier) : JKExtraModifierElement() {
|
class JKExtraModifierElementImpl(override var extraModifier: ExtraModifier) : JKExtraModifierElement() {
|
||||||
override fun <R, D> accept(visitor: JKVisitor<R, D>, data: D): R = visitor.visitExtraModifierElement(this, data)
|
override fun <R, D> accept(visitor: JKVisitor<R, D>, data: D): R = visitor.visitExtraModifierElement(this, data)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class JKMethodReferenceExpressionImpl(
|
||||||
|
qualifier: JKExpression,
|
||||||
|
override val identifier: JKNamedSymbol,
|
||||||
|
functionalType: JKTypeElement,
|
||||||
|
override val isConstructorCall: Boolean
|
||||||
|
) : JKMethodReferenceExpression, JKBranchElementBase(), PsiOwner by PsiOwnerImpl() {
|
||||||
|
override val qualifier by child(qualifier)
|
||||||
|
override val functionalType by child(functionalType)
|
||||||
|
|
||||||
|
|
||||||
|
override fun <R, D> accept(visitor: JKVisitor<R, D>, data: D): R = visitor.visitMethodReferenceExpression(this, data)
|
||||||
|
}
|
||||||
@@ -76,6 +76,28 @@ interface JKMethodSymbol : JKNamedSymbol {
|
|||||||
val returnType: JKType?
|
val returnType: JKType?
|
||||||
}
|
}
|
||||||
|
|
||||||
|
val JKMethodSymbol.parameterNames: List<String>?
|
||||||
|
get() {
|
||||||
|
return when (this) {
|
||||||
|
is JKMultiverseFunctionSymbol -> target.valueParameters.map { it.name ?: return null }
|
||||||
|
is JKMultiverseMethodSymbol -> target.parameters.map { it.name ?: return null }
|
||||||
|
is JKUniverseMethodSymbol -> target.parameters.map { it.name.value }
|
||||||
|
is JKUnresolvedSymbol -> null
|
||||||
|
else -> null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
val JKMethodSymbol.isStatic: Boolean
|
||||||
|
get() = when (this) {
|
||||||
|
is JKMultiverseFunctionSymbol -> target.parent is KtObjectDeclaration
|
||||||
|
is JKMultiverseMethodSymbol -> target.hasModifierProperty(PsiModifier.STATIC)
|
||||||
|
is JKUniverseMethodSymbol -> target.parent?.parent?.safeAs<JKClass>()?.classKind == JKClass.ClassKind.COMPANION
|
||||||
|
is JKUnresolvedSymbol -> false
|
||||||
|
else -> false
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
fun JKMethodSymbol.parameterTypesWithUnfoldedVarargs(): Sequence<JKType>? {
|
fun JKMethodSymbol.parameterTypesWithUnfoldedVarargs(): Sequence<JKType>? {
|
||||||
val realParameterTypes = parameterTypes ?: return null
|
val realParameterTypes = parameterTypes ?: return null
|
||||||
if (realParameterTypes.isEmpty()) return emptySequence()
|
if (realParameterTypes.isEmpty()) return emptySequence()
|
||||||
|
|||||||
@@ -291,6 +291,13 @@ interface JKNameIdentifier : JKIdentifier {
|
|||||||
|
|
||||||
interface JKExpression : JKTreeElement, JKAnnotationMemberValue
|
interface JKExpression : JKTreeElement, JKAnnotationMemberValue
|
||||||
|
|
||||||
|
interface JKMethodReferenceExpression : JKExpression, PsiOwner {
|
||||||
|
val qualifier: JKExpression
|
||||||
|
val identifier: JKNamedSymbol
|
||||||
|
val functionalType: JKTypeElement
|
||||||
|
val isConstructorCall: Boolean
|
||||||
|
}
|
||||||
|
|
||||||
abstract class JKExpressionStatement : JKStatement() {
|
abstract class JKExpressionStatement : JKStatement() {
|
||||||
abstract val expression: JKExpression
|
abstract val expression: JKExpression
|
||||||
}
|
}
|
||||||
@@ -455,6 +462,7 @@ interface JKLambdaExpression : JKExpression {
|
|||||||
var parameters: List<JKParameter>
|
var parameters: List<JKParameter>
|
||||||
val returnType: JKTypeElement
|
val returnType: JKTypeElement
|
||||||
var statement: JKStatement
|
var statement: JKStatement
|
||||||
|
val functionalType: JKTypeElement
|
||||||
}
|
}
|
||||||
|
|
||||||
interface JKDelegationConstructorCall : JKMethodCallExpression {
|
interface JKDelegationConstructorCall : JKMethodCallExpression {
|
||||||
|
|||||||
@@ -14,8 +14,8 @@ import org.jetbrains.kotlin.idea.caches.resolve.util.getJavaClassDescriptor
|
|||||||
import org.jetbrains.kotlin.j2k.ast.Nullability
|
import org.jetbrains.kotlin.j2k.ast.Nullability
|
||||||
import org.jetbrains.kotlin.js.descriptorUtils.getJetTypeFqName
|
import org.jetbrains.kotlin.js.descriptorUtils.getJetTypeFqName
|
||||||
import org.jetbrains.kotlin.name.ClassId
|
import org.jetbrains.kotlin.name.ClassId
|
||||||
import org.jetbrains.kotlin.nj2k.NewJ2kConverterContext
|
|
||||||
import org.jetbrains.kotlin.nj2k.JKSymbolProvider
|
import org.jetbrains.kotlin.nj2k.JKSymbolProvider
|
||||||
|
import org.jetbrains.kotlin.nj2k.NewJ2kConverterContext
|
||||||
import org.jetbrains.kotlin.nj2k.kotlinTypeByName
|
import org.jetbrains.kotlin.nj2k.kotlinTypeByName
|
||||||
import org.jetbrains.kotlin.nj2k.tree.impl.*
|
import org.jetbrains.kotlin.nj2k.tree.impl.*
|
||||||
import org.jetbrains.kotlin.psi.KtClass
|
import org.jetbrains.kotlin.psi.KtClass
|
||||||
@@ -68,6 +68,7 @@ fun JKExpression.type(symbolProvider: JKSymbolProvider): JKType? =
|
|||||||
is JKLambdaExpression -> returnType.type
|
is JKLambdaExpression -> returnType.type
|
||||||
is JKLabeledStatement ->
|
is JKLabeledStatement ->
|
||||||
statement.safeAs<JKExpressionStatement>()?.expression?.type(symbolProvider)
|
statement.safeAs<JKExpressionStatement>()?.expression?.type(symbolProvider)
|
||||||
|
is JKMethodReferenceExpression -> JKNoTypeImpl //TODO
|
||||||
else -> TODO(this::class.java.toString())
|
else -> TODO(this::class.java.toString())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -37,6 +37,7 @@ interface JKVisitor<out R, in D> {
|
|||||||
fun visitIdentifier(identifier: JKIdentifier, data: D): R = visitTreeElement(identifier, data)
|
fun visitIdentifier(identifier: JKIdentifier, data: D): R = visitTreeElement(identifier, data)
|
||||||
fun visitNameIdentifier(nameIdentifier: JKNameIdentifier, data: D): R = visitIdentifier(nameIdentifier, data)
|
fun visitNameIdentifier(nameIdentifier: JKNameIdentifier, data: D): R = visitIdentifier(nameIdentifier, data)
|
||||||
fun visitExpression(expression: JKExpression, data: D): R = visitTreeElement(expression, data)
|
fun visitExpression(expression: JKExpression, data: D): R = visitTreeElement(expression, data)
|
||||||
|
fun visitMethodReferenceExpression(methodReferenceExpression: JKMethodReferenceExpression, data: D): R = visitExpression(methodReferenceExpression, data)
|
||||||
fun visitExpressionStatement(expressionStatement: JKExpressionStatement, data: D): R = visitStatement(expressionStatement, data)
|
fun visitExpressionStatement(expressionStatement: JKExpressionStatement, data: D): R = visitStatement(expressionStatement, data)
|
||||||
fun visitDeclarationStatement(declarationStatement: JKDeclarationStatement, data: D): R = visitStatement(declarationStatement, data)
|
fun visitDeclarationStatement(declarationStatement: JKDeclarationStatement, data: D): R = visitStatement(declarationStatement, data)
|
||||||
fun visitOperatorExpression(operatorExpression: JKOperatorExpression, data: D): R = visitExpression(operatorExpression, data)
|
fun visitOperatorExpression(operatorExpression: JKOperatorExpression, data: D): R = visitExpression(operatorExpression, data)
|
||||||
|
|||||||
@@ -71,6 +71,8 @@ interface JKVisitorVoid : JKVisitor<Unit, Nothing?> {
|
|||||||
override fun visitNameIdentifier(nameIdentifier: JKNameIdentifier, data: Nothing?) = visitNameIdentifier(nameIdentifier)
|
override fun visitNameIdentifier(nameIdentifier: JKNameIdentifier, data: Nothing?) = visitNameIdentifier(nameIdentifier)
|
||||||
fun visitExpression(expression: JKExpression) = visitTreeElement(expression, null)
|
fun visitExpression(expression: JKExpression) = visitTreeElement(expression, null)
|
||||||
override fun visitExpression(expression: JKExpression, data: Nothing?) = visitExpression(expression)
|
override fun visitExpression(expression: JKExpression, data: Nothing?) = visitExpression(expression)
|
||||||
|
fun visitMethodReferenceExpression(methodReferenceExpression: JKMethodReferenceExpression) = visitExpression(methodReferenceExpression, null)
|
||||||
|
override fun visitMethodReferenceExpression(methodReferenceExpression: JKMethodReferenceExpression, data: Nothing?) = visitMethodReferenceExpression(methodReferenceExpression)
|
||||||
fun visitExpressionStatement(expressionStatement: JKExpressionStatement) = visitStatement(expressionStatement, null)
|
fun visitExpressionStatement(expressionStatement: JKExpressionStatement) = visitStatement(expressionStatement, null)
|
||||||
override fun visitExpressionStatement(expressionStatement: JKExpressionStatement, data: Nothing?) = visitExpressionStatement(expressionStatement)
|
override fun visitExpressionStatement(expressionStatement: JKExpressionStatement, data: Nothing?) = visitExpressionStatement(expressionStatement)
|
||||||
fun visitDeclarationStatement(declarationStatement: JKDeclarationStatement) = visitStatement(declarationStatement, null)
|
fun visitDeclarationStatement(declarationStatement: JKDeclarationStatement) = visitStatement(declarationStatement, null)
|
||||||
|
|||||||
@@ -278,6 +278,14 @@ interface JKVisitorWithCommentsPrinting : JKVisitorVoid {
|
|||||||
|
|
||||||
fun visitExpressionRaw(expression: JKExpression) = visitTreeElementRaw(expression)
|
fun visitExpressionRaw(expression: JKExpression) = visitTreeElementRaw(expression)
|
||||||
|
|
||||||
|
override fun visitMethodReferenceExpression(methodReferenceExpression: JKMethodReferenceExpression) {
|
||||||
|
printLeftNonCodeElements(methodReferenceExpression)
|
||||||
|
visitMethodReferenceExpressionRaw(methodReferenceExpression)
|
||||||
|
printRightNonCodeElements(methodReferenceExpression)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun visitMethodReferenceExpressionRaw(methodReferenceExpression: JKMethodReferenceExpression) = visitExpressionRaw(methodReferenceExpression)
|
||||||
|
|
||||||
override fun visitExpressionStatement(expressionStatement: JKExpressionStatement) {
|
override fun visitExpressionStatement(expressionStatement: JKExpressionStatement) {
|
||||||
printLeftNonCodeElements(expressionStatement)
|
printLeftNonCodeElements(expressionStatement)
|
||||||
visitExpressionStatementRaw(expressionStatement)
|
visitExpressionStatementRaw(expressionStatement)
|
||||||
|
|||||||
Reference in New Issue
Block a user