diff --git a/.idea/dictionaries/valentin.xml b/.idea/dictionaries/valentin.xml index 55471258d54..70d806d6359 100644 --- a/.idea/dictionaries/valentin.xml +++ b/.idea/dictionaries/valentin.xml @@ -1,6 +1,7 @@ + initializers pparent rparenth diff --git a/annotations/com/intellij/psi/annotations.xml b/annotations/com/intellij/psi/annotations.xml index b5f752134d5..c3d8770e4dd 100644 --- a/annotations/com/intellij/psi/annotations.xml +++ b/annotations/com/intellij/psi/annotations.xml @@ -1,10 +1,245 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -14,16 +249,217 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/compiler/jet.as.java.psi/src/org/jetbrains/jet/asJava/lightClassUtils.kt b/compiler/jet.as.java.psi/src/org/jetbrains/jet/asJava/lightClassUtils.kt index e24766091f6..fac206714eb 100644 --- a/compiler/jet.as.java.psi/src/org/jetbrains/jet/asJava/lightClassUtils.kt +++ b/compiler/jet.as.java.psi/src/org/jetbrains/jet/asJava/lightClassUtils.kt @@ -56,7 +56,7 @@ public fun JetDeclaration.toLightElements(): List = elements } is JetTypeParameter -> toPsiTypeParameters() - else -> Collections.emptyList() + else -> listOf() } public fun PsiElement.toLightMethods(): List = @@ -66,7 +66,7 @@ public fun PsiElement.toLightMethods(): List = is JetParameter -> LightClassUtil.getLightClassPropertyMethods(this).toList() is JetPropertyAccessor -> Collections.singletonList(LightClassUtil.getLightClassAccessorMethod(this)) is PsiMethod -> Collections.singletonList(this) - else -> Collections.emptyList() + else -> listOf() } public fun PsiElement.getRepresentativeLightMethod(): PsiMethod? = @@ -102,13 +102,13 @@ public fun JetParameter.toPsiParameter(): PsiParameter? { public fun JetTypeParameter.toPsiTypeParameters(): List { val paramList = getParentByType(javaClass()) - if (paramList == null) return Collections.emptyList() + if (paramList == null) return listOf() val paramIndex = paramList.getParameters().indexOf(this) - val lightOwners = paramList.getParentByType(javaClass())?.toLightElements() + val jetDeclaration = paramList.getParentByType(javaClass()) ?: return listOf() + val lightOwners = jetDeclaration.toLightElements() - return lightOwners?.map { lightOwner -> (lightOwner as PsiTypeParameterListOwner).getTypeParameters()[paramIndex] } - ?: Collections.emptyList() + return lightOwners.map { lightOwner -> (lightOwner as PsiTypeParameterListOwner).getTypeParameters()[paramIndex] } } // Returns original declaration if given PsiElement is a Kotlin light element, and element itself otherwise diff --git a/idea/src/org/jetbrains/jet/plugin/actions/JavaToKotlinActionUtil.java b/idea/src/org/jetbrains/jet/plugin/actions/JavaToKotlinActionUtil.java index 5a9e79a6122..9f3c3c2729d 100644 --- a/idea/src/org/jetbrains/jet/plugin/actions/JavaToKotlinActionUtil.java +++ b/idea/src/org/jetbrains/jet/plugin/actions/JavaToKotlinActionUtil.java @@ -39,7 +39,7 @@ public class JavaToKotlinActionUtil { static void setClassIdentifiers(@NotNull Converter converter, @NotNull PsiFile psiFile) { ClassVisitor c = new ClassVisitor(); psiFile.accept(c); - converter.setClassIdentifiers(c.getClassIdentifiers()); + converter.setClassIdentifiers(new HashSet(c.getClassIdentifiers())); } @NotNull diff --git a/idea/tests/org/jetbrains/jet/plugin/refactoring/introduce/introduceVariable/AbstractJetExtractionTest.kt b/idea/tests/org/jetbrains/jet/plugin/refactoring/introduce/introduceVariable/AbstractJetExtractionTest.kt index eb903114173..4992e099eb2 100644 --- a/idea/tests/org/jetbrains/jet/plugin/refactoring/introduce/introduceVariable/AbstractJetExtractionTest.kt +++ b/idea/tests/org/jetbrains/jet/plugin/refactoring/introduce/introduceVariable/AbstractJetExtractionTest.kt @@ -52,8 +52,8 @@ public abstract class AbstractJetExtractionTest() : LightCodeInsightFixtureTestC var explicitPreviousSibling: PsiElement? = null file.accept( object: JetTreeVisitorVoid() { - override fun visitComment(comment: PsiComment?) { - if (comment?.getText() == "// SIBLING:") { + override fun visitComment(comment: PsiComment) { + if (comment.getText() == "// SIBLING:") { explicitPreviousSibling = PsiTreeUtil.skipSiblingsForward( comment, javaClass(), diff --git a/j2k/src/org/jetbrains/jet/j2k/ConstructorUtils.kt b/j2k/src/org/jetbrains/jet/j2k/ConstructorUtils.kt index b80807732c5..461241a9505 100644 --- a/j2k/src/org/jetbrains/jet/j2k/ConstructorUtils.kt +++ b/j2k/src/org/jetbrains/jet/j2k/ConstructorUtils.kt @@ -19,9 +19,9 @@ package org.jetbrains.jet.j2k import com.intellij.psi.PsiMethod import com.intellij.psi.PsiClass import com.intellij.psi.PsiReferenceExpression -import com.intellij.psi.PsiElement import com.intellij.psi.JavaRecursiveElementVisitor import java.util.LinkedHashSet +import com.intellij.psi.PsiReference fun isConstructorPrimary(constructor: PsiMethod): Boolean { val parent = constructor.getParent() @@ -30,8 +30,9 @@ fun isConstructorPrimary(constructor: PsiMethod): Boolean { return true } else { - val c = getPrimaryConstructorForThisCase(parent) - if (c != null && c.hashCode() == constructor.hashCode()) { + val primary = getPrimaryConstructorForThisCase(parent) + //TODO: I do not understand code below + if (primary != null && primary.hashCode() == constructor.hashCode()) { return true } } @@ -39,37 +40,39 @@ fun isConstructorPrimary(constructor: PsiMethod): Boolean { return false } -private fun getPrimaryConstructorForThisCase(psiClass: PsiClass): PsiMethod? { - val tv = FindPrimaryConstructorVisitor() - psiClass.accept(tv) - return tv.getPrimaryConstructor() -} +fun getPrimaryConstructorForThisCase(psiClass: PsiClass): PsiMethod? { + class FindPrimaryConstructorVisitor() : JavaRecursiveElementVisitor() { + private val resolvedConstructors = LinkedHashSet() -private class FindPrimaryConstructorVisitor() : JavaRecursiveElementVisitor() { - private val myResolvedConstructors = LinkedHashSet() + override fun visitReferenceExpression(expression: PsiReferenceExpression) { + expression.getReferences() + .filter { it.getCanonicalText() == "this" } + .map { it.resolve() } + .filterIsInstance(javaClass()) + .filterTo(resolvedConstructors) { it.isConstructor() } + } - override fun visitReferenceExpression(expression: PsiReferenceExpression?) { - for (r in expression?.getReferences()!!) { - if (r.getCanonicalText() == "this") { - val res: PsiElement? = r.resolve() - if (res is PsiMethod && res.isConstructor()) { - myResolvedConstructors.add(res) - } + val result: PsiMethod? + get() { + if (resolvedConstructors.isEmpty()) return null + //TODO: I do not understand code below + val first = resolvedConstructors.first() + return if (resolvedConstructors.all { it.hashCode() == first.hashCode() }) first else null } - } } - fun getPrimaryConstructor(): PsiMethod? { - if (myResolvedConstructors.size() > 0) { - val first: PsiMethod = myResolvedConstructors.iterator().next() - for (m in myResolvedConstructors) - if (m.hashCode() != first.hashCode()) { - return null - } - - return first - } - return null - } + val visitor = FindPrimaryConstructorVisitor() + psiClass.accept(visitor) + return visitor.result } +fun isSuperConstructorRef(ref: PsiReference): Boolean { + if (ref.getCanonicalText().equals("super")) { + val baseConstructor = ref.resolve() + if (baseConstructor is PsiMethod && baseConstructor.isConstructor()) { + return true + } + } + + return false +} diff --git a/j2k/src/org/jetbrains/jet/j2k/Converter.kt b/j2k/src/org/jetbrains/jet/j2k/Converter.kt index b39f605cacf..7d599fd18fd 100644 --- a/j2k/src/org/jetbrains/jet/j2k/Converter.kt +++ b/j2k/src/org/jetbrains/jet/j2k/Converter.kt @@ -16,36 +16,31 @@ package org.jetbrains.jet.j2k -import com.google.common.collect.ImmutableMap -import com.google.common.collect.ImmutableSet -import com.google.common.collect.Sets import com.intellij.psi.* import org.jetbrains.jet.j2k.ast.* import org.jetbrains.jet.j2k.ast.types.ClassType import org.jetbrains.jet.j2k.ast.types.EmptyType import org.jetbrains.jet.j2k.ast.types.Type import org.jetbrains.jet.j2k.visitors.* -import org.jetbrains.jet.lang.types.expressions.OperatorConventions import java.util.* import com.intellij.psi.CommonClassNames.* import org.jetbrains.jet.lang.types.expressions.OperatorConventions.* -import com.intellij.psi.util.PsiUtil import com.intellij.openapi.project.Project public class Converter(val project: Project, val settings: ConverterSettings) { - private var classIdentifiersSet: MutableSet = Sets.newHashSet()!! + private var classIdentifiersSet: MutableSet = HashSet() private val dispatcher: Dispatcher = Dispatcher(this) - var methodReturnType: PsiType? = null + public var methodReturnType: PsiType? = null private set public fun setClassIdentifiers(identifiers: MutableSet) { classIdentifiersSet = identifiers } - fun getClassIdentifiers(): Set { + public fun getClassIdentifiers(): Set { return Collections.unmodifiableSet(classIdentifiersSet) } @@ -53,12 +48,10 @@ public class Converter(val project: Project, val settings: ConverterSettings) { classIdentifiersSet.clear() } - public fun elementToKotlin(element: PsiElement): String { - val kElement = convertTopElement(element) - return kElement?.toKotlin() ?: "" - } + public fun elementToKotlin(element: PsiElement): String + = convertTopElement(element)?.toKotlin() ?: "" - fun convertTopElement(element: PsiElement?): Element? = when(element) { + private fun convertTopElement(element: PsiElement?): Element? = when(element) { is PsiJavaFile -> convertFile(element) is PsiClass -> convertClass(element) is PsiMethod -> convertMethod(element) @@ -74,22 +67,18 @@ public class Converter(val project: Project, val settings: ConverterSettings) { } public fun convertFile(javaFile: PsiJavaFile): File { - val fileMembers = FileMemberList(javaFile.getChildren() .map { convertTopElement(it) } .filterNotNull()) + val fileMembers = FileMemberList(javaFile.getChildren().map { convertTopElement(it) }.filterNotNull()) return File(fileMembers, createMainFunction(javaFile)) } - fun convertAnonymousClass(anonymousClass: PsiAnonymousClass): AnonymousClass { + public fun convertAnonymousClass(anonymousClass: PsiAnonymousClass): AnonymousClass { return AnonymousClass(this, convertMembers(anonymousClass)) } private fun convertMembers(psiClass: PsiClass): List { - val members = ArrayList() val allChildren = psiClass.getChildren().toList() - for (e in allChildren.subList(allChildren.indexOf(psiClass.getLBrace()), allChildren.size)) { - val converted = convertMember(e, psiClass) - if (converted != null) members.add(converted) - } - return members + val lBraceIndex = allChildren.indexOf(psiClass.getLBrace()) + return allChildren.subList(lBraceIndex, allChildren.size).map { convertMember(it, psiClass) }.filterNotNull() } private fun getComments(member: PsiMember): MemberComments { @@ -118,59 +107,60 @@ public class Converter(val project: Project, val settings: ConverterSettings) { val typeParameters = convertTypeParameterList(psiClass.getTypeParameterList()) val implementsTypes = convertToNotNullableTypes(psiClass.getImplementsListTypes()) val extendsTypes = convertToNotNullableTypes(psiClass.getExtendsListTypes()) - val name: Identifier = Identifier(psiClass.getName()!!) - val baseClassParams = ArrayList() + val name = Identifier(psiClass.getName()!!) val members = ArrayList(convertMembers(psiClass)) - val visitor = SuperVisitor() - psiClass.accept(visitor) - val resolvedSuperCallParameters = visitor.resolvedSuperCallParameters - if (resolvedSuperCallParameters.size() == 1) { - val psiExpressionList = resolvedSuperCallParameters.iterator().next() - baseClassParams.addAll(convertExpressions(psiExpressionList.getExpressions())) + + val baseClassParams: List = run { + val superVisitor = SuperVisitor() + psiClass.accept(superVisitor) + val resolvedSuperCallParameters = superVisitor.resolvedSuperCallParameters + if (resolvedSuperCallParameters.size() == 1) { + convertExpressions(resolvedSuperCallParameters.single().getExpressions()) + } + else { + listOf() + } } - if (!psiClass.isEnum() && !psiClass.isInterface() && psiClass.getConstructors().size > 1 && - getPrimaryConstructorForThisCase(psiClass) == null) { - val finalOrWithEmptyInitializer: List = getFinalOrWithEmptyInitializer(fields) + if (!psiClass.isEnum() && !psiClass.isInterface() && psiClass.getConstructors().size > 1 && getPrimaryConstructorForThisCase(psiClass) == null) { + val finalOrWithEmptyInitializer = fields.filter { it.isVal() || it.initializer.toKotlin().isEmpty() } val initializers = HashMap() - for (m in members) { - if (m is Constructor) { - if (!m.isPrimary) { - for (fo in finalOrWithEmptyInitializer) { - val init = getDefaultInitializer(fo) - initializers.put(fo.identifier.toKotlin(), init) - } - val newStatements = ArrayList() - for (s in m.block!!.statements) { - var isRemoved: Boolean = false - if (s is AssignmentExpression) { - val assignee = s.left - if (assignee is CallChainExpression) { - for (fo : Field in finalOrWithEmptyInitializer) { - val id: String = fo.identifier.toKotlin() - if (assignee.identifier.toKotlin().endsWith("." + id)) { - initializers.put(id, s.right.toKotlin()) - isRemoved = true - } - - } - } - - } - - if (!isRemoved) { - newStatements.add(s) - } - - } - newStatements.add(0, DummyStringExpression("val __ = " + createPrimaryConstructorInvocation(name.toKotlin(), finalOrWithEmptyInitializer, initializers))) - m.block = Block(newStatements) + for (member in members) { + if (member is Constructor && !member.isPrimary) { + for (field in finalOrWithEmptyInitializer) { + initializers.put(field.identifier.toKotlin(), getDefaultInitializer(field)) } + + val newStatements = ArrayList() + 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 + } + + } + } + + } + + 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(), - ClassType(name, Collections.emptyList(), false, this), + ClassType(name, listOf(), false, this), TypeParameterList.Empty, ParameterList(createParametersFromFields(finalOrWithEmptyInitializer)), Block(createInitStatementsFromFields(finalOrWithEmptyInitializer)), @@ -178,18 +168,18 @@ public class Converter(val project: Project, val settings: ConverterSettings) { } if (psiClass.isInterface()) { - return Trait(this, name, getComments(psiClass), modifiers, typeParameters, extendsTypes, Collections.emptyList(), implementsTypes, members) + return Trait(this, name, getComments(psiClass), modifiers, typeParameters, extendsTypes, listOf(), implementsTypes, members) } if (psiClass.isEnum()) { - return Enum(this, name, getComments(psiClass), modifiers, typeParameters, Collections.emptyList(), Collections.emptyList(), implementsTypes, members) + 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(i: PsiClassInitializer): Initializer { - return Initializer(convertBlock(i.getBody(), true), convertModifierList(i.getModifierList())) + private fun convertInitializer(initializer: PsiClassInitializer): Initializer { + return Initializer(convertBlock(initializer.getBody(), true), convertModifierList(initializer.getModifierList())) } private fun convertFields(fields: Array, psiClass: PsiClass): List { @@ -216,7 +206,7 @@ public class Converter(val project: Project, val settings: ConverterSettings) { modifiers, kType, convertExpression(field.getInitializer(), field.getType()), - countWritingAccesses(field, psiClass)) + countWriteAccesses(field, psiClass)) } private fun convertMethod(method: PsiMethod): Function { @@ -231,13 +221,13 @@ public class Converter(val project: Project, val settings: ConverterSettings) { dispatcher.expressionVisitor = ExpressionVisitor(this) } methodReturnType = method.getReturnType() - val identifier: Identifier = Identifier(method.getName()) - val returnType: Type = convertType(method.getReturnType(), isAnnotatedAsNotNull(method.getModifierList())) + val identifier = Identifier(method.getName()) + val returnType = convertType(method.getReturnType(), isAnnotatedAsNotNull(method.getModifierList())) val body = convertBlock(method.getBody(), notEmpty) - val params: Element = createFunctionParameters(method) + val params = createFunctionParameters(method) val typeParameterList = convertTypeParameterList(method.getTypeParameterList()) - val modifiers = convertModifierList(method.getModifierList()) + val modifiers = HashSet(convertModifierList(method.getModifierList())) if (isOverride(method)) { modifiers.add(Modifier.OVERRIDE) } @@ -261,62 +251,49 @@ public class Converter(val project: Project, val settings: ConverterSettings) { private fun createFunctionParameters(method: PsiMethod): ParameterList { val result = ArrayList() - for (parameter : PsiParameter? in method.getParameterList().getParameters()) { - result.add(Parameter(Identifier(parameter?.getName()!!), - convertType(parameter?.getType(), - isAnnotatedAsNotNull(parameter?.getModifierList())), + for (parameter in method.getParameterList().getParameters()) { + result.add(Parameter(Identifier(parameter.getName()!!), + convertType(parameter.getType(), isAnnotatedAsNotNull(parameter.getModifierList())), isReadOnly(parameter, method.getBody()))) } return ParameterList(result) } - fun convertBlock(block: PsiCodeBlock?, notEmpty: Boolean): Block { - if (block == null) - return Block.Empty + public fun convertBlock(block: PsiCodeBlock?, notEmpty: Boolean = true): Block { + if (block == null) return Block.Empty return Block(convertStatements(block.getChildren().toList()), notEmpty) } - fun convertBlock(block: PsiCodeBlock?): Block { - return convertBlock(block, true) - } - - fun convertStatements(statements: List): StatementList { + public fun convertStatements(statements: List): StatementList { return StatementList(statements.map { if (it is PsiStatement) convertStatement(it) else convertElement(it) }) } - fun convertStatement(s: PsiStatement?): Statement { - if (s == null) - return Statement.Empty + public fun convertStatement(statement: PsiStatement?): Statement { + if (statement == null) return Statement.Empty val statementVisitor: StatementVisitor = StatementVisitor(this) - s.accept(statementVisitor) - return statementVisitor.getResult() as Statement + statement.accept(statementVisitor) + return statementVisitor.result } - fun convertExpressions(expressions: Array): List { - val result = ArrayList() - for (e : PsiExpression? in expressions) - result.add(convertExpression(e)) - return result + public fun convertExpressions(expressions: Array): List + = expressions.map { convertExpression(it) } + + public fun convertExpression(expression: PsiExpression?): Expression { + if (expression == null) return Expression.Empty + + val expressionVisitor = dispatcher.expressionVisitor + expression.accept(expressionVisitor) + return expressionVisitor.result } - fun convertExpression(e: PsiExpression?): Expression { - if (e == null) - return Expression.Empty + public fun convertElement(element: PsiElement?): Element { + if (element == null) return Element.Empty - val expressionVisitor: ExpressionVisitor = dispatcher.expressionVisitor - e.accept(expressionVisitor) - return expressionVisitor.getResult() - } - - fun convertElement(e: PsiElement?): Element { - if (e == null) - return Element.Empty - - val elementVisitor: ElementVisitor = ElementVisitor(this) - e.accept(elementVisitor) - return elementVisitor.getResult() + val elementVisitor = ElementVisitor(this) + element.accept(elementVisitor) + return elementVisitor.result } fun convertElements(elements: Array): List { @@ -327,28 +304,25 @@ public class Converter(val project: Project, val settings: ConverterSettings) { return result } - fun convertTypeElement(element: PsiTypeElement?): TypeElement { + public fun convertTypeElement(element: PsiTypeElement?): TypeElement { return TypeElement(if (element == null) EmptyType() else convertType(element.getType())) } - fun convertType(`type`: PsiType?): Type { - if (`type` == null) - return EmptyType() + public fun convertType(`type`: PsiType?): Type { + if (`type` == null) return EmptyType() - val typeVisitor: TypeVisitor = TypeVisitor(this) - `type`.accept(typeVisitor) - return typeVisitor.getResult() + return `type`.accept(TypeVisitor(this))!! } - fun convertTypes(types: Array): List { + public fun convertTypes(types: Array): List { return types.map { convertType(it) } } - fun convertType(`type`: PsiType?, notNull: Boolean): Type { - val result: Type = convertType(`type`) + public fun convertType(`type`: PsiType?, notNull: Boolean): Type { + val result = convertType(`type`) if (notNull) { return result.convertedToNotNull() } @@ -356,57 +330,39 @@ public class Converter(val project: Project, val settings: ConverterSettings) { return result } - private fun convertToNotNullableTypes(types: Array): List { - val result = ArrayList() - for (aType in types) { - result.add(convertType(aType).convertedToNotNull()) - } - return result - } + private fun convertToNotNullableTypes(types: Array): List + = types.map { convertType(it).convertedToNotNull() } - fun convertParameterList(parameters: Array): List { - return parameters.map { convertParameter(it) } - } + public fun convertParameterList(parameters: Array): List + = parameters.map { convertParameter(it) } - fun convertParameter(parameter: PsiParameter, forceNotNull: Boolean = false): Parameter { + public fun convertParameter(parameter: PsiParameter, forceNotNull: Boolean = false): Parameter { return Parameter(Identifier(parameter.getName()!!), convertType(parameter.getType(), forceNotNull || isAnnotatedAsNotNull(parameter.getModifierList())), true) } - fun convertArguments(expression: PsiCallExpression): List { - val argumentList: PsiExpressionList? = expression.getArgumentList() - val arguments: Array = (if (argumentList != null) - argumentList.getExpressions() + public fun convertArguments(expression: PsiCallExpression): List { + val arguments = expression.getArgumentList()?.getExpressions() ?: array() + val resolved = expression.resolveMethod() + val expectedTypes = if (resolved != null) + resolved.getParameterList().getParameters().map { it.getType() } else - PsiExpression.EMPTY_ARRAY) - val result = ArrayList() - val resolved: PsiMethod? = expression.resolveMethod() - val expectedTypes = ArrayList() - if (resolved != null) { - for (p : PsiParameter? in resolved.getParameterList().getParameters()) - expectedTypes.add(p?.getType()) - } + listOf() - if (arguments.size == expectedTypes.size()) { - for (i in 0..expectedTypes.size() - 1) result.add(convertExpression(arguments[i], expectedTypes.get(i))) - } - else { - for (argument : PsiExpression? in arguments) { - result.add(convertExpression(argument)) - } - } - return result + return if (arguments.size == expectedTypes.size()) + (0..expectedTypes.lastIndex).map { i -> convertExpression(arguments[i], expectedTypes[i]) } + else + arguments.map { convertExpression(it) } } - fun convertExpression(argument: PsiExpression?, expectedType: PsiType?): Expression { - if (argument == null) - return Identifier.Empty + public fun convertExpression(argument: PsiExpression?, expectedType: PsiType?): Expression { + if (argument == null) return Identifier.Empty - var expression: Expression = convertExpression(argument) - val actualType: PsiType? = argument.getType() - val isPrimitiveTypeOrNull: Boolean = actualType == null || actualType is PsiPrimitiveType - if (isPrimitiveTypeOrNull && expression.isNullable()) { + var expression = convertExpression(argument) + val actualType = argument.getType() + val isPrimitiveTypeOrNull = actualType == null || actualType is PsiPrimitiveType + if (isPrimitiveTypeOrNull && expression.isNullable) { expression = BangBangExpression(expression) } else if (expectedType is PsiPrimitiveType && actualType is PsiClassType) { @@ -416,9 +372,8 @@ public class Converter(val project: Project, val settings: ConverterSettings) { } if (actualType != null) { - if (isConversionNeeded(actualType, expectedType) && !(expression is LiteralExpression)) - { - val conversion: String? = PRIMITIVE_TYPE_CONVERSIONS.get(expectedType?.getCanonicalText()) + if (isConversionNeeded(actualType, expectedType) && expression !is LiteralExpression) { + val conversion = PRIMITIVE_TYPE_CONVERSIONS[expectedType?.getCanonicalText()] if (conversion != null) { expression = MethodCallExpression.build(expression, conversion) } @@ -429,29 +384,15 @@ public class Converter(val project: Project, val settings: ConverterSettings) { return expression } - fun quoteKeywords(packageName: String): String { - return packageName.split("\\.").map { Identifier(it).toKotlin() }.makeString(".") - } - - private fun getFinalOrWithEmptyInitializer(fields: List): List { - val result = ArrayList() - for (f : Field in fields) - if (f.isVal() || f.initializer.toKotlin().isEmpty()) { - result.add(f) - } - - return result - } - private fun createParametersFromFields(fields: List): List { return fields.map { Parameter(Identifier("_" + it.identifier.name), it.`type`, true) } } private fun createInitStatementsFromFields(fields: List): List { val result = ArrayList() - for (f : Field in fields) { - val identifierToKotlin: String? = f.identifier.toKotlin() - result.add(DummyStringExpression(identifierToKotlin + " = " + "_" + identifierToKotlin)) + for (field in fields) { + val kotlinIdentifier = field.identifier.toKotlin() + result.add(DummyStringExpression(kotlinIdentifier + " = " + "_" + kotlinIdentifier)) } return result } @@ -460,151 +401,78 @@ public class Converter(val project: Project, val settings: ConverterSettings) { return s + "(" + fields.map { initializers[it.identifier.toKotlin()] }.makeString(", ") + ")" } - fun convertIdentifier(identifier: PsiIdentifier?): Identifier { - if (identifier == null) - return Identifier.Empty + public fun convertIdentifier(identifier: PsiIdentifier?): Identifier { + if (identifier == null) return Identifier.Empty return Identifier(identifier.getText()!!) } - fun convertModifierList(modifierList: PsiModifierList?): MutableSet { - val modifiersSet: HashSet = hashSetOf() - if (modifierList != null) { - if (modifierList.hasExplicitModifier(PsiModifier.ABSTRACT)) - modifiersSet.add(Modifier.ABSTRACT) + public fun convertModifierList(modifierList: PsiModifierList?): Set { + if (modifierList == null) return setOf() - if (modifierList.hasModifierProperty(PsiModifier.FINAL)) - modifiersSet.add(Modifier.FINAL) + val modifiersSet = HashSet() - if (modifierList.hasModifierProperty(PsiModifier.STATIC)) - modifiersSet.add(Modifier.STATIC) + if (modifierList.hasExplicitModifier(PsiModifier.ABSTRACT)) + modifiersSet.add(Modifier.ABSTRACT) - if (modifierList.hasExplicitModifier(PsiModifier.PUBLIC)) - modifiersSet.add(Modifier.PUBLIC) + if (modifierList.hasModifierProperty(PsiModifier.FINAL)) + modifiersSet.add(Modifier.FINAL) - if (modifierList.hasExplicitModifier(PsiModifier.PROTECTED)) - modifiersSet.add(Modifier.PROTECTED) + if (modifierList.hasModifierProperty(PsiModifier.STATIC)) + modifiersSet.add(Modifier.STATIC) - if (modifierList.hasExplicitModifier(PsiModifier.PACKAGE_LOCAL)) - modifiersSet.add(Modifier.INTERNAL) + if (modifierList.hasExplicitModifier(PsiModifier.PUBLIC)) + modifiersSet.add(Modifier.PUBLIC) - if (modifierList.hasExplicitModifier(PsiModifier.PRIVATE)) - modifiersSet.add(Modifier.PRIVATE) - } + if (modifierList.hasExplicitModifier(PsiModifier.PROTECTED)) + modifiersSet.add(Modifier.PROTECTED) + + if (modifierList.hasExplicitModifier(PsiModifier.PACKAGE_LOCAL)) + modifiersSet.add(Modifier.INTERNAL) + + if (modifierList.hasExplicitModifier(PsiModifier.PRIVATE)) + modifiersSet.add(Modifier.PRIVATE) return modifiersSet } + private val TYPE_MAP: Map = mapOf( + JAVA_LANG_BYTE to "byte", + JAVA_LANG_SHORT to "short", + JAVA_LANG_INTEGER to "int", + JAVA_LANG_LONG to "long", + JAVA_LANG_FLOAT to "float", + JAVA_LANG_DOUBLE to "double", + JAVA_LANG_CHARACTER to "char" + ) + private fun isConversionNeeded(actual: PsiType?, expected: PsiType?): Boolean { - if (actual == null || expected == null) { - return false - } + if (actual == null || expected == null) return false - val typeMap = HashMap() - typeMap.put(JAVA_LANG_BYTE, "byte") - typeMap.put(JAVA_LANG_SHORT, "short") - typeMap.put(JAVA_LANG_INTEGER, "int") - typeMap.put(JAVA_LANG_LONG, "long") - typeMap.put(JAVA_LANG_FLOAT, "float") - typeMap.put(JAVA_LANG_DOUBLE, "double") - typeMap.put(JAVA_LANG_CHARACTER, "char") - val expectedStr: String? = expected.getCanonicalText() - val actualStr: String? = actual.getCanonicalText() - val o1: Boolean = expectedStr == typeMap[actualStr] - val o2: Boolean = actualStr == typeMap[expectedStr] - return actualStr != expectedStr && (!(o1 xor o2)) + val expectedStr = expected.getCanonicalText() + val actualStr = actual.getCanonicalText() + if (expectedStr == actualStr) return false + val o1 = expectedStr == TYPE_MAP[actualStr] + val o2 = actualStr == TYPE_MAP[expectedStr] + return o1 == o2 } } -val NOT_NULL_ANNOTATIONS: Set = ImmutableSet.of("org.jetbrains.annotations.NotNull", "com.sun.istack.internal.NotNull", "javax.annotation.Nonnull")!! -val PRIMITIVE_TYPE_CONVERSIONS: Map = ImmutableMap.builder() -?.put("byte", BYTE.asString()) -?.put("short", SHORT.asString()) -?.put("int", INT.asString()) -?.put("long", LONG.asString()) -?.put("float", FLOAT.asString()) -?.put("double", DOUBLE.asString()) -?.put("char", CHAR.asString()) -?.put(JAVA_LANG_BYTE, BYTE.asString()) -?.put(JAVA_LANG_SHORT, SHORT.asString()) -?.put(JAVA_LANG_INTEGER, INT.asString()) -?.put(JAVA_LANG_LONG, LONG.asString()) -?.put(JAVA_LANG_FLOAT, FLOAT.asString()) -?.put(JAVA_LANG_DOUBLE, DOUBLE.asString()) -?.put(JAVA_LANG_CHARACTER, CHAR.asString()) -?.build()!! +val NOT_NULL_ANNOTATIONS: Set = setOf("org.jetbrains.annotations.NotNull", "com.sun.istack.internal.NotNull", "javax.annotation.Nonnull") - -fun countWritingAccesses(element: PsiElement?, container: PsiElement?): Int { - var counter: Int = 0 - if (container != null) { - val visitor: ReferenceCollector = ReferenceCollector() - container.accept(visitor) - for (e : PsiReferenceExpression in visitor.getCollectedReferences()) - if (e.isReferenceTo(element) && PsiUtil.isAccessedForWriting(e)) { - counter++ - } - } - - return counter -} - -open class ReferenceCollector() : JavaRecursiveElementVisitor() { - private val myCollectedReferences = ArrayList() - - open fun getCollectedReferences(): List { - return myCollectedReferences - } - - override fun visitReferenceExpression(expression: PsiReferenceExpression?) { - super.visitReferenceExpression(expression) - if (expression != null) { - myCollectedReferences.add(expression) - } - } -} - -fun isReadOnly(element: PsiElement?, container: PsiElement?): Boolean { - return countWritingAccesses(element, container) == 0 -} - -fun isAnnotatedAsNotNull(modifierList: PsiModifierList?): Boolean { - if (modifierList != null) { - val annotations: Array = modifierList.getAnnotations() - for (a : PsiAnnotation in annotations) { - val qualifiedName: String? = a.getQualifiedName() - if (qualifiedName != null && NOT_NULL_ANNOTATIONS.contains(qualifiedName)) { - return true - } - } - } - return false -} - -fun isDefinitelyNotNull(element: PsiElement?): Boolean = when(element) { - is PsiLiteralExpression -> element.getValue() != null - is PsiNewExpression -> true - else -> false -} - -fun getDefaultInitializer(f: Field): String { - if (f.`type`.nullable) { - return "null" - } - else { - val typeToKotlin = f.`type`.toKotlin() - if (typeToKotlin.equals("Boolean")) - return "false" - - if (typeToKotlin.equals("Char")) - return "' '" - - if (typeToKotlin.equals("Double")) - return "0." + OperatorConventions.DOUBLE + "()" - - if (typeToKotlin.equals("Float")) - return "0." + OperatorConventions.FLOAT + "()" - - return "0" - } -} \ No newline at end of file +val PRIMITIVE_TYPE_CONVERSIONS: Map = mapOf( + "byte" to BYTE.asString(), + "short" to SHORT.asString(), + "int" to INT.asString(), + "long" to LONG.asString(), + "float" to FLOAT.asString(), + "double" to DOUBLE.asString(), + "char" to CHAR.asString(), + JAVA_LANG_BYTE to BYTE.asString(), + JAVA_LANG_SHORT to SHORT.asString(), + JAVA_LANG_INTEGER to INT.asString(), + JAVA_LANG_LONG to LONG.asString(), + JAVA_LANG_FLOAT to FLOAT.asString(), + JAVA_LANG_DOUBLE to DOUBLE.asString(), + JAVA_LANG_CHARACTER to CHAR.asString() +) diff --git a/j2k/src/org/jetbrains/jet/j2k/JavaToKotlinTranslator.kt b/j2k/src/org/jetbrains/jet/j2k/JavaToKotlinTranslator.kt index abb7da62ccb..4bc31473654 100644 --- a/j2k/src/org/jetbrains/jet/j2k/JavaToKotlinTranslator.kt +++ b/j2k/src/org/jetbrains/jet/j2k/JavaToKotlinTranslator.kt @@ -92,7 +92,7 @@ public object JavaToKotlinTranslator { val c = ClassVisitor() psiFile.accept(c) converter.clearClassIdentifiers() - converter.setClassIdentifiers(HashSet(c.getClassIdentifiers())) + converter.setClassIdentifiers(HashSet(c.classIdentifiers)) } fun generateKotlinCode(javaCode: String): String { diff --git a/j2k/src/org/jetbrains/jet/j2k/MethodUtils.kt b/j2k/src/org/jetbrains/jet/j2k/MethodUtils.kt index 4b883ebfdd6..3784c0a65de 100644 --- a/j2k/src/org/jetbrains/jet/j2k/MethodUtils.kt +++ b/j2k/src/org/jetbrains/jet/j2k/MethodUtils.kt @@ -69,10 +69,8 @@ fun isNotOpenMethod(method: PsiMethod): Boolean { fun directlyOverridesMethodFromObject(method: PsiMethod): Boolean { var superSignatures = method.getHierarchicalMethodSignature().getSuperSignatures() if (superSignatures.size() == 1) { - val qualifiedName = superSignatures.first!!.getMethod().getContainingClass()?.getQualifiedName() - if (qualifiedName == JAVA_LANG_OBJECT) { - return true - } + val qualifiedName = superSignatures.single().getMethod().getContainingClass()?.getQualifiedName() + return qualifiedName == JAVA_LANG_OBJECT } return false } \ No newline at end of file diff --git a/j2k/src/org/jetbrains/jet/j2k/Utils.kt b/j2k/src/org/jetbrains/jet/j2k/Utils.kt new file mode 100644 index 00000000000..d514d63f632 --- /dev/null +++ b/j2k/src/org/jetbrains/jet/j2k/Utils.kt @@ -0,0 +1,86 @@ +/* + * Copyright 2010-2014 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +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 + +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() + + public val collectedReferences: List + get() = _collectedReferences + + override fun visitReferenceExpression(expression: PsiReferenceExpression) { + super.visitReferenceExpression(expression) + _collectedReferences.add(expression) + } + } + + val collector = ReferenceCollector() + container.accept(collector) + return collector.collectedReferences.count { it.isReferenceTo(element) && PsiUtil.isAccessedForWriting(it) } +} + +fun isReadOnly(element: PsiElement?, container: PsiElement?): Boolean + = countWriteAccesses(element, container) == 0 + +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 + is PsiNewExpression -> true + else -> false +} + +fun getDefaultInitializer(field: Field): String { + if (field.`type`.isNullable) { + return "null" + } + else { + return when(field.`type`.toKotlin()) { + "Boolean" -> "false" + "Char" -> "' '" + "Double" -> "0." + OperatorConventions.DOUBLE + "()" + "Float" -> "0." + OperatorConventions.FLOAT + "()" + else -> "0" + } + } +} \ No newline at end of file diff --git a/j2k/src/org/jetbrains/jet/j2k/ast/AnonymousClass.kt b/j2k/src/org/jetbrains/jet/j2k/ast/AnonymousClass.kt index 2cb5c7a07e0..61d99ecd2bb 100644 --- a/j2k/src/org/jetbrains/jet/j2k/ast/AnonymousClass.kt +++ b/j2k/src/org/jetbrains/jet/j2k/ast/AnonymousClass.kt @@ -26,8 +26,9 @@ class AnonymousClass(converter: Converter, members: List) MemberComments.Empty, Collections.emptySet(), TypeParameterList.Empty, - Collections.emptyList(), - Collections.emptyList(), - Collections.emptyList(), members) { + listOf(), + listOf(), + listOf(), + members) { override fun toKotlin() = bodyToKotlin() } diff --git a/j2k/src/org/jetbrains/jet/j2k/ast/Block.kt b/j2k/src/org/jetbrains/jet/j2k/ast/Block.kt index 97653605397..1454b5c63ca 100644 --- a/j2k/src/org/jetbrains/jet/j2k/ast/Block.kt +++ b/j2k/src/org/jetbrains/jet/j2k/ast/Block.kt @@ -30,12 +30,12 @@ class Block(val statementList: StatementList, val notEmpty: Boolean = false) : S val statements: List = statementList.statements - override fun isEmpty(): Boolean { - return !notEmpty && statements.all { it.isEmpty() } - } + + override val isEmpty: Boolean + get() = !notEmpty && statements.all { it.isEmpty } override fun toKotlin(): String { - if (!isEmpty()) { + if (!isEmpty) { return "{${statementList.toKotlin()}}" } diff --git a/j2k/src/org/jetbrains/jet/j2k/ast/CallChainExpression.kt b/j2k/src/org/jetbrains/jet/j2k/ast/CallChainExpression.kt index 27a16de4a77..d18af29a2a6 100644 --- a/j2k/src/org/jetbrains/jet/j2k/ast/CallChainExpression.kt +++ b/j2k/src/org/jetbrains/jet/j2k/ast/CallChainExpression.kt @@ -17,14 +17,15 @@ package org.jetbrains.jet.j2k.ast class CallChainExpression(val expression: Expression, val identifier: Expression) : Expression() { - override fun isNullable(): Boolean { - if (!expression.isEmpty() && expression.isNullable()) return true - return identifier.isNullable() - } + override val isNullable: Boolean + get() { + if (!expression.isEmpty && expression.isNullable) return true + return identifier.isNullable + } override fun toKotlin(): String { - if (!expression.isEmpty()) { - return expression.toKotlin() + (if (expression.isNullable()) "?." else ".") + identifier.toKotlin() + if (!expression.isEmpty) { + return expression.toKotlin() + (if (expression.isNullable) "?." else ".") + identifier.toKotlin() } return identifier.toKotlin() diff --git a/j2k/src/org/jetbrains/jet/j2k/ast/Class.kt b/j2k/src/org/jetbrains/jet/j2k/ast/Class.kt index 9f1a77020de..661170885fe 100644 --- a/j2k/src/org/jetbrains/jet/j2k/ast/Class.kt +++ b/j2k/src/org/jetbrains/jet/j2k/ast/Class.kt @@ -45,7 +45,7 @@ open class Class( fun primaryConstructorBodyToKotlin(): String? { val maybeConstructor = classMembers.primaryConstructor - if (maybeConstructor != null && !(maybeConstructor.block?.isEmpty() ?: true)) { + if (maybeConstructor != null && !(maybeConstructor.block?.isEmpty ?: true)) { return "\n" + maybeConstructor.primaryBodyToKotlin() + "\n" } return "" diff --git a/j2k/src/org/jetbrains/jet/j2k/ast/Element.kt b/j2k/src/org/jetbrains/jet/j2k/ast/Element.kt index 19a87da3f6b..4e4f0f2bed5 100644 --- a/j2k/src/org/jetbrains/jet/j2k/ast/Element.kt +++ b/j2k/src/org/jetbrains/jet/j2k/ast/Element.kt @@ -18,11 +18,11 @@ package org.jetbrains.jet.j2k.ast trait Element : Node { - fun isEmpty(): Boolean = false + val isEmpty: Boolean get() = false object Empty : Element { override fun toKotlin() = "" - override fun isEmpty() = true + override val isEmpty: Boolean get() = true } } diff --git a/j2k/src/org/jetbrains/jet/j2k/ast/Expression.kt b/j2k/src/org/jetbrains/jet/j2k/ast/Expression.kt index d03230a21c8..2152a1d6fa3 100644 --- a/j2k/src/org/jetbrains/jet/j2k/ast/Expression.kt +++ b/j2k/src/org/jetbrains/jet/j2k/ast/Expression.kt @@ -18,12 +18,11 @@ package org.jetbrains.jet.j2k.ast abstract class Expression() : Statement() { - open fun isNullable(): Boolean { - return false - } + open val isNullable: Boolean get() = false object Empty : Expression() { override fun toKotlin() = "" - override fun isEmpty() = true + + override val isEmpty: Boolean get() = true } } diff --git a/j2k/src/org/jetbrains/jet/j2k/ast/ExpressionList.kt b/j2k/src/org/jetbrains/jet/j2k/ast/ExpressionList.kt index 742b056cd76..614dd5f9114 100644 --- a/j2k/src/org/jetbrains/jet/j2k/ast/ExpressionList.kt +++ b/j2k/src/org/jetbrains/jet/j2k/ast/ExpressionList.kt @@ -18,5 +18,7 @@ package org.jetbrains.jet.j2k.ast open class ExpressionList(val expressions: List) : Expression() { override fun toKotlin(): String = expressions.map { it.toKotlin() }.makeString(", ") - override fun isEmpty(): Boolean = expressions.isEmpty() + + override val isEmpty: Boolean + get() = expressions.isEmpty() } diff --git a/j2k/src/org/jetbrains/jet/j2k/ast/Expressions.kt b/j2k/src/org/jetbrains/jet/j2k/ast/Expressions.kt index a38cd866758..bfcbe495968 100644 --- a/j2k/src/org/jetbrains/jet/j2k/ast/Expressions.kt +++ b/j2k/src/org/jetbrains/jet/j2k/ast/Expressions.kt @@ -20,7 +20,7 @@ import org.jetbrains.jet.j2k.ast.types.Type open class ArrayAccessExpression(val expression: Expression, val index: Expression, val lvalue: Boolean) : Expression() { override fun toKotlin() = expression.toKotlin() + - (if (!lvalue && expression.isNullable()) "!!" else "") + + (if (!lvalue && expression.isNullable) "!!" else "") + "[" + index.toKotlin() + "]" } @@ -58,7 +58,9 @@ open class ParenthesizedExpression(val expression: Expression) : Expression() { open class PrefixOperator(val op: String, val expression: Expression) : Expression() { override fun toKotlin() = op + expression.toKotlin() - override fun isNullable() = expression.isNullable() + + override val isNullable: Boolean + get() = expression.isNullable } open class PostfixOperator(val op: String, val expression: Expression) : Expression() { diff --git a/j2k/src/org/jetbrains/jet/j2k/ast/Field.kt b/j2k/src/org/jetbrains/jet/j2k/ast/Field.kt index a151d99d8c2..b1b14b6d409 100644 --- a/j2k/src/org/jetbrains/jet/j2k/ast/Field.kt +++ b/j2k/src/org/jetbrains/jet/j2k/ast/Field.kt @@ -48,7 +48,7 @@ open class Field( override fun toKotlin(): String { val declaration: String = commentsToKotlin() + modifiersToKotlin() + identifier.toKotlin() + " : " + `type`.toKotlin() - if (initializer.isEmpty()) { + if (initializer.isEmpty) { return declaration + ((if (isVal() && !isStatic() && writingAccesses != 0) "" else diff --git a/j2k/src/org/jetbrains/jet/j2k/ast/Identifier.kt b/j2k/src/org/jetbrains/jet/j2k/ast/Identifier.kt index 2e8d5889cbf..35027e25253 100644 --- a/j2k/src/org/jetbrains/jet/j2k/ast/Identifier.kt +++ b/j2k/src/org/jetbrains/jet/j2k/ast/Identifier.kt @@ -17,31 +17,28 @@ package org.jetbrains.jet.j2k.ast -open class Identifier( +class Identifier( val name: String, - val myNullable: Boolean = true, - val quotingNeeded: Boolean = true + public override val isNullable: Boolean = true, + private val quotingNeeded: Boolean = true ) : Expression() { - override fun isEmpty() = name.length() == 0 - private open fun ifNeedQuote(): String { - if (quotingNeeded && (ONLY_KOTLIN_KEYWORDS.contains(name)) || name.contains("$")) { + override val isEmpty: Boolean + get() = name.isEmpty() + + override fun toKotlin(): String { + if (quotingNeeded && ONLY_KOTLIN_KEYWORDS.contains(name) || name.contains("$")) { return quote(name) } return name } - override fun toKotlin(): String = ifNeedQuote() - override fun isNullable(): Boolean = myNullable + private fun quote(str: String): String = "`" + str + "`" class object { val Empty = Identifier("") - private open fun quote(str: String): String { - return "`" + str + "`" - } - val ONLY_KOTLIN_KEYWORDS: Set = setOf( "package", "as", "type", "val", "var", "fun", "is", "in", "object", "when", "trait", "This" ); diff --git a/j2k/src/org/jetbrains/jet/j2k/ast/Imports.kt b/j2k/src/org/jetbrains/jet/j2k/ast/Imports.kt index 3275689a062..8bbf9dcac9d 100644 --- a/j2k/src/org/jetbrains/jet/j2k/ast/Imports.kt +++ b/j2k/src/org/jetbrains/jet/j2k/ast/Imports.kt @@ -42,9 +42,9 @@ class ImportList(val imports: List) : Element { } } - override fun isEmpty(): Boolean { - return filteredImports.isEmpty() - } + + override val isEmpty: Boolean + get() = filteredImports.isEmpty() override fun toKotlin() = filteredImports.toKotlin("\n") } diff --git a/j2k/src/org/jetbrains/jet/j2k/ast/LocalVariable.kt b/j2k/src/org/jetbrains/jet/j2k/ast/LocalVariable.kt index 85b05bcd431..dc8dfd8ce0d 100644 --- a/j2k/src/org/jetbrains/jet/j2k/ast/LocalVariable.kt +++ b/j2k/src/org/jetbrains/jet/j2k/ast/LocalVariable.kt @@ -27,11 +27,11 @@ class LocalVariable( val converter: Converter ) : Expression() { - fun isImmutable(): Boolean = - converter.settings.forceLocalVariableImmutability || modifiersSet.contains(Modifier.FINAL) + val isImmutable: Boolean + get() = converter.settings.forceLocalVariableImmutability || modifiersSet.contains(Modifier.FINAL) override fun toKotlin(): String { - if (initializer.isEmpty()) { + if (initializer.isEmpty) { return "${identifier.toKotlin()} : ${javaType.toKotlin()}" } diff --git a/j2k/src/org/jetbrains/jet/j2k/ast/MethodCallExpression.kt b/j2k/src/org/jetbrains/jet/j2k/ast/MethodCallExpression.kt index 1f911ea7c7a..63264d8c38e 100644 --- a/j2k/src/org/jetbrains/jet/j2k/ast/MethodCallExpression.kt +++ b/j2k/src/org/jetbrains/jet/j2k/ast/MethodCallExpression.kt @@ -25,7 +25,9 @@ open class MethodCallExpression( val typeParameters: List, val resultIsNullable: Boolean = false ) : Expression() { - override fun isNullable(): Boolean = methodCall.isNullable() || resultIsNullable + + override val isNullable: Boolean + get() = methodCall.isNullable || resultIsNullable override fun toKotlin(): String { val typeParamsToKotlin: String = typeParameters.toKotlin(", ", "<", ">") diff --git a/j2k/src/org/jetbrains/jet/j2k/ast/NewClassExpression.kt b/j2k/src/org/jetbrains/jet/j2k/ast/NewClassExpression.kt index d05bb973a19..d94639b17c5 100644 --- a/j2k/src/org/jetbrains/jet/j2k/ast/NewClassExpression.kt +++ b/j2k/src/org/jetbrains/jet/j2k/ast/NewClassExpression.kt @@ -23,11 +23,11 @@ open class NewClassExpression( val anonymousClass: AnonymousClass? = null ) : Expression() { override fun toKotlin(): String { - val callOperator: String? = (if (qualifier.isNullable()) + val callOperator: String? = (if (qualifier.isNullable) "?." else ".") - val qualifier: String? = (if (qualifier.isEmpty()) + val qualifier: String? = (if (qualifier.isEmpty) "" else qualifier.toKotlin() + callOperator) diff --git a/j2k/src/org/jetbrains/jet/j2k/ast/Statements.kt b/j2k/src/org/jetbrains/jet/j2k/ast/Statements.kt index 98756847148..7486d969bc6 100644 --- a/j2k/src/org/jetbrains/jet/j2k/ast/Statements.kt +++ b/j2k/src/org/jetbrains/jet/j2k/ast/Statements.kt @@ -20,22 +20,18 @@ package org.jetbrains.jet.j2k.ast abstract class Statement() : Element { object Empty : Statement() { override fun toKotlin() = "" - override fun isEmpty() = true + + override val isEmpty: Boolean + get() = true } } open class DeclarationStatement(val elements: List) : Statement() { - override fun toKotlin(): String { - return elements.filter { it is LocalVariable }.map { convertDeclaration(it as LocalVariable) }.makeString("\n") - } + override fun toKotlin(): String + = elements.filterIsInstance(javaClass()).map { convertDeclaration(it) }.makeString("\n") - private fun convertDeclaration(v: LocalVariable): String { - val varKeyword: String? = (if (v.isImmutable()) - "val" - else - "var") - return varKeyword + " " + v.toKotlin() - } + private fun convertDeclaration(v: LocalVariable): String + = (if (v.isImmutable) "val" else "var") + " " + v.toKotlin() } open class ExpressionListStatement(val expressions: List) : Expression() { @@ -80,7 +76,7 @@ open class ForeachStatement( val expression: Expression, val body: Element ) : Statement() { - override fun toKotlin() = "for (" + variable.identifier.name + " in " + + override fun toKotlin() = "for (" + variable.identifier.toKotlin() + " in " + expression.toKotlin() + ")\n" + body.toKotlin() } @@ -104,10 +100,16 @@ open class ContinueStatement(val label: Identifier = Identifier.Empty) : Stateme open class TryStatement(val block: Block, val catches: List, val finallyBlock: Block) : Statement() { override fun toKotlin(): String { - return "try\n" + block.toKotlin() + "\n" + catches.toKotlin("\n") + "\n" + (if (finallyBlock.isEmpty()) - "" - else - "finally\n" + finallyBlock.toKotlin()) + val builder = StringBuilder() + .append("try\n") + .append(block.toKotlin()) + .append("\n") + .append(catches.toKotlin("\n")) + .append("\n") + if (!finallyBlock.isEmpty) { + builder.append("finally\n").append(finallyBlock.toKotlin()) + } + return builder.toString() } } @@ -126,14 +128,9 @@ open class SwitchContainer(val expression: Expression, val caseContainers: List< } open class CaseContainer(val caseStatement: List, statements: List) : Statement() { - private val myBlock: Block + private val block = Block(statements.filterNot { it is BreakStatement || it is ContinueStatement }, true) - { - val newStatements = statements.filterNot { it is BreakStatement || it is ContinueStatement } - myBlock = Block(newStatements, true) - } - - override fun toKotlin() = caseStatement.toKotlin(", ") + " -> " + myBlock.toKotlin() + override fun toKotlin() = caseStatement.toKotlin(", ") + " -> " + block.toKotlin() } open class SwitchLabelStatement(val expression: Expression) : Statement() { @@ -152,5 +149,5 @@ open class SynchronizedStatement(val expression: Expression, val block: Block) : class StatementList(elements: List) : WhiteSpaceSeparatedElementList(elements, WhiteSpace.NewLine) { val statements: List - get() = elements.filter { it is Statement }.map { it as Statement } + get() = elements.filterIsInstance(javaClass()) } \ No newline at end of file diff --git a/j2k/src/org/jetbrains/jet/j2k/ast/TypeParameters.kt b/j2k/src/org/jetbrains/jet/j2k/ast/TypeParameters.kt index 82b9692cbb6..803fe1714d8 100644 --- a/j2k/src/org/jetbrains/jet/j2k/ast/TypeParameters.kt +++ b/j2k/src/org/jetbrains/jet/j2k/ast/TypeParameters.kt @@ -56,7 +56,9 @@ class TypeParameterList(val parameters: List) : Element { return "" } - override fun isEmpty(): Boolean = parameters.isEmpty() + + override val isEmpty: Boolean + get() = parameters.isEmpty() private fun hasWhere(): Boolean = parameters.any { it.hasWhere() } diff --git a/j2k/src/org/jetbrains/jet/j2k/ast/Util.kt b/j2k/src/org/jetbrains/jet/j2k/ast/Util.kt index 6a5ecd1f472..0ace8e6159a 100644 --- a/j2k/src/org/jetbrains/jet/j2k/ast/Util.kt +++ b/j2k/src/org/jetbrains/jet/j2k/ast/Util.kt @@ -18,60 +18,32 @@ package org.jetbrains.jet.j2k.ast import java.util.ArrayList -fun List.toKotlin(separator: String, prefix: String = "", suffix: String = ""): String { - val result = StringBuilder() - if (size() > 0) { - result.append(prefix) - var first = true - for (x in this) { - if (!first) result.append(separator) - first = false - result.append(x.toKotlin()) - } - result.append(suffix) - } - return result.toString() -} +fun List.toKotlin(separator: String, prefix: String = "", postfix: String = ""): String + = if (isNotEmpty()) map { it.toKotlin() }.makeString(separator, prefix, postfix) else "" -fun Collection.toKotlin(separator: String = " "): String { - val result = StringBuilder() - for (x in this) { - result.append(x.name) - result.append(separator) - } - return result.toString() -} +fun Collection.toKotlin(separator: String = " "): String + = if (isNotEmpty()) map { it.name }.makeString(separator) + separator else "" fun String.withSuffix(suffix: String): String = if (isEmpty()) "" else this + suffix fun String.withPrefix(prefix: String): String = if (isEmpty()) "" else prefix + this -fun Expression.withPrefix(prefix: String): String = if (isEmpty()) "" else prefix + toKotlin() +fun Expression.withPrefix(prefix: String): String = if (isEmpty) "" else prefix + toKotlin() open class WhiteSpaceSeparatedElementList( val elements: List, val minimalWhiteSpace: WhiteSpace, val ensureSurroundedByWhiteSpace: Boolean = true ) { - val nonEmptyElements = elements.filterNot { it.isEmpty() } + val nonEmptyElements = elements.filter { !it.isEmpty } fun isEmpty() = nonEmptyElements.all { it is WhiteSpace } fun toKotlin(): String { - if (isEmpty()) { - return "" - } + if (isEmpty()) return "" return nonEmptyElements.surroundWithWhiteSpaces().insertAndMergeWhiteSpaces().map { it.toKotlin() }.makeString("") } - private fun List.surroundWithWhiteSpaces(): List { - if (!ensureSurroundedByWhiteSpace) { - return this - } - val result = ArrayList() - result.add(minimalWhiteSpace) - result.addAll(this) - result.add(minimalWhiteSpace) - return result - } + private fun List.surroundWithWhiteSpaces(): List + = if (ensureSurroundedByWhiteSpace) listOf(minimalWhiteSpace) + this + listOf(minimalWhiteSpace) else this // ensure that there is whitespace between non-whitespace elements @@ -80,22 +52,20 @@ open class WhiteSpaceSeparatedElementList( private fun List.insertAndMergeWhiteSpaces(): List { var currentWhiteSpace: WhiteSpace? = null val result = ArrayList() - var isFirst = true - for (element in this) { + for (i in 0..lastIndex) { + val element = get(i) if (element is WhiteSpace) { if (currentWhiteSpace == null || element > currentWhiteSpace!!) { currentWhiteSpace = if (element > minimalWhiteSpace) element else minimalWhiteSpace } } else { - if (!isFirst) { - //do not insert whitespace before first element + if (i != 0) { //do not insert whitespace before first element result.add(currentWhiteSpace ?: minimalWhiteSpace) } result.add(element) currentWhiteSpace = null } - isFirst = false } if (currentWhiteSpace != null) { result.add(currentWhiteSpace!!) diff --git a/j2k/src/org/jetbrains/jet/j2k/ast/WhiteSpace.kt b/j2k/src/org/jetbrains/jet/j2k/ast/WhiteSpace.kt index 91d70e56f6d..4f0e275932a 100644 --- a/j2k/src/org/jetbrains/jet/j2k/ast/WhiteSpace.kt +++ b/j2k/src/org/jetbrains/jet/j2k/ast/WhiteSpace.kt @@ -19,16 +19,16 @@ package org.jetbrains.jet.j2k.ast class WhiteSpace(val text: String) : Element { override fun toKotlin() = text - override fun isEmpty() = text.isEmpty() + + override val isEmpty: Boolean + get() = text.isEmpty() fun compareTo(other: WhiteSpace): Int { fun newLinesCount(w: WhiteSpace) = w.text.count { it == '\n' } val lineCountDiff = newLinesCount(this) - newLinesCount(other) - if (lineCountDiff != 0) { - return lineCountDiff - } + if (lineCountDiff != 0) return lineCountDiff fun spacesCount(w: WhiteSpace) = w.text.count { it == ' ' } diff --git a/j2k/src/org/jetbrains/jet/j2k/ast/types/Type.kt b/j2k/src/org/jetbrains/jet/j2k/ast/types/Type.kt index 29741bea4c1..c02d85e56b5 100644 --- a/j2k/src/org/jetbrains/jet/j2k/ast/types/Type.kt +++ b/j2k/src/org/jetbrains/jet/j2k/ast/types/Type.kt @@ -23,11 +23,11 @@ fun Type.isPrimitive(): Boolean = this is PrimitiveType fun Type.isUnit(): Boolean = this == UnitType abstract class MayBeNullableType(nullable: Boolean, val converter: Converter) : Type { - override val nullable: Boolean = !converter.settings.forceNotNullTypes && nullable + override val isNullable: Boolean = !converter.settings.forceNotNullTypes && nullable } trait NotNullType : Type { - override val nullable: Boolean + override val isNullable: Boolean get() = false } @@ -36,15 +36,14 @@ object UnitType: NotNullType { } trait Type : Element { - - val nullable: Boolean + val isNullable: Boolean open fun convertedToNotNull(): Type { - if (nullable) throw UnsupportedOperationException("convertedToNotNull must be defined") + if (isNullable) throw UnsupportedOperationException("convertedToNotNull must be defined") return this } protected fun isNullableStr(): String? { - return if (nullable) "?" else "" + return if (isNullable) "?" else "" } } diff --git a/j2k/src/org/jetbrains/jet/j2k/visitors/ClassVisitor.kt b/j2k/src/org/jetbrains/jet/j2k/visitors/ClassVisitor.kt index 1f88b1a19fd..388707d8c58 100644 --- a/j2k/src/org/jetbrains/jet/j2k/visitors/ClassVisitor.kt +++ b/j2k/src/org/jetbrains/jet/j2k/visitors/ClassVisitor.kt @@ -21,16 +21,15 @@ import com.intellij.psi.PsiClass import java.util.HashSet public open class ClassVisitor() : JavaRecursiveElementVisitor() { - private val myClassIdentifiers = HashSet() + private val _classIdentifiers = HashSet() - public fun getClassIdentifiers(): Set { - return HashSet(myClassIdentifiers) - } + public val classIdentifiers: Set + get() = _classIdentifiers - override fun visitClass(aClass: PsiClass?) { - val qName = aClass?.getQualifiedName() + override fun visitClass(aClass: PsiClass) { + val qName = aClass.getQualifiedName() if (qName != null) { - myClassIdentifiers.add(qName) + _classIdentifiers.add(qName) } super.visitClass(aClass) } diff --git a/j2k/src/org/jetbrains/jet/j2k/visitors/ElementVisitor.kt b/j2k/src/org/jetbrains/jet/j2k/visitors/ElementVisitor.kt index 74f2e274f16..8ec1176e663 100644 --- a/j2k/src/org/jetbrains/jet/j2k/visitors/ElementVisitor.kt +++ b/j2k/src/org/jetbrains/jet/j2k/visitors/ElementVisitor.kt @@ -21,71 +21,61 @@ import org.jetbrains.jet.j2k.* import org.jetbrains.jet.j2k.ast.* import org.jetbrains.jet.j2k.ast.types.Type -open class ElementVisitor(val myConverter: Converter) : JavaElementVisitor() { - protected var myResult: Element = Element.Empty +class ElementVisitor(public val converter: Converter) : JavaElementVisitor() { + public var result: Element = Element.Empty + protected set - fun getConverter(): Converter { - return myConverter - } - - open fun getResult(): Element { - return myResult - } - - override fun visitLocalVariable(variable: PsiLocalVariable?) { - val theVariable = variable!! - var kType = myConverter.convertType(theVariable.getType(), isAnnotatedAsNotNull(theVariable.getModifierList())) - if (theVariable.hasModifierProperty(PsiModifier.FINAL) && isDefinitelyNotNull(theVariable.getInitializer())) { + 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(); } - myResult = LocalVariable(Identifier(theVariable.getName()!!), - myConverter.convertModifierList(theVariable.getModifierList()), + result = LocalVariable(Identifier(variable.getName()!!), + converter.convertModifierList(variable.getModifierList()), kType, - myConverter.convertExpression(theVariable.getInitializer(), theVariable.getType()), - myConverter) + converter.convertExpression(variable.getInitializer(), variable.getType()), + converter) } - override fun visitExpressionList(list: PsiExpressionList?) { - myResult = ExpressionList(myConverter.convertExpressions(list!!.getExpressions())) + override fun visitExpressionList(list: PsiExpressionList) { + result = ExpressionList(converter.convertExpressions(list.getExpressions())) } - override fun visitReferenceElement(reference: PsiJavaCodeReferenceElement?) { - val theReference = reference!! - val types: List = myConverter.convertTypes(theReference.getTypeParameters()) - if (!theReference.isQualified()) { - myResult = ReferenceElement(Identifier(theReference.getReferenceName()!!), types) + override fun visitReferenceElement(reference: PsiJavaCodeReferenceElement) { + val types = converter.convertTypes(reference.getTypeParameters()) + if (!reference.isQualified()) { + result = ReferenceElement(Identifier(reference.getReferenceName()!!), types) } else { - var result: String = Identifier(reference.getReferenceName()!!).toKotlin() - var qualifier: PsiElement? = theReference.getQualifier() - while (qualifier != null) - { - val p: PsiJavaCodeReferenceElement = (qualifier as PsiJavaCodeReferenceElement) - result = Identifier(p.getReferenceName()!!).toKotlin() + "." + result + var code = Identifier(reference.getReferenceName()!!).toKotlin() + var qualifier = reference.getQualifier() + while (qualifier != null) { + val p = qualifier as PsiJavaCodeReferenceElement + code = Identifier(p.getReferenceName()!!).toKotlin() + "." + code qualifier = p.getQualifier() } - myResult = ReferenceElement(Identifier(result), types) + result = ReferenceElement(Identifier(code), types) } } - override fun visitTypeElement(`type`: PsiTypeElement?) { - myResult = TypeElement(myConverter.convertType(`type`!!.getType())) + override fun visitTypeElement(`type`: PsiTypeElement) { + result = TypeElement(converter.convertType(`type`.getType())) } - override fun visitTypeParameter(classParameter: PsiTypeParameter?) { - myResult = TypeParameter(Identifier(classParameter!!.getName()!!), - classParameter.getExtendsListTypes().map { myConverter.convertType(it) }) + override fun visitTypeParameter(classParameter: PsiTypeParameter) { + result = TypeParameter(Identifier(classParameter.getName()!!), + classParameter.getExtendsListTypes().map { converter.convertType(it) }) } - override fun visitParameterList(list: PsiParameterList?) { - myResult = ParameterList(myConverter.convertParameterList(list!!.getParameters()).requireNoNulls()) + override fun visitParameterList(list: PsiParameterList) { + result = ParameterList(converter.convertParameterList(list.getParameters())) } - override fun visitComment(comment: PsiComment?) { - myResult = Comment(comment!!.getText()!!) + override fun visitComment(comment: PsiComment) { + result = Comment(comment.getText()!!) } - override fun visitWhiteSpace(space: PsiWhiteSpace?) { - myResult = WhiteSpace(space!!.getText()!!) + override fun visitWhiteSpace(space: PsiWhiteSpace) { + result = WhiteSpace(space.getText()!!) } } diff --git a/j2k/src/org/jetbrains/jet/j2k/visitors/ExpressionVisitor.kt b/j2k/src/org/jetbrains/jet/j2k/visitors/ExpressionVisitor.kt index d2ed7c1a75b..9c2393a083b 100644 --- a/j2k/src/org/jetbrains/jet/j2k/visitors/ExpressionVisitor.kt +++ b/j2k/src/org/jetbrains/jet/j2k/visitors/ExpressionVisitor.kt @@ -19,43 +19,36 @@ package org.jetbrains.jet.j2k.visitors import com.intellij.psi.* import com.intellij.psi.tree.IElementType import org.jetbrains.jet.j2k.ast.* -import org.jetbrains.jet.j2k.ast.types.Type import org.jetbrains.jet.lang.types.expressions.OperatorConventions import java.util.ArrayList -import java.util.Collections import com.intellij.psi.CommonClassNames.* import com.intellij.psi.util.PsiTreeUtil import org.jetbrains.jet.lang.types.lang.PrimitiveType import org.jetbrains.jet.j2k.* import org.jetbrains.jet.j2k.ast.types.ArrayType -open class ExpressionVisitor(converter: Converter) : StatementVisitor(converter) { - { - myResult = Expression.Empty - } +open class ExpressionVisitor(public val converter: Converter) : JavaElementVisitor() { + public var result: Expression = Expression.Empty + protected set - override fun getResult(): Expression { - return myResult as Expression - } - - override fun visitArrayAccessExpression(expression: PsiArrayAccessExpression?) { + override fun visitArrayAccessExpression(expression: PsiArrayAccessExpression) { val assignment = PsiTreeUtil.getParentOfType(expression, javaClass()) val lvalue = assignment != null && expression == assignment.getLExpression(); - myResult = ArrayAccessExpression(getConverter().convertExpression(expression?.getArrayExpression()), - getConverter().convertExpression(expression?.getIndexExpression()), + result = ArrayAccessExpression(converter.convertExpression(expression.getArrayExpression()), + converter.convertExpression(expression.getIndexExpression()), lvalue) } - override fun visitArrayInitializerExpression(expression: PsiArrayInitializerExpression?) { - val expressionType = getConverter().convertType(expression?.getType()) + override fun visitArrayInitializerExpression(expression: PsiArrayInitializerExpression) { + val expressionType = converter.convertType(expression.getType()) assert(expressionType is ArrayType) { "Array initializer must have array type" } - myResult = ArrayInitializerExpression(expressionType as ArrayType, - getConverter().convertExpressions(expression?.getInitializers()!!)) + result = ArrayInitializerExpression(expressionType as ArrayType, + converter.convertExpressions(expression.getInitializers())) } - override fun visitAssignmentExpression(expression: PsiAssignmentExpression?) { - val tokenType: IElementType = expression?.getOperationSign()?.getTokenType()!! - val secondOp: String = when(tokenType) { + override fun visitAssignmentExpression(expression: PsiAssignmentExpression) { + val tokenType = expression.getOperationSign().getTokenType() + val secondOp = when(tokenType) { JavaTokenType.GTGTEQ -> "shr" JavaTokenType.LTLTEQ -> "shl" JavaTokenType.XOREQ -> "xor" @@ -65,61 +58,61 @@ open class ExpressionVisitor(converter: Converter) : StatementVisitor(converter) else -> "" } - val lhs = getConverter().convertExpression(expression?.getLExpression()!!) - val rhs = getConverter().convertExpression(expression?.getRExpression()!!, expression?.getLExpression()?.getType()) + val lhs = converter.convertExpression(expression.getLExpression()) + val rhs = converter.convertExpression(expression.getRExpression()!!, expression.getLExpression().getType()) if (!secondOp.isEmpty()) { - myResult = AssignmentExpression(lhs, BinaryExpression(lhs, rhs, secondOp), "=") + result = AssignmentExpression(lhs, BinaryExpression(lhs, rhs, secondOp), "=") } else { - myResult = AssignmentExpression(lhs, rhs, expression?.getOperationSign()?.getText()!!) + result = AssignmentExpression(lhs, rhs, expression.getOperationSign().getText()!!) } } - override fun visitBinaryExpression(expression: PsiBinaryExpression?) { - val lhs = getConverter().convertExpression(expression?.getLOperand()!!, expression?.getType()) - val rhs = getConverter().convertExpression(expression?.getROperand(), expression?.getType()) - if (expression?.getOperationSign()?.getTokenType() == JavaTokenType.GTGTGT) { - myResult = MethodCallExpression.build(lhs, "ushr", listOf(rhs)) + override fun visitBinaryExpression(expression: PsiBinaryExpression) { + val lhs = converter.convertExpression(expression.getLOperand(), expression.getType()) + val rhs = converter.convertExpression(expression.getROperand(), expression.getType()) + if (expression.getOperationSign().getTokenType() == JavaTokenType.GTGTGT) { + result = MethodCallExpression.build(lhs, "ushr", listOf(rhs)) } else { - myResult = BinaryExpression(lhs, rhs, - getOperatorString(expression?.getOperationSign()?.getTokenType()!!)) + result = BinaryExpression(lhs, rhs, + getOperatorString(expression.getOperationSign().getTokenType())) } } - override fun visitClassObjectAccessExpression(expression: PsiClassObjectAccessExpression?) { - myResult = ClassObjectAccessExpression(getConverter().convertTypeElement(expression?.getOperand())) + override fun visitClassObjectAccessExpression(expression: PsiClassObjectAccessExpression) { + result = ClassObjectAccessExpression(converter.convertTypeElement(expression.getOperand())) } - override fun visitConditionalExpression(expression: PsiConditionalExpression?) { - val condition: PsiExpression? = expression?.getCondition() - val `type`: PsiType? = condition?.getType() - val e: Expression = (if (`type` != null) - getConverter().convertExpression(condition, `type`) + override fun visitConditionalExpression(expression: PsiConditionalExpression) { + val condition = expression.getCondition() + val `type` = condition.getType() + val e = if (`type` != null) + converter.convertExpression(condition, `type`) else - getConverter().convertExpression(condition)) - myResult = ParenthesizedExpression(IfStatement(e, - getConverter().convertExpression(expression?.getThenExpression()), - getConverter().convertExpression(expression?.getElseExpression()))) + converter.convertExpression(condition) + result = ParenthesizedExpression(IfStatement(e, + converter.convertExpression(expression.getThenExpression()), + converter.convertExpression(expression.getElseExpression()))) } - override fun visitExpressionList(list: PsiExpressionList?) { - myResult = ExpressionList(getConverter().convertExpressions(list!!.getExpressions())) + override fun visitExpressionList(list: PsiExpressionList) { + result = ExpressionList(converter.convertExpressions(list.getExpressions())) } - override fun visitInstanceOfExpression(expression: PsiInstanceOfExpression?) { - val checkType: PsiTypeElement? = expression?.getCheckType() - myResult = IsOperator(getConverter().convertExpression(expression?.getOperand()), - myConverter.convertTypeElement(checkType)) + override fun visitInstanceOfExpression(expression: PsiInstanceOfExpression) { + val checkType = expression.getCheckType() + result = IsOperator(converter.convertExpression(expression.getOperand()), + converter.convertTypeElement(checkType)) } - override fun visitLiteralExpression(expression: PsiLiteralExpression?) { - val value: Any? = expression?.getValue() - var text: String = expression?.getText()!! - val `type`: PsiType? = expression?.getType() + override fun visitLiteralExpression(expression: PsiLiteralExpression) { + val value = expression.getValue() + var text = expression.getText()!! + val `type` = expression.getType() if (`type` != null) { - val canonicalTypeStr: String? = `type`.getCanonicalText() - if (canonicalTypeStr?.equals("double")!! || canonicalTypeStr?.equals(JAVA_LANG_DOUBLE)!!) { + val canonicalTypeStr = `type`.getCanonicalText() + if (canonicalTypeStr == "double" || canonicalTypeStr == JAVA_LANG_DOUBLE) { text = text.replace("D", "").replace("d", "") if (!text.contains(".")) { text += ".0" @@ -127,124 +120,110 @@ open class ExpressionVisitor(converter: Converter) : StatementVisitor(converter) } - if (canonicalTypeStr?.equals("float")!! || canonicalTypeStr?.equals(JAVA_LANG_FLOAT)!!) { + if (canonicalTypeStr == "float" || canonicalTypeStr == JAVA_LANG_FLOAT) { text = text.replace("F", "").replace("f", "") + "." + OperatorConventions.FLOAT + "()" } - if (canonicalTypeStr?.equals("long")!! || canonicalTypeStr?.equals(JAVA_LANG_LONG)!!) { + if (canonicalTypeStr == "long" || canonicalTypeStr == JAVA_LANG_LONG) { text = text.replace("L", "").replace("l", "") } - if (canonicalTypeStr?.equals("int")!! || canonicalTypeStr?.equals(JAVA_LANG_INTEGER)!!) { - text = (if (value != null) value.toString() else text) + if (canonicalTypeStr == "int" || canonicalTypeStr == JAVA_LANG_INTEGER) { + text = if (value != null) value.toString() else text } } - myResult = LiteralExpression(text) + result = LiteralExpression(text) } - override fun visitMethodCallExpression(expression: PsiMethodCallExpression?) { - convertMethodCallExpression(expression!!) + override fun visitMethodCallExpression(expression: PsiMethodCallExpression) { + convertMethodCallExpression(expression) } protected fun convertMethodCallExpression(expression: PsiMethodCallExpression) { - if (!SuperVisitor.isSuper(expression.getMethodExpression()) || !isInsidePrimaryConstructor(expression)) { - myResult = MethodCallExpression(getConverter().convertExpression(expression.getMethodExpression()), - getConverter().convertArguments(expression), - getConverter().convertTypes(expression.getTypeArguments()), - getConverter().convertType(expression.getType()).nullable) + if (!isSuperConstructorRef(expression.getMethodExpression()) || !isInsidePrimaryConstructor(expression)) { + result = MethodCallExpression(converter.convertExpression(expression.getMethodExpression()), + converter.convertArguments(expression), + converter.convertTypes(expression.getTypeArguments()), + converter.convertType(expression.getType()).isNullable) } } - override fun visitNewExpression(expression: PsiNewExpression?) { - if (expression?.getArrayInitializer() != null) - { - myResult = createNewEmptyArray(expression) + override fun visitNewExpression(expression: PsiNewExpression) { + if (expression.getArrayInitializer() != null) { + result = createNewEmptyArray(expression) + } + else if (expression.getArrayDimensions().size > 0) { + result = createNewEmptyArrayWithoutInitialization(expression) + } + else { + result = createNewClassExpression(expression) } - else - if (expression?.getArrayDimensions()?.size!! > 0) { - myResult = createNewEmptyArrayWithoutInitialization(expression!!) - } - else - { - myResult = createNewClassExpression(expression) - } } - private fun createNewClassExpression(expression: PsiNewExpression?): Expression { - val anonymousClass: PsiAnonymousClass? = expression?.getAnonymousClass() - val constructor: PsiMethod? = expression?.resolveMethod() - var classReference: PsiJavaCodeReferenceElement? = expression?.getClassOrAnonymousClassReference() - val isNotConvertedClass: Boolean = classReference != null && !getConverter().getClassIdentifiers().contains(classReference?.getQualifiedName()) - var argumentList: PsiExpressionList? = expression?.getArgumentList() - var arguments: Array = (if (argumentList != null) - argumentList?.getExpressions()!! - else - array()) - if (constructor == null || isConstructorPrimary(constructor) || isNotConvertedClass) - { - return NewClassExpression(getConverter().convertElement(classReference), - getConverter().convertArguments(expression!!), - getConverter().convertExpression(expression.getQualifier()), - (if (anonymousClass != null) - getConverter().convertAnonymousClass(anonymousClass) - else - null)) + private fun createNewClassExpression(expression: PsiNewExpression): Expression { + val anonymousClass = expression.getAnonymousClass() + val constructor = expression.resolveMethod() + val classReference = expression.getClassOrAnonymousClassReference() + val isNotConvertedClass = classReference != null && !converter.getClassIdentifiers().contains(classReference.getQualifiedName()) + val argumentList = expression.getArgumentList() + var arguments = argumentList?.getExpressions() ?: array() + if (constructor == null || isConstructorPrimary(constructor) || isNotConvertedClass) { + return NewClassExpression(converter.convertElement(classReference), + converter.convertArguments(expression), + converter.convertExpression(expression.getQualifier()), + if (anonymousClass != null) converter.convertAnonymousClass(anonymousClass) else null) } - val reference: PsiJavaCodeReferenceElement? = expression?.getClassReference() - val typeParameters: List = (if (reference != null) - getConverter().convertTypes(reference.getTypeParameters()) - else - Collections.emptyList()) + val reference = expression.getClassReference() + val typeParameters = if (reference != null) converter.convertTypes(reference.getTypeParameters()) else listOf() return CallChainExpression(Identifier(constructor.getName(), false), - MethodCallExpression(Identifier("init"), getConverter().convertExpressions(arguments), typeParameters, false)) + MethodCallExpression(Identifier("init"), converter.convertExpressions(arguments), typeParameters, false)) } private fun createNewEmptyArrayWithoutInitialization(expression: PsiNewExpression): Expression { return ArrayWithoutInitializationExpression( - getConverter().convertType(expression.getType(), true), - getConverter().convertExpressions(expression.getArrayDimensions())) + converter.convertType(expression.getType(), true), + converter.convertExpressions(expression.getArrayDimensions())) } - private fun createNewEmptyArray(expression: PsiNewExpression?): Expression { - return getConverter().convertExpression(expression?.getArrayInitializer()) + private fun createNewEmptyArray(expression: PsiNewExpression): Expression { + return converter.convertExpression(expression.getArrayInitializer()) } - override fun visitParenthesizedExpression(expression: PsiParenthesizedExpression?) { - myResult = ParenthesizedExpression(getConverter().convertExpression(expression?.getExpression())) + override fun visitParenthesizedExpression(expression: PsiParenthesizedExpression) { + result = ParenthesizedExpression(converter.convertExpression(expression.getExpression())) } - override fun visitPostfixExpression(expression: PsiPostfixExpression?) { - myResult = PostfixOperator(getOperatorString(expression!!.getOperationSign().getTokenType()!!), - getConverter().convertExpression(expression.getOperand())) + override fun visitPostfixExpression(expression: PsiPostfixExpression) { + result = PostfixOperator(getOperatorString(expression.getOperationSign().getTokenType()), + converter.convertExpression(expression.getOperand())) } - override fun visitPrefixExpression(expression: PsiPrefixExpression?) { - val operand = getConverter().convertExpression(expression?.getOperand(), expression?.getOperand()!!.getType()) - val token = expression?.getOperationTokenType()!! + override fun visitPrefixExpression(expression: PsiPrefixExpression) { + val operand = converter.convertExpression(expression.getOperand(), expression.getOperand()!!.getType()) + val token = expression.getOperationTokenType() if (token == JavaTokenType.TILDE) { - myResult = MethodCallExpression.build(ParenthesizedExpression(operand), "inv", ArrayList()) + result = MethodCallExpression.build(ParenthesizedExpression(operand), "inv", ArrayList()) } else { - myResult = PrefixOperator(getOperatorString(token), operand) + result = PrefixOperator(getOperatorString(token), operand) } } - override fun visitReferenceExpression(expression: PsiReferenceExpression?) { - val isFieldReference: Boolean = isFieldReference(expression!!, getContainingClass(expression)) - val insideSecondaryConstructor: Boolean = isInsideSecondaryConstructor(expression) - val hasReceiver: Boolean = isFieldReference && insideSecondaryConstructor - val isThis: Boolean = isThisExpression(expression) + 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: Boolean = getConverter().convertType(expression.getType(), notNull).nullable - val className: String = getClassNameWithConstructor(expression) + val isNullable = converter.convertType(expression.getType(), notNull).isNullable + val className = getClassNameWithConstructor(expression) val referencedName = expression.getReferenceName()!! var identifier: Expression = Identifier(referencedName, isNullable) - val __: String = "__" val qualifier = expression.getQualifierExpression() if (hasReceiver) { - identifier = CallChainExpression(Identifier(__, false), Identifier(referencedName, isNullable)) + identifier = CallChainExpression(Identifier("__", false), Identifier(referencedName, isNullable)) } else if (insideSecondaryConstructor && isThis) { identifier = Identifier("val __ = " + className) @@ -255,29 +234,29 @@ open class ExpressionVisitor(converter: Converter) : StatementVisitor(converter) else if (qualifier == null) { val resolved = expression.getReference()?.resolve() if (resolved is PsiClass) { - val clazz = resolved as PsiClass - - if (PrimitiveType.values() any { it.getTypeName().asString() == clazz.getName() }) { - myResult = Identifier(clazz.getQualifiedName()!!, false) + if (PrimitiveType.values() any { it.getTypeName().asString() == resolved.getName() }) { + result = Identifier(resolved.getQualifiedName()!!, false) return } } - if (resolved is PsiMember && resolved.hasModifierProperty(PsiModifier.STATIC) && - resolved.getContainingClass() != null && - PsiTreeUtil.getParentOfType(expression, javaClass()) != resolved.getContainingClass() && - !isStaticallyImported(resolved, expression)) { + + if (resolved is PsiMember + && resolved.hasModifierProperty(PsiModifier.STATIC) + && resolved.getContainingClass() != null + && PsiTreeUtil.getParentOfType(expression, javaClass()) != resolved.getContainingClass() + && !isStaticallyImported(resolved, expression)) { var member = resolved as PsiMember - var result = Identifier(referencedName).toKotlin() + var code = Identifier(referencedName).toKotlin() while (member.getContainingClass() != null) { - result = Identifier(member.getContainingClass()!!.getName()!!).toKotlin() + "." + result + code = Identifier(member.getContainingClass()!!.getName()!!).toKotlin() + "." + code member = member.getContainingClass()!! } - myResult = Identifier(result, false, false) + result = Identifier(code, false, false) return } } - myResult = CallChainExpression(getConverter().convertExpression(qualifier), identifier) + result = CallChainExpression(converter.convertExpression(qualifier), identifier) } private fun isResolvedToNotNull(expression: PsiReference): Boolean { @@ -291,238 +270,193 @@ open class ExpressionVisitor(converter: Converter) : StatementVisitor(converter) return false; } - override fun visitSuperExpression(expression: PsiSuperExpression?) { - val qualifier: PsiJavaCodeReferenceElement? = expression?.getQualifier() - myResult = SuperExpression((if (qualifier != null) + override fun visitSuperExpression(expression: PsiSuperExpression) { + val qualifier: PsiJavaCodeReferenceElement? = expression.getQualifier() + result = SuperExpression((if (qualifier != null) Identifier(qualifier.getQualifiedName()!!) else Identifier.Empty)) } - override fun visitThisExpression(expression: PsiThisExpression?) { - val qualifier: PsiJavaCodeReferenceElement? = expression?.getQualifier() - myResult = ThisExpression((if (qualifier != null) + override fun visitThisExpression(expression: PsiThisExpression) { + val qualifier: PsiJavaCodeReferenceElement? = expression.getQualifier() + result = ThisExpression((if (qualifier != null) Identifier(qualifier.getQualifiedName()!!) else Identifier.Empty)) } - override fun visitTypeCastExpression(expression: PsiTypeCastExpression?) { - val castType: PsiTypeElement? = expression?.getCastType() + override fun visitTypeCastExpression(expression: PsiTypeCastExpression) { + val castType: PsiTypeElement? = expression.getCastType() if (castType != null) { - val operand = expression?.getOperand() + 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) { - myResult = MethodCallExpression.build(getConverter().convertExpression(operand), typeConversion) + result = MethodCallExpression.build(converter.convertExpression(operand), typeConversion) } else { - myResult = TypeCastExpression(getConverter().convertType(castType.getType()), - getConverter().convertExpression(operand)) + result = TypeCastExpression(converter.convertType(castType.getType()), + converter.convertExpression(operand)) } } } - override fun visitPolyadicExpression(expression: PsiPolyadicExpression?) { + override fun visitPolyadicExpression(expression: PsiPolyadicExpression) { var parameters = ArrayList() - for (operand : PsiExpression in expression?.getOperands()!!) { - parameters.add(getConverter().convertExpression(operand, expression?.getType())) + for (operand : PsiExpression in expression.getOperands()) { + parameters.add(converter.convertExpression(operand, expression.getType())) } - myResult = PolyadicExpression(parameters, getOperatorString(expression?.getOperationTokenType()!!)) + result = PolyadicExpression(parameters, getOperatorString(expression.getOperationTokenType())) } - class object { - private fun getOperatorString(tokenType: IElementType): String { - if (tokenType == JavaTokenType.PLUS) - return "+" - - if (tokenType == JavaTokenType.MINUS) - return "-" - - if (tokenType == JavaTokenType.ASTERISK) - return "*" - - if (tokenType == JavaTokenType.DIV) - return "/" - - if (tokenType == JavaTokenType.PERC) - return "%" - - if (tokenType == JavaTokenType.GTGT) - return "shr" - - if (tokenType == JavaTokenType.LTLT) - return "shl" - - if (tokenType == JavaTokenType.XOR) - return "xor" - - if (tokenType == JavaTokenType.AND) - return "and" - - if (tokenType == JavaTokenType.OR) - return "or" - - if (tokenType == JavaTokenType.GTGTGT) - return "ushr" - - if (tokenType == JavaTokenType.GT) - return ">" - - if (tokenType == JavaTokenType.LT) - return "<" - - if (tokenType == JavaTokenType.GE) - return ">=" - - if (tokenType == JavaTokenType.LE) - return "<=" - - if (tokenType == JavaTokenType.EQEQ) - return "==" - - if (tokenType == JavaTokenType.NE) - return "!=" - - if (tokenType == JavaTokenType.ANDAND) - return "&&" - - if (tokenType == JavaTokenType.OROR) - return "||" - - if (tokenType == JavaTokenType.PLUSPLUS) - return "++" - - if (tokenType == JavaTokenType.MINUSMINUS) - return "--" - - if (tokenType == JavaTokenType.EXCL) - return "!" - - // System.out.println("UNSUPPORTED TOKEN TYPE: " + tokenType?.toString()) - return "" + private fun getOperatorString(tokenType: IElementType): String { + return when(tokenType) { + JavaTokenType.EQEQ -> "==" + JavaTokenType.NE -> "!=" + JavaTokenType.ANDAND -> "&&" + JavaTokenType.OROR -> "||" + JavaTokenType.GT -> ">" + JavaTokenType.LT -> "<" + JavaTokenType.GE -> ">=" + JavaTokenType.LE -> "<=" + JavaTokenType.EXCL -> "!" + JavaTokenType.PLUS -> "+" + JavaTokenType.MINUS -> "-" + JavaTokenType.ASTERISK -> "*" + JavaTokenType.DIV -> "/" + JavaTokenType.PERC -> "%" + JavaTokenType.GTGT -> "shr" + JavaTokenType.LTLT -> "shl" + JavaTokenType.XOR -> "xor" + JavaTokenType.AND -> "and" + JavaTokenType.OR -> "or" + JavaTokenType.GTGTGT -> "ushr" + JavaTokenType.PLUSPLUS -> "++" + JavaTokenType.MINUSMINUS -> "--" + else -> "" //System.out.println("UNSUPPORTED TOKEN TYPE: " + tokenType?.toString()) } + } - private fun getClassNameWithConstructor(expression: PsiReferenceExpression): String { - var context: PsiElement? = expression.getContext() - while (context != null) { - if (context is PsiMethod && ((context as PsiMethod)).isConstructor()) { - val containingClass: PsiClass? = ((context as PsiMethod)).getContainingClass() - if (containingClass != null) { - val identifier: PsiIdentifier? = containingClass.getNameIdentifier() - if (identifier != null) { - return identifier.getText()!! - } - - } - - } - - context = context?.getContext() - } - return "" - } - - open fun getClassName(expression: PsiExpression): String { - var context: PsiElement? = expression.getContext() - while (context != null) - { - if ((context is PsiClass?)) { - val containingClass: PsiClass? = (context as PsiClass?) - val identifier: PsiIdentifier? = containingClass?.getNameIdentifier() + 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 "" - } - - private fun isFieldReference(expression: PsiReferenceExpression, currentClass: PsiClass?): Boolean { - val reference: PsiReference? = expression.getReference() - if (reference != null) { - val resolvedReference: PsiElement? = reference.resolve() - if (resolvedReference is PsiField) { - return (resolvedReference as PsiField).getContainingClass() == currentClass - } } - return false + context = _context.getContext() } + return "" + } - private fun isInsideSecondaryConstructor(expression: PsiReferenceExpression): Boolean { - var context: PsiElement? = expression.getContext() - while (context != null) { - if (context is PsiMethod && (context as PsiMethod).isConstructor()) { - return !isConstructorPrimary((context as PsiMethod)) + protected fun getClassName(expression: PsiExpression): String { + var context = expression.getContext() + while (context != null) { + val _context = context!! + if (_context is PsiClass) { + val identifier = _context.getNameIdentifier() + if (identifier != null) { + return identifier.getText()!! } - context = context?.getContext() } - return false + + context = _context.getContext() } + return "" + } - private fun isInsidePrimaryConstructor(expression: PsiExpression): Boolean { - var context: PsiElement? = expression.getContext() - while (context != null) { - if (context is PsiMethod && (context as PsiMethod).isConstructor()) { - return isConstructorPrimary(context as PsiMethod) - } - - context = context?.getContext() + 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: PsiElement? = expression.getContext() - while (context != null) - { - if (context is PsiMethod && (context as PsiMethod).isConstructor()) - { - return (context as PsiMethod).getContainingClass() - } + return false + } - context = context?.getContext() + private fun isInsideSecondaryConstructor(expression: PsiReferenceExpression): Boolean { + var context = expression.getContext() + while (context != null) { + val _context = context!! + if (_context is PsiMethod && _context.isConstructor()) { + return !isConstructorPrimary(_context) } - return null - } - private fun isThisExpression(expression: PsiReferenceExpression): Boolean { - for (r : PsiReference? in expression.getReferences()) - if (r?.getCanonicalText()?.equals("this")!!) - { - val res: PsiElement? = r?.resolve() - if (res is PsiMethod && res.isConstructor()) { - return true - } + context = _context.getContext() + } + return false + } + + private fun isInsidePrimaryConstructor(expression: PsiExpression): Boolean { + var context = expression.getContext() + while (context != null) { + val _context = context!! + if (_context is PsiMethod && _context.isConstructor()) { + return isConstructorPrimary(_context) + } + + context = _context.getContext() + } + 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 + } } + + return false + } + + private fun isStaticallyImported(member: PsiMember, context: PsiElement): Boolean { + val containingFile = context.getContainingFile() + val targetContainingClass = member.getContainingClass() + if (containingFile is PsiJavaFile && targetContainingClass != null) { + val importList = containingFile.getImportList(); + if (importList != null) { + return importList.getImportStaticStatements().any { importResolvesTo(it, member) } + } + } + return false + } + + private fun importResolvesTo(importStatement: PsiImportStaticStatement, member: PsiMember): Boolean { + val targetContainingClass = member.getContainingClass() + val importedClass = importStatement.resolveTargetClass() + return importedClass == targetContainingClass + && (importStatement.isOnDemand() || importStatement.getReferenceName() == member.getName()) } } - -private fun isStaticallyImported(member: PsiMember, context: PsiElement): Boolean { - val containingFile = context.getContainingFile() - val targetContainingClass = member.getContainingClass() - if (containingFile is PsiJavaFile && targetContainingClass != null) { - val importList = containingFile.getImportList(); - if (importList != null) { - val importStatics = importList.getImportStaticStatements(); - return importStatics.any { importResolvesTo(it, member) } - } - } - return false -} - -private fun importResolvesTo(stmt: PsiImportStaticStatement?, member: PsiMember): Boolean { - val targetContainingClass = member.getContainingClass() - var importedClass = stmt?.resolveTargetClass() - return importedClass == targetContainingClass && (stmt?.isOnDemand() ?: false || - stmt?.getReferenceName() == member.getName()) -} diff --git a/j2k/src/org/jetbrains/jet/j2k/visitors/ExpressionVisitorForDirectObjectInheritors.kt b/j2k/src/org/jetbrains/jet/j2k/visitors/ExpressionVisitorForDirectObjectInheritors.kt index 5de326a5408..9d834f1ee67 100644 --- a/j2k/src/org/jetbrains/jet/j2k/visitors/ExpressionVisitorForDirectObjectInheritors.kt +++ b/j2k/src/org/jetbrains/jet/j2k/visitors/ExpressionVisitorForDirectObjectInheritors.kt @@ -24,34 +24,30 @@ import com.intellij.psi.CommonClassNames.JAVA_LANG_OBJECT import org.jetbrains.jet.j2k.ast.MethodCallExpression open class ExpressionVisitorForDirectObjectInheritors(converter: Converter) : ExpressionVisitor(converter) { - override fun visitMethodCallExpression(expression: PsiMethodCallExpression?) { - val methodExpression = expression?.getMethodExpression()!! + override fun visitMethodCallExpression(expression: PsiMethodCallExpression) { + val methodExpression = expression.getMethodExpression() if (superMethodInvocation(methodExpression, "hashCode")) { - myResult = MethodCallExpression.build(Identifier("System", false), "identityHashCode", listOf(Identifier("this"))) + result = MethodCallExpression.build(Identifier("System", false), "identityHashCode", listOf(Identifier("this"))) } else if (superMethodInvocation(methodExpression, "equals")) { - myResult = MethodCallExpression.build(Identifier("this", false), "identityEquals", getConverter().convertArguments(expression!!)) + result = MethodCallExpression.build(Identifier("this", false), "identityEquals", converter.convertArguments(expression)) } else if (superMethodInvocation(methodExpression, "toString")) { - myResult = DummyStringExpression(java.lang.String.format("getJavaClass<%s>.getName() + '@' + Integer.toHexString(hashCode())", - ExpressionVisitor.getClassName(methodExpression))) + result = DummyStringExpression("getJavaClass<${getClassName(methodExpression)}>.getName() + '@' + Integer.toHexString(hashCode())") } else { - convertMethodCallExpression(expression!!) + convertMethodCallExpression(expression) } } - class object { - private fun superMethodInvocation(expression: PsiReferenceExpression, methodName: String?): Boolean { - val referenceName: String? = expression.getReferenceName() - val qualifierExpression: PsiExpression? = expression.getQualifierExpression() - if (referenceName == methodName && qualifierExpression is PsiSuperExpression) { - val `type`: PsiType? = qualifierExpression.getType() - if (`type` != null && `type`.getCanonicalText() == JAVA_LANG_OBJECT) { - return true - } + private fun superMethodInvocation(expression: PsiReferenceExpression, methodName: String?): Boolean { + val referenceName: String? = expression.getReferenceName() + val qualifierExpression: PsiExpression? = expression.getQualifierExpression() + if (referenceName == methodName && qualifierExpression is PsiSuperExpression) { + if (qualifierExpression.getType()?.getCanonicalText() == JAVA_LANG_OBJECT) { + return true } - return false } + return false } } diff --git a/j2k/src/org/jetbrains/jet/j2k/visitors/StatementVisitor.kt b/j2k/src/org/jetbrains/jet/j2k/visitors/StatementVisitor.kt index cd661031b44..dfefbbb5063 100644 --- a/j2k/src/org/jetbrains/jet/j2k/visitors/StatementVisitor.kt +++ b/j2k/src/org/jetbrains/jet/j2k/visitors/StatementVisitor.kt @@ -19,157 +19,154 @@ package org.jetbrains.jet.j2k.visitors import com.intellij.psi.* import org.jetbrains.jet.j2k.Converter import org.jetbrains.jet.j2k.ast.* -import org.jetbrains.jet.j2k.countWritingAccesses +import org.jetbrains.jet.j2k.countWriteAccesses import java.util.ArrayList -open class StatementVisitor(converter: Converter) : ElementVisitor(converter) { - override fun visitAssertStatement(statement: PsiAssertStatement?) { - myResult = AssertStatement(getConverter().convertExpression(statement?.getAssertCondition()), - getConverter().convertExpression(statement?.getAssertDescription())) +class StatementVisitor(public val converter: Converter) : JavaElementVisitor() { + public var result: Statement = Statement.Empty + private set + + override fun visitAssertStatement(statement: PsiAssertStatement) { + result = AssertStatement(converter.convertExpression(statement.getAssertCondition()), + converter.convertExpression(statement.getAssertDescription())) } - override fun visitBlockStatement(statement: PsiBlockStatement?) { - myResult = getConverter().convertBlock(statement?.getCodeBlock(), true) + override fun visitBlockStatement(statement: PsiBlockStatement) { + result = converter.convertBlock(statement.getCodeBlock(), true) } - override fun visitBreakStatement(statement: PsiBreakStatement?) { - if (statement?.getLabelIdentifier() == null) { - myResult = BreakStatement(Identifier.Empty) + override fun visitBreakStatement(statement: PsiBreakStatement) { + if (statement.getLabelIdentifier() == null) { + result = BreakStatement(Identifier.Empty) } - else - { - myResult = BreakStatement(getConverter().convertIdentifier(statement?.getLabelIdentifier())) + else { + result = BreakStatement(converter.convertIdentifier(statement.getLabelIdentifier())) } } - override fun visitContinueStatement(statement: PsiContinueStatement?) { - if (statement?.getLabelIdentifier() == null) - { - myResult = ContinueStatement(Identifier.Empty) + override fun visitContinueStatement(statement: PsiContinueStatement) { + if (statement.getLabelIdentifier() == null) { + result = ContinueStatement(Identifier.Empty) } - else - { - myResult = ContinueStatement(getConverter().convertIdentifier(statement?.getLabelIdentifier())) + else { + result = ContinueStatement(converter.convertIdentifier(statement.getLabelIdentifier())) } } - override fun visitDeclarationStatement(statement: PsiDeclarationStatement?) { - myResult = DeclarationStatement(getConverter().convertElements(statement?.getDeclaredElements()!!)) + override fun visitDeclarationStatement(statement: PsiDeclarationStatement) { + result = DeclarationStatement(converter.convertElements(statement.getDeclaredElements())) } - override fun visitDoWhileStatement(statement: PsiDoWhileStatement?) { - val condition: PsiExpression? = statement?.getCondition() - val expression: Expression = (if (condition != null && condition.getType() != null) - getConverter().convertExpression(condition, condition.getType()) + override fun visitDoWhileStatement(statement: PsiDoWhileStatement) { + val condition = statement.getCondition() + val expression = if (condition != null && condition.getType() != null) + converter.convertExpression(condition, condition.getType()) else - getConverter().convertExpression(condition)) - myResult = DoWhileStatement(expression, getConverter().convertStatement(statement?.getBody())) + converter.convertExpression(condition) + result = DoWhileStatement(expression, converter.convertStatement(statement.getBody())) } - override fun visitExpressionStatement(statement: PsiExpressionStatement?) { - myResult = getConverter().convertExpression(statement?.getExpression()) + override fun visitExpressionStatement(statement: PsiExpressionStatement) { + result = converter.convertExpression(statement.getExpression()) } - override fun visitExpressionListStatement(statement: PsiExpressionListStatement?) { - myResult = ExpressionListStatement(getConverter().convertExpressions( - statement?.getExpressionList()?.getExpressions()!!)) + override fun visitExpressionListStatement(statement: PsiExpressionListStatement) { + result = ExpressionListStatement(converter.convertExpressions(statement.getExpressionList().getExpressions())) } - override fun visitForStatement(statement: PsiForStatement?) { - val initialization = statement?.getInitialization() - val update = statement?.getUpdate() - val condition = statement?.getCondition() - val body = statement?.getBody() - val firstChild = (if (initialization != null && (initialization.getFirstChild() is PsiLocalVariable)) - (initialization.getFirstChild() as PsiLocalVariable) - else - null) - var bodyWriteCount = countWritingAccesses(firstChild, body) - var conditionWriteCount = countWritingAccesses(firstChild, condition) - var updateWriteCount = countWritingAccesses(firstChild, update) + override fun visitForStatement(statement: PsiForStatement) { + val initialization = statement.getInitialization() + 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 operationTokenType = (if (condition is PsiBinaryExpression) - condition.getOperationTokenType() - else - null) - if (initialization is PsiDeclarationStatement && initialization.getFirstChild() == initialization.getLastChild() && - condition != null && update != null && update.getChildren().size == 1 && - (isPlusPlusExpression(update.getChildren()[0])) && (operationTokenType == JavaTokenType.LT || operationTokenType == JavaTokenType.LE) && - initialization.getFirstChild() != null && (initialization.getFirstChild() is PsiLocalVariable) && - firstChild != null && firstChild.getNameIdentifier() != null && onceWritableIterator) { - val end = getConverter().convertExpression((condition as PsiBinaryExpression).getROperand()) - val endExpression = (if (operationTokenType == JavaTokenType.LT) + val operationTokenType = (condition as? PsiBinaryExpression)?.getOperationTokenType() + if (initialization is PsiDeclarationStatement + && initialization.getFirstChild() == initialization.getLastChild() + && condition != null + && update != null + && update.getChildren().size == 1 + && isPlusPlusExpression(update.getChildren().single()) + && (operationTokenType == JavaTokenType.LT || operationTokenType == JavaTokenType.LE) + && firstChildLocalVar != null + && firstChildLocalVar.getNameIdentifier() != null + && onceWritableIterator) { + val end = converter.convertExpression((condition as PsiBinaryExpression).getROperand()) + val endExpression = if (operationTokenType == JavaTokenType.LT) BinaryExpression(end, Identifier("1"), "-") else - end) - myResult = ForeachWithRangeStatement(Identifier(firstChild.getName()!!), - getConverter().convertExpression(firstChild.getInitializer()), + end + result = ForeachWithRangeStatement(Identifier(firstChildLocalVar.getName()!!), + converter.convertExpression(firstChildLocalVar.getInitializer()), endExpression, - getConverter().convertStatement(body)) + converter.convertStatement(body)) } else { var forStatements = ArrayList() - forStatements.add(getConverter().convertStatement(initialization)) - val bodyAndUpdate = listOf(getConverter().convertStatement(body), - Block(listOf(getConverter().convertStatement(update)))) + forStatements.add(converter.convertStatement(initialization)) + val bodyAndUpdate = listOf(converter.convertStatement(body), + Block(listOf(converter.convertStatement(update)))) forStatements.add(WhileStatement( if (condition == null) LiteralExpression("true") else - getConverter().convertExpression(condition), + converter.convertExpression(condition), Block(bodyAndUpdate))) - myResult = Block(forStatements) + result = Block(forStatements) } } - override fun visitForeachStatement(statement: PsiForeachStatement?) { - val iterator = { - val iteratorExpr = getConverter().convertExpression(statement?.getIteratedValue()) - if (iteratorExpr.isNullable()) + override fun visitForeachStatement(statement: PsiForeachStatement) { + val iterator = run { + val iteratorExpr = converter.convertExpression(statement.getIteratedValue()) + if (iteratorExpr.isNullable) BangBangExpression(iteratorExpr) else iteratorExpr - }() - myResult = ForeachStatement(getConverter().convertParameter(statement?.getIterationParameter()!!), - iterator, - getConverter().convertStatement(statement?.getBody())) + } + result = ForeachStatement(converter.convertParameter(statement.getIterationParameter()), + iterator, + converter.convertStatement(statement.getBody())) } - override fun visitIfStatement(statement: PsiIfStatement?) { - val condition: PsiExpression? = statement?.getCondition() - val expression: Expression = getConverter().convertExpression(condition, PsiType.BOOLEAN) - myResult = IfStatement(expression, - getConverter().convertStatement(statement?.getThenBranch()), - getConverter().convertStatement(statement?.getElseBranch())) + override fun visitIfStatement(statement: PsiIfStatement) { + val condition = statement.getCondition() + val expression = converter.convertExpression(condition, PsiType.BOOLEAN) + result = IfStatement(expression, + converter.convertStatement(statement.getThenBranch()), + converter.convertStatement(statement.getElseBranch())) } - override fun visitLabeledStatement(statement: PsiLabeledStatement?) { - myResult = LabelStatement(getConverter().convertIdentifier(statement?.getLabelIdentifier()), - getConverter().convertStatement(statement?.getStatement())) + override fun visitLabeledStatement(statement: PsiLabeledStatement) { + result = LabelStatement(converter.convertIdentifier(statement.getLabelIdentifier()), + converter.convertStatement(statement.getStatement())) } - override fun visitSwitchLabelStatement(statement: PsiSwitchLabelStatement?) { - myResult = (if (statement?.isDefaultCase()!!) + override fun visitSwitchLabelStatement(statement: PsiSwitchLabelStatement) { + result = if (statement.isDefaultCase()) DefaultSwitchLabelStatement() else - SwitchLabelStatement(getConverter().convertExpression(statement?.getCaseValue()))) + SwitchLabelStatement(converter.convertExpression(statement.getCaseValue())) } - override fun visitSwitchStatement(statement: PsiSwitchStatement?) { - myResult = SwitchContainer(getConverter().convertExpression(statement?.getExpression()), - switchBodyToCases(statement?.getBody())) + override fun visitSwitchStatement(statement: PsiSwitchStatement) { + result = SwitchContainer(converter.convertExpression(statement.getExpression()), + switchBodyToCases(statement.getBody())) } - private open fun switchBodyToCases(body: PsiCodeBlock?): List { + private fun switchBodyToCases(body: PsiCodeBlock?): List { val cases: List> = splitToCases(body) val allSwitchStatements = ArrayList() if (body != null) { - // TODO Arrays.asList() - for (s in body.getStatements()) allSwitchStatements.add(s) + allSwitchStatements.addAll(body.getStatements()) } val result = ArrayList() var pendingLabels = ArrayList() - var i: Int = 0 + var i = 0 var hasDefaultCase: Boolean = false for (ls in cases) { // TODO assert {(ls?.size()).sure() > 0} @@ -179,21 +176,21 @@ open class StatementVisitor(converter: Converter) : ElementVisitor(converter) { // TODO assert {(label is PsiSwitchLabelStatement?)} // TODO assert("not a right index") {allSwitchStatements?.get(i) == label} if (ls.size() > 1) { - pendingLabels.add(getConverter().convertStatement(label)) + pendingLabels.add(converter.convertStatement(label)) val slice: List = ls.subList(1, (ls.size())) if (!containsBreak(slice)) { - val statements = ArrayList(getConverter().convertStatements(slice).statements) - statements.addAll(getConverter().convertStatements(getAllToNextBreak(allSwitchStatements, i + ls.size())).statements) + val statements = ArrayList(converter.convertStatements(slice).statements) + statements.addAll(converter.convertStatements(getAllToNextBreak(allSwitchStatements, i + ls.size())).statements) result.add(CaseContainer(pendingLabels, statements)) pendingLabels = ArrayList() } else { - result.add(CaseContainer(pendingLabels, getConverter().convertStatements(slice).statements)) + result.add(CaseContainer(pendingLabels, converter.convertStatements(slice).statements)) pendingLabels = ArrayList() } } else { - pendingLabels.add(getConverter().convertStatement(label)) + pendingLabels.add(converter.convertStatement(label)) } i += ls.size() } @@ -203,97 +200,95 @@ open class StatementVisitor(converter: Converter) : ElementVisitor(converter) { return result } - override fun visitSynchronizedStatement(statement: PsiSynchronizedStatement?) { - myResult = SynchronizedStatement(getConverter().convertExpression(statement?.getLockExpression()), - getConverter().convertBlock(statement?.getBody())) + override fun visitSynchronizedStatement(statement: PsiSynchronizedStatement) { + result = SynchronizedStatement(converter.convertExpression(statement.getLockExpression()), + converter.convertBlock(statement.getBody())) } - override fun visitThrowStatement(statement: PsiThrowStatement?) { - myResult = ThrowStatement(getConverter().convertExpression(statement?.getException())) + override fun visitThrowStatement(statement: PsiThrowStatement) { + result = ThrowStatement(converter.convertExpression(statement.getException())) } - override fun visitTryStatement(statement: PsiTryStatement?) { + override fun visitTryStatement(statement: PsiTryStatement) { val catches = ArrayList() - val catchBlocks = statement?.getCatchBlocks()!! - val catchBlockParameters = statement?.getCatchBlockParameters()!! + val catchBlocks = statement.getCatchBlocks() + val catchBlockParameters = statement.getCatchBlockParameters() for (i in 0..catchBlocks.size - 1) { - catches.add(CatchStatement(getConverter().convertParameter(catchBlockParameters[i], true), - getConverter().convertBlock(catchBlocks[i], true))) + catches.add(CatchStatement(converter.convertParameter(catchBlockParameters[i], true), + converter.convertBlock(catchBlocks[i], true))) } - myResult = TryStatement(getConverter().convertBlock(statement?.getTryBlock(), true), - catches, getConverter().convertBlock(statement?.getFinallyBlock(), true)) + result = TryStatement(converter.convertBlock(statement.getTryBlock(), true), + catches, converter.convertBlock(statement.getFinallyBlock(), true)) } - override fun visitWhileStatement(statement: PsiWhileStatement?) { - var condition: PsiExpression? = statement?.getCondition() + override fun visitWhileStatement(statement: PsiWhileStatement) { + var condition: PsiExpression? = statement.getCondition() val expression: Expression = (if (condition != null && condition?.getType() != null) - this.getConverter().convertExpression(condition, condition?.getType()) + this.converter.convertExpression(condition, condition?.getType()) else - getConverter().convertExpression(condition)) - myResult = WhileStatement(expression, getConverter().convertStatement(statement?.getBody())) + converter.convertExpression(condition)) + result = WhileStatement(expression, converter.convertStatement(statement.getBody())) } - override fun visitReturnStatement(statement: PsiReturnStatement?) { - val returnValue: PsiExpression? = statement?.getReturnValue() - val methodReturnType: PsiType? = getConverter().methodReturnType - val expression: Expression = (if (returnValue != null && methodReturnType != null) - this.getConverter().convertExpression(returnValue, methodReturnType) + override fun visitReturnStatement(statement: PsiReturnStatement) { + val returnValue = statement.getReturnValue() + val methodReturnType = converter.methodReturnType + val expression = (if (returnValue != null && methodReturnType != null) + this.converter.convertExpression(returnValue, methodReturnType) else - getConverter().convertExpression(returnValue)) - myResult = ReturnStatement(expression) + converter.convertExpression(returnValue)) + result = ReturnStatement(expression) } - class object { - private open fun isPlusPlusExpression(psiElement: PsiElement): Boolean { - return (psiElement is PsiPostfixExpression && psiElement.getOperationTokenType() == JavaTokenType.PLUSPLUS) || - (psiElement is PsiPrefixExpression && psiElement.getOperationTokenType() == JavaTokenType.PLUSPLUS) - } + override fun visitEmptyStatement(statement: PsiEmptyStatement) { + result = Statement.Empty + } - private fun containsBreak(slice: List) = slice.any { it is PsiBreakStatement } + private fun isPlusPlusExpression(psiElement: PsiElement): Boolean { + return (psiElement is PsiPostfixExpression && psiElement.getOperationTokenType() == JavaTokenType.PLUSPLUS) || + (psiElement is PsiPrefixExpression && psiElement.getOperationTokenType() == JavaTokenType.PLUSPLUS) + } - private open fun getAllToNextBreak(allStatements: List, start: Int): List { - val result = ArrayList() - for (i in start..allStatements.size() - 1) { - val s = allStatements.get(i) - if (s is PsiBreakStatement || s is PsiReturnStatement) { - return result - } - - if (!(s is PsiSwitchLabelStatement)) { - result.add(s) - } + private fun containsBreak(slice: List) = slice.any { it is PsiBreakStatement } + private fun getAllToNextBreak(allStatements: List, start: Int): List { + val result = ArrayList() + for (i in start..allStatements.size() - 1) { + val s = allStatements[i] + if (s is PsiBreakStatement || s is PsiReturnStatement) { + return result } - return result - } - private open fun splitToCases(body: PsiCodeBlock?): List> { - val cases = ArrayList>() - var currentCaseStatements = ArrayList() - var isFirst: Boolean = true - if (body != null) { - for (s in body.getChildren()) { - if (s !is PsiStatement && s !is PsiComment) continue - if (s is PsiSwitchLabelStatement) { - if (isFirst) { - isFirst = false - } - else { - cases.add(currentCaseStatements) - currentCaseStatements = ArrayList() - } + if (s !is PsiSwitchLabelStatement) { + result.add(s) + } + + } + return result + } + + private fun splitToCases(body: PsiCodeBlock?): List> { + val cases = ArrayList>() + var currentCaseStatements = ArrayList() + if (body != null) { + var isFirst = true + for (s in body.getChildren()) { + if (s !is PsiStatement && s !is PsiComment) continue + if (s is PsiSwitchLabelStatement) { + if (isFirst) { + isFirst = false + } + else { + cases.add(currentCaseStatements) + currentCaseStatements = ArrayList() } - - currentCaseStatements.add(s) } - cases.add(currentCaseStatements) + + currentCaseStatements.add(s) } - - return cases + cases.add(currentCaseStatements) } - } - override fun visitEmptyStatement(statement: PsiEmptyStatement?) { - myResult = Statement.Empty + return cases } } diff --git a/j2k/src/org/jetbrains/jet/j2k/visitors/SuperVisitor.kt b/j2k/src/org/jetbrains/jet/j2k/visitors/SuperVisitor.kt index 4bb424f3bfe..1f1c9d24581 100644 --- a/j2k/src/org/jetbrains/jet/j2k/visitors/SuperVisitor.kt +++ b/j2k/src/org/jetbrains/jet/j2k/visitors/SuperVisitor.kt @@ -18,25 +18,17 @@ package org.jetbrains.jet.j2k.visitors import com.intellij.psi.* import java.util.HashSet +import org.jetbrains.jet.j2k.isSuperConstructorRef -open class SuperVisitor() : JavaRecursiveElementVisitor() { - val resolvedSuperCallParameters: HashSet = HashSet() +class SuperVisitor() : JavaRecursiveElementVisitor() { + private val _resolvedSuperCallParameters = HashSet() - override fun visitMethodCallExpression(expression: PsiMethodCallExpression?) { - if (expression != null && isSuper(expression.getMethodExpression())) { - resolvedSuperCallParameters.add(expression.getArgumentList()) - } - } - class object { - open fun isSuper(r: PsiReference): Boolean { - if (r.getCanonicalText().equals("super")) { - val baseConstructor: PsiElement? = r.resolve() - if (baseConstructor != null && baseConstructor is PsiMethod && baseConstructor.isConstructor()) { - return true - } - } + public val resolvedSuperCallParameters: Set + get() = _resolvedSuperCallParameters - return false + override fun visitMethodCallExpression(expression: PsiMethodCallExpression) { + if (isSuperConstructorRef(expression.getMethodExpression())) { + _resolvedSuperCallParameters.add(expression.getArgumentList()) } } } diff --git a/j2k/src/org/jetbrains/jet/j2k/visitors/TypeVisitor.kt b/j2k/src/org/jetbrains/jet/j2k/visitors/TypeVisitor.kt index b640351e86e..1cb506fb052 100644 --- a/j2k/src/org/jetbrains/jet/j2k/visitors/TypeVisitor.kt +++ b/j2k/src/org/jetbrains/jet/j2k/visitors/TypeVisitor.kt @@ -28,75 +28,55 @@ import org.jetbrains.jet.lang.resolve.java.JvmPrimitiveType private val PRIMITIVE_TYPES_NAMES = JvmPrimitiveType.values().map { it.getName() } -open class TypeVisitor(private val myConverter: Converter) : PsiTypeVisitor() { - private var myResult: Type = EmptyType() - open fun getResult(): Type { - return myResult - } - - override fun visitPrimitiveType(primitiveType: PsiPrimitiveType?): Type { - val name: String = primitiveType?.getCanonicalText()!! - if (name == "void") { - myResult = UnitType +open class TypeVisitor(private val converter: Converter) : PsiTypeVisitor() { + override fun visitPrimitiveType(primitiveType: PsiPrimitiveType): Type { + val name = primitiveType.getCanonicalText() + return if (name == "void") { + UnitType } else if (PRIMITIVE_TYPES_NAMES.contains(name)) { - myResult = PrimitiveType(Identifier(StringUtil.capitalize(name))) + PrimitiveType(Identifier(StringUtil.capitalize(name))) } else { - myResult = PrimitiveType(Identifier(name)) + PrimitiveType(Identifier(name)) } - return myResult } - override fun visitArrayType(arrayType: PsiArrayType?): Type { - if (myResult is EmptyType) { - myResult = ArrayType(myConverter.convertType(arrayType?.getComponentType()), true, myConverter) - } - - return myResult + override fun visitArrayType(arrayType: PsiArrayType): Type { + return ArrayType(converter.convertType(arrayType.getComponentType()), true, converter) } - override fun visitClassType(classType: PsiClassType?): Type { - if (classType == null) return myResult - val identifier: Identifier = constructClassTypeIdentifier(classType) - val resolvedClassTypeParams: List = createRawTypesForResolvedReference(classType) + override fun visitClassType(classType: PsiClassType): Type { + val identifier = constructClassTypeIdentifier(classType) + val resolvedClassTypeParams = createRawTypesForResolvedReference(classType) if (classType.getParameterCount() == 0 && resolvedClassTypeParams.size() > 0) { - val starParamList: ArrayList = ArrayList() + val starParamList = ArrayList() if (resolvedClassTypeParams.size() == 1) { - if ((resolvedClassTypeParams.get(0) as ClassType).`type`.name == "Any") { + if ((resolvedClassTypeParams.single() as ClassType).`type`.name == "Any") { starParamList.add(StarProjectionType()) - myResult = ClassType(identifier, starParamList, true, myConverter) + return ClassType(identifier, starParamList, true, converter) } else { - myResult = ClassType(identifier, resolvedClassTypeParams, true, myConverter) + return ClassType(identifier, resolvedClassTypeParams, true, converter) } } else { - myResult = ClassType(identifier, resolvedClassTypeParams, true, myConverter) + return ClassType(identifier, resolvedClassTypeParams, true, converter) } } else { - myResult = ClassType(identifier, myConverter.convertTypes(classType.getParameters()), true, myConverter) + return ClassType(identifier, converter.convertTypes(classType.getParameters()), true, converter) } - return myResult } private fun constructClassTypeIdentifier(classType: PsiClassType): Identifier { - val psiClass: PsiClass? = classType.resolve() + val psiClass = classType.resolve() if (psiClass != null) { - val qualifiedName: String? = psiClass.getQualifiedName() - if (qualifiedName != null) { - if (qualifiedName.equals(CommonClassNames.JAVA_LANG_ITERABLE)) { - return Identifier(CommonClassNames.JAVA_LANG_ITERABLE) - } - - if (qualifiedName.equals(CommonClassNames.JAVA_UTIL_ITERATOR)) { - return Identifier(CommonClassNames.JAVA_UTIL_ITERATOR) - } - - if (qualifiedName.equals(CommonClassNames.JAVA_UTIL_LIST)) { - return Identifier("MutableList") - } + val qualifiedName = psiClass.getQualifiedName() + when(qualifiedName) { + CommonClassNames.JAVA_LANG_ITERABLE -> return Identifier(CommonClassNames.JAVA_LANG_ITERABLE) + CommonClassNames.JAVA_UTIL_ITERATOR -> return Identifier(CommonClassNames.JAVA_UTIL_ITERATOR) + CommonClassNames.JAVA_UTIL_LIST -> return Identifier("MutableList") } } @@ -111,17 +91,18 @@ open class TypeVisitor(private val myConverter: Converter) : PsiTypeVisitor { val typeParams = LinkedList() if (classType is PsiClassReferenceType) { - val reference: PsiJavaCodeReferenceElement? = (classType as PsiClassReferenceType).getReference() - val resolve: PsiElement? = reference?.resolve() + val reference = classType.getReference() + val resolve = reference.resolve() if (resolve is PsiClass) { - for (p : PsiTypeParameter? in (resolve as PsiClass).getTypeParameters()) { - val superTypes = p!!.getSuperTypes() - val boundType: Type = (if (superTypes.size > 0) + for (typeParam in resolve.getTypeParameters()) { + val superTypes = typeParam.getSuperTypes() + val boundType = if (superTypes.size > 0) ClassType(Identifier(getClassTypeName(superTypes[0])), - myConverter.convertTypes(superTypes[0].getParameters()), - true, myConverter) + converter.convertTypes(superTypes[0].getParameters()), + true, + converter) else - StarProjectionType()) + StarProjectionType() typeParams.add(boundType) } } @@ -130,64 +111,50 @@ open class TypeVisitor(private val myConverter: Converter) : PsiTypeVisitor OutProjectionType(converter.convertType(wildcardType.getExtendsBound())) + wildcardType.isSuper() -> InProjectionType(converter.convertType(wildcardType.getSuperBound())) + else -> StarProjectionType() } - else - if (wildcardType.isSuper()) { - myResult = InProjectionType(myConverter.convertType(wildcardType.getSuperBound())) - } - else { - myResult = StarProjectionType() - } - return myResult } - override fun visitEllipsisType(ellipsisType: PsiEllipsisType?): Type { - myResult = VarArg(myConverter.convertType(ellipsisType?.getComponentType())) - return myResult + override fun visitEllipsisType(ellipsisType: PsiEllipsisType): Type { + return VarArg(converter.convertType(ellipsisType.getComponentType())) } - class object { - private fun createQualifiedName(classType: PsiClassType): String { - if (classType is PsiClassReferenceType) - { - val reference: PsiJavaCodeReferenceElement? = (classType as PsiClassReferenceType).getReference() - if (reference != null && reference.isQualified()) { - var result: String = Identifier(reference.getReferenceName()!!).toKotlin() - var qualifier: PsiElement? = reference.getQualifier() - while (qualifier != null) - { - val p: PsiJavaCodeReferenceElement = (qualifier as PsiJavaCodeReferenceElement) - result = Identifier(p.getReferenceName()!!).toKotlin() + "." + result - qualifier = p.getQualifier() - } - return result + private fun createQualifiedName(classType: PsiClassType): String { + if (classType is PsiClassReferenceType) { + val reference = classType.getReference() + if (reference.isQualified()) { + var result = Identifier(reference.getReferenceName()!!).toKotlin() + var qualifier = reference.getQualifier() + while (qualifier != null) { + val codeRefElement = qualifier as PsiJavaCodeReferenceElement + result = Identifier(codeRefElement.getReferenceName()!!).toKotlin() + "." + result + qualifier = codeRefElement.getQualifier() } + return result } - - return "" } - private fun getClassTypeName(classType: PsiClassType): String { - var canonicalTypeStr: String? = classType.getCanonicalText() - return when(canonicalTypeStr) { - CommonClassNames.JAVA_LANG_OBJECT -> "Any" - CommonClassNames.JAVA_LANG_BYTE -> "Byte" - CommonClassNames.JAVA_LANG_CHARACTER -> "Char" - CommonClassNames.JAVA_LANG_DOUBLE -> "Double" - CommonClassNames.JAVA_LANG_FLOAT -> "Float" - CommonClassNames.JAVA_LANG_INTEGER -> "Int" - CommonClassNames.JAVA_LANG_LONG -> "Long" - CommonClassNames.JAVA_LANG_SHORT -> "Short" - CommonClassNames.JAVA_LANG_BOOLEAN -> "Boolean" + return "" + } - else -> (if (classType.getClassName() != null) - classType.getClassName()!! - else - classType.getCanonicalText())!! - } + private fun getClassTypeName(classType: PsiClassType): String { + var canonicalTypeStr: String? = classType.getCanonicalText() + return when(canonicalTypeStr) { + CommonClassNames.JAVA_LANG_OBJECT -> "Any" + CommonClassNames.JAVA_LANG_BYTE -> "Byte" + CommonClassNames.JAVA_LANG_CHARACTER -> "Char" + CommonClassNames.JAVA_LANG_DOUBLE -> "Double" + CommonClassNames.JAVA_LANG_FLOAT -> "Float" + CommonClassNames.JAVA_LANG_INTEGER -> "Int" + CommonClassNames.JAVA_LANG_LONG -> "Long" + CommonClassNames.JAVA_LANG_SHORT -> "Short" + CommonClassNames.JAVA_LANG_BOOLEAN -> "Boolean" + + else -> classType.getClassName() ?: classType.getCanonicalText() } } }