Java to Kotlin convertor: more code improvements
This commit is contained in:
@@ -21,8 +21,8 @@ import com.intellij.psi.PsiClass
|
||||
import com.intellij.psi.PsiReferenceExpression
|
||||
import com.intellij.psi.JavaRecursiveElementVisitor
|
||||
import java.util.LinkedHashSet
|
||||
import com.intellij.psi.PsiReference
|
||||
import com.intellij.psi.PsiElement
|
||||
import com.intellij.psi.PsiMethodCallExpression
|
||||
|
||||
fun PsiMethod.isPrimaryConstructor(): Boolean {
|
||||
if (!isConstructor()) return false
|
||||
@@ -64,12 +64,9 @@ fun PsiClass.getPrimaryConstructor(): PsiMethod? {
|
||||
}
|
||||
|
||||
fun isInsidePrimaryConstructor(element: PsiElement): Boolean
|
||||
= containingConstructor(element)?.isPrimaryConstructor() ?: false
|
||||
= getContainingConstructor(element)?.isPrimaryConstructor() ?: false
|
||||
|
||||
fun isInsideSecondaryConstructor(element: PsiElement): Boolean
|
||||
= !(containingConstructor(element)?.isPrimaryConstructor() ?: true)
|
||||
|
||||
fun containingConstructor(element: PsiElement): PsiMethod? {
|
||||
fun getContainingConstructor(element: PsiElement): PsiMethod? {
|
||||
var context = element.getContext()
|
||||
while (context != null) {
|
||||
val _context = context!!
|
||||
@@ -82,10 +79,14 @@ fun containingConstructor(element: PsiElement): PsiMethod? {
|
||||
return null
|
||||
}
|
||||
|
||||
fun isSuperConstructorRef(ref: PsiReference): Boolean {
|
||||
fun PsiMethodCallExpression.isSuperConstructorCall(): Boolean {
|
||||
val ref = getMethodExpression()
|
||||
if (ref.getCanonicalText().equals("super")) {
|
||||
val target = ref.resolve()
|
||||
return target is PsiMethod && target.isConstructor()
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
fun PsiReferenceExpression.isThisConstructorCall(): Boolean
|
||||
= getReferences().filter { it.getCanonicalText() == "this" }.map { it.resolve() }.any { it is PsiMethod && it.isConstructor() }
|
||||
|
||||
@@ -55,7 +55,7 @@ public class Converter(val project: Project, val settings: ConverterSettings) {
|
||||
is PsiJavaFile -> convertFile(element)
|
||||
is PsiClass -> convertClass(element)
|
||||
is PsiMethod -> convertMethod(element)
|
||||
is PsiField -> convertField(element, element.getContainingClass())
|
||||
is PsiField -> convertField(element)
|
||||
is PsiStatement -> convertStatement(element)
|
||||
is PsiExpression -> convertExpression(element)
|
||||
is PsiComment -> Comment(element.getText()!!)
|
||||
@@ -78,7 +78,7 @@ public class Converter(val project: Project, val settings: ConverterSettings) {
|
||||
private fun convertMembers(psiClass: PsiClass): List<Element> {
|
||||
val allChildren = psiClass.getChildren().toList()
|
||||
val lBraceIndex = allChildren.indexOf(psiClass.getLBrace())
|
||||
return allChildren.subList(lBraceIndex, allChildren.size).map { convertMember(it, psiClass) }.filterNotNull()
|
||||
return allChildren.subList(lBraceIndex, allChildren.size).map { convertMember(it) }.filterNotNull()
|
||||
}
|
||||
|
||||
private fun getComments(member: PsiMember): MemberComments {
|
||||
@@ -93,9 +93,9 @@ public class Converter(val project: Project, val settings: ConverterSettings) {
|
||||
return MemberComments(whiteSpacesAndComments)
|
||||
}
|
||||
|
||||
private fun convertMember(e: PsiElement?, containingClass: PsiClass): Element? = when(e) {
|
||||
private fun convertMember(e: PsiElement?): Element? = when(e) {
|
||||
is PsiMethod -> convertMethod(e, true)
|
||||
is PsiField -> convertField(e, containingClass)
|
||||
is PsiField -> convertField(e)
|
||||
is PsiClass -> convertClass(e)
|
||||
is PsiClassInitializer -> convertInitializer(e)
|
||||
else -> convertElement(e)
|
||||
@@ -103,90 +103,86 @@ public class Converter(val project: Project, val settings: ConverterSettings) {
|
||||
|
||||
private fun convertClass(psiClass: PsiClass): Class {
|
||||
val modifiers = convertModifierList(psiClass.getModifierList())
|
||||
val fields = convertFields(psiClass.getFields(), psiClass)
|
||||
val typeParameters = convertTypeParameterList(psiClass.getTypeParameterList())
|
||||
val implementsTypes = convertToNotNullableTypes(psiClass.getImplementsListTypes())
|
||||
val extendsTypes = convertToNotNullableTypes(psiClass.getExtendsListTypes())
|
||||
val name = Identifier(psiClass.getName()!!)
|
||||
val members = ArrayList(convertMembers(psiClass))
|
||||
|
||||
val baseClassParams: List<Expression> = run {
|
||||
val superVisitor = SuperVisitor()
|
||||
psiClass.accept(superVisitor)
|
||||
val resolvedSuperCallParameters = superVisitor.resolvedSuperCallParameters
|
||||
if (resolvedSuperCallParameters.size() == 1) {
|
||||
convertExpressions(resolvedSuperCallParameters.single().getExpressions())
|
||||
}
|
||||
else {
|
||||
listOf()
|
||||
}
|
||||
}
|
||||
when {
|
||||
psiClass.isInterface() -> return Trait(this, name, getComments(psiClass), modifiers, typeParameters, extendsTypes, listOf(), implementsTypes, members)
|
||||
|
||||
if (!psiClass.isEnum() && !psiClass.isInterface() && psiClass.getConstructors().size > 1 && psiClass.getPrimaryConstructor() == null) {
|
||||
val finalOrWithEmptyInitializer = fields.filter { it.isVal() || it.initializer.toKotlin().isEmpty() }
|
||||
val initializers = HashMap<String, String>()
|
||||
for (member in members) {
|
||||
if (member is Constructor && !member.isPrimary) {
|
||||
for (field in finalOrWithEmptyInitializer) {
|
||||
initializers.put(field.identifier.toKotlin(), getDefaultInitializer(field))
|
||||
}
|
||||
psiClass.isEnum() -> return Enum(this, name, getComments(psiClass), modifiers, typeParameters, listOf(), listOf(), implementsTypes, members)
|
||||
|
||||
val newStatements = ArrayList<Statement>()
|
||||
for (statement in member.block!!.statements) {
|
||||
var isRemoved = false
|
||||
if (statement is AssignmentExpression) {
|
||||
val assignee = statement.left
|
||||
if (assignee is CallChainExpression) {
|
||||
for (field in finalOrWithEmptyInitializer) {
|
||||
val id = field.identifier.toKotlin()
|
||||
if (assignee.identifier.toKotlin().endsWith("." + id)) {
|
||||
initializers.put(id, statement.right.toKotlin())
|
||||
isRemoved = true
|
||||
else -> {
|
||||
if (psiClass.getConstructors().size > 1 && psiClass.getPrimaryConstructor() == null) {
|
||||
val finalOrWithEmptyInitializerFields = members.filterIsInstance(javaClass<Field>()).filter { it.isVal() || it.initializer.toKotlin().isEmpty() }
|
||||
val initializers = HashMap<String, String>()
|
||||
for (member in members) {
|
||||
if (member is Constructor && !member.isPrimary) {
|
||||
for (field in finalOrWithEmptyInitializerFields) {
|
||||
initializers.put(field.identifier.toKotlin(), getDefaultInitializer(field))
|
||||
}
|
||||
|
||||
val newStatements = ArrayList<Statement>()
|
||||
for (statement in member.block!!.statements) {
|
||||
var keepStatement = true
|
||||
if (statement is AssignmentExpression) {
|
||||
val assignee = statement.left
|
||||
if (assignee is CallChainExpression) {
|
||||
for (field in finalOrWithEmptyInitializerFields) {
|
||||
val id = field.identifier.toKotlin()
|
||||
if (assignee.identifier.toKotlin().endsWith("." + id)) {
|
||||
initializers.put(id, statement.right.toKotlin())
|
||||
keepStatement = false
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (keepStatement) {
|
||||
newStatements.add(statement)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
newStatements.add(0, DummyStringExpression("val __ = " + createPrimaryConstructorInvocation(name.toKotlin(), finalOrWithEmptyInitializerFields, initializers)))
|
||||
member.block = Block(newStatements)
|
||||
}
|
||||
|
||||
if (!isRemoved) {
|
||||
newStatements.add(statement)
|
||||
}
|
||||
|
||||
}
|
||||
newStatements.add(0, DummyStringExpression("val __ = " + createPrimaryConstructorInvocation(name.toKotlin(), finalOrWithEmptyInitializer, initializers)))
|
||||
member.block = Block(newStatements)
|
||||
|
||||
//TODO: comments?
|
||||
members.add(Constructor(this, Identifier.Empty, MemberComments.Empty, Collections.emptySet<Modifier>(),
|
||||
ClassType(name, listOf(), false, this),
|
||||
TypeParameterList.Empty,
|
||||
ParameterList(createParametersFromFields(finalOrWithEmptyInitializerFields)),
|
||||
Block(createInitStatementsFromFields(finalOrWithEmptyInitializerFields)),
|
||||
true))
|
||||
}
|
||||
|
||||
val baseClassParams: List<Expression> = run {
|
||||
val superVisitor = SuperVisitor()
|
||||
psiClass.accept(superVisitor)
|
||||
val resolvedSuperCallParameters = superVisitor.resolvedSuperCallParameters
|
||||
if (resolvedSuperCallParameters.size() == 1) {
|
||||
convertExpressions(resolvedSuperCallParameters.single().getExpressions())
|
||||
}
|
||||
else {
|
||||
listOf()
|
||||
}
|
||||
}
|
||||
|
||||
return Class(this, name, getComments(psiClass), modifiers, typeParameters, extendsTypes, baseClassParams, implementsTypes, members)
|
||||
}
|
||||
//TODO: comments?
|
||||
members.add(Constructor(this, Identifier.Empty, MemberComments.Empty, Collections.emptySet<Modifier>(),
|
||||
ClassType(name, listOf(), false, this),
|
||||
TypeParameterList.Empty,
|
||||
ParameterList(createParametersFromFields(finalOrWithEmptyInitializer)),
|
||||
Block(createInitStatementsFromFields(finalOrWithEmptyInitializer)),
|
||||
true))
|
||||
}
|
||||
|
||||
if (psiClass.isInterface()) {
|
||||
return Trait(this, name, getComments(psiClass), modifiers, typeParameters, extendsTypes, listOf(), implementsTypes, members)
|
||||
}
|
||||
|
||||
if (psiClass.isEnum()) {
|
||||
return Enum(this, name, getComments(psiClass), modifiers, typeParameters, listOf(), listOf(), implementsTypes, members)
|
||||
}
|
||||
|
||||
return Class(this, name, getComments(psiClass), modifiers, typeParameters, extendsTypes, baseClassParams, implementsTypes, members)
|
||||
}
|
||||
|
||||
private fun convertInitializer(initializer: PsiClassInitializer): Initializer {
|
||||
return Initializer(convertBlock(initializer.getBody(), true), convertModifierList(initializer.getModifierList()))
|
||||
}
|
||||
|
||||
private fun convertFields(fields: Array<PsiField>, psiClass: PsiClass): List<Field> {
|
||||
return fields.map { convertField(it, psiClass) }
|
||||
}
|
||||
|
||||
private fun convertField(field: PsiField, psiClass: PsiClass?): Field {
|
||||
private fun convertField(field: PsiField): Field {
|
||||
val modifiers = convertModifierList(field.getModifierList())
|
||||
if (field is PsiEnumConstant) {
|
||||
return EnumConstant(Identifier(field.getName()!!),
|
||||
@@ -196,8 +192,8 @@ public class Converter(val project: Project, val settings: ConverterSettings) {
|
||||
convertElement(field.getArgumentList()))
|
||||
}
|
||||
|
||||
var kType = convertType(field.getType(), isAnnotatedAsNotNull(field.getModifierList()))
|
||||
if (field.hasModifierProperty(PsiModifier.FINAL) && isDefinitelyNotNull(field.getInitializer())) {
|
||||
var kType = convertType(field.getType(), field.isAnnotatedAsNotNull())
|
||||
if (field.hasModifierProperty(PsiModifier.FINAL) && field.getInitializer().isDefinitelyNotNull()) {
|
||||
kType = kType.convertedToNotNull();
|
||||
}
|
||||
|
||||
@@ -206,7 +202,7 @@ public class Converter(val project: Project, val settings: ConverterSettings) {
|
||||
modifiers,
|
||||
kType,
|
||||
convertExpression(field.getInitializer(), field.getType()),
|
||||
countWriteAccesses(field, psiClass))
|
||||
field.countWriteAccesses(field.getContainingClass()))
|
||||
}
|
||||
|
||||
private fun convertMethod(method: PsiMethod): Function {
|
||||
@@ -222,7 +218,7 @@ public class Converter(val project: Project, val settings: ConverterSettings) {
|
||||
}
|
||||
methodReturnType = method.getReturnType()
|
||||
val identifier = Identifier(method.getName())
|
||||
val returnType = convertType(method.getReturnType(), isAnnotatedAsNotNull(method.getModifierList()))
|
||||
val returnType = convertType(method.getReturnType(), method.isAnnotatedAsNotNull())
|
||||
val body = convertBlock(method.getBody(), notEmpty)
|
||||
|
||||
val params = createFunctionParameters(method)
|
||||
@@ -253,8 +249,8 @@ public class Converter(val project: Project, val settings: ConverterSettings) {
|
||||
val result = ArrayList<Parameter>()
|
||||
for (parameter in method.getParameterList().getParameters()) {
|
||||
result.add(Parameter(Identifier(parameter.getName()!!),
|
||||
convertType(parameter.getType(), isAnnotatedAsNotNull(parameter.getModifierList())),
|
||||
isReadOnly(parameter, method.getBody())))
|
||||
convertType(parameter.getType(), parameter.isAnnotatedAsNotNull()),
|
||||
parameter.countWriteAccesses(method.getBody()) == 0))
|
||||
}
|
||||
return ParameterList(result)
|
||||
}
|
||||
@@ -339,7 +335,7 @@ public class Converter(val project: Project, val settings: ConverterSettings) {
|
||||
public fun convertParameter(parameter: PsiParameter, forceNotNull: Boolean = false): Parameter {
|
||||
return Parameter(Identifier(parameter.getName()!!),
|
||||
convertType(parameter.getType(),
|
||||
forceNotNull || isAnnotatedAsNotNull(parameter.getModifierList())), true)
|
||||
forceNotNull || parameter.isAnnotatedAsNotNull()), true)
|
||||
}
|
||||
|
||||
public fun convertArguments(expression: PsiCallExpression): List<Expression> {
|
||||
|
||||
@@ -19,53 +19,36 @@ package org.jetbrains.jet.j2k
|
||||
import org.jetbrains.jet.j2k.ast.Identifier
|
||||
import com.intellij.psi.PsiElement
|
||||
import com.intellij.psi.JavaRecursiveElementVisitor
|
||||
import java.util.ArrayList
|
||||
import com.intellij.psi.PsiReferenceExpression
|
||||
import com.intellij.psi.util.PsiUtil
|
||||
import com.intellij.psi.PsiModifierList
|
||||
import com.intellij.psi.PsiAnnotation
|
||||
import com.intellij.psi.PsiLiteralExpression
|
||||
import com.intellij.psi.PsiNewExpression
|
||||
import org.jetbrains.jet.j2k.ast.Field
|
||||
import org.jetbrains.jet.lang.types.expressions.OperatorConventions
|
||||
import com.intellij.psi.util.PsiUtil
|
||||
import com.intellij.psi.PsiModifierListOwner
|
||||
|
||||
fun quoteKeywords(packageName: String): String = packageName.split("\\.").map { Identifier(it).toKotlin() }.makeString(".")
|
||||
|
||||
fun countWriteAccesses(element: PsiElement?, container: PsiElement?): Int {
|
||||
if (container == null) return 0
|
||||
|
||||
class ReferenceCollector() : JavaRecursiveElementVisitor() {
|
||||
private val _collectedReferences = ArrayList<PsiReferenceExpression>()
|
||||
|
||||
public val collectedReferences: List<PsiReferenceExpression>
|
||||
get() = _collectedReferences
|
||||
fun PsiElement.countWriteAccesses(scope: PsiElement?): Int {
|
||||
if (scope == null) return 0
|
||||
|
||||
var writes = 0
|
||||
scope.accept(object: JavaRecursiveElementVisitor() {
|
||||
override fun visitReferenceExpression(expression: PsiReferenceExpression) {
|
||||
super.visitReferenceExpression(expression)
|
||||
_collectedReferences.add(expression)
|
||||
if (PsiUtil.isAccessedForWriting(expression) && expression.isReferenceTo(this@countWriteAccesses)) {
|
||||
writes++
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
val collector = ReferenceCollector()
|
||||
container.accept(collector)
|
||||
return collector.collectedReferences.count { it.isReferenceTo(element) && PsiUtil.isAccessedForWriting(it) }
|
||||
})
|
||||
return writes
|
||||
}
|
||||
|
||||
fun isReadOnly(element: PsiElement?, container: PsiElement?): Boolean
|
||||
= countWriteAccesses(element, container) == 0
|
||||
fun PsiModifierListOwner.isAnnotatedAsNotNull(): Boolean
|
||||
= getModifierList()?.getAnnotations()?.any { NOT_NULL_ANNOTATIONS.contains(it.getQualifiedName()) } ?: false
|
||||
|
||||
fun isAnnotatedAsNotNull(modifierList: PsiModifierList?): Boolean {
|
||||
if (modifierList != null) {
|
||||
for (annotation in modifierList.getAnnotations()) {
|
||||
val qualifiedName = annotation.getQualifiedName()
|
||||
return qualifiedName != null && NOT_NULL_ANNOTATIONS.contains(qualifiedName)
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
fun isDefinitelyNotNull(element: PsiElement?): Boolean = when(element) {
|
||||
is PsiLiteralExpression -> element.getValue() != null
|
||||
fun PsiElement?.isDefinitelyNotNull(): Boolean = when(this) {
|
||||
is PsiLiteralExpression -> getValue() != null
|
||||
is PsiNewExpression -> true
|
||||
else -> false
|
||||
}
|
||||
|
||||
@@ -26,9 +26,9 @@ class ElementVisitor(public val converter: Converter) : JavaElementVisitor() {
|
||||
protected set
|
||||
|
||||
override fun visitLocalVariable(variable: PsiLocalVariable) {
|
||||
var kType = converter.convertType(variable.getType(), isAnnotatedAsNotNull(variable.getModifierList()))
|
||||
if (variable.hasModifierProperty(PsiModifier.FINAL) && isDefinitelyNotNull(variable.getInitializer())) {
|
||||
kType = kType.convertedToNotNull();
|
||||
var kType = converter.convertType(variable.getType(), variable.isAnnotatedAsNotNull())
|
||||
if (variable.hasModifierProperty(PsiModifier.FINAL) && variable.getInitializer().isDefinitelyNotNull()) {
|
||||
kType = kType.convertedToNotNull()
|
||||
}
|
||||
result = LocalVariable(Identifier(variable.getName()!!),
|
||||
converter.convertModifierList(variable.getModifierList()),
|
||||
|
||||
@@ -141,7 +141,7 @@ open class ExpressionVisitor(public val converter: Converter) : JavaElementVisit
|
||||
}
|
||||
|
||||
protected fun convertMethodCallExpression(expression: PsiMethodCallExpression) {
|
||||
if (!isSuperConstructorRef(expression.getMethodExpression()) || !isInsidePrimaryConstructor(expression)) {
|
||||
if (!expression.isSuperConstructorCall() || !isInsidePrimaryConstructor(expression)) {
|
||||
result = MethodCallExpression(converter.convertExpression(expression.getMethodExpression()),
|
||||
converter.convertArguments(expression),
|
||||
converter.convertTypes(expression.getTypeArguments()),
|
||||
@@ -212,21 +212,20 @@ open class ExpressionVisitor(public val converter: Converter) : JavaElementVisit
|
||||
}
|
||||
|
||||
override fun visitReferenceExpression(expression: PsiReferenceExpression) {
|
||||
val isFieldReference = isFieldReference(expression, getContainingClass(expression))
|
||||
val insideSecondaryConstructor = isInsideSecondaryConstructor(expression)
|
||||
val hasReceiver = isFieldReference && insideSecondaryConstructor
|
||||
val isThis = isThisExpression(expression)
|
||||
val notNull = isResolvedToNotNull(expression)
|
||||
val isNullable = converter.convertType(expression.getType(), notNull).isNullable
|
||||
val className = getClassNameWithConstructor(expression)
|
||||
val containingConstructor = getContainingConstructor(expression)
|
||||
val insideSecondaryConstructor = containingConstructor != null && !containingConstructor.isPrimaryConstructor()
|
||||
val addReceiver = insideSecondaryConstructor && (expression.getReference()?.resolve() as? PsiField)?.getContainingClass() == containingConstructor!!.getContainingClass()
|
||||
|
||||
val isNullable = converter.convertType(expression.getType(), expression.isResolvedToNotNull()).isNullable
|
||||
val referencedName = expression.getReferenceName()!!
|
||||
var identifier: Expression = Identifier(referencedName, isNullable)
|
||||
val qualifier = expression.getQualifierExpression()
|
||||
if (hasReceiver) {
|
||||
|
||||
if (addReceiver) {
|
||||
identifier = CallChainExpression(Identifier("__", false), Identifier(referencedName, isNullable))
|
||||
}
|
||||
else if (insideSecondaryConstructor && isThis) {
|
||||
identifier = Identifier("val __ = " + className)
|
||||
else if (insideSecondaryConstructor && expression.isThisConstructorCall()) {
|
||||
identifier = Identifier("val __ = " + (containingConstructor?.getContainingClass()?.getNameIdentifier()?.getText() ?: ""))
|
||||
}
|
||||
else if (qualifier != null && qualifier.getType() is PsiArrayType && referencedName == "length") {
|
||||
identifier = Identifier("size", isNullable)
|
||||
@@ -259,15 +258,13 @@ open class ExpressionVisitor(public val converter: Converter) : JavaElementVisit
|
||||
result = CallChainExpression(converter.convertExpression(qualifier), identifier)
|
||||
}
|
||||
|
||||
private fun isResolvedToNotNull(expression: PsiReference): Boolean {
|
||||
val target = expression.resolve()
|
||||
if (target is PsiEnumConstant) {
|
||||
return true;
|
||||
private fun PsiReference.isResolvedToNotNull(): Boolean {
|
||||
val target = resolve()
|
||||
return when(target) {
|
||||
is PsiEnumConstant -> true
|
||||
is PsiModifierListOwner -> target.isAnnotatedAsNotNull()
|
||||
else -> false
|
||||
}
|
||||
if (target is PsiModifierListOwner) {
|
||||
return isAnnotatedAsNotNull(target.getModifierList());
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
override fun visitSuperExpression(expression: PsiSuperExpression) {
|
||||
@@ -287,19 +284,17 @@ open class ExpressionVisitor(public val converter: Converter) : JavaElementVisit
|
||||
}
|
||||
|
||||
override fun visitTypeCastExpression(expression: PsiTypeCastExpression) {
|
||||
val castType: PsiTypeElement? = expression.getCastType()
|
||||
if (castType != null) {
|
||||
val operand = expression.getOperand()
|
||||
val operandType = operand?.getType()
|
||||
val typeText = castType.getType().getCanonicalText()
|
||||
val typeConversion = PRIMITIVE_TYPE_CONVERSIONS[typeText]
|
||||
if (operandType is PsiPrimitiveType && typeConversion != null) {
|
||||
result = MethodCallExpression.build(converter.convertExpression(operand), typeConversion)
|
||||
}
|
||||
else {
|
||||
result = TypeCastExpression(converter.convertType(castType.getType()),
|
||||
converter.convertExpression(operand))
|
||||
}
|
||||
val castType = expression.getCastType() ?: return
|
||||
val operand = expression.getOperand()
|
||||
val operandType = operand?.getType()
|
||||
val typeText = castType.getType().getCanonicalText()
|
||||
val typeConversion = PRIMITIVE_TYPE_CONVERSIONS[typeText]
|
||||
if (operandType is PsiPrimitiveType && typeConversion != null) {
|
||||
result = MethodCallExpression.build(converter.convertExpression(operand), typeConversion)
|
||||
}
|
||||
else {
|
||||
result = TypeCastExpression(converter.convertType(castType.getType()),
|
||||
converter.convertExpression(operand))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -339,26 +334,6 @@ open class ExpressionVisitor(public val converter: Converter) : JavaElementVisit
|
||||
}
|
||||
}
|
||||
|
||||
private fun getClassNameWithConstructor(expression: PsiReferenceExpression): String {
|
||||
var context = expression.getContext()
|
||||
while (context != null) {
|
||||
val _context = context!!
|
||||
if (_context is PsiMethod && _context.isConstructor()) {
|
||||
val containingClass = _context.getContainingClass()
|
||||
if (containingClass != null) {
|
||||
val identifier = containingClass.getNameIdentifier()
|
||||
if (identifier != null) {
|
||||
return identifier.getText()!!
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
context = _context.getContext()
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
protected fun getClassName(expression: PsiExpression): String {
|
||||
var context = expression.getContext()
|
||||
while (context != null) {
|
||||
@@ -376,45 +351,6 @@ open class ExpressionVisitor(public val converter: Converter) : JavaElementVisit
|
||||
return ""
|
||||
}
|
||||
|
||||
private fun isFieldReference(expression: PsiReferenceExpression, currentClass: PsiClass?): Boolean {
|
||||
val reference = expression.getReference()
|
||||
if (reference != null) {
|
||||
val target = reference.resolve()
|
||||
if (target is PsiField) {
|
||||
return target.getContainingClass() == currentClass
|
||||
}
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
private fun getContainingClass(expression: PsiExpression): PsiClass? {
|
||||
var context = expression.getContext()
|
||||
while (context != null) {
|
||||
val _context = context!!
|
||||
if (_context is PsiMethod && _context.isConstructor()) {
|
||||
return _context.getContainingClass()
|
||||
}
|
||||
|
||||
context = _context.getContext()
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
||||
private fun isThisExpression(expression: PsiReferenceExpression): Boolean {
|
||||
for (ref in expression.getReferences()) {
|
||||
if (ref.getCanonicalText() == "this") {
|
||||
val target = ref.resolve()
|
||||
if (target is PsiMethod && target.isConstructor()) {
|
||||
return true
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
private fun isStaticallyImported(member: PsiMember, context: PsiElement): Boolean {
|
||||
val containingFile = context.getContainingFile()
|
||||
val targetContainingClass = member.getContainingClass()
|
||||
|
||||
@@ -79,11 +79,13 @@ class StatementVisitor(public val converter: Converter) : JavaElementVisitor() {
|
||||
val update = statement.getUpdate()
|
||||
val condition = statement.getCondition()
|
||||
val body = statement.getBody()
|
||||
val firstChildLocalVar = initialization?.getFirstChild() as? PsiLocalVariable
|
||||
var bodyWriteCount = countWriteAccesses(firstChildLocalVar, body)
|
||||
var conditionWriteCount = countWriteAccesses(firstChildLocalVar, condition)
|
||||
var updateWriteCount = countWriteAccesses(firstChildLocalVar, update)
|
||||
val onceWritableIterator = updateWriteCount == 1 && bodyWriteCount + conditionWriteCount == 0
|
||||
|
||||
val initializationVar = initialization?.getFirstChild() as? PsiLocalVariable
|
||||
val onceWritableIterator = initializationVar != null
|
||||
&& initializationVar.countWriteAccesses(body) == 0
|
||||
&& initializationVar.countWriteAccesses(condition) == 0
|
||||
&& initializationVar.countWriteAccesses(update) == 1
|
||||
|
||||
val operationTokenType = (condition as? PsiBinaryExpression)?.getOperationTokenType()
|
||||
if (initialization is PsiDeclarationStatement
|
||||
&& initialization.getFirstChild() == initialization.getLastChild()
|
||||
@@ -92,16 +94,16 @@ class StatementVisitor(public val converter: Converter) : JavaElementVisitor() {
|
||||
&& update.getChildren().size == 1
|
||||
&& isPlusPlusExpression(update.getChildren().single())
|
||||
&& (operationTokenType == JavaTokenType.LT || operationTokenType == JavaTokenType.LE)
|
||||
&& firstChildLocalVar != null
|
||||
&& firstChildLocalVar.getNameIdentifier() != null
|
||||
&& initializationVar != null
|
||||
&& initializationVar.getNameIdentifier() != null
|
||||
&& onceWritableIterator) {
|
||||
val end = converter.convertExpression((condition as PsiBinaryExpression).getROperand())
|
||||
val endExpression = if (operationTokenType == JavaTokenType.LT)
|
||||
BinaryExpression(end, Identifier("1"), "-")
|
||||
else
|
||||
end
|
||||
result = ForeachWithRangeStatement(Identifier(firstChildLocalVar.getName()!!),
|
||||
converter.convertExpression(firstChildLocalVar.getInitializer()),
|
||||
result = ForeachWithRangeStatement(Identifier(initializationVar.getName()!!),
|
||||
converter.convertExpression(initializationVar.getInitializer()),
|
||||
endExpression,
|
||||
converter.convertStatement(body))
|
||||
}
|
||||
|
||||
@@ -18,7 +18,7 @@ package org.jetbrains.jet.j2k.visitors
|
||||
|
||||
import com.intellij.psi.*
|
||||
import java.util.HashSet
|
||||
import org.jetbrains.jet.j2k.isSuperConstructorRef
|
||||
import org.jetbrains.jet.j2k.isSuperConstructorCall
|
||||
|
||||
class SuperVisitor() : JavaRecursiveElementVisitor() {
|
||||
private val _resolvedSuperCallParameters = HashSet<PsiExpressionList>()
|
||||
@@ -27,7 +27,7 @@ class SuperVisitor() : JavaRecursiveElementVisitor() {
|
||||
get() = _resolvedSuperCallParameters
|
||||
|
||||
override fun visitMethodCallExpression(expression: PsiMethodCallExpression) {
|
||||
if (isSuperConstructorRef(expression.getMethodExpression())) {
|
||||
if (expression.isSuperConstructorCall()) {
|
||||
_resolvedSuperCallParameters.add(expression.getArgumentList())
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user