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), DefaultArgumentsConversion(context),
TypeMappingConversion(context), TypeMappingConversion(context),
FieldToPropertyConversion(), FieldToPropertyConversion(),
PrintlnConversion(context),
AssignmentAsExpressionToAlsoConversion(context), AssignmentAsExpressionToAlsoConversion(context),
AssignmentStatementValCreationConversion(context), AssignmentStatementValCreationConversion(context),
AssignmentStatementOperatorConversion(), 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 package org.jetbrains.kotlin.j2k.conversions
import com.intellij.psi.PsiElement import com.intellij.psi.PsiElement
import com.intellij.psi.PsiPolyVariantReference
import org.jetbrains.kotlin.j2k.ConversionContext import org.jetbrains.kotlin.j2k.ConversionContext
import org.jetbrains.kotlin.j2k.tree.JKTreeElement import org.jetbrains.kotlin.j2k.tree.JKTreeElement
import org.jetbrains.kotlin.name.ClassId import org.jetbrains.kotlin.name.ClassId
import org.jetbrains.kotlin.psi.KtDotQualifiedExpression import org.jetbrains.kotlin.psi.KtDotQualifiedExpression
import org.jetbrains.kotlin.psi.KtImportDirective
import org.jetbrains.kotlin.psi.KtPsiFactory import org.jetbrains.kotlin.psi.KtPsiFactory
import org.jetbrains.kotlin.psi.analysisContext import org.jetbrains.kotlin.psi.analysisContext
import org.jetbrains.kotlin.psi.psiUtil.getChildOfType 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? { internal fun resolveFqName(classId: ClassId, element: PsiElement): PsiElement? {
val importDirective = KtPsiFactory(element).createImportDirective(ImportPath(classId.asSingleFqName(), false)) return constructImportDirectiveWithContext(classId, element)
importDirective.containingKtFile.analysisContext = element.containingFile .getChildOfType<KtDotQualifiedExpression>()
return importDirective.getChildOfType<KtDotQualifiedExpression>()
?.selectorExpression ?.selectorExpression
?.let { ?.let {
it.references.mapNotNull { it.resolve() }.firstOrNull() 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()
} }