New J2K: add support of method reference conversion
This commit is contained in:
@@ -68,10 +68,8 @@ object ConversionsRunner {
|
||||
+LabeledStatementConversion()
|
||||
+TypeParametersNullabilityConversion()
|
||||
+ArrayOperationsConversion(context)
|
||||
+BuiltinMembersConversion(context)
|
||||
+EqualsOperatorConversion(context)
|
||||
+TypeMappingConversion(context)
|
||||
+ImplicitCastsConversion(context)
|
||||
+InternalDeclarationConversion(context)
|
||||
|
||||
//Kotlin --> Kotlin conversions
|
||||
@@ -80,6 +78,10 @@ object ConversionsRunner {
|
||||
+StaticsToCompanionExtractConversion()
|
||||
+InterfaceWithFieldConversion()
|
||||
+ClassToObjectPromotionConversion(context)
|
||||
+MethodReferenceToLambdaConversion(context)
|
||||
+BuiltinMembersConversion(context)
|
||||
+ImplicitCastsConversion(context)
|
||||
|
||||
+CollectImportsConversion(context)
|
||||
+SortClassMembersConversion()
|
||||
+AddElementsInfoConversion(context)
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
|
||||
package org.jetbrains.kotlin.nj2k
|
||||
|
||||
import com.intellij.codeInsight.daemon.impl.quickfix.AddTypeArgumentsFix
|
||||
import com.intellij.lang.jvm.JvmAnnotatedElement
|
||||
import com.intellij.lang.jvm.JvmModifier
|
||||
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.PsiLiteralExpressionImpl
|
||||
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.search.searches.ReferencesSearch
|
||||
import com.intellij.psi.tree.IElementType
|
||||
import com.intellij.psi.util.InheritanceUtil
|
||||
import com.intellij.psi.util.PsiTreeUtil
|
||||
import com.intellij.psi.util.PsiUtil
|
||||
import org.jetbrains.kotlin.asJava.classes.KtLightClassForFacade
|
||||
import org.jetbrains.kotlin.asJava.elements.KtLightField
|
||||
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.psiUtil.getStrictParentOfType
|
||||
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.safeAs
|
||||
|
||||
@@ -265,21 +264,32 @@ class JavaToJKTreeBuilder constructor(
|
||||
else -> JKBlockStatementImpl(JKBodyStubImpl)
|
||||
}
|
||||
},
|
||||
with(declarationMapper) { parameterList.parameters.map { it.toJK() } }
|
||||
with(declarationMapper) { parameterList.parameters.map { it.toJK() } },
|
||||
functionalType()
|
||||
).also {
|
||||
it.assignNonCodeElements(this)
|
||||
}
|
||||
}
|
||||
|
||||
private fun JKExpression.qualified(qualifier: JKExpression?) =
|
||||
if (qualifier != null && qualifier !is JKStubExpression) {
|
||||
JKQualifiedExpressionImpl(qualifier, JKJavaQualifierImpl.DOT, this)
|
||||
} else this
|
||||
private fun PsiMethodCallExpression.getExplicitTypeArguments(): PsiReferenceParameterList {
|
||||
if (typeArguments.isNotEmpty()) return typeArgumentList
|
||||
|
||||
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
|
||||
fun PsiMethodCallExpression.toJK(): JKExpression {
|
||||
val arguments = argumentList
|
||||
val typeArguments = typeArgumentList.toJK()
|
||||
val typeArguments = getExplicitTypeArguments().toJK()
|
||||
val qualifier = methodExpression.qualifierExpression?.toJK()
|
||||
val target = methodExpression.resolve()
|
||||
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 {
|
||||
if (this is PsiMethodReferenceExpression) return toJK()
|
||||
val target = resolve()
|
||||
if (target is KtLightClassForFacade
|
||||
|| target is KtLightClassForDecompiledDeclaration
|
||||
|
||||
@@ -702,7 +702,7 @@ class NewCodeBuilder(context: NewJ2kConverterContext) {
|
||||
}
|
||||
renderClassSymbol(javaNewExpression.classSymbol, javaNewExpression)
|
||||
javaNewExpression.typeArgumentList.accept(this)
|
||||
if (!javaNewExpression.classSymbol.isInterface()) {
|
||||
if (!javaNewExpression.classSymbol.isInterface() || javaNewExpression.arguments.arguments.isNotEmpty()) {
|
||||
printer.par(ROUND) {
|
||||
javaNewExpression.arguments.accept(this)
|
||||
}
|
||||
@@ -775,6 +775,18 @@ class NewCodeBuilder(context: NewJ2kConverterContext) {
|
||||
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) {
|
||||
delegationConstructorCall.expression.accept(this)
|
||||
printer.par {
|
||||
@@ -839,24 +851,35 @@ class NewCodeBuilder(context: NewJ2kConverterContext) {
|
||||
}
|
||||
|
||||
override fun visitLambdaExpressionRaw(lambdaExpression: JKLambdaExpression) {
|
||||
printer.par(CURVED) {
|
||||
if (lambdaExpression.statement.statements.size > 1)
|
||||
printer.println()
|
||||
lambdaExpression.parameters.firstOrNull()?.accept(this)
|
||||
lambdaExpression.parameters.asSequence().drop(1).forEach { printer.printWithNoIndent(", "); it.accept(this) }
|
||||
if (lambdaExpression.parameters.isNotEmpty()) {
|
||||
printer.printWithNoIndent(" -> ")
|
||||
}
|
||||
val printLambda = {
|
||||
printer.par(CURVED) {
|
||||
if (lambdaExpression.statement.statements.size > 1)
|
||||
printer.println()
|
||||
lambdaExpression.parameters.firstOrNull()?.accept(this)
|
||||
lambdaExpression.parameters.asSequence().drop(1).forEach { printer.printWithNoIndent(", "); it.accept(this) }
|
||||
if (lambdaExpression.parameters.isNotEmpty()) {
|
||||
printer.printWithNoIndent(" -> ")
|
||||
}
|
||||
|
||||
val statement = lambdaExpression.statement
|
||||
if (statement is JKBlockStatement) {
|
||||
renderList(statement.block.statements, { printer.println() }) { it.accept(this) }
|
||||
} else {
|
||||
statement.accept(this)
|
||||
val statement = lambdaExpression.statement
|
||||
if (statement is JKBlockStatement) {
|
||||
renderList(statement.block.statements, { printer.println() }) { it.accept(this) }
|
||||
} else {
|
||||
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) {
|
||||
|
||||
@@ -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 =
|
||||
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(
|
||||
statement: JKStatement,
|
||||
parameters: List<JKParameter>,
|
||||
functionalType: JKTypeElement = JKTypeElementImpl(JKNoTypeImpl),
|
||||
returnType: JKTypeElement = JKTypeElementImpl(JKContextType)//TODO use function type
|
||||
) : JKLambdaExpression, JKBranchElementBase(), PsiOwner by PsiOwnerImpl() {
|
||||
override var statement by child(statement)
|
||||
override val returnType by child(returnType)
|
||||
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)
|
||||
}
|
||||
|
||||
@@ -634,4 +637,17 @@ class JKVisibilityModifierElementImpl(override var visibility: Visibility) : JKV
|
||||
|
||||
class JKExtraModifierElementImpl(override var extraModifier: ExtraModifier) : JKExtraModifierElement() {
|
||||
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 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>? {
|
||||
val realParameterTypes = parameterTypes ?: return null
|
||||
if (realParameterTypes.isEmpty()) return emptySequence()
|
||||
|
||||
@@ -291,6 +291,13 @@ interface JKNameIdentifier : JKIdentifier {
|
||||
|
||||
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 val expression: JKExpression
|
||||
}
|
||||
@@ -455,6 +462,7 @@ interface JKLambdaExpression : JKExpression {
|
||||
var parameters: List<JKParameter>
|
||||
val returnType: JKTypeElement
|
||||
var statement: JKStatement
|
||||
val functionalType: JKTypeElement
|
||||
}
|
||||
|
||||
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.js.descriptorUtils.getJetTypeFqName
|
||||
import org.jetbrains.kotlin.name.ClassId
|
||||
import org.jetbrains.kotlin.nj2k.NewJ2kConverterContext
|
||||
import org.jetbrains.kotlin.nj2k.JKSymbolProvider
|
||||
import org.jetbrains.kotlin.nj2k.NewJ2kConverterContext
|
||||
import org.jetbrains.kotlin.nj2k.kotlinTypeByName
|
||||
import org.jetbrains.kotlin.nj2k.tree.impl.*
|
||||
import org.jetbrains.kotlin.psi.KtClass
|
||||
@@ -68,6 +68,7 @@ fun JKExpression.type(symbolProvider: JKSymbolProvider): JKType? =
|
||||
is JKLambdaExpression -> returnType.type
|
||||
is JKLabeledStatement ->
|
||||
statement.safeAs<JKExpressionStatement>()?.expression?.type(symbolProvider)
|
||||
is JKMethodReferenceExpression -> JKNoTypeImpl //TODO
|
||||
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 visitNameIdentifier(nameIdentifier: JKNameIdentifier, data: D): R = visitIdentifier(nameIdentifier, 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 visitDeclarationStatement(declarationStatement: JKDeclarationStatement, data: D): R = visitStatement(declarationStatement, 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)
|
||||
fun visitExpression(expression: JKExpression) = visitTreeElement(expression, null)
|
||||
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)
|
||||
override fun visitExpressionStatement(expressionStatement: JKExpressionStatement, data: Nothing?) = visitExpressionStatement(expressionStatement)
|
||||
fun visitDeclarationStatement(declarationStatement: JKDeclarationStatement) = visitStatement(declarationStatement, null)
|
||||
|
||||
@@ -278,6 +278,14 @@ interface JKVisitorWithCommentsPrinting : JKVisitorVoid {
|
||||
|
||||
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) {
|
||||
printLeftNonCodeElements(expressionStatement)
|
||||
visitExpressionStatementRaw(expressionStatement)
|
||||
|
||||
Reference in New Issue
Block a user