New J2K: add support of method reference conversion

This commit is contained in:
Ilya Kirillov
2019-04-22 14:24:34 +03:00
parent 8f4f80256a
commit f11311a20b
12 changed files with 240 additions and 28 deletions
@@ -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)