New J2K: Add temporary conversion for println calls

This commit is contained in:
Simon Ogorodnik
2018-08-07 07:03:33 +03:00
committed by Ilya Kirillov
parent 911f234ba4
commit 800b09b183
3 changed files with 65 additions and 3 deletions
@@ -27,6 +27,7 @@ object ConversionsRunner {
DefaultArgumentsConversion(context),
TypeMappingConversion(context),
FieldToPropertyConversion(),
PrintlnConversion(context),
AssignmentAsExpressionToAlsoConversion(context),
AssignmentStatementValCreationConversion(context),
AssignmentStatementOperatorConversion(),
@@ -0,0 +1,45 @@
/*
* Copyright 2010-2018 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.j2k.conversions
import org.jetbrains.kotlin.j2k.ConversionContext
import org.jetbrains.kotlin.j2k.tree.*
import org.jetbrains.kotlin.j2k.tree.impl.JKKtCallExpressionImpl
import org.jetbrains.kotlin.j2k.tree.impl.JKMethodSymbol
import org.jetbrains.kotlin.name.ClassId
// TODO: Full special methods conversion
class PrintlnConversion(private val context: ConversionContext) : RecursiveApplicableConversionBase() {
override fun applyToElement(element: JKTreeElement): JKTreeElement {
return if (element is JKQualifiedExpression) {
recurse(processQualified(element))
} else {
recurse(element)
}
}
private fun processQualified(element: JKQualifiedExpression): JKExpression {
val receiver = element.receiver as? JKQualifiedExpression ?: return element
val classReference = receiver.receiver as? JKClassAccessExpression ?: return element
if (classReference.identifier.fqName != "java.lang.System") return element
val fieldReference = receiver.selector as? JKFieldAccessExpression ?: return element
if (fieldReference.identifier.name != "out") return element
val selector = element.selector as? JKMethodCallExpression ?: return element
if (selector.identifier.name != "println") return element
val contextElement = element.parentOfType<JKClass>() ?: return element
val targetElements = multiResolveFqName(ClassId.fromString("kotlin/io/println"), context.backAnnotator(contextElement)!!)
if (targetElements.isEmpty()) return element
selector.invalidate()
return JKKtCallExpressionImpl(
context.symbolProvider.provideDirectSymbol(targetElements.first()) as JKMethodSymbol,
selector.arguments
)
}
}
@@ -6,10 +6,12 @@
package org.jetbrains.kotlin.j2k.conversions
import com.intellij.psi.PsiElement
import com.intellij.psi.PsiPolyVariantReference
import org.jetbrains.kotlin.j2k.ConversionContext
import org.jetbrains.kotlin.j2k.tree.JKTreeElement
import org.jetbrains.kotlin.name.ClassId
import org.jetbrains.kotlin.psi.KtDotQualifiedExpression
import org.jetbrains.kotlin.psi.KtImportDirective
import org.jetbrains.kotlin.psi.KtPsiFactory
import org.jetbrains.kotlin.psi.analysisContext
import org.jetbrains.kotlin.psi.psiUtil.getChildOfType
@@ -22,11 +24,25 @@ internal fun resolveFqName(classId: ClassId, contextElement: JKTreeElement, cont
}
internal fun resolveFqName(classId: ClassId, element: PsiElement): PsiElement? {
val importDirective = KtPsiFactory(element).createImportDirective(ImportPath(classId.asSingleFqName(), false))
importDirective.containingKtFile.analysisContext = element.containingFile
return importDirective.getChildOfType<KtDotQualifiedExpression>()
return constructImportDirectiveWithContext(classId, element)
.getChildOfType<KtDotQualifiedExpression>()
?.selectorExpression
?.let {
it.references.mapNotNull { it.resolve() }.firstOrNull()
}
}
private fun constructImportDirectiveWithContext(classId: ClassId, element: PsiElement): KtImportDirective {
val importDirective = KtPsiFactory(element).createImportDirective(ImportPath(classId.asSingleFqName(), false))
importDirective.containingKtFile.analysisContext = element.containingFile
return importDirective
}
internal fun multiResolveFqName(classId: ClassId, elementForContext: PsiElement): List<PsiElement> {
return constructImportDirectiveWithContext(classId, elementForContext)
.getChildOfType<KtDotQualifiedExpression>()
?.selectorExpression
?.let {
it.references.filterIsInstance<PsiPolyVariantReference>().flatMap { it.multiResolve(false).mapNotNull { it.element } }
}.orEmpty()
}