Run code cleanup on j2k module
This commit is contained in:
@@ -27,20 +27,20 @@ import java.lang.annotation.ElementType
|
||||
import java.lang.annotation.Target
|
||||
|
||||
class AnnotationConverter(private val converter: Converter) {
|
||||
private val annotationsToRemove: Set<String> = (NullableNotNullManager.getInstance(converter.project).getNotNulls()
|
||||
+ NullableNotNullManager.getInstance(converter.project).getNullables()
|
||||
+ listOf(CommonClassNames.JAVA_LANG_OVERRIDE, javaClass<ElementType>().name)).toSet()
|
||||
private val annotationsToRemove: Set<String> = (NullableNotNullManager.getInstance(converter.project).notNulls
|
||||
+ NullableNotNullManager.getInstance(converter.project).nullables
|
||||
+ listOf(CommonClassNames.JAVA_LANG_OVERRIDE, ElementType::class.java.name)).toSet()
|
||||
|
||||
public fun isImportNotRequired(annotationName: String): Boolean {
|
||||
return annotationName in annotationsToRemove || annotationName == javaClass<Target>().name
|
||||
return annotationName in annotationsToRemove || annotationName == Target::class.java.name
|
||||
}
|
||||
|
||||
public fun convertAnnotations(owner: PsiModifierListOwner): Annotations
|
||||
= convertAnnotationsOnly(owner) + convertModifiersToAnnotations(owner)
|
||||
|
||||
private fun convertAnnotationsOnly(owner: PsiModifierListOwner): Annotations {
|
||||
val modifierList = owner.getModifierList()
|
||||
val annotations = modifierList?.getAnnotations()?.filter { it.getQualifiedName() !in annotationsToRemove }
|
||||
val modifierList = owner.modifierList
|
||||
val annotations = modifierList?.annotations?.filter { !annotationsToRemove.containsRaw(it.qualifiedName) }
|
||||
|
||||
var convertedAnnotations: List<Annotation> = if (annotations != null && annotations.isNotEmpty()) {
|
||||
val newLines = if (!modifierList!!.isInSingleLine()) {
|
||||
@@ -49,8 +49,8 @@ class AnnotationConverter(private val converter: Converter) {
|
||||
else {
|
||||
var child: PsiElement? = modifierList
|
||||
while (true) {
|
||||
child = child!!.getNextSibling()
|
||||
if (child == null || child.getTextLength() != 0) break
|
||||
child = child!!.nextSibling
|
||||
if (child == null || child.textLength != 0) break
|
||||
}
|
||||
if (child is PsiWhiteSpace) !child.isInSingleLine() else false
|
||||
}
|
||||
@@ -72,11 +72,11 @@ class AnnotationConverter(private val converter: Converter) {
|
||||
}
|
||||
|
||||
private fun convertDeprecatedJavadocTag(element: PsiDocCommentOwner): Annotation? {
|
||||
val deprecatedTag = element.getDocComment()?.findTagByName("deprecated") ?: return null
|
||||
val deprecatedTag = element.docComment?.findTagByName("deprecated") ?: return null
|
||||
val deferredExpression = converter.deferredElement<Expression> {
|
||||
LiteralExpression("\"" + StringUtil.escapeStringCharacters(deprecatedTag.content()) + "\"").assignNoPrototype()
|
||||
}
|
||||
return Annotation(Identifier("Deprecated").assignPrototype(deprecatedTag.getNameElement()),
|
||||
return Annotation(Identifier("Deprecated").assignPrototype(deprecatedTag.nameElement),
|
||||
listOf(null to deferredExpression), newLineAfter = true)
|
||||
.assignPrototype(deprecatedTag)
|
||||
}
|
||||
@@ -100,8 +100,8 @@ class AnnotationConverter(private val converter: Converter) {
|
||||
}
|
||||
|
||||
public fun convertAnnotation(annotation: PsiAnnotation, newLineAfter: Boolean): Annotation? {
|
||||
val qualifiedName = annotation.getQualifiedName()
|
||||
if (qualifiedName == CommonClassNames.JAVA_LANG_DEPRECATED && annotation.getParameterList().getAttributes().isEmpty()) {
|
||||
val qualifiedName = annotation.qualifiedName
|
||||
if (qualifiedName == CommonClassNames.JAVA_LANG_DEPRECATED && annotation.parameterList.attributes.isEmpty()) {
|
||||
val deferredExpression = converter.deferredElement<Expression> { LiteralExpression("\"\"").assignNoPrototype() }
|
||||
return Annotation(Identifier("Deprecated").assignNoPrototype(), listOf(null to deferredExpression), newLineAfter).assignPrototype(annotation) //TODO: insert comment
|
||||
}
|
||||
@@ -114,7 +114,7 @@ class AnnotationConverter(private val converter: Converter) {
|
||||
else {
|
||||
val value = attributes[0].value
|
||||
arguments = when (value) {
|
||||
is PsiArrayInitializerMemberValue -> value.getInitializers().filterIsInstance<PsiReferenceExpression>()
|
||||
is PsiArrayInitializerMemberValue -> value.initializers.filterIsInstance<PsiReferenceExpression>()
|
||||
.flatMap { mapTargetByName(it) }
|
||||
.toSet()
|
||||
is PsiReferenceExpression -> mapTargetByName(value)
|
||||
@@ -122,7 +122,7 @@ class AnnotationConverter(private val converter: Converter) {
|
||||
}
|
||||
}
|
||||
val deferredExpressionList = arguments.map {
|
||||
val name = it.name()
|
||||
val name = it.name
|
||||
null to converter.deferredElement<Expression> {
|
||||
QualifiedExpression(Identifier("AnnotationTarget", false).assignNoPrototype(),
|
||||
Identifier(name, false).assignNoPrototype())
|
||||
@@ -132,19 +132,19 @@ class AnnotationConverter(private val converter: Converter) {
|
||||
deferredExpressionList, newLineAfter).assignPrototype(annotation)
|
||||
}
|
||||
|
||||
val nameRef = annotation.getNameReferenceElement()
|
||||
val name = Identifier((nameRef ?: return null).getText()!!).assignPrototype(nameRef)
|
||||
val nameRef = annotation.nameReferenceElement
|
||||
val name = Identifier((nameRef ?: return null).text!!).assignPrototype(nameRef)
|
||||
val annotationClass = nameRef.resolve() as? PsiClass
|
||||
val arguments = annotation.getParameterList().getAttributes().flatMap {
|
||||
val parameterName = it.getName() ?: "value"
|
||||
val arguments = annotation.parameterList.attributes.flatMap {
|
||||
val parameterName = it.name ?: "value"
|
||||
val method = annotationClass?.findMethodsByName(parameterName, false)?.firstOrNull()
|
||||
val expectedType = method?.getReturnType()
|
||||
val expectedType = method?.returnType
|
||||
|
||||
val attrName = it.getName()?.let { Identifier(it).assignNoPrototype() }
|
||||
val value = it.getValue()
|
||||
val attrName = it.name?.let { Identifier(it).assignNoPrototype() }
|
||||
val value = it.value
|
||||
|
||||
val isVarArg = parameterName == "value" /* converted to vararg in Kotlin */
|
||||
val attrValues = convertAttributeValue(value, expectedType, isVarArg, it.getName() == null)
|
||||
val attrValues = convertAttributeValue(value, expectedType, isVarArg, it.name == null)
|
||||
|
||||
attrValues.map { attrName to converter.deferredElement(it) }
|
||||
}
|
||||
@@ -152,8 +152,8 @@ class AnnotationConverter(private val converter: Converter) {
|
||||
}
|
||||
|
||||
public fun convertAnnotationMethodDefault(method: PsiAnnotationMethod): DeferredElement<Expression>? {
|
||||
val value = method.getDefaultValue() ?: return null
|
||||
return converter.deferredElement(convertAttributeValue(value, method.getReturnType(), false, false).single())
|
||||
val value = method.defaultValue ?: return null
|
||||
return converter.deferredElement(convertAttributeValue(value, method.returnType, false, false).single())
|
||||
}
|
||||
|
||||
private fun convertAttributeValue(value: PsiAnnotationMemberValue?, expectedType: PsiType?, isVararg: Boolean, isUnnamed: Boolean): List<(CodeConverter) -> Expression> {
|
||||
@@ -161,8 +161,8 @@ class AnnotationConverter(private val converter: Converter) {
|
||||
is PsiExpression -> listOf({ codeConverter -> convertExpressionValue(codeConverter, value, expectedType) })
|
||||
|
||||
is PsiArrayInitializerMemberValue -> {
|
||||
val componentType = (expectedType as? PsiArrayType)?.getComponentType()
|
||||
val componentGenerators = value.getInitializers().map { convertAttributeValue(it, componentType, false, true).single() }
|
||||
val componentType = (expectedType as? PsiArrayType)?.componentType
|
||||
val componentGenerators = value.initializers.map { convertAttributeValue(it, componentType, false, true).single() }
|
||||
if (isVararg && isUnnamed) {
|
||||
componentGenerators
|
||||
}
|
||||
@@ -171,13 +171,13 @@ class AnnotationConverter(private val converter: Converter) {
|
||||
}
|
||||
}
|
||||
|
||||
else -> listOf({ codeConverter -> DummyStringExpression(value?.getText() ?: "").assignPrototype(value) })
|
||||
else -> listOf({ codeConverter -> DummyStringExpression(value?.text ?: "").assignPrototype(value) })
|
||||
}
|
||||
}
|
||||
|
||||
private fun convertExpressionValue(codeConverter: CodeConverter, value: PsiExpression, expectedType: PsiType?): Expression {
|
||||
val expression = if (value is PsiClassObjectAccessExpression) {
|
||||
val type = converter.convertTypeElement(value.getOperand(), Nullability.NotNull)
|
||||
val type = converter.convertTypeElement(value.operand, Nullability.NotNull)
|
||||
ClassLiteralExpression(type)
|
||||
}
|
||||
else {
|
||||
@@ -204,7 +204,7 @@ class AnnotationConverter(private val converter: Converter) {
|
||||
}
|
||||
}
|
||||
else {
|
||||
DummyStringExpression(value.getText()!!).assignPrototype(value)
|
||||
DummyStringExpression(value.text!!).assignPrototype(value)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -69,13 +69,13 @@ class ClassBodyConverter(private val psiClass: PsiClass,
|
||||
classKind.isOpen(),
|
||||
converter.referenceSearcher)
|
||||
|
||||
val constructorConverter = if (psiClass.getName() != null && !classKind.isObject())
|
||||
val constructorConverter = if (psiClass.name != null && !classKind.isObject())
|
||||
ConstructorConverter(psiClass, converter, { field -> memberToPropertyInfo[field]!! }, overloadReducer)
|
||||
else
|
||||
null
|
||||
|
||||
val convertedMembers = LinkedHashMap<PsiMember, Member>()
|
||||
for (element in psiClass.getChildren()) {
|
||||
for (element in psiClass.children) {
|
||||
if (element is PsiMember) {
|
||||
if (element is PsiAnnotationMethod) continue // converted in convertAnnotationType()
|
||||
if (classKind.isObject() && element.isConstructor()) continue // no constructor in object
|
||||
@@ -90,11 +90,11 @@ class ClassBodyConverter(private val psiClass: PsiClass,
|
||||
|
||||
fieldsToDrop.forEach { convertedMembers.remove(it) }
|
||||
|
||||
val lBrace = LBrace().assignPrototype(psiClass.getLBrace())
|
||||
val rBrace = RBrace().assignPrototype(psiClass.getRBrace())
|
||||
val lBrace = LBrace().assignPrototype(psiClass.lBrace)
|
||||
val rBrace = RBrace().assignPrototype(psiClass.rBrace)
|
||||
|
||||
if (classKind.isObject()) {
|
||||
val psiMembers = convertedMembers.keySet()
|
||||
val psiMembers = convertedMembers.keys
|
||||
if (psiMembers.all { it is PsiMethod }) { // for object with no fields we can use faster external usage processing
|
||||
converter.addUsageProcessing(ToObjectWithOnlyMethodsProcessing(psiClass))
|
||||
}
|
||||
@@ -107,7 +107,7 @@ class ClassBodyConverter(private val psiClass: PsiClass,
|
||||
}
|
||||
}
|
||||
|
||||
return ClassBody(null, null, convertedMembers.values().toList(), emptyList(), lBrace, rBrace, classKind)
|
||||
return ClassBody(null, null, convertedMembers.values.toList(), emptyList(), lBrace, rBrace, classKind)
|
||||
}
|
||||
|
||||
val useCompanionObject = shouldGenerateCompanionObject(convertedMembers)
|
||||
@@ -125,7 +125,7 @@ class ClassBodyConverter(private val psiClass: PsiClass,
|
||||
companionObjectMembers.add(member)
|
||||
if (psiMember is PsiMethod /* fields in companion object can be accessed as fields from java */
|
||||
&& !psiMember.hasModifierProperty(PsiModifier.PRIVATE)) {
|
||||
converter.addUsageProcessing(MethodIntoObjectProcessing(psiMember, SpecialNames.DEFAULT_NAME_FOR_COMPANION_OBJECT.getIdentifier()))
|
||||
converter.addUsageProcessing(MethodIntoObjectProcessing(psiMember, SpecialNames.DEFAULT_NAME_FOR_COMPANION_OBJECT.identifier))
|
||||
}
|
||||
}
|
||||
else {
|
||||
@@ -180,7 +180,7 @@ class ClassBodyConverter(private val psiClass: PsiClass,
|
||||
|
||||
// do not convert private static methods into companion object if possible
|
||||
private fun shouldGenerateCompanionObject(convertedMembers: Map<PsiMember, Member>): Boolean {
|
||||
val members = convertedMembers.keySet().filter { !it.isConstructor() }
|
||||
val members = convertedMembers.keys.filter { !it.isConstructor() }
|
||||
val companionObjectMembers = members.filter { it !is PsiClass && it !is PsiEnumConstant && it.hasModifierProperty(PsiModifier.STATIC) }
|
||||
val nestedClasses = members.filterIsInstance<PsiClass>().filter { it.hasModifierProperty(PsiModifier.STATIC) }
|
||||
if (companionObjectMembers.all { it is PsiMethod && it.hasModifierProperty(PsiModifier.PRIVATE) }) {
|
||||
|
||||
@@ -25,9 +25,7 @@ import org.jetbrains.kotlin.j2k.ast.Element
|
||||
import org.jetbrains.kotlin.j2k.ast.SpacesInheritance
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
import org.jetbrains.kotlin.psi.psiUtil.isAncestor
|
||||
import java.util.ArrayList
|
||||
import java.util.HashSet
|
||||
import java.util.LinkedHashSet
|
||||
import java.util.*
|
||||
|
||||
fun<T> CodeBuilder.buildList(generators: Collection<() -> T>, separator: String, prefix: String = "", suffix: String = ""): CodeBuilder {
|
||||
if (generators.isNotEmpty()) {
|
||||
@@ -72,7 +70,7 @@ class CodeBuilder(private val topElement: PsiElement?, private var docConverter:
|
||||
append(docConverter.convertDocComment(element), false)
|
||||
}
|
||||
else {
|
||||
append(element.getText()!!, element.isEndOfLineComment())
|
||||
append(element.text!!, element.isEndOfLineComment())
|
||||
}
|
||||
}
|
||||
|
||||
@@ -245,7 +243,7 @@ class CodeBuilder(private val topElement: PsiElement?, private var docConverter:
|
||||
private fun MutableList<PsiElement>.collectCommentsAndSpacesBefore(element: PsiElement): MutableList<PsiElement> {
|
||||
if (element == topElement) return this
|
||||
|
||||
val prev = element.getPrevSibling()
|
||||
val prev = element.prevSibling
|
||||
if (prev != null) {
|
||||
if (prev.isCommentOrSpace()) {
|
||||
if (prev !in commentsAndSpacesUsed) {
|
||||
@@ -258,7 +256,7 @@ class CodeBuilder(private val topElement: PsiElement?, private var docConverter:
|
||||
}
|
||||
}
|
||||
else {
|
||||
collectCommentsAndSpacesBefore(element.getParent()!!)
|
||||
collectCommentsAndSpacesBefore(element.parent!!)
|
||||
}
|
||||
return this
|
||||
}
|
||||
@@ -266,7 +264,7 @@ class CodeBuilder(private val topElement: PsiElement?, private var docConverter:
|
||||
private fun MutableList<PsiElement>.collectCommentsAndSpacesAfter(element: PsiElement): MutableList<PsiElement> {
|
||||
if (element == topElement) return this
|
||||
|
||||
val next = element.getNextSibling()
|
||||
val next = element.nextSibling
|
||||
if (next != null) {
|
||||
if (next.isCommentOrSpace()) {
|
||||
if (next is PsiWhiteSpace && next.hasLineBreaks()) return this // do not attach anything on next line after element
|
||||
@@ -280,13 +278,13 @@ class CodeBuilder(private val topElement: PsiElement?, private var docConverter:
|
||||
}
|
||||
}
|
||||
else {
|
||||
collectCommentsAndSpacesAfter(element.getParent()!!)
|
||||
collectCommentsAndSpacesAfter(element.parent!!)
|
||||
}
|
||||
return this
|
||||
}
|
||||
|
||||
private fun MutableList<PsiElement>.collectCommentsAndSpacesAtStart(element: PsiElement): MutableList<PsiElement> {
|
||||
var child = element.getFirstChild()
|
||||
var child = element.firstChild
|
||||
while(child != null) {
|
||||
if (child.isCommentOrSpace()) {
|
||||
if (child !in commentsAndSpacesUsed) add(child) else break
|
||||
@@ -295,13 +293,13 @@ class CodeBuilder(private val topElement: PsiElement?, private var docConverter:
|
||||
collectCommentsAndSpacesAtStart(child)
|
||||
break
|
||||
}
|
||||
child = child.getNextSibling()
|
||||
child = child.nextSibling
|
||||
}
|
||||
return this
|
||||
}
|
||||
|
||||
private fun MutableList<PsiElement>.collectCommentsAndSpacesAtEnd(element: PsiElement): MutableList<PsiElement> {
|
||||
var child = element.getLastChild()
|
||||
var child = element.lastChild
|
||||
while(child != null) {
|
||||
if (child.isCommentOrSpace()) {
|
||||
if (child !in commentsAndSpacesUsed) add(child) else break
|
||||
@@ -310,7 +308,7 @@ class CodeBuilder(private val topElement: PsiElement?, private var docConverter:
|
||||
collectCommentsAndSpacesAtEnd(child)
|
||||
break
|
||||
}
|
||||
child = child.getPrevSibling()
|
||||
child = child.prevSibling
|
||||
}
|
||||
return this
|
||||
}
|
||||
@@ -323,7 +321,7 @@ class CodeBuilder(private val topElement: PsiElement?, private var docConverter:
|
||||
other.isEmpty() -> return this
|
||||
|
||||
else -> {
|
||||
val result = ArrayList<T>(size() + other.size())
|
||||
val result = ArrayList<T>(size + other.size)
|
||||
result.addAll(this)
|
||||
result.addAll(other)
|
||||
return result
|
||||
@@ -332,7 +330,7 @@ class CodeBuilder(private val topElement: PsiElement?, private var docConverter:
|
||||
}
|
||||
|
||||
fun<T> List<T>.reversed(): List<T> {
|
||||
return if (size() <= 1)
|
||||
return if (size <= 1)
|
||||
this
|
||||
else
|
||||
this.asReversed()
|
||||
@@ -340,20 +338,20 @@ class CodeBuilder(private val topElement: PsiElement?, private var docConverter:
|
||||
|
||||
fun PsiElement.isCommentOrSpace() = this is PsiComment || this is PsiWhiteSpace
|
||||
|
||||
fun PsiElement.isEndOfLineComment() = this is PsiComment && getTokenType() == JavaTokenType.END_OF_LINE_COMMENT
|
||||
fun PsiElement.isEndOfLineComment() = this is PsiComment && tokenType == JavaTokenType.END_OF_LINE_COMMENT
|
||||
|
||||
fun PsiElement.isEmptyElement() = getFirstChild() == null && getTextLength() == 0
|
||||
fun PsiElement.isEmptyElement() = firstChild == null && textLength == 0
|
||||
|
||||
fun PsiWhiteSpace.lineBreakCount() = StringUtil.getLineBreakCount(getText())
|
||||
fun PsiWhiteSpace.lineBreakCount() = StringUtil.getLineBreakCount(text)
|
||||
|
||||
fun PsiWhiteSpace.hasLineBreaks() = StringUtil.containsLineBreak(getText())
|
||||
fun PsiWhiteSpace.hasLineBreaks() = StringUtil.containsLineBreak(text)
|
||||
|
||||
fun CharSequence.trailingLineBreakCount(): Int {
|
||||
var i = length() - 1
|
||||
var i = length - 1
|
||||
while (i >= 0 && this[i] == '\n') {
|
||||
i--
|
||||
}
|
||||
return length() - i - 1
|
||||
return length - i - 1
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -46,9 +46,9 @@ class CodeConverter(
|
||||
public fun convertBlock(block: PsiCodeBlock?, notEmpty: Boolean = true, statementFilter: (PsiStatement) -> Boolean = { true }): Block {
|
||||
if (block == null) return Block.Empty
|
||||
|
||||
val lBrace = LBrace().assignPrototype(block.getLBrace())
|
||||
val rBrace = RBrace().assignPrototype(block.getRBrace())
|
||||
return Block(block.getStatements().filter(statementFilter).map { convertStatement(it) }, lBrace, rBrace, notEmpty).assignPrototype(block)
|
||||
val lBrace = LBrace().assignPrototype(block.lBrace)
|
||||
val rBrace = RBrace().assignPrototype(block.rBrace)
|
||||
return Block(block.statements.filter(statementFilter).map { convertStatement(it) }, lBrace, rBrace, notEmpty).assignPrototype(block)
|
||||
}
|
||||
|
||||
public fun convertStatement(statement: PsiStatement?): Statement {
|
||||
@@ -71,7 +71,7 @@ class CodeConverter(
|
||||
|
||||
public fun convertLocalVariable(variable: PsiLocalVariable): LocalVariable {
|
||||
val isVal = variable.hasModifierProperty(PsiModifier.FINAL) ||
|
||||
variable.getInitializer() == null/* we do not know actually and prefer val until we have better analysis*/ ||
|
||||
variable.initializer == null/* we do not know actually and prefer val until we have better analysis*/ ||
|
||||
!variable.hasWriteAccesses(converter.referenceSearcher, variable.getContainingMethod())
|
||||
val type = typeConverter.convertVariableType(variable)
|
||||
val explicitType = type.check { settings.specifyLocalVariableTypeByDefault || converter.shouldDeclareVariableType(variable, type, isVal) }
|
||||
@@ -79,7 +79,7 @@ class CodeConverter(
|
||||
converter.convertAnnotations(variable),
|
||||
converter.convertModifiers(variable, false),
|
||||
explicitType,
|
||||
convertExpression(variable.getInitializer(), variable.getType()),
|
||||
convertExpression(variable.initializer, variable.type),
|
||||
isVal).assignPrototype(variable)
|
||||
}
|
||||
|
||||
@@ -89,19 +89,19 @@ class CodeConverter(
|
||||
var convertedExpression = convertExpression(expression)
|
||||
if (expectedType == null || expectedType == PsiType.VOID) return convertedExpression
|
||||
|
||||
val actualType = expression.getType() ?: return convertedExpression
|
||||
val actualType = expression.type ?: return convertedExpression
|
||||
|
||||
if (actualType is PsiPrimitiveType || actualType is PsiClassType && expectedType is PsiPrimitiveType) {
|
||||
convertedExpression = BangBangExpression.surroundIfNullable(convertedExpression)
|
||||
}
|
||||
|
||||
if (needConversion(actualType, expectedType)) {
|
||||
val expectedTypeStr = expectedType.getCanonicalText()
|
||||
val expectedTypeStr = expectedType.canonicalText
|
||||
if (expression is PsiLiteralExpression) {
|
||||
if (expectedTypeStr == "float" || expectedTypeStr == "double") {
|
||||
var text = convertedExpression.canonicalCode()
|
||||
if (text.last() in setOf('f', 'L')) {
|
||||
text = text.substring(0, text.length() - 1)
|
||||
text = text.substring(0, text.length - 1)
|
||||
}
|
||||
if (expectedTypeStr == "float") {
|
||||
text += "f"
|
||||
@@ -115,8 +115,8 @@ class CodeConverter(
|
||||
}
|
||||
}
|
||||
else if (expression is PsiPrefixExpression && expression.isLiteralWithSign()) {
|
||||
val operandConverted = convertExpression(expression.getOperand(), expectedType)
|
||||
convertedExpression = PrefixExpression(Operator(expression.getOperationSign().getTokenType()).assignPrototype(expression.getOperationSign()), operandConverted)
|
||||
val operandConverted = convertExpression(expression.operand, expectedType)
|
||||
convertedExpression = PrefixExpression(Operator(expression.operationSign.tokenType).assignPrototype(expression.operationSign), operandConverted)
|
||||
}
|
||||
else {
|
||||
val conversion = PRIMITIVE_TYPE_CONVERSIONS[expectedTypeStr]
|
||||
@@ -131,7 +131,7 @@ class CodeConverter(
|
||||
|
||||
public fun convertedExpressionType(expression: PsiExpression, expectedType: PsiType): Type {
|
||||
var convertedExpression = convertExpression(expression)
|
||||
val actualType = expression.getType() ?: return ErrorType()
|
||||
val actualType = expression.type ?: return ErrorType()
|
||||
var resultType = typeConverter.convertType(actualType, if (convertedExpression.isNullable) Nullability.Nullable else Nullability.NotNull)
|
||||
|
||||
if (actualType is PsiPrimitiveType && resultType.isNullable ||
|
||||
@@ -140,7 +140,7 @@ class CodeConverter(
|
||||
}
|
||||
|
||||
if (needConversion(actualType, expectedType)) {
|
||||
val expectedTypeStr = expectedType.getCanonicalText()
|
||||
val expectedTypeStr = expectedType.canonicalText
|
||||
|
||||
val willConvert = if (convertedExpression is LiteralExpression
|
||||
|| expression is PsiPrefixExpression && expression.isLiteralWithSign() )
|
||||
@@ -157,11 +157,11 @@ class CodeConverter(
|
||||
}
|
||||
|
||||
private fun PsiPrefixExpression.isLiteralWithSign()
|
||||
= getOperand() is PsiLiteralExpression && getOperationTokenType() in setOf(JavaTokenType.PLUS, JavaTokenType.MINUS)
|
||||
= operand is PsiLiteralExpression && operationTokenType in setOf(JavaTokenType.PLUS, JavaTokenType.MINUS)
|
||||
|
||||
private fun needConversion(actual: PsiType, expected: PsiType): Boolean {
|
||||
val expectedStr = expected.getCanonicalText()
|
||||
val actualStr = actual.getCanonicalText()
|
||||
val expectedStr = expected.canonicalText
|
||||
val actualStr = actual.canonicalText
|
||||
return expectedStr != actualStr &&
|
||||
expectedStr != typeConversionMap[actualStr] &&
|
||||
actualStr != typeConversionMap[expectedStr]
|
||||
|
||||
@@ -27,11 +27,11 @@ class ConstructorConverter(
|
||||
private val fieldToPropertyInfo: (PsiField) -> PropertyInfo,
|
||||
private val overloadReducer: OverloadReducer
|
||||
) {
|
||||
private val constructors = psiClass.getConstructors().asList()
|
||||
private val constructors = psiClass.constructors.asList()
|
||||
|
||||
private val toTargetConstructorMap = buildToTargetConstructorMap()
|
||||
|
||||
private val primaryConstructor: PsiMethod? = when (constructors.size()) {
|
||||
private val primaryConstructor: PsiMethod? = when (constructors.size) {
|
||||
0 -> null
|
||||
1 -> constructors.single()
|
||||
else -> choosePrimaryConstructor()
|
||||
@@ -39,25 +39,25 @@ class ConstructorConverter(
|
||||
|
||||
private fun choosePrimaryConstructor(): PsiMethod? {
|
||||
val candidates = constructors.filter { it !in toTargetConstructorMap }
|
||||
if (candidates.size() != 1) return null // there should be only one constructor which does not call other constructor
|
||||
if (candidates.size != 1) return null // there should be only one constructor which does not call other constructor
|
||||
val primary = candidates.single()
|
||||
if (toTargetConstructorMap.values().any() { it != primary }) return null // all other constructors call our candidate (directly or indirectly)
|
||||
if (toTargetConstructorMap.values.any() { it != primary }) return null // all other constructors call our candidate (directly or indirectly)
|
||||
return primary
|
||||
}
|
||||
|
||||
private fun buildToTargetConstructorMap(): Map<PsiMethod, PsiMethod> {
|
||||
val toTargetConstructorMap = HashMap<PsiMethod, PsiMethod>()
|
||||
for (constructor in constructors) {
|
||||
val firstStatement = constructor.getBody()?.getStatements()?.firstOrNull()
|
||||
val methodCall = (firstStatement as? PsiExpressionStatement)?.getExpression() as? PsiMethodCallExpression
|
||||
val firstStatement = constructor.body?.statements?.firstOrNull()
|
||||
val methodCall = (firstStatement as? PsiExpressionStatement)?.expression as? PsiMethodCallExpression
|
||||
if (methodCall != null) {
|
||||
val refExpr = methodCall.getMethodExpression()
|
||||
if (refExpr.getCanonicalText() == "this") {
|
||||
val refExpr = methodCall.methodExpression
|
||||
if (refExpr.canonicalText == "this") {
|
||||
val target = refExpr.resolve() as? PsiMethod
|
||||
if (target != null && target.isConstructor()) {
|
||||
if (target != null && target.isConstructor) {
|
||||
val finalTarget = toTargetConstructorMap[target] ?: target
|
||||
toTargetConstructorMap[constructor] = finalTarget
|
||||
for (entry in toTargetConstructorMap.entrySet()) {
|
||||
for (entry in toTargetConstructorMap.entries) {
|
||||
if (entry.value == constructor) {
|
||||
entry.setValue(finalTarget)
|
||||
}
|
||||
@@ -87,7 +87,7 @@ class ConstructorConverter(
|
||||
|
||||
val thisOrSuper = findThisOrSuperCall(constructor)
|
||||
val thisOrSuperDeferred = if (thisOrSuper != null)
|
||||
converter.deferredElement { it.convertExpression(thisOrSuper.getExpression()) }
|
||||
converter.deferredElement { it.convertExpression(thisOrSuper.expression) }
|
||||
else
|
||||
null
|
||||
|
||||
@@ -99,7 +99,7 @@ class ConstructorConverter(
|
||||
}
|
||||
return null
|
||||
}
|
||||
}).convertBlock(constructor.getBody()))
|
||||
}).convertBlock(constructor.body))
|
||||
}
|
||||
|
||||
SecondaryConstructor(annotations, modifiers, params, converter.deferredElement(::convertBody), thisOrSuperDeferred)
|
||||
@@ -108,9 +108,9 @@ class ConstructorConverter(
|
||||
}
|
||||
|
||||
private fun findThisOrSuperCall(constructor: PsiMethod): PsiExpressionStatement? {
|
||||
val statement = constructor.getBody()?.getStatements()?.firstOrNull() as? PsiExpressionStatement ?: return null
|
||||
val methodCall = statement.getExpression() as? PsiMethodCallExpression ?: return null
|
||||
val text = methodCall.getMethodExpression().getText()
|
||||
val statement = constructor.body?.statements?.firstOrNull() as? PsiExpressionStatement ?: return null
|
||||
val methodCall = statement.expression as? PsiMethodCallExpression ?: return null
|
||||
val text = methodCall.methodExpression.text
|
||||
return if (text == "this" || text == "super") statement else null
|
||||
}
|
||||
|
||||
@@ -118,9 +118,9 @@ class ConstructorConverter(
|
||||
modifiers: Modifiers,
|
||||
fieldsToDrop: MutableSet<PsiField>,
|
||||
postProcessBody: (Block) -> Block): PrimaryConstructor {
|
||||
val params = primaryConstructor!!.getParameterList().getParameters()
|
||||
val params = primaryConstructor!!.parameterList.parameters
|
||||
val parameterToField = HashMap<PsiParameter, Pair<PsiField, Type>>()
|
||||
val body = primaryConstructor.getBody()
|
||||
val body = primaryConstructor.body
|
||||
|
||||
val parameterUsageReplacementMap = HashMap<String, String>()
|
||||
val correctedTypeConverter = converter.withSpecialContext(psiClass).typeConverter /* to correct nested class references */
|
||||
@@ -151,8 +151,8 @@ class ConstructorConverter(
|
||||
fieldsToDrop.add(field)
|
||||
|
||||
val fieldName = propertyInfo.name
|
||||
if (fieldName != parameter.getName()) {
|
||||
parameterUsageReplacementMap.put(parameter.getName()!!, fieldName)
|
||||
if (fieldName != parameter.name) {
|
||||
parameterUsageReplacementMap.put(parameter.name!!, fieldName)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -179,10 +179,10 @@ class ConstructorConverter(
|
||||
|
||||
fun CodeConverter.correct() = withSpecialExpressionConverter(ReplacingExpressionConverter(parameterUsageReplacementMap))
|
||||
|
||||
val statement = primaryConstructor.getBody()?.getStatements()?.firstOrNull()
|
||||
val methodCall = (statement as? PsiExpressionStatement)?.getExpression() as? PsiMethodCallExpression
|
||||
val statement = primaryConstructor.body?.statements?.firstOrNull()
|
||||
val methodCall = (statement as? PsiExpressionStatement)?.expression as? PsiMethodCallExpression
|
||||
if (methodCall != null && methodCall.isSuperConstructorCall()) {
|
||||
baseClassParams = methodCall.getArgumentList().getExpressions().map {
|
||||
baseClassParams = methodCall.argumentList.expressions.map {
|
||||
correctedConverter.deferredElement { codeConverter -> codeConverter.correct().convertExpression(it) }
|
||||
}
|
||||
}
|
||||
@@ -218,25 +218,25 @@ class ConstructorConverter(
|
||||
}
|
||||
|
||||
private fun findBackingFieldForConstructorParameter(parameter: PsiParameter, constructor: PsiMethod): Pair<PsiField, PsiStatement>? {
|
||||
val body = constructor.getBody() ?: return null
|
||||
val body = constructor.body ?: return null
|
||||
|
||||
val refs = converter.referenceSearcher.findVariableUsages(parameter, body)
|
||||
|
||||
if (refs.any { PsiUtil.isAccessedForWriting(it) }) return null
|
||||
|
||||
for (ref in refs) {
|
||||
val assignment = ref.getParent() as? PsiAssignmentExpression ?: continue
|
||||
if (assignment.getOperationSign().getTokenType() != JavaTokenType.EQ) continue
|
||||
val assignee = assignment.getLExpression() as? PsiReferenceExpression ?: continue
|
||||
val assignment = ref.parent as? PsiAssignmentExpression ?: continue
|
||||
if (assignment.operationSign.tokenType != JavaTokenType.EQ) continue
|
||||
val assignee = assignment.lExpression as? PsiReferenceExpression ?: continue
|
||||
if (!assignee.isQualifierEmptyOrThis()) continue
|
||||
val field = assignee.resolve() as? PsiField ?: continue
|
||||
if (field.getContainingClass() != constructor.getContainingClass()) continue
|
||||
if (field.containingClass != constructor.containingClass) continue
|
||||
if (field.hasModifierProperty(PsiModifier.STATIC)) continue
|
||||
if (field.getInitializer() != null) continue
|
||||
if (field.initializer != null) continue
|
||||
|
||||
// assignment should be a top-level statement
|
||||
val statement = assignment.getParent() as? PsiExpressionStatement ?: continue
|
||||
if (statement.getParent() != body) continue
|
||||
val statement = assignment.parent as? PsiExpressionStatement ?: continue
|
||||
if (statement.parent != body) continue
|
||||
|
||||
// and no other assignments to field should exist in the constructor
|
||||
if (converter.referenceSearcher.findVariableUsages(field, body).any { it != assignee && PsiUtil.isAccessedForWriting(it) && it.isQualifierEmptyOrThis() }) continue
|
||||
@@ -248,19 +248,19 @@ class ConstructorConverter(
|
||||
return null
|
||||
}
|
||||
|
||||
private fun PsiExpression.isSuperConstructorCall() = (this as? PsiMethodCallExpression)?.getMethodExpression()?.getText() == "super"
|
||||
private fun PsiExpression.isThisConstructorCall() = (this as? PsiMethodCallExpression)?.getMethodExpression()?.getText() == "this"
|
||||
private fun PsiExpression.isSuperConstructorCall() = (this as? PsiMethodCallExpression)?.methodExpression?.text == "super"
|
||||
private fun PsiExpression.isThisConstructorCall() = (this as? PsiMethodCallExpression)?.methodExpression?.text == "this"
|
||||
|
||||
private inner open class ReplacingExpressionConverter(val parameterUsageReplacementMap: Map<String, String>) : SpecialExpressionConverter {
|
||||
override fun convertExpression(expression: PsiExpression, codeConverter: CodeConverter): Expression? {
|
||||
if (expression is PsiReferenceExpression && expression.getQualifier() == null) {
|
||||
val replacement = parameterUsageReplacementMap[expression.getReferenceName()]
|
||||
if (expression is PsiReferenceExpression && expression.qualifier == null) {
|
||||
val replacement = parameterUsageReplacementMap[expression.referenceName]
|
||||
if (replacement != null) {
|
||||
val target = expression.resolve()
|
||||
if (target is PsiParameter) {
|
||||
val scope = target.getDeclarationScope()
|
||||
val scope = target.declarationScope
|
||||
// we do not check for exactly this constructor because default values reference parameters in other constructors
|
||||
if (scope is PsiMember && scope.isConstructor() && scope.getParent() == psiClass) {
|
||||
if (scope is PsiMember && scope.isConstructor() && scope.parent == psiClass) {
|
||||
return Identifier(replacement, codeConverter.typeConverter.variableNullability(target).isNullable(codeConverter.settings))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -51,7 +51,7 @@ class Converter private constructor(
|
||||
// state which may differ in different converter's
|
||||
public class PersonalState(val specialContext: PsiElement?)
|
||||
|
||||
public val project: Project = elementToConvert.getProject()
|
||||
public val project: Project = elementToConvert.project
|
||||
public val typeConverter: TypeConverter = TypeConverter(this)
|
||||
public val annotationConverter: AnnotationConverter = AnnotationConverter(this)
|
||||
|
||||
@@ -113,7 +113,7 @@ class Converter private constructor(
|
||||
is PsiImportList -> convertImportList(element)
|
||||
is PsiImportStatementBase -> convertImport(element, false)
|
||||
is PsiAnnotation -> annotationConverter.convertAnnotation(element, newLineAfter = false)
|
||||
is PsiPackageStatement -> PackageStatement(quoteKeywords(element.getPackageName() ?: "")).assignPrototype(element)
|
||||
is PsiPackageStatement -> PackageStatement(quoteKeywords(element.packageName ?: "")).assignPrototype(element)
|
||||
is PsiJavaCodeReferenceElement -> {
|
||||
if (element.parent is PsiReferenceList) {
|
||||
val factory = JavaPsiFacade.getInstance(project).elementFactory
|
||||
@@ -129,7 +129,7 @@ class Converter private constructor(
|
||||
|
||||
// we use loop with index because new deferred elements can be added during unfolding
|
||||
var i = 0
|
||||
while (i < commonState.deferredElements.size()) {
|
||||
while (i < commonState.deferredElements.size) {
|
||||
val deferredElement = commonState.deferredElements[i++]
|
||||
deferredElement.unfold(codeConverter.withConverter(this.withState(deferredElement.converterState)))
|
||||
}
|
||||
@@ -152,7 +152,7 @@ class Converter private constructor(
|
||||
}
|
||||
|
||||
private fun convertFile(javaFile: PsiJavaFile): File {
|
||||
var convertedChildren = javaFile.getChildren().mapNotNull { convertTopElement(it) }
|
||||
var convertedChildren = javaFile.children.mapNotNull { convertTopElement(it) }
|
||||
return File(convertedChildren).assignPrototype(javaFile)
|
||||
}
|
||||
|
||||
@@ -160,26 +160,26 @@ class Converter private constructor(
|
||||
= annotationConverter.convertAnnotations(owner)
|
||||
|
||||
public fun convertClass(psiClass: PsiClass): Class {
|
||||
if (psiClass.isAnnotationType()) {
|
||||
if (psiClass.isAnnotationType) {
|
||||
return convertAnnotationType(psiClass)
|
||||
}
|
||||
|
||||
val annotations = convertAnnotations(psiClass)
|
||||
var modifiers = convertModifiers(psiClass, false)
|
||||
val typeParameters = convertTypeParameterList(psiClass.getTypeParameterList())
|
||||
val extendsTypes = convertToNotNullableTypes(psiClass.getExtendsListTypes())
|
||||
val implementsTypes = convertToNotNullableTypes(psiClass.getImplementsListTypes())
|
||||
val typeParameters = convertTypeParameterList(psiClass.typeParameterList)
|
||||
val extendsTypes = convertToNotNullableTypes(psiClass.extendsListTypes)
|
||||
val implementsTypes = convertToNotNullableTypes(psiClass.implementsListTypes)
|
||||
val name = psiClass.declarationIdentifier()
|
||||
|
||||
return when {
|
||||
psiClass.isInterface() -> {
|
||||
psiClass.isInterface -> {
|
||||
val classBody = ClassBodyConverter(psiClass, ClassKind.INTERFACE, this).convertBody()
|
||||
Interface(name, annotations, modifiers, typeParameters, extendsTypes, implementsTypes, classBody)
|
||||
}
|
||||
|
||||
psiClass.isEnum() -> {
|
||||
psiClass.isEnum -> {
|
||||
modifiers = modifiers.without(Modifier.ABSTRACT)
|
||||
val hasInheritors = psiClass.getFields().any { it is PsiEnumConstant && it.getInitializingClass() != null }
|
||||
val hasInheritors = psiClass.fields.any { it is PsiEnumConstant && it.initializingClass != null }
|
||||
val classBody = ClassBodyConverter(psiClass, if (hasInheritors) ClassKind.OPEN_ENUM else ClassKind.FINAL_ENUM, this).convertBody()
|
||||
Enum(name, annotations, modifiers, typeParameters, implementsTypes, classBody)
|
||||
}
|
||||
@@ -190,7 +190,7 @@ class Converter private constructor(
|
||||
Object(name, annotations, modifiers.without(Modifier.ABSTRACT), classBody)
|
||||
}
|
||||
else {
|
||||
if (psiClass.getContainingClass() != null && !psiClass.hasModifierProperty(PsiModifier.STATIC)) {
|
||||
if (psiClass.containingClass != null && !psiClass.hasModifierProperty(PsiModifier.STATIC)) {
|
||||
modifiers = modifiers.with(Modifier.INNER)
|
||||
}
|
||||
|
||||
@@ -214,25 +214,25 @@ class Converter private constructor(
|
||||
}
|
||||
|
||||
private fun shouldConvertIntoObject(psiClass: PsiClass): Boolean {
|
||||
val methods = psiClass.getMethods()
|
||||
val fields = psiClass.getFields()
|
||||
val classes = psiClass.getInnerClasses()
|
||||
val methods = psiClass.methods
|
||||
val fields = psiClass.fields
|
||||
val classes = psiClass.innerClasses
|
||||
if (methods.isEmpty() && fields.isEmpty()) return false
|
||||
fun isStatic(member: PsiMember) = member.hasModifierProperty(PsiModifier.STATIC)
|
||||
if (!methods.all { isStatic(it) || it.isConstructor() } || !fields.all(::isStatic) || !classes.all(::isStatic)) return false
|
||||
if (!methods.all { isStatic(it) || it.isConstructor } || !fields.all(::isStatic) || !classes.all(::isStatic)) return false
|
||||
|
||||
val constructors = psiClass.getConstructors()
|
||||
if (constructors.size() > 1) return false
|
||||
val constructors = psiClass.constructors
|
||||
if (constructors.size > 1) return false
|
||||
val constructor = constructors.singleOrNull()
|
||||
if (constructor != null) {
|
||||
if (!constructor.hasModifierProperty(PsiModifier.PRIVATE)) return false
|
||||
if (constructor.getParameterList().getParameters().isNotEmpty()) return false
|
||||
if (constructor.getBody()?.getStatements()?.isNotEmpty() ?: false) return false
|
||||
if (constructor.getModifierList().getAnnotations().isNotEmpty()) return false
|
||||
if (constructor.parameterList.parameters.isNotEmpty()) return false
|
||||
if (constructor.body?.statements?.isNotEmpty() ?: false) return false
|
||||
if (constructor.modifierList.annotations.isNotEmpty()) return false
|
||||
}
|
||||
|
||||
if (psiClass.getExtendsListTypes().isNotEmpty() || psiClass.getImplementsListTypes().isNotEmpty()) return false
|
||||
if (psiClass.getTypeParameters().isNotEmpty()) return false
|
||||
if (psiClass.extendsListTypes.isNotEmpty() || psiClass.implementsListTypes.isNotEmpty()) return false
|
||||
if (psiClass.typeParameters.isNotEmpty()) return false
|
||||
|
||||
if (referenceSearcher.hasInheritors(psiClass)) return false
|
||||
|
||||
@@ -241,11 +241,11 @@ class Converter private constructor(
|
||||
|
||||
private fun convertAnnotationType(psiClass: PsiClass): Class {
|
||||
val paramModifiers = Modifiers(listOf(Modifier.PUBLIC)).assignNoPrototype()
|
||||
val annotationMethods = psiClass.getMethods().filterIsInstance<PsiAnnotationMethod>()
|
||||
val (methodsNamedValue, otherMethods) = annotationMethods.partition { it.getName() == "value" }
|
||||
val annotationMethods = psiClass.methods.filterIsInstance<PsiAnnotationMethod>()
|
||||
val (methodsNamedValue, otherMethods) = annotationMethods.partition { it.name == "value" }
|
||||
|
||||
fun createParameter(type: Type, method: PsiAnnotationMethod): FunctionParameter {
|
||||
type.assignPrototype(method.getReturnTypeElement(), CommentsAndSpacesInheritance.NO_SPACES)
|
||||
type.assignPrototype(method.returnTypeElement, CommentsAndSpacesInheritance.NO_SPACES)
|
||||
|
||||
return FunctionParameter(method.declarationIdentifier(),
|
||||
type,
|
||||
@@ -263,15 +263,15 @@ class Converter private constructor(
|
||||
// Argument named `value` comes first if it exists
|
||||
// Convert it as vararg if it's array
|
||||
methodsNamedValue.map { method ->
|
||||
val returnType = method.getReturnType()
|
||||
val returnType = method.returnType
|
||||
val typeConverted = if (returnType is PsiArrayType)
|
||||
VarArgType(convertType(returnType.getComponentType()))
|
||||
VarArgType(convertType(returnType.componentType))
|
||||
else
|
||||
convertType(returnType)
|
||||
|
||||
createParameter(typeConverted, method)
|
||||
} +
|
||||
otherMethods.map { method -> createParameter(convertType(method.getReturnType()), method) }
|
||||
otherMethods.map { method -> createParameter(convertType(method.returnType), method) }
|
||||
|
||||
val parameterList = ParameterList(parameters).assignNoPrototype()
|
||||
val constructorSignature = if (parameterList.parameters.isNotEmpty())
|
||||
@@ -295,7 +295,7 @@ class Converter private constructor(
|
||||
}
|
||||
|
||||
public fun convertInitializer(initializer: PsiClassInitializer): Initializer {
|
||||
return Initializer(deferredElement { codeConverter -> codeConverter.convertBlock(initializer.getBody()) },
|
||||
return Initializer(deferredElement { codeConverter -> codeConverter.convertBlock(initializer.body) },
|
||||
convertModifiers(initializer, false)).assignPrototype(initializer)
|
||||
}
|
||||
|
||||
@@ -312,11 +312,11 @@ class Converter private constructor(
|
||||
val name = propertyInfo.identifier
|
||||
if (field is PsiEnumConstant) {
|
||||
assert(getMethod == null && setMethod == null)
|
||||
val argumentList = field.getArgumentList()
|
||||
val argumentList = field.argumentList
|
||||
val params = deferredElement { codeConverter ->
|
||||
ExpressionList(codeConverter.convertExpressions(argumentList?.getExpressions() ?: arrayOf<PsiExpression>())).assignPrototype(argumentList)
|
||||
ExpressionList(codeConverter.convertExpressions(argumentList?.expressions ?: arrayOf<PsiExpression>())).assignPrototype(argumentList)
|
||||
}
|
||||
val body = field.getInitializingClass()?.let { convertAnonymousClassBody(it) }
|
||||
val body = field.initializingClass?.let { convertAnonymousClassBody(it) }
|
||||
return EnumConstant(name, annotations, modifiers, params, body)
|
||||
.assignPrototype(field, CommentsAndSpacesInheritance.LINE_BREAKS)
|
||||
}
|
||||
@@ -443,12 +443,12 @@ class Converter private constructor(
|
||||
}
|
||||
|
||||
public fun shouldDeclareVariableType(variable: PsiVariable, type: Type, canChangeType: Boolean): Boolean {
|
||||
val initializer = variable.getInitializer()
|
||||
val initializer = variable.initializer
|
||||
if (initializer == null || initializer.isNullLiteral()) return true
|
||||
|
||||
if (canChangeType) return false
|
||||
|
||||
var initializerType = createDefaultCodeConverter().convertedExpressionType(initializer, variable.getType())
|
||||
var initializerType = createDefaultCodeConverter().convertedExpressionType(initializer, variable.type)
|
||||
if (initializerType is ErrorType) return false // do not add explicit type when initializer is not resolved, let user add it if really needed
|
||||
return type != initializerType
|
||||
}
|
||||
@@ -467,7 +467,7 @@ class Converter private constructor(
|
||||
var modifiers = convertModifiers(method, classKind.isOpen())
|
||||
|
||||
val statementsToInsert = ArrayList<Statement>()
|
||||
for (parameter in method.getParameterList().getParameters()) {
|
||||
for (parameter in method.parameterList.parameters) {
|
||||
if (parameter.hasWriteAccesses(referenceSearcher, method)) {
|
||||
val variable = LocalVariable(parameter.declarationIdentifier(),
|
||||
Annotations.Empty,
|
||||
@@ -487,15 +487,15 @@ class Converter private constructor(
|
||||
}
|
||||
}
|
||||
|
||||
val function = if (method.isConstructor() && constructorConverter != null) {
|
||||
val function = if (method.isConstructor && constructorConverter != null) {
|
||||
constructorConverter.convertConstructor(method, annotations, modifiers, fieldsToDrop!!, postProcessBody)
|
||||
}
|
||||
else {
|
||||
val containingClass = method.getContainingClass()
|
||||
val containingClass = method.containingClass
|
||||
|
||||
if (settings.openByDefault) {
|
||||
val isEffectivelyFinal = method.hasModifierProperty(PsiModifier.FINAL) ||
|
||||
containingClass != null && (containingClass.hasModifierProperty(PsiModifier.FINAL) || containingClass.isEnum())
|
||||
containingClass != null && (containingClass.hasModifierProperty(PsiModifier.FINAL) || containingClass.isEnum)
|
||||
if (!isEffectivelyFinal && !modifiers.contains(Modifier.ABSTRACT) && !modifiers.isPrivate) {
|
||||
modifiers = modifiers.with(Modifier.OPEN)
|
||||
}
|
||||
@@ -503,9 +503,9 @@ class Converter private constructor(
|
||||
|
||||
var params = convertParameterList(method, overloadReducer)
|
||||
|
||||
val typeParameterList = convertTypeParameterList(method.getTypeParameterList())
|
||||
val typeParameterList = convertTypeParameterList(method.typeParameterList)
|
||||
var body = deferredElement { codeConverter: CodeConverter ->
|
||||
val body = codeConverter.withMethodReturnType(method.getReturnType()).convertBlock(method.getBody())
|
||||
val body = codeConverter.withMethodReturnType(method.returnType).convertBlock(method.body)
|
||||
postProcessBody(body)
|
||||
}
|
||||
Function(method.declarationIdentifier(), annotations, modifiers, returnType, typeParameterList, params, body, classKind == ClassKind.INTERFACE)
|
||||
@@ -534,27 +534,27 @@ class Converter private constructor(
|
||||
* Overrides of methods from Object should not be marked as overrides in Kotlin unless the class itself has java ancestors
|
||||
*/
|
||||
private fun isOverride(method: PsiMethod): Boolean {
|
||||
val superSignatures = method.getHierarchicalMethodSignature().getSuperSignatures()
|
||||
val superSignatures = method.hierarchicalMethodSignature.superSignatures
|
||||
|
||||
val overridesMethodNotFromObject = superSignatures.any {
|
||||
it.getMethod().getContainingClass()?.getQualifiedName() != JAVA_LANG_OBJECT
|
||||
it.method.containingClass?.qualifiedName != JAVA_LANG_OBJECT
|
||||
}
|
||||
if (overridesMethodNotFromObject) return true
|
||||
|
||||
val overridesMethodFromObject = superSignatures.any {
|
||||
it.getMethod().getContainingClass()?.getQualifiedName() == JAVA_LANG_OBJECT
|
||||
it.method.containingClass?.qualifiedName == JAVA_LANG_OBJECT
|
||||
}
|
||||
if (overridesMethodFromObject) {
|
||||
when (method.getName()) {
|
||||
when (method.name) {
|
||||
"equals", "hashCode", "toString" -> return true // these methods from java.lang.Object exist in kotlin.Any
|
||||
|
||||
else -> {
|
||||
val containing = method.getContainingClass()
|
||||
val containing = method.containingClass
|
||||
if (containing != null) {
|
||||
val hasOtherJavaSuperclasses = containing.getSuperTypes().any {
|
||||
val hasOtherJavaSuperclasses = containing.superTypes.any {
|
||||
//TODO: correctly check for kotlin class
|
||||
val klass = it.resolve()
|
||||
klass != null && klass.getQualifiedName() != JAVA_LANG_OBJECT && !inConversionScope(klass)
|
||||
klass != null && klass.qualifiedName != JAVA_LANG_OBJECT && !inConversionScope(klass)
|
||||
}
|
||||
if (hasOtherJavaSuperclasses) return true
|
||||
}
|
||||
@@ -579,15 +579,15 @@ class Converter private constructor(
|
||||
}
|
||||
|
||||
public fun convertCodeReferenceElement(element: PsiJavaCodeReferenceElement, hasExternalQualifier: Boolean, typeArgsConverted: List<Element>? = null): ReferenceElement {
|
||||
val typeArgs = typeArgsConverted ?: typeConverter.convertTypes(element.getTypeParameters())
|
||||
val typeArgs = typeArgsConverted ?: typeConverter.convertTypes(element.typeParameters)
|
||||
|
||||
if (element.isQualified()) {
|
||||
var result = Identifier.toKotlin(element.getReferenceName()!!)
|
||||
var qualifier = element.getQualifier()
|
||||
if (element.isQualified) {
|
||||
var result = Identifier.toKotlin(element.referenceName!!)
|
||||
var qualifier = element.qualifier
|
||||
while (qualifier != null) {
|
||||
val codeRefElement = qualifier as PsiJavaCodeReferenceElement
|
||||
result = Identifier.toKotlin(codeRefElement.getReferenceName()!!) + "." + result
|
||||
qualifier = codeRefElement.getQualifier()
|
||||
result = Identifier.toKotlin(codeRefElement.referenceName!!) + "." + result
|
||||
qualifier = codeRefElement.qualifier
|
||||
}
|
||||
return ReferenceElement(Identifier(result).assignNoPrototype(), typeArgs).assignPrototype(element)
|
||||
}
|
||||
@@ -603,17 +603,17 @@ class Converter private constructor(
|
||||
}
|
||||
}
|
||||
|
||||
return ReferenceElement(Identifier(element.getReferenceName()!!).assignNoPrototype(), typeArgs).assignPrototype(element)
|
||||
return ReferenceElement(Identifier(element.referenceName!!).assignNoPrototype(), typeArgs).assignPrototype(element)
|
||||
}
|
||||
}
|
||||
|
||||
private fun constructNestedClassReferenceIdentifier(psiClass: PsiClass, context: PsiElement): Identifier? {
|
||||
val outerClass = psiClass.getContainingClass()
|
||||
val outerClass = psiClass.containingClass
|
||||
if (outerClass != null
|
||||
&& !PsiTreeUtil.isAncestor(outerClass, context, true)
|
||||
&& !psiClass.isImported(context.getContainingFile() as PsiJavaFile)) {
|
||||
val qualifier = constructNestedClassReferenceIdentifier(outerClass, context)?.name ?: outerClass.getName()!!
|
||||
return Identifier(Identifier.toKotlin(qualifier) + "." + Identifier.toKotlin(psiClass.getName()!!)).assignNoPrototype()
|
||||
&& !psiClass.isImported(context.containingFile as PsiJavaFile)) {
|
||||
val qualifier = constructNestedClassReferenceIdentifier(outerClass, context)?.name ?: outerClass.name!!
|
||||
return Identifier(Identifier.toKotlin(qualifier) + "." + Identifier.toKotlin(psiClass.name!!)).assignNoPrototype()
|
||||
}
|
||||
return null
|
||||
}
|
||||
@@ -643,12 +643,12 @@ class Converter private constructor(
|
||||
public fun convertIdentifier(identifier: PsiIdentifier?): Identifier {
|
||||
if (identifier == null) return Identifier.Empty
|
||||
|
||||
return Identifier(identifier.getText()!!).assignPrototype(identifier)
|
||||
return Identifier(identifier.text!!).assignPrototype(identifier)
|
||||
}
|
||||
|
||||
public fun convertModifiers(owner: PsiModifierListOwner, isMethodInOpenClass: Boolean): Modifiers {
|
||||
var modifiers = Modifiers(MODIFIERS_MAP.filter { owner.hasModifierProperty(it.first) }.map { it.second })
|
||||
.assignPrototype(owner.getModifierList(), CommentsAndSpacesInheritance.NO_SPACES)
|
||||
.assignPrototype(owner.modifierList, CommentsAndSpacesInheritance.NO_SPACES)
|
||||
|
||||
if (owner is PsiMethod) {
|
||||
val isOverride = isOverride(owner)
|
||||
@@ -682,7 +682,7 @@ class Converter private constructor(
|
||||
|
||||
public fun convertAnonymousClassBody(anonymousClass: PsiAnonymousClass): AnonymousClassBody {
|
||||
return AnonymousClassBody(ClassBodyConverter(anonymousClass, ClassKind.ANONYMOUS_OBJECT, this).convertBody(),
|
||||
anonymousClass.getBaseClassType().resolve()?.isInterface() ?: false).assignPrototype(anonymousClass)
|
||||
anonymousClass.baseClassType.resolve()?.isInterface ?: false).assignPrototype(anonymousClass)
|
||||
}
|
||||
|
||||
private val MODIFIERS_MAP = listOf(
|
||||
@@ -694,10 +694,10 @@ class Converter private constructor(
|
||||
)
|
||||
|
||||
private fun convertThrows(method: PsiMethod): Annotations {
|
||||
val throwsList = method.getThrowsList()
|
||||
val types = throwsList.getReferencedTypes()
|
||||
val refElements = throwsList.getReferenceElements()
|
||||
assert(types.size() == refElements.size())
|
||||
val throwsList = method.throwsList
|
||||
val types = throwsList.referencedTypes
|
||||
val refElements = throwsList.referenceElements
|
||||
assert(types.size == refElements.size)
|
||||
if (types.isEmpty()) return Annotations.Empty
|
||||
val arguments = types.indices.map { index ->
|
||||
val convertedType = typeConverter.convertType(types[index], Nullability.NotNull)
|
||||
|
||||
@@ -30,8 +30,8 @@ object EmptyDocCommentConverter: DocCommentConverter {
|
||||
}
|
||||
|
||||
fun PsiDocTag.content(): String =
|
||||
getChildren()
|
||||
.dropWhile { it.getNode().getElementType() == JavaDocTokenType.DOC_TAG_NAME }
|
||||
children
|
||||
.dropWhile { it.node.elementType == JavaDocTokenType.DOC_TAG_NAME }
|
||||
.dropWhile { it is PsiWhiteSpace }
|
||||
.filterNot { it.getNode().getElementType() == JavaDocTokenType.DOC_COMMENT_LEADING_ASTERISKS }
|
||||
.joinToString("") { it.getText() }
|
||||
.filterNot { it.node.elementType == JavaDocTokenType.DOC_COMMENT_LEADING_ASTERISKS }
|
||||
.joinToString("") { it.text }
|
||||
|
||||
@@ -68,26 +68,26 @@ class DefaultExpressionConverter : JavaElementVisitor(), ExpressionConverter {
|
||||
|
||||
override fun visitArrayAccessExpression(expression: PsiArrayAccessExpression) {
|
||||
val assignment = expression.getStrictParentOfType<PsiAssignmentExpression>()
|
||||
val lvalue = assignment != null && expression == assignment.getLExpression();
|
||||
result = ArrayAccessExpression(codeConverter.convertExpression(expression.getArrayExpression()),
|
||||
codeConverter.convertExpression(expression.getIndexExpression()),
|
||||
lvalue)
|
||||
val lvalue = assignment != null && expression == assignment.lExpression;
|
||||
result = ArrayAccessExpression(codeConverter.convertExpression(expression.arrayExpression),
|
||||
codeConverter.convertExpression(expression.indexExpression),
|
||||
lvalue)
|
||||
}
|
||||
|
||||
override fun visitArrayInitializerExpression(expression: PsiArrayInitializerExpression) {
|
||||
val arrayType = expression.getType()
|
||||
val componentType = (arrayType as? PsiArrayType)?.getComponentType()
|
||||
val arrayType = expression.type
|
||||
val componentType = (arrayType as? PsiArrayType)?.componentType
|
||||
val expressionType = typeConverter.convertType(arrayType)
|
||||
assert(expressionType is ArrayType) { "Array initializer must have array type: expressionType = $expressionType expression = $expression" }
|
||||
result = createArrayInitializerExpression(expressionType as ArrayType,
|
||||
expression.getInitializers().map { codeConverter.convertExpression(it, componentType) })
|
||||
expression.initializers.map { codeConverter.convertExpression(it, componentType) })
|
||||
}
|
||||
|
||||
override fun visitAssignmentExpression(expression: PsiAssignmentExpression) {
|
||||
val tokenType = expression.getOperationSign().getTokenType()
|
||||
val tokenType = expression.operationSign.tokenType
|
||||
|
||||
val lhs = codeConverter.convertExpression(expression.getLExpression())
|
||||
val rhs = codeConverter.convertExpression(expression.getRExpression()!!, expression.getLExpression().getType())
|
||||
val lhs = codeConverter.convertExpression(expression.lExpression)
|
||||
val rhs = codeConverter.convertExpression(expression.rExpression!!, expression.lExpression.type)
|
||||
|
||||
val secondOp = when(tokenType) {
|
||||
JavaTokenType.GTGTEQ, JavaTokenType.LTLTEQ, JavaTokenType.GTGTGTEQ,
|
||||
@@ -106,12 +106,12 @@ class DefaultExpressionConverter : JavaElementVisitor(), ExpressionConverter {
|
||||
}
|
||||
|
||||
override fun visitBinaryExpression(expression: PsiBinaryExpression) {
|
||||
val left = expression.getLOperand()
|
||||
val right = expression.getROperand()
|
||||
val left = expression.lOperand
|
||||
val right = expression.rOperand
|
||||
var leftConverted = codeConverter.convertExpression(left, null)
|
||||
var rightConverted = codeConverter.convertExpression(right, null)
|
||||
|
||||
val operationTokenType = expression.getOperationTokenType()
|
||||
val operationTokenType = expression.operationTokenType
|
||||
if (operationTokenType in NON_NULL_OPERAND_OPS) {
|
||||
leftConverted = BangBangExpression.surroundIfNullable(leftConverted)
|
||||
rightConverted = BangBangExpression.surroundIfNullable(rightConverted)
|
||||
@@ -133,18 +133,18 @@ class DefaultExpressionConverter : JavaElementVisitor(), ExpressionConverter {
|
||||
|
||||
private fun canKeepEqEq(left: PsiExpression, right: PsiExpression?): Boolean {
|
||||
if (left.isNullLiteral() || (right?.isNullLiteral() ?: false)) return true
|
||||
val type = left.getType()
|
||||
val type = left.type
|
||||
when (type) {
|
||||
is PsiPrimitiveType, is PsiArrayType -> return true
|
||||
|
||||
is PsiClassType -> {
|
||||
val psiClass = type.resolve() ?: return false
|
||||
if (!psiClass.hasModifierProperty(PsiModifier.FINAL)) return false
|
||||
if (psiClass.isEnum()) return true
|
||||
if (psiClass.isEnum) return true
|
||||
|
||||
val equalsSignature = getEqualsSignature(converter.project, GlobalSearchScope.allScope(converter.project))
|
||||
val equalsMethod = MethodSignatureUtil.findMethodBySignature(psiClass, equalsSignature, true)
|
||||
if (equalsMethod != null && equalsMethod.getContainingClass()?.getQualifiedName() != CommonClassNames.JAVA_LANG_OBJECT) return false
|
||||
if (equalsMethod != null && equalsMethod.containingClass?.qualifiedName != CommonClassNames.JAVA_LANG_OBJECT) return false
|
||||
|
||||
return true
|
||||
}
|
||||
@@ -172,11 +172,11 @@ class DefaultExpressionConverter : JavaElementVisitor(), ExpressionConverter {
|
||||
JavaTokenType.GTGTGT)
|
||||
|
||||
override fun visitClassObjectAccessExpression(expression: PsiClassObjectAccessExpression) {
|
||||
val operand = expression.getOperand()
|
||||
val typeName = operand.getType().getCanonicalText()
|
||||
val primitiveType = JvmPrimitiveType.values().firstOrNull { it.getJavaKeywordName() == typeName }
|
||||
val operand = expression.operand
|
||||
val typeName = operand.type.canonicalText
|
||||
val primitiveType = JvmPrimitiveType.values.firstOrNull { it.javaKeywordName == typeName }
|
||||
val wrapperTypeName = if (primitiveType != null) {
|
||||
primitiveType.getWrapperFqName()
|
||||
primitiveType.wrapperFqName
|
||||
}
|
||||
else if (typeName == "void") { // by unknown reason it's not in JvmPrimitiveType enum
|
||||
FqName("java.lang.Void")
|
||||
@@ -198,30 +198,30 @@ class DefaultExpressionConverter : JavaElementVisitor(), ExpressionConverter {
|
||||
}
|
||||
|
||||
override fun visitConditionalExpression(expression: PsiConditionalExpression) {
|
||||
val condition = expression.getCondition()
|
||||
val type = condition.getType()
|
||||
val condition = expression.condition
|
||||
val type = condition.type
|
||||
val expr = if (type != null)
|
||||
codeConverter.convertExpression(condition, type)
|
||||
else
|
||||
codeConverter.convertExpression(condition)
|
||||
result = IfStatement(expr,
|
||||
codeConverter.convertExpression(expression.getThenExpression()),
|
||||
codeConverter.convertExpression(expression.getElseExpression()),
|
||||
codeConverter.convertExpression(expression.thenExpression),
|
||||
codeConverter.convertExpression(expression.elseExpression),
|
||||
expression.isInSingleLine())
|
||||
}
|
||||
|
||||
override fun visitInstanceOfExpression(expression: PsiInstanceOfExpression) {
|
||||
val checkType = expression.getCheckType()
|
||||
result = IsOperator(codeConverter.convertExpression(expression.getOperand()),
|
||||
converter.convertTypeElement(checkType, Nullability.NotNull))
|
||||
val checkType = expression.checkType
|
||||
result = IsOperator(codeConverter.convertExpression(expression.operand),
|
||||
converter.convertTypeElement(checkType, Nullability.NotNull))
|
||||
}
|
||||
|
||||
override fun visitLiteralExpression(expression: PsiLiteralExpression) {
|
||||
val value = expression.getValue()
|
||||
var text = expression.getText()!!
|
||||
val type = expression.getType()
|
||||
val value = expression.value
|
||||
var text = expression.text!!
|
||||
val type = expression.type
|
||||
if (type != null) {
|
||||
val typeStr = type.getCanonicalText()
|
||||
val typeStr = type.canonicalText
|
||||
if (typeStr == "double") {
|
||||
text = text.replace("D", "").replace("d", "")
|
||||
if (!text.contains(".")) {
|
||||
@@ -247,8 +247,8 @@ class DefaultExpressionConverter : JavaElementVisitor(), ExpressionConverter {
|
||||
}
|
||||
|
||||
override fun visitMethodCallExpression(expression: PsiMethodCallExpression) {
|
||||
val methodExpr = expression.getMethodExpression()
|
||||
val arguments = expression.getArgumentList().getExpressions()
|
||||
val methodExpr = expression.methodExpression
|
||||
val arguments = expression.argumentList.expressions
|
||||
val target = methodExpr.resolve()
|
||||
val isNullable = if (target is PsiMethod) typeConverter.methodNullability(target).isNullable(codeConverter.settings) else false
|
||||
val typeArguments = convertTypeArguments(expression)
|
||||
@@ -258,12 +258,12 @@ class DefaultExpressionConverter : JavaElementVisitor(), ExpressionConverter {
|
||||
val isTopLevel = origin?.getStrictParentOfType<KtClassOrObject>() == null
|
||||
if (origin is KtProperty || origin is KtPropertyAccessor || origin is KtParameter) {
|
||||
val property = if (origin is KtPropertyAccessor)
|
||||
origin.getParent() as KtProperty
|
||||
origin.parent as KtProperty
|
||||
else
|
||||
origin as KtNamedDeclaration
|
||||
val parameterCount = target.getParameterList().getParameters().size()
|
||||
if (parameterCount == arguments.size()) {
|
||||
val propertyName = Identifier(property.getName()!!, isNullable).assignNoPrototype()
|
||||
val parameterCount = target.parameterList.parameters.size
|
||||
if (parameterCount == arguments.size) {
|
||||
val propertyName = Identifier(property.name!!, isNullable).assignNoPrototype()
|
||||
val isExtension = property.isExtensionDeclaration()
|
||||
val propertyAccess = if (isTopLevel) {
|
||||
if (isExtension)
|
||||
@@ -272,7 +272,7 @@ class DefaultExpressionConverter : JavaElementVisitor(), ExpressionConverter {
|
||||
propertyName
|
||||
}
|
||||
else {
|
||||
QualifiedExpression(codeConverter.convertExpression(methodExpr.getQualifierExpression()), propertyName).assignNoPrototype()
|
||||
QualifiedExpression(codeConverter.convertExpression(methodExpr.qualifierExpression), propertyName).assignNoPrototype()
|
||||
}
|
||||
|
||||
when(if (isExtension) parameterCount - 1 else parameterCount) {
|
||||
@@ -294,14 +294,14 @@ class DefaultExpressionConverter : JavaElementVisitor(), ExpressionConverter {
|
||||
result = if (origin.isExtensionDeclaration()) {
|
||||
val qualifier = codeConverter.convertExpression(arguments.firstOrNull())
|
||||
MethodCallExpression.build(qualifier,
|
||||
origin.getName()!!,
|
||||
origin.name!!,
|
||||
convertArguments(expression, isExtension = true),
|
||||
typeArguments,
|
||||
isNullable)
|
||||
}
|
||||
else {
|
||||
MethodCallExpression.build(null,
|
||||
origin.getName()!!,
|
||||
origin.name!!,
|
||||
convertArguments(expression),
|
||||
typeArguments,
|
||||
isNullable)
|
||||
@@ -312,9 +312,9 @@ class DefaultExpressionConverter : JavaElementVisitor(), ExpressionConverter {
|
||||
}
|
||||
|
||||
if (target is PsiMethod) {
|
||||
val specialMethod = SpecialMethod.match(target, arguments.size(), converter.services)
|
||||
val specialMethod = SpecialMethod.match(target, arguments.size, converter.services)
|
||||
if (specialMethod != null) {
|
||||
val converted = specialMethod.convertCall(methodExpr.getQualifierExpression(), arguments, typeArguments, codeConverter)
|
||||
val converted = specialMethod.convertCall(methodExpr.qualifierExpression, arguments, typeArguments, codeConverter)
|
||||
if (converted != null) {
|
||||
result = converted
|
||||
return
|
||||
@@ -329,17 +329,17 @@ class DefaultExpressionConverter : JavaElementVisitor(), ExpressionConverter {
|
||||
}
|
||||
|
||||
private fun convertTypeArguments(call: PsiCallExpression): List<Type> {
|
||||
var typeArgs = call.getTypeArguments().toList()
|
||||
var typeArgs = call.typeArguments.toList()
|
||||
|
||||
// always add explicit type arguments and remove them if they are redundant later
|
||||
if (typeArgs.size() == 0) {
|
||||
if (typeArgs.size == 0) {
|
||||
val resolve = call.resolveMethodGenerics()
|
||||
if (resolve.isValidResult()) {
|
||||
val method = resolve.getElement() as? PsiMethod
|
||||
if (resolve.isValidResult) {
|
||||
val method = resolve.element as? PsiMethod
|
||||
if (method != null) {
|
||||
val typeParameters = method.getTypeParameters()
|
||||
val typeParameters = method.typeParameters
|
||||
if (typeParameters.isNotEmpty()) {
|
||||
val map = resolve.getSubstitutor().getSubstitutionMap()
|
||||
val map = resolve.substitutor.substitutionMap
|
||||
typeArgs = typeParameters.map { map[it] ?: return listOf() }
|
||||
}
|
||||
}
|
||||
@@ -351,13 +351,13 @@ class DefaultExpressionConverter : JavaElementVisitor(), ExpressionConverter {
|
||||
|
||||
override fun visitNewExpression(expression: PsiNewExpression) {
|
||||
val type = expression.type
|
||||
if (expression.getArrayInitializer() != null) {
|
||||
result = codeConverter.convertExpression(expression.getArrayInitializer())
|
||||
if (expression.arrayInitializer != null) {
|
||||
result = codeConverter.convertExpression(expression.arrayInitializer)
|
||||
}
|
||||
else if (expression.getArrayDimensions().size() > 0 && expression.getType() is PsiArrayType) {
|
||||
else if (expression.arrayDimensions.size > 0 && expression.type is PsiArrayType) {
|
||||
result = ArrayWithoutInitializationExpression(
|
||||
typeConverter.convertType(expression.type, Nullability.NotNull) as ArrayType,
|
||||
codeConverter.convertExpressions(expression.getArrayDimensions()))
|
||||
codeConverter.convertExpressions(expression.arrayDimensions))
|
||||
}
|
||||
else {
|
||||
if (type?.canonicalText in PsiPrimitiveType.getAllBoxedTypeNames()) {
|
||||
@@ -368,8 +368,8 @@ class DefaultExpressionConverter : JavaElementVisitor(), ExpressionConverter {
|
||||
}
|
||||
}
|
||||
|
||||
val qualifier = expression.getQualifier()
|
||||
val classRef = expression.getClassOrAnonymousClassReference()
|
||||
val qualifier = expression.qualifier
|
||||
val classRef = expression.classOrAnonymousClassReference
|
||||
val classRefConverted = if (classRef != null) converter.convertCodeReferenceElement(classRef, hasExternalQualifier = qualifier != null) else null
|
||||
result = NewClassExpression(classRefConverted,
|
||||
convertArguments(expression),
|
||||
@@ -379,17 +379,17 @@ class DefaultExpressionConverter : JavaElementVisitor(), ExpressionConverter {
|
||||
}
|
||||
|
||||
override fun visitParenthesizedExpression(expression: PsiParenthesizedExpression) {
|
||||
result = ParenthesizedExpression(codeConverter.convertExpression(expression.getExpression()))
|
||||
result = ParenthesizedExpression(codeConverter.convertExpression(expression.expression))
|
||||
}
|
||||
|
||||
override fun visitPostfixExpression(expression: PsiPostfixExpression) {
|
||||
result = PostfixExpression(Operator(expression.getOperationSign().getTokenType()).assignPrototype(expression.operationSign),
|
||||
codeConverter.convertExpression(expression.getOperand()))
|
||||
result = PostfixExpression(Operator(expression.operationSign.tokenType).assignPrototype(expression.operationSign),
|
||||
codeConverter.convertExpression(expression.operand))
|
||||
}
|
||||
|
||||
override fun visitPrefixExpression(expression: PsiPrefixExpression) {
|
||||
val operand = codeConverter.convertExpression(expression.getOperand(), expression.getOperand()!!.getType())
|
||||
val token = expression.getOperationTokenType()
|
||||
val operand = codeConverter.convertExpression(expression.operand, expression.operand!!.type)
|
||||
val token = expression.operationTokenType
|
||||
if (token == JavaTokenType.TILDE) {
|
||||
result = MethodCallExpression.buildNotNull(operand, "inv")
|
||||
}
|
||||
@@ -403,22 +403,22 @@ class DefaultExpressionConverter : JavaElementVisitor(), ExpressionConverter {
|
||||
|
||||
override fun visitReferenceExpression(expression: PsiReferenceExpression) {
|
||||
// to avoid quoting of 'this' and 'super' in calls to this/super class constructors
|
||||
if (expression.getText() == "this") {
|
||||
if (expression.text == "this") {
|
||||
result = ThisExpression(Identifier.Empty)
|
||||
return
|
||||
}
|
||||
if (expression.getText() == "super") {
|
||||
if (expression.text == "super") {
|
||||
result = SuperExpression(Identifier.Empty)
|
||||
return
|
||||
}
|
||||
|
||||
val referenceName = expression.getReferenceName()!!
|
||||
val referenceName = expression.referenceName!!
|
||||
val target = expression.resolve()
|
||||
val isNullable = target is PsiVariable && typeConverter.variableNullability(target).isNullable(codeConverter.settings)
|
||||
val qualifier = expression.getQualifierExpression()
|
||||
val qualifier = expression.qualifierExpression
|
||||
|
||||
var identifier = Identifier(referenceName, isNullable).assignNoPrototype()
|
||||
if (qualifier != null && qualifier.getType() is PsiArrayType && referenceName == "length") {
|
||||
if (qualifier != null && qualifier.type is PsiArrayType && referenceName == "length") {
|
||||
identifier = Identifier("size", isNullable).assignNoPrototype()
|
||||
}
|
||||
else if (qualifier != null) {
|
||||
@@ -429,8 +429,8 @@ class DefaultExpressionConverter : JavaElementVisitor(), ExpressionConverter {
|
||||
}
|
||||
else {
|
||||
if (target is PsiClass) {
|
||||
if (PrimitiveType.values().any { it.getTypeName().asString() == target.getName() }) {
|
||||
result = Identifier(target.getQualifiedName()!!, false)
|
||||
if (PrimitiveType.values().any { it.typeName.asString() == target.name }) {
|
||||
result = Identifier(target.qualifiedName!!, false)
|
||||
return
|
||||
}
|
||||
}
|
||||
@@ -439,14 +439,14 @@ class DefaultExpressionConverter : JavaElementVisitor(), ExpressionConverter {
|
||||
val context = converter.specialContext ?: expression
|
||||
if (target is PsiMember
|
||||
&& target.hasModifierProperty(PsiModifier.STATIC)
|
||||
&& target.getContainingClass() != null
|
||||
&& !PsiTreeUtil.isAncestor(target.getContainingClass(), context, true)
|
||||
&& !target.isImported(context.getContainingFile() as PsiJavaFile)) {
|
||||
&& target.containingClass != null
|
||||
&& !PsiTreeUtil.isAncestor(target.containingClass, context, true)
|
||||
&& !target.isImported(context.containingFile as PsiJavaFile)) {
|
||||
var member: PsiMember = target
|
||||
var code = Identifier.toKotlin(referenceName)
|
||||
while (true) {
|
||||
val containingClass = member.getContainingClass() ?: break
|
||||
code = Identifier.toKotlin(containingClass.getName()!!) + "." + code
|
||||
val containingClass = member.containingClass ?: break
|
||||
code = Identifier.toKotlin(containingClass.name!!) + "." + code
|
||||
member = containingClass
|
||||
}
|
||||
result = Identifier(code, false, false)
|
||||
@@ -458,22 +458,22 @@ class DefaultExpressionConverter : JavaElementVisitor(), ExpressionConverter {
|
||||
}
|
||||
|
||||
override fun visitSuperExpression(expression: PsiSuperExpression) {
|
||||
val psiQualifier = expression.getQualifier()
|
||||
val qualifier = psiQualifier?.getReferenceName()
|
||||
val psiQualifier = expression.qualifier
|
||||
val qualifier = psiQualifier?.referenceName
|
||||
result = SuperExpression(if (qualifier != null) Identifier(qualifier).assignPrototype(psiQualifier) else Identifier.Empty)
|
||||
}
|
||||
|
||||
override fun visitThisExpression(expression: PsiThisExpression) {
|
||||
val psiQualifier = expression.getQualifier()
|
||||
val qualifier = psiQualifier?.getReferenceName()
|
||||
val psiQualifier = expression.qualifier
|
||||
val qualifier = psiQualifier?.referenceName
|
||||
result = ThisExpression(if (qualifier != null) Identifier(qualifier).assignPrototype(psiQualifier) else Identifier.Empty)
|
||||
}
|
||||
|
||||
override fun visitTypeCastExpression(expression: PsiTypeCastExpression) {
|
||||
val castType = expression.getCastType() ?: return
|
||||
val operand = expression.getOperand()
|
||||
val operandType = operand?.getType()
|
||||
val typeText = castType.getType().getCanonicalText()
|
||||
val castType = expression.castType ?: return
|
||||
val operand = expression.operand
|
||||
val operandType = operand?.type
|
||||
val typeText = castType.type.canonicalText
|
||||
val typeConversion = PRIMITIVE_TYPE_CONVERSIONS[typeText]
|
||||
val operandConverted = codeConverter.convertExpression(operand)
|
||||
if (operandType is PsiPrimitiveType && typeConversion != null) {
|
||||
@@ -500,10 +500,10 @@ class DefaultExpressionConverter : JavaElementVisitor(), ExpressionConverter {
|
||||
|
||||
override fun visitPolyadicExpression(expression: PsiPolyadicExpression) {
|
||||
val commentsAndSpacesInheritance = CommentsAndSpacesInheritance.LINE_BREAKS
|
||||
val args = expression.getOperands().map {
|
||||
codeConverter.convertExpression(it, expression.getType()).assignPrototype(it, commentsAndSpacesInheritance)
|
||||
val args = expression.operands.map {
|
||||
codeConverter.convertExpression(it, expression.type).assignPrototype(it, commentsAndSpacesInheritance)
|
||||
}
|
||||
val operators = expression.getOperands().map {
|
||||
val operators = expression.operands.map {
|
||||
expression.getTokenBeforeOperand(it)?.let {
|
||||
Operator(it.tokenType).assignPrototype(it, commentsAndSpacesInheritance)
|
||||
}
|
||||
@@ -513,21 +513,21 @@ class DefaultExpressionConverter : JavaElementVisitor(), ExpressionConverter {
|
||||
}
|
||||
|
||||
private fun convertArguments(expression: PsiCallExpression, isExtension: Boolean = false): List<Expression> {
|
||||
var arguments = expression.getArgumentList()?.getExpressions()?.toList() ?: listOf()
|
||||
var arguments = expression.argumentList?.expressions?.toList() ?: listOf()
|
||||
if (isExtension && arguments.isNotEmpty()) {
|
||||
arguments = arguments.drop(1)
|
||||
}
|
||||
|
||||
val resolved = expression.resolveMethod()
|
||||
val parameters = resolved?.getParameterList()?.getParameters()
|
||||
val expectedTypes = parameters?.map { it.getType() } ?: listOf()
|
||||
val parameters = resolved?.parameterList?.parameters
|
||||
val expectedTypes = parameters?.map { it.type } ?: listOf()
|
||||
|
||||
val commentsAndSpacesInheritance = CommentsAndSpacesInheritance.LINE_BREAKS
|
||||
|
||||
return if (arguments.size() == expectedTypes.size()) {
|
||||
return if (arguments.size == expectedTypes.size) {
|
||||
arguments.mapIndexed { i, argument ->
|
||||
val converted = codeConverter.convertExpression(argument, expectedTypes[i])
|
||||
val result = if (parameters != null && i == arguments.lastIndex && parameters[i].isVarArgs() && argument.getType() is PsiArrayType)
|
||||
val result = if (parameters != null && i == arguments.lastIndex && parameters[i].isVarArgs && argument.type is PsiArrayType)
|
||||
StarExpression(converted)
|
||||
else
|
||||
converted
|
||||
@@ -630,7 +630,7 @@ class DefaultExpressionConverter : JavaElementVisitor(), ExpressionConverter {
|
||||
}
|
||||
|
||||
val lambdaParameterList = ParameterList(
|
||||
if (parameters.size() == 1 && !isKotlinFunctionType) {
|
||||
if (parameters.size == 1 && !isKotlinFunctionType) {
|
||||
// for lambdas all parameters with types should be present
|
||||
emptyList()
|
||||
} else {
|
||||
@@ -690,7 +690,7 @@ class DefaultExpressionConverter : JavaElementVisitor(), ExpressionConverter {
|
||||
newParameters.add(Identifier(it.name ?: "p", false).assignNoPrototype() to parameterType)
|
||||
}
|
||||
|
||||
if (newParameters.size() == 1 && !isKotlinFunctionType) {
|
||||
if (newParameters.size == 1 && !isKotlinFunctionType) {
|
||||
newParameters.clear()
|
||||
newParameters.add(Identifier("it", false).assignNoPrototype() to null)
|
||||
}
|
||||
|
||||
@@ -31,19 +31,19 @@ class ForConverter(
|
||||
private val settings = codeConverter.settings
|
||||
private val project = codeConverter.converter.project
|
||||
|
||||
private val initialization = statement.getInitialization()
|
||||
private val update = statement.getUpdate()
|
||||
private val condition = statement.getCondition()
|
||||
private val body = statement.getBody()
|
||||
private val initialization = statement.initialization
|
||||
private val update = statement.update
|
||||
private val condition = statement.condition
|
||||
private val body = statement.body
|
||||
|
||||
public fun execute(): Statement {
|
||||
val foreach = convertToForeach()
|
||||
if (foreach != null) return foreach
|
||||
|
||||
val initialization = statement.getInitialization()
|
||||
val update = statement.getUpdate()
|
||||
val condition = statement.getCondition()
|
||||
val body = statement.getBody()
|
||||
val initialization = statement.initialization
|
||||
val update = statement.update
|
||||
val condition = statement.condition
|
||||
val body = statement.body
|
||||
|
||||
val initializationConverted = codeConverter.convertStatement(initialization)
|
||||
val updateConverted = codeConverter.convertStatement(update)
|
||||
@@ -60,7 +60,7 @@ class ForConverter(
|
||||
|
||||
val continueConverted = this@ForConverter.codeConverter.convertStatement(statement)
|
||||
val statements = listOf(updateConverted, continueConverted)
|
||||
if (statement.getParent() is PsiCodeBlock) {
|
||||
if (statement.parent is PsiCodeBlock) {
|
||||
// generate fictive statement which will generate multiple statements
|
||||
return object : Statement() {
|
||||
override fun generateCode(builder: CodeBuilder) {
|
||||
@@ -75,10 +75,10 @@ class ForConverter(
|
||||
})
|
||||
|
||||
if (body is PsiBlockStatement) {
|
||||
val nameConflict = initialization is PsiDeclarationStatement && initialization.getDeclaredElements().any { loopVar ->
|
||||
loopVar is PsiNamedElement && body.getCodeBlock().getStatements().any { statement ->
|
||||
statement is PsiDeclarationStatement && statement.getDeclaredElements().any {
|
||||
it is PsiNamedElement && it.getName() == loopVar.getName()
|
||||
val nameConflict = initialization is PsiDeclarationStatement && initialization.declaredElements.any { loopVar ->
|
||||
loopVar is PsiNamedElement && body.codeBlock.statements.any { statement ->
|
||||
statement is PsiDeclarationStatement && statement.declaredElements.any {
|
||||
it is PsiNamedElement && it.name == loopVar.name
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -88,7 +88,7 @@ class ForConverter(
|
||||
Block(statements, LBrace().assignNoPrototype(), RBrace().assignNoPrototype(), true).assignNoPrototype()
|
||||
}
|
||||
else {
|
||||
val block = codeConverterToUse.convertBlock(body.getCodeBlock(), true)
|
||||
val block = codeConverterToUse.convertBlock(body.codeBlock, true)
|
||||
Block(block.statements + listOf(updateConverted), block.lBrace, block.rBrace, true).assignPrototypesFrom(block)
|
||||
}
|
||||
}
|
||||
@@ -147,23 +147,23 @@ class ForConverter(
|
||||
|
||||
private fun convertToForeach(): ForeachStatement? {
|
||||
if (initialization is PsiDeclarationStatement) {
|
||||
val loopVar = initialization.getDeclaredElements().singleOrNull() as? PsiLocalVariable ?: return null
|
||||
val loopVar = initialization.declaredElements.singleOrNull() as? PsiLocalVariable ?: return null
|
||||
if (!loopVar.hasWriteAccesses(referenceSearcher, body)
|
||||
&& !loopVar.hasWriteAccesses(referenceSearcher, condition)
|
||||
&& condition is PsiBinaryExpression) {
|
||||
|
||||
val left = condition.getLOperand() as? PsiReferenceExpression ?: return null
|
||||
val right = condition.getROperand() ?: return null
|
||||
val left = condition.lOperand as? PsiReferenceExpression ?: return null
|
||||
val right = condition.rOperand ?: return null
|
||||
if (left.resolve() == loopVar) {
|
||||
val start = loopVar.getInitializer() ?: return null
|
||||
val operationType = (update as? PsiExpressionStatement)?.getExpression()?.isVariableIncrementOrDecrement(loopVar)
|
||||
val start = loopVar.initializer ?: return null
|
||||
val operationType = (update as? PsiExpressionStatement)?.expression?.isVariableIncrementOrDecrement(loopVar)
|
||||
val reversed = when (operationType) {
|
||||
JavaTokenType.PLUSPLUS -> false
|
||||
JavaTokenType.MINUSMINUS -> true
|
||||
else -> return null
|
||||
}
|
||||
|
||||
val inclusive = when (condition.getOperationTokenType()) {
|
||||
val inclusive = when (condition.operationTokenType) {
|
||||
JavaTokenType.LT -> if (reversed) return null else false
|
||||
JavaTokenType.LE -> if (reversed) return null else true
|
||||
JavaTokenType.GT -> if (reversed) false else return null
|
||||
@@ -187,8 +187,8 @@ class ForConverter(
|
||||
private fun PsiElement.isVariableIncrementOrDecrement(variable: PsiVariable): IElementType? {
|
||||
//TODO: simplify code when KT-5453 fixed
|
||||
val pair = when (this) {
|
||||
is PsiPostfixExpression -> getOperationTokenType() to getOperand()
|
||||
is PsiPrefixExpression -> getOperationTokenType() to getOperand()
|
||||
is PsiPostfixExpression -> operationTokenType to operand
|
||||
is PsiPrefixExpression -> operationTokenType to operand
|
||||
else -> return null
|
||||
}
|
||||
if ((pair.second as? PsiReferenceExpression)?.resolve() != variable) return null
|
||||
@@ -210,16 +210,16 @@ class ForConverter(
|
||||
val collectionSize = if (reversed) {
|
||||
if (!inclusiveComparison) return null
|
||||
|
||||
if ((bound as? PsiLiteralExpression)?.getValue() != 0) return null
|
||||
if ((bound as? PsiLiteralExpression)?.value != 0) return null
|
||||
|
||||
if (start !is PsiBinaryExpression) return null
|
||||
if (start.getOperationTokenType() != JavaTokenType.MINUS) return null
|
||||
if ((start.getROperand() as? PsiLiteralExpression)?.getValue() != 1) return null
|
||||
start.getLOperand()
|
||||
if (start.operationTokenType != JavaTokenType.MINUS) return null
|
||||
if ((start.rOperand as? PsiLiteralExpression)?.value != 1) return null
|
||||
start.lOperand
|
||||
}
|
||||
else {
|
||||
if (inclusiveComparison) return null
|
||||
if ((start as? PsiLiteralExpression)?.getValue() != 0) return null
|
||||
if ((start as? PsiLiteralExpression)?.value != 0) return null
|
||||
bound
|
||||
}
|
||||
|
||||
@@ -227,13 +227,13 @@ class ForConverter(
|
||||
var indices: Expression? = null
|
||||
|
||||
// check if it's iteration through list indices
|
||||
if (collectionSize is PsiMethodCallExpression && collectionSize.getArgumentList().getExpressions().isEmpty()) {
|
||||
val methodExpr = collectionSize.getMethodExpression()
|
||||
if (methodExpr is PsiReferenceExpression && methodExpr.getReferenceName() == "size") {
|
||||
val qualifier = methodExpr.getQualifierExpression()
|
||||
if (collectionSize is PsiMethodCallExpression && collectionSize.argumentList.expressions.isEmpty()) {
|
||||
val methodExpr = collectionSize.methodExpression
|
||||
if (methodExpr is PsiReferenceExpression && methodExpr.referenceName == "size") {
|
||||
val qualifier = methodExpr.qualifierExpression
|
||||
if (qualifier is PsiReferenceExpression /* we don't convert to .indices if qualifier is method call or something because of possible side effects */) {
|
||||
val collectionType = PsiElementFactory.SERVICE.getInstance(project).createTypeByFQClassName(CommonClassNames.JAVA_UTIL_COLLECTION)
|
||||
val qualifierType = qualifier.getType()
|
||||
val qualifierType = qualifier.type
|
||||
if (qualifierType != null && collectionType.isAssignableFrom(qualifierType)) {
|
||||
indices = QualifiedExpression(codeConverter.convertExpression(qualifier), Identifier("indices", false).assignNoPrototype())
|
||||
}
|
||||
@@ -242,9 +242,9 @@ class ForConverter(
|
||||
}
|
||||
// check if it's iteration through array indices
|
||||
else if (collectionSize is PsiReferenceExpression /* we don't convert to .indices if qualifier is method call or something because of possible side effects */
|
||||
&& collectionSize.getReferenceName() == "length") {
|
||||
val qualifier = collectionSize.getQualifierExpression()
|
||||
if (qualifier is PsiReferenceExpression && qualifier.getType() is PsiArrayType) {
|
||||
&& collectionSize.referenceName == "length") {
|
||||
val qualifier = collectionSize.qualifierExpression
|
||||
if (qualifier is PsiReferenceExpression && qualifier.type is PsiArrayType) {
|
||||
indices = QualifiedExpression(codeConverter.convertExpression(qualifier), Identifier("indices", false).assignNoPrototype())
|
||||
}
|
||||
}
|
||||
@@ -263,7 +263,7 @@ class ForConverter(
|
||||
}
|
||||
|
||||
if (bound is PsiLiteralExpression) {
|
||||
val value = bound.getValue()
|
||||
val value = bound.value
|
||||
if (value is Int) {
|
||||
return LiteralExpression((value + correction).toString()).assignPrototype(bound)
|
||||
}
|
||||
@@ -277,13 +277,13 @@ class ForConverter(
|
||||
private fun PsiStatement.toContinuedLoop(): PsiLoopStatement? {
|
||||
return when (this) {
|
||||
is PsiLoopStatement -> this
|
||||
is PsiLabeledStatement -> this.getStatement()?.toContinuedLoop()
|
||||
is PsiLabeledStatement -> this.statement?.toContinuedLoop()
|
||||
else -> null
|
||||
}
|
||||
}
|
||||
|
||||
private fun hasNameConflict(): Boolean {
|
||||
val names = statement.getInitialization()?.declaredVariableNames() ?: return false
|
||||
val names = statement.initialization?.declaredVariableNames() ?: return false
|
||||
if (names.isEmpty()) return false
|
||||
|
||||
val factory = PsiElementFactory.SERVICE.getInstance(project)
|
||||
@@ -315,8 +315,8 @@ class ForConverter(
|
||||
|
||||
private fun PsiStatement.declaredVariableNames(): Collection<String> {
|
||||
val declarationStatement = this as? PsiDeclarationStatement ?: return listOf()
|
||||
return declarationStatement.getDeclaredElements()
|
||||
return declarationStatement.declaredElements
|
||||
.filterIsInstance<PsiVariable>()
|
||||
.map { it.getName()!! }
|
||||
.map { it.name!! }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -76,7 +76,7 @@ public class JavaToKotlinConverter(
|
||||
|
||||
AfterConversionPass(project, postProcessor).run(kotlinFile, range = null)
|
||||
|
||||
kotlinFile.getText()
|
||||
kotlinFile.text
|
||||
}
|
||||
catch(e: ProcessCanceledException) {
|
||||
throw e
|
||||
@@ -150,7 +150,7 @@ public class JavaToKotlinConverter(
|
||||
): ExternalCodeProcessing? {
|
||||
if (usageProcessings.isEmpty()) return null
|
||||
|
||||
val map: Map<PsiElement, Collection<UsageProcessing>> = usageProcessings.values()
|
||||
val map: Map<PsiElement, Collection<UsageProcessing>> = usageProcessings.values
|
||||
.flatMap { it }
|
||||
.filter { it.javaCodeProcessor != null || it.kotlinCodeProcessor != null }
|
||||
.groupBy { it.targetElement }
|
||||
@@ -160,13 +160,13 @@ public class JavaToKotlinConverter(
|
||||
override fun prepareWriteOperation(progress: ProgressIndicator): () -> Unit {
|
||||
val refs = ArrayList<ReferenceInfo>()
|
||||
|
||||
progress.setText("Searching usages to update...")
|
||||
progress.text = "Searching usages to update..."
|
||||
|
||||
for ((i, entry) in map.entrySet().withIndex()) {
|
||||
for ((i, entry) in map.entries.withIndex()) {
|
||||
val psiElement = entry.key
|
||||
val processings = entry.value
|
||||
|
||||
progress.setText2((psiElement as? PsiNamedElement)?.getName() ?: "")
|
||||
progress.text2 = (psiElement as? PsiNamedElement)?.name ?: ""
|
||||
progress.checkCanceled()
|
||||
|
||||
ProgressManager.getInstance().runProcess(
|
||||
@@ -174,10 +174,10 @@ public class JavaToKotlinConverter(
|
||||
val searchJava = processings.any { it.javaCodeProcessor != null }
|
||||
val searchKotlin = processings.any { it.kotlinCodeProcessor != null }
|
||||
services.referenceSearcher.findUsagesForExternalCodeProcessing(psiElement, searchJava, searchKotlin)
|
||||
.filterNot { inConversionScope(it.getElement()) }
|
||||
.mapTo(refs) { ReferenceInfo(it, psiElement, it.getElement().getContainingFile(), processings) }
|
||||
.filterNot { inConversionScope(it.element) }
|
||||
.mapTo(refs) { ReferenceInfo(it, psiElement, it.element.containingFile, processings) }
|
||||
},
|
||||
ProgressPortionReporter(progress, i / map.size().toDouble(), 1.0 / map.size()))
|
||||
ProgressPortionReporter(progress, i / map.size.toDouble(), 1.0 / map.size))
|
||||
|
||||
}
|
||||
|
||||
@@ -187,10 +187,10 @@ public class JavaToKotlinConverter(
|
||||
}
|
||||
|
||||
private fun processUsages(refs: Collection<ReferenceInfo>) {
|
||||
for (fileRefs in refs.groupBy { it.file }.values()) { // group by file for faster sorting
|
||||
for (fileRefs in refs.groupBy { it.file }.values) { // group by file for faster sorting
|
||||
ReferenceLoop@
|
||||
for ((reference, target, file, processings) in fileRefs.sortedWith(ReferenceComparator)) {
|
||||
val processors = when (reference.getElement().getLanguage()) {
|
||||
val processors = when (reference.element.language) {
|
||||
JavaLanguage.INSTANCE -> processings.mapNotNull { it.javaCodeProcessor }
|
||||
KotlinLanguage.INSTANCE -> processings.mapNotNull { it.kotlinCodeProcessor }
|
||||
else -> continue@ReferenceLoop
|
||||
@@ -208,8 +208,8 @@ public class JavaToKotlinConverter(
|
||||
}
|
||||
|
||||
private fun checkReferenceValid(reference: PsiReference, afterProcessor: ExternalCodeProcessor?) {
|
||||
val element = reference.getElement()
|
||||
assert(element.isValid() && element.getContainingFile() !is DummyHolder) {
|
||||
val element = reference.element
|
||||
assert(element.isValid && element.containingFile !is DummyHolder) {
|
||||
"Reference $reference got invalidated" + (if (afterProcessor != null) " after processing with $afterProcessor" else "")
|
||||
}
|
||||
}
|
||||
@@ -233,7 +233,7 @@ public class JavaToKotlinConverter(
|
||||
}
|
||||
|
||||
private val progressText = "Converting Java to Kotlin"
|
||||
private val fileCount = files?.size() ?: 0
|
||||
private val fileCount = files?.size ?: 0
|
||||
private val fileCountText = fileCount.toString() + " " + if (fileCount > 1) "files" else "file"
|
||||
private var fraction = 0.0
|
||||
private var pass = 1
|
||||
@@ -247,13 +247,13 @@ public class JavaToKotlinConverter(
|
||||
// we use special process with EmptyProgressIndicator to avoid changing text in our progress by inheritors search inside etc
|
||||
ProgressManager.getInstance().runProcess(
|
||||
{
|
||||
progress?.setText("$progressText ($fileCountText) - pass $pass of 3")
|
||||
progress?.text = "$progressText ($fileCountText) - pass $pass of 3"
|
||||
|
||||
for ((i, item) in inputItems.withIndex()) {
|
||||
progress?.checkCanceled()
|
||||
progress?.setFraction(fraction + fractionPortion * i / fileCount)
|
||||
progress?.fraction = fraction + fractionPortion * i / fileCount
|
||||
|
||||
progress?.setText2(files!![i].getVirtualFile().getPresentableUrl())
|
||||
progress?.text2 = files!![i].virtualFile.presentableUrl
|
||||
|
||||
outputItems.add(processItem(item))
|
||||
}
|
||||
@@ -273,15 +273,15 @@ public class JavaToKotlinConverter(
|
||||
) : DelegatingProgressIndicator(indicator) {
|
||||
|
||||
init {
|
||||
setFraction(0.0)
|
||||
fraction = 0.0
|
||||
}
|
||||
|
||||
override fun start() {
|
||||
setFraction(0.0)
|
||||
fraction = 0.0
|
||||
}
|
||||
|
||||
override fun stop() {
|
||||
setFraction(portion)
|
||||
fraction = portion
|
||||
}
|
||||
|
||||
override fun setFraction(fraction: Double) {
|
||||
|
||||
@@ -45,7 +45,7 @@ public object JavaToKotlinTranslator {
|
||||
public fun generateKotlinCode(javaCode: String, project: Project): String {
|
||||
val file = createFile(javaCode, project)
|
||||
if (file is PsiJavaFile) {
|
||||
val converter = JavaToKotlinConverter(file.getProject(), ConverterSettings.defaultSettings, EmptyJavaToKotlinServices)
|
||||
val converter = JavaToKotlinConverter(file.project, ConverterSettings.defaultSettings, EmptyJavaToKotlinServices)
|
||||
return prettify(converter.elementsToKotlin(listOf(file)).results.single()!!.text) //TODO: imports
|
||||
}
|
||||
return ""
|
||||
|
||||
@@ -18,9 +18,7 @@ package org.jetbrains.kotlin.j2k
|
||||
|
||||
import com.intellij.psi.*
|
||||
import org.jetbrains.kotlin.j2k.ast.*
|
||||
import java.util.ArrayList
|
||||
import java.util.HashMap
|
||||
import java.util.HashSet
|
||||
import java.util.*
|
||||
|
||||
class OverloadReducer(
|
||||
private val methods: Collection<PsiMethod>,
|
||||
@@ -39,8 +37,8 @@ class OverloadReducer(
|
||||
|
||||
public fun parameterDefault(method: PsiMethod, parameterIndex: Int): PsiExpression? {
|
||||
val defaults = methodToLastParameterDefaults[method] ?: return null
|
||||
val index = method.getParameterList().getParametersCount() - parameterIndex - 1
|
||||
return if (index < defaults.size()) defaults[index] else null
|
||||
val index = method.parameterList.parametersCount - parameterIndex - 1
|
||||
return if (index < defaults.size) defaults[index] else null
|
||||
}
|
||||
|
||||
private class EquivalentOverloadInfo(
|
||||
@@ -55,15 +53,15 @@ class OverloadReducer(
|
||||
|
||||
private fun buildOverloadEquivalenceMap(): Map<PsiMethod, EquivalentOverloadInfo> {
|
||||
val overloadGroups = methods
|
||||
.groupBy { listOf(if (it.isConstructor()) null else it.getName(),
|
||||
.groupBy { listOf(if (it.isConstructor) null else it.name,
|
||||
it.accessModifier(),
|
||||
it.getReturnType(),
|
||||
it.returnType,
|
||||
it.hasModifierProperty(PsiModifier.STATIC),
|
||||
getAnnotationsFingerprint(it)) }
|
||||
.values()
|
||||
.filter { it.size() > 1 }
|
||||
.values
|
||||
.filter { it.size > 1 }
|
||||
.map { it.filterNot { shouldSkipOverload(it) } }
|
||||
.filter { it.size() > 1 }
|
||||
.filter { it.size > 1 }
|
||||
|
||||
val map = HashMap<PsiMethod, EquivalentOverloadInfo>()
|
||||
for (group in overloadGroups) {
|
||||
@@ -79,7 +77,7 @@ class OverloadReducer(
|
||||
}
|
||||
|
||||
map[method] = resultOverloadInfo
|
||||
for (entry in map.entrySet()) {
|
||||
for (entry in map.entries) {
|
||||
if (entry.value.method == method) {
|
||||
val newParameterDefaults = entry.value.parameterDefaults + resultOverloadInfo.parameterDefaults
|
||||
entry.setValue(EquivalentOverloadInfo(resultOverloadInfo.method, newParameterDefaults))
|
||||
@@ -93,27 +91,27 @@ class OverloadReducer(
|
||||
}
|
||||
|
||||
private fun shouldSkipOverload(method: PsiMethod): Boolean {
|
||||
if (method.isConstructor()) return false
|
||||
if (method.isConstructor) return false
|
||||
if (method.hasModifierProperty(PsiModifier.ABSTRACT)) return true
|
||||
if (method.hasModifierProperty(PsiModifier.NATIVE)) return true
|
||||
if (method.hasModifierProperty(PsiModifier.SYNCHRONIZED)) return true
|
||||
if (method.getHierarchicalMethodSignature().getSuperSignatures().isNotEmpty()) return true
|
||||
if (method.hierarchicalMethodSignature.superSignatures.isNotEmpty()) return true
|
||||
if (isOpenClass && referenceSearcher.hasOverrides(method)) return true
|
||||
return false
|
||||
}
|
||||
|
||||
private fun findEquivalentOverload(method: PsiMethod, overloads: Collection<PsiMethod>): EquivalentOverloadInfo? {
|
||||
val statement = method.getBody()?.getStatements()?.singleOrNull() ?: return null
|
||||
val statement = method.body?.statements?.singleOrNull() ?: return null
|
||||
|
||||
val methodCall = when (statement) {
|
||||
is PsiExpressionStatement -> statement.getExpression()
|
||||
is PsiReturnStatement -> statement.getReturnValue()
|
||||
is PsiExpressionStatement -> statement.expression
|
||||
is PsiReturnStatement -> statement.returnValue
|
||||
else -> null
|
||||
} as? PsiMethodCallExpression ?: return null
|
||||
|
||||
val expectedMethodName = if (method.isConstructor()) "this" else method.getName()
|
||||
val refExpr = methodCall.getMethodExpression()
|
||||
if (refExpr.isQualified() || refExpr.getReferenceName() != expectedMethodName) return null
|
||||
val expectedMethodName = if (method.isConstructor) "this" else method.name
|
||||
val refExpr = methodCall.methodExpression
|
||||
if (refExpr.isQualified || refExpr.referenceName != expectedMethodName) return null
|
||||
|
||||
val target = refExpr.resolve() as? PsiMethod ?: return null
|
||||
if (target !in overloads) return null
|
||||
@@ -123,21 +121,21 @@ class OverloadReducer(
|
||||
}
|
||||
|
||||
private fun calcTargetParameterDefaults(method: PsiMethod, target: PsiMethod, targetCall: PsiMethodCallExpression): List<PsiExpression>? {
|
||||
val parameters = method.getParameterList().getParameters()
|
||||
val targetParameters = target.getParameterList().getParameters()
|
||||
if (parameters.size() >= targetParameters.size()) return null
|
||||
val args = targetCall.getArgumentList().getExpressions()
|
||||
if (args.size() != targetParameters.size()) return null // incorrect code
|
||||
val parameters = method.parameterList.parameters
|
||||
val targetParameters = target.parameterList.parameters
|
||||
if (parameters.size >= targetParameters.size) return null
|
||||
val args = targetCall.argumentList.expressions
|
||||
if (args.size != targetParameters.size) return null // incorrect code
|
||||
|
||||
for (i in parameters.indices) {
|
||||
val parameter = parameters[i]
|
||||
val targetParameter = targetParameters[i]
|
||||
if (parameter.getName() != targetParameter.getName() || parameter.getType() != targetParameter.getType()) return null
|
||||
if (parameter.name != targetParameter.name || parameter.type != targetParameter.type) return null
|
||||
val arg = args[i]
|
||||
if (arg !is PsiReferenceExpression || arg.resolve() != parameter) return null
|
||||
}
|
||||
|
||||
return args.drop(parameters.size())
|
||||
return args.drop(parameters.size)
|
||||
}
|
||||
|
||||
private fun dropOverloadsForDefaultValues(equivalenceMap: Map<PsiMethod, EquivalentOverloadInfo>) {
|
||||
@@ -147,19 +145,19 @@ class OverloadReducer(
|
||||
|
||||
DropCandidatesLoop@
|
||||
for (method in dropCandidates) {
|
||||
val paramCount = method.getParameterList().getParametersCount()
|
||||
val paramCount = method.parameterList.parametersCount
|
||||
val targetInfo = equivalenceMap[method]!!
|
||||
val targetParamCount = targetInfo.method.getParameterList().getParametersCount()
|
||||
val targetParamCount = targetInfo.method.parameterList.parametersCount
|
||||
assert(paramCount < targetParamCount)
|
||||
val defaults = targetInfo.parameterDefaults
|
||||
assert(defaults.size() == targetParamCount - paramCount)
|
||||
assert(defaults.size == targetParamCount - paramCount)
|
||||
|
||||
val targetDefaults = methodToLastParameterDefaults.getOrPut(targetInfo.method, { ArrayList() })
|
||||
|
||||
for (i in defaults.indices) {
|
||||
val default = defaults[defaults.size() - i - 1]
|
||||
if (i < targetDefaults.size()) { // default for this parameter has already been assigned
|
||||
if (targetDefaults[i].getText() != default.getText()) continue@DropCandidatesLoop
|
||||
val default = defaults[defaults.size - i - 1]
|
||||
if (i < targetDefaults.size) { // default for this parameter has already been assigned
|
||||
if (targetDefaults[i].text != default.text) continue@DropCandidatesLoop
|
||||
}
|
||||
else {
|
||||
targetDefaults.add(default)
|
||||
@@ -171,7 +169,7 @@ class OverloadReducer(
|
||||
}
|
||||
|
||||
private fun getAnnotationsFingerprint(method: PsiMethod): Any {
|
||||
return method.getModifierList().getAnnotations().map { it.getText() }
|
||||
return method.modifierList.annotations.map { it.text }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -181,13 +179,13 @@ public fun Converter.convertParameterList(
|
||||
convertParameter: (parameter: PsiParameter, default: DeferredElement<Expression>?) -> FunctionParameter = { parameter, default -> convertParameter(parameter, defaultValue = default) },
|
||||
correctCodeConverter: CodeConverter.() -> CodeConverter = { this }
|
||||
): ParameterList {
|
||||
val parameterList = method.getParameterList()
|
||||
val params = parameterList.getParameters()
|
||||
val parameterList = method.parameterList
|
||||
val params = parameterList.parameters
|
||||
return ParameterList(params.indices.map { i ->
|
||||
val parameter = params[i]
|
||||
val defaultValue = overloadReducer?.parameterDefault(method, i)
|
||||
val defaultValueConverted = if (defaultValue != null)
|
||||
deferredElement { codeConverter -> codeConverter.correctCodeConverter().convertExpression(defaultValue, parameter.getType()) }
|
||||
deferredElement { codeConverter -> codeConverter.correctCodeConverter().convertExpression(defaultValue, parameter.type) }
|
||||
else
|
||||
null
|
||||
convertParameter(parameter, defaultValueConverted)
|
||||
|
||||
@@ -33,8 +33,8 @@ public fun ReferenceSearcher.findVariableUsages(variable: PsiVariable, scope: Ps
|
||||
public fun ReferenceSearcher.findMethodCalls(method: PsiMethod, scope: PsiElement): Collection<PsiMethodCallExpression> {
|
||||
return findLocalUsages(method, scope).mapNotNull {
|
||||
if (it is PsiReferenceExpression) {
|
||||
val methodCall = it.getParent() as? PsiMethodCallExpression
|
||||
if (methodCall?.getMethodExpression() == it) methodCall else null
|
||||
val methodCall = it.parent as? PsiMethodCallExpression
|
||||
if (methodCall?.methodExpression == it) methodCall else null
|
||||
}
|
||||
else {
|
||||
null
|
||||
@@ -45,14 +45,14 @@ public fun ReferenceSearcher.findMethodCalls(method: PsiMethod, scope: PsiElemen
|
||||
public fun PsiField.isVar(searcher: ReferenceSearcher): Boolean {
|
||||
if (hasModifierProperty(PsiModifier.FINAL)) return false
|
||||
if (!hasModifierProperty(PsiModifier.PRIVATE)) return true
|
||||
val containingClass = getContainingClass() ?: return true
|
||||
val containingClass = containingClass ?: return true
|
||||
val writes = searcher.findVariableUsages(this, containingClass).filter { PsiUtil.isAccessedForWriting(it) }
|
||||
if (writes.size() == 0) return false
|
||||
if (writes.size() > 1) return true
|
||||
if (writes.size == 0) return false
|
||||
if (writes.size > 1) return true
|
||||
val write = writes.single()
|
||||
val parent = write.getParent()
|
||||
val parent = write.parent
|
||||
if (parent is PsiAssignmentExpression
|
||||
&& parent.getOperationSign().getTokenType() == JavaTokenType.EQ
|
||||
&& parent.operationSign.tokenType == JavaTokenType.EQ
|
||||
&& write.isQualifierEmptyOrThis()
|
||||
) {
|
||||
val constructor = write.getContainingConstructor()
|
||||
|
||||
@@ -16,8 +16,8 @@
|
||||
|
||||
package org.jetbrains.kotlin.j2k
|
||||
|
||||
import org.jetbrains.kotlin.psi.KtDeclaration
|
||||
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
|
||||
import org.jetbrains.kotlin.psi.KtDeclaration
|
||||
|
||||
public interface ResolverForConverter {
|
||||
public fun resolveToDescriptor(declaration: KtDeclaration): DeclarationDescriptor?
|
||||
|
||||
@@ -131,7 +131,7 @@ enum class SpecialMethod(val qualifiedClassName: String?, val methodName: String
|
||||
|
||||
OBJECT_EQUALS(null, "equals", 1) {
|
||||
override fun matches(method: PsiMethod, superMethodsSearcher: SuperMethodsSearcher): Boolean
|
||||
= super.matches(method, superMethodsSearcher) && method.getParameterList().getParameters().single().getType().getCanonicalText() == JAVA_LANG_OBJECT
|
||||
= super.matches(method, superMethodsSearcher) && method.parameterList.parameters.single().type.canonicalText == JAVA_LANG_OBJECT
|
||||
|
||||
override fun convertCall(qualifier: PsiExpression?, arguments: Array<PsiExpression>, typeArgumentsConverted: List<Type>, codeConverter: CodeConverter): Expression? {
|
||||
if (qualifier == null || qualifier is PsiSuperExpression) return null
|
||||
@@ -253,7 +253,7 @@ enum class SpecialMethod(val qualifiedClassName: String?, val methodName: String
|
||||
= super.matches(method, superMethodsSearcher) && method.parameterList.let { it.parametersCount == 2 && it.parameters.last().isVarArgs }
|
||||
|
||||
override fun convertCall(qualifier: PsiExpression?, arguments: Array<PsiExpression>, typeArgumentsConverted: List<Type>, codeConverter: CodeConverter): Expression? {
|
||||
if (arguments.size() == 2 && arguments.last().isAssignableToCharSequenceArray()) {
|
||||
if (arguments.size == 2 && arguments.last().isAssignableToCharSequenceArray()) {
|
||||
return STRING_JOIN.convertCall(qualifier, arguments, typeArgumentsConverted, codeConverter)
|
||||
}
|
||||
else {
|
||||
@@ -305,7 +305,7 @@ enum class SpecialMethod(val qualifiedClassName: String?, val methodName: String
|
||||
method.parameterList.parameters.let { it.first().type.canonicalText == "java.util.Locale" && it.last().isVarArgs }
|
||||
|
||||
override fun convertCall(qualifier: PsiExpression?, arguments: Array<PsiExpression>, typeArgumentsConverted: List<Type>, codeConverter: CodeConverter): Expression? {
|
||||
if (arguments.size() < 2) return null // incorrect call
|
||||
if (arguments.size < 2) return null // incorrect call
|
||||
return MethodCallExpression.build(codeConverter.convertExpression(arguments[1]), "format", codeConverter.convertExpressions(listOf(arguments[0]) + arguments.drop(2)), emptyList(), false)
|
||||
}
|
||||
},
|
||||
@@ -404,9 +404,9 @@ private fun convertSystemOutMethodCall(
|
||||
codeConverter: CodeConverter
|
||||
): Expression? {
|
||||
if (qualifier !is PsiReferenceExpression) return null
|
||||
val qqualifier = qualifier.getQualifierExpression() as? PsiReferenceExpression ?: return null
|
||||
if (qqualifier.getCanonicalText() != "java.lang.System") return null
|
||||
if (qualifier.getReferenceName() != "out") return null
|
||||
val qqualifier = qualifier.qualifierExpression as? PsiReferenceExpression ?: return null
|
||||
if (qqualifier.canonicalText != "java.lang.System") return null
|
||||
if (qualifier.referenceName != "out") return null
|
||||
if (typeArgumentsConverted.isNotEmpty()) return null
|
||||
return MethodCallExpression.build(null, methodName, arguments.map { codeConverter.convertExpression(it) }, emptyList(), false)
|
||||
}
|
||||
|
||||
@@ -18,7 +18,7 @@ package org.jetbrains.kotlin.j2k
|
||||
|
||||
import com.intellij.psi.*
|
||||
import org.jetbrains.kotlin.j2k.ast.*
|
||||
import java.util.ArrayList
|
||||
import java.util.*
|
||||
|
||||
interface StatementConverter {
|
||||
fun convertStatement(statement: PsiStatement, codeConverter: CodeConverter): Statement
|
||||
@@ -51,8 +51,8 @@ class DefaultStatementConverter : JavaElementVisitor(), StatementConverter {
|
||||
}
|
||||
|
||||
override fun visitAssertStatement(statement: PsiAssertStatement) {
|
||||
val descriptionExpr = statement.getAssertDescription()
|
||||
val condition = codeConverter.convertExpression(statement.getAssertCondition())
|
||||
val descriptionExpr = statement.assertDescription
|
||||
val condition = codeConverter.convertExpression(statement.assertCondition)
|
||||
if (descriptionExpr == null) {
|
||||
result = MethodCallExpression.buildNotNull(null, "assert", listOf(condition))
|
||||
}
|
||||
@@ -65,30 +65,30 @@ class DefaultStatementConverter : JavaElementVisitor(), StatementConverter {
|
||||
}
|
||||
|
||||
override fun visitBlockStatement(statement: PsiBlockStatement) {
|
||||
val block = codeConverter.convertBlock(statement.getCodeBlock())
|
||||
val block = codeConverter.convertBlock(statement.codeBlock)
|
||||
result = MethodCallExpression.build(null, "run", listOf(LambdaExpression(null, block).assignNoPrototype()), listOf(), false)
|
||||
}
|
||||
|
||||
override fun visitBreakStatement(statement: PsiBreakStatement) {
|
||||
if (statement.getLabelIdentifier() == null) {
|
||||
if (statement.labelIdentifier == null) {
|
||||
result = BreakStatement(Identifier.Empty)
|
||||
}
|
||||
else {
|
||||
result = BreakStatement(converter.convertIdentifier(statement.getLabelIdentifier()))
|
||||
result = BreakStatement(converter.convertIdentifier(statement.labelIdentifier))
|
||||
}
|
||||
}
|
||||
|
||||
override fun visitContinueStatement(statement: PsiContinueStatement) {
|
||||
if (statement.getLabelIdentifier() == null) {
|
||||
if (statement.labelIdentifier == null) {
|
||||
result = ContinueStatement(Identifier.Empty)
|
||||
}
|
||||
else {
|
||||
result = ContinueStatement(converter.convertIdentifier(statement.getLabelIdentifier()))
|
||||
result = ContinueStatement(converter.convertIdentifier(statement.labelIdentifier))
|
||||
}
|
||||
}
|
||||
|
||||
override fun visitDeclarationStatement(statement: PsiDeclarationStatement) {
|
||||
result = DeclarationStatement(statement.getDeclaredElements().map {
|
||||
result = DeclarationStatement(statement.declaredElements.map {
|
||||
when (it) {
|
||||
is PsiLocalVariable -> codeConverter.convertLocalVariable(it)
|
||||
is PsiClass -> converter.convertClass(it)
|
||||
@@ -98,20 +98,20 @@ class DefaultStatementConverter : JavaElementVisitor(), StatementConverter {
|
||||
}
|
||||
|
||||
override fun visitDoWhileStatement(statement: PsiDoWhileStatement) {
|
||||
val condition = statement.getCondition()
|
||||
val expression = if (condition != null && condition.getType() != null)
|
||||
codeConverter.convertExpression(condition, condition.getType())
|
||||
val condition = statement.condition
|
||||
val expression = if (condition != null && condition.type != null)
|
||||
codeConverter.convertExpression(condition, condition.type)
|
||||
else
|
||||
codeConverter.convertExpression(condition)
|
||||
result = DoWhileStatement(expression, codeConverter.convertStatementOrBlock(statement.getBody()), statement.isInSingleLine())
|
||||
result = DoWhileStatement(expression, codeConverter.convertStatementOrBlock(statement.body), statement.isInSingleLine())
|
||||
}
|
||||
|
||||
override fun visitExpressionStatement(statement: PsiExpressionStatement) {
|
||||
result = codeConverter.convertExpression(statement.getExpression())
|
||||
result = codeConverter.convertExpression(statement.expression)
|
||||
}
|
||||
|
||||
override fun visitExpressionListStatement(statement: PsiExpressionListStatement) {
|
||||
result = ExpressionListStatement(codeConverter.convertExpressions(statement.getExpressionList().getExpressions()))
|
||||
result = ExpressionListStatement(codeConverter.convertExpressions(statement.expressionList.expressions))
|
||||
}
|
||||
|
||||
override fun visitForStatement(statement: PsiForStatement) {
|
||||
@@ -119,28 +119,28 @@ class DefaultStatementConverter : JavaElementVisitor(), StatementConverter {
|
||||
}
|
||||
|
||||
override fun visitForeachStatement(statement: PsiForeachStatement) {
|
||||
val iteratorExpr = codeConverter.convertExpression(statement.getIteratedValue())
|
||||
val iteratorExpr = codeConverter.convertExpression(statement.iteratedValue)
|
||||
val iterator = BangBangExpression.surroundIfNullable(iteratorExpr)
|
||||
val iterationParameter = statement.getIterationParameter()
|
||||
val iterationParameter = statement.iterationParameter
|
||||
result = ForeachStatement(iterationParameter.declarationIdentifier(),
|
||||
if (codeConverter.settings.specifyLocalVariableTypeByDefault) codeConverter.typeConverter.convertVariableType(iterationParameter) else null,
|
||||
iterator,
|
||||
codeConverter.convertStatementOrBlock(statement.getBody()),
|
||||
codeConverter.convertStatementOrBlock(statement.body),
|
||||
statement.isInSingleLine())
|
||||
}
|
||||
|
||||
override fun visitIfStatement(statement: PsiIfStatement) {
|
||||
val condition = statement.getCondition()
|
||||
val condition = statement.condition
|
||||
val expression = codeConverter.convertExpression(condition, PsiType.BOOLEAN)
|
||||
result = IfStatement(expression,
|
||||
codeConverter.convertStatementOrBlock(statement.getThenBranch()),
|
||||
codeConverter.convertStatementOrBlock(statement.getElseBranch()),
|
||||
codeConverter.convertStatementOrBlock(statement.thenBranch),
|
||||
codeConverter.convertStatementOrBlock(statement.elseBranch),
|
||||
statement.isInSingleLine())
|
||||
}
|
||||
|
||||
override fun visitLabeledStatement(statement: PsiLabeledStatement) {
|
||||
val statementConverted = codeConverter.convertStatement(statement.getStatement())
|
||||
val identifier = converter.convertIdentifier(statement.getLabelIdentifier())
|
||||
val statementConverted = codeConverter.convertStatement(statement.statement)
|
||||
val identifier = converter.convertIdentifier(statement.labelIdentifier)
|
||||
if (statementConverted is ForConverter.WhileWithInitializationPseudoStatement) { // special case - if our loop gets converted to while with initialization we should move the label to the loop
|
||||
val labeledLoop = LabeledStatement(identifier, statementConverted.loop).assignPrototype(statement)
|
||||
result = ForConverter.WhileWithInitializationPseudoStatement(statementConverted.initialization, labeledLoop, statementConverted.kind)
|
||||
@@ -151,10 +151,10 @@ class DefaultStatementConverter : JavaElementVisitor(), StatementConverter {
|
||||
}
|
||||
|
||||
override fun visitSwitchLabelStatement(statement: PsiSwitchLabelStatement) {
|
||||
result = if (statement.isDefaultCase())
|
||||
result = if (statement.isDefaultCase)
|
||||
ElseWhenEntrySelector()
|
||||
else
|
||||
ValueWhenEntrySelector(codeConverter.convertExpression(statement.getCaseValue()))
|
||||
ValueWhenEntrySelector(codeConverter.convertExpression(statement.caseValue))
|
||||
}
|
||||
|
||||
override fun visitSwitchStatement(statement: PsiSwitchStatement) {
|
||||
@@ -162,22 +162,22 @@ class DefaultStatementConverter : JavaElementVisitor(), StatementConverter {
|
||||
}
|
||||
|
||||
override fun visitSynchronizedStatement(statement: PsiSynchronizedStatement) {
|
||||
result = SynchronizedStatement(codeConverter.convertExpression(statement.getLockExpression()),
|
||||
codeConverter.convertBlock(statement.getBody()))
|
||||
result = SynchronizedStatement(codeConverter.convertExpression(statement.lockExpression),
|
||||
codeConverter.convertBlock(statement.body))
|
||||
}
|
||||
|
||||
override fun visitThrowStatement(statement: PsiThrowStatement) {
|
||||
result = ThrowStatement(codeConverter.convertExpression(statement.getException()))
|
||||
result = ThrowStatement(codeConverter.convertExpression(statement.exception))
|
||||
}
|
||||
|
||||
override fun visitTryStatement(tryStatement: PsiTryStatement) {
|
||||
val tryBlock = tryStatement.getTryBlock()
|
||||
val tryBlock = tryStatement.tryBlock
|
||||
val catchesConverted = convertCatches(tryStatement)
|
||||
val finallyConverted = codeConverter.convertBlock(tryStatement.getFinallyBlock())
|
||||
val finallyConverted = codeConverter.convertBlock(tryStatement.finallyBlock)
|
||||
|
||||
val resourceList = tryStatement.getResourceList()
|
||||
val resourceList = tryStatement.resourceList
|
||||
if (resourceList != null) {
|
||||
val variables = resourceList.getResourceVariables()
|
||||
val variables = resourceList.resourceVariables
|
||||
if (variables.isNotEmpty()) {
|
||||
result = convertTryWithResources(tryBlock, variables, catchesConverted, finallyConverted)
|
||||
return
|
||||
@@ -189,12 +189,12 @@ class DefaultStatementConverter : JavaElementVisitor(), StatementConverter {
|
||||
|
||||
private fun convertCatches(tryStatement: PsiTryStatement): List<CatchStatement> {
|
||||
val catches = ArrayList<CatchStatement>()
|
||||
for ((block, parameter) in tryStatement.getCatchBlocks().zip(tryStatement.getCatchBlockParameters())) {
|
||||
for ((block, parameter) in tryStatement.catchBlocks.zip(tryStatement.catchBlockParameters)) {
|
||||
val blockConverted = codeConverter.convertBlock(block)
|
||||
val annotations = converter.convertAnnotations(parameter)
|
||||
val parameterType = parameter.getType()
|
||||
val parameterType = parameter.type
|
||||
val types = if (parameterType is PsiDisjunctionType)
|
||||
parameterType.getDisjunctions()
|
||||
parameterType.disjunctions
|
||||
else
|
||||
listOf(parameterType)
|
||||
for (t in types) {
|
||||
@@ -220,7 +220,7 @@ class DefaultStatementConverter : JavaElementVisitor(), StatementConverter {
|
||||
val parameter = LambdaParameter(Identifier(variable.name!!).assignNoPrototype(), null).assignNoPrototype()
|
||||
val parameterList = ParameterList(listOf(parameter)).assignNoPrototype()
|
||||
val lambda = LambdaExpression(parameterList, block)
|
||||
expression = MethodCallExpression.build(codeConverter.convertExpression(variable.getInitializer()), "use", listOf(lambda), listOf(), false)
|
||||
expression = MethodCallExpression.build(codeConverter.convertExpression(variable.initializer), "use", listOf(lambda), listOf(), false)
|
||||
expression.assignNoPrototype()
|
||||
block = Block(listOf(expression), LBrace().assignNoPrototype(), RBrace().assignNoPrototype()).assignNoPrototype()
|
||||
}
|
||||
@@ -229,21 +229,21 @@ class DefaultStatementConverter : JavaElementVisitor(), StatementConverter {
|
||||
return wrapResultStatement(expression)
|
||||
}
|
||||
|
||||
block = Block(listOf(wrapResultStatement(expression)), LBrace().assignPrototype(tryBlock?.getLBrace()), RBrace().assignPrototype(tryBlock?.getRBrace()), true)
|
||||
block = Block(listOf(wrapResultStatement(expression)), LBrace().assignPrototype(tryBlock?.lBrace), RBrace().assignPrototype(tryBlock?.rBrace), true)
|
||||
return TryStatement(block.assignPrototype(tryBlock), catchesConverted, finallyConverted)
|
||||
}
|
||||
|
||||
override fun visitWhileStatement(statement: PsiWhileStatement) {
|
||||
val condition = statement.getCondition()
|
||||
val expression = if (condition?.getType() != null)
|
||||
codeConverter.convertExpression(condition, condition!!.getType())
|
||||
val condition = statement.condition
|
||||
val expression = if (condition?.type != null)
|
||||
codeConverter.convertExpression(condition, condition!!.type)
|
||||
else
|
||||
codeConverter.convertExpression(condition)
|
||||
result = WhileStatement(expression, codeConverter.convertStatementOrBlock(statement.getBody()), statement.isInSingleLine())
|
||||
result = WhileStatement(expression, codeConverter.convertStatementOrBlock(statement.body), statement.isInSingleLine())
|
||||
}
|
||||
|
||||
override fun visitReturnStatement(statement: PsiReturnStatement) {
|
||||
val returnValue = statement.getReturnValue()
|
||||
val returnValue = statement.returnValue
|
||||
val methodReturnType = codeConverter.methodReturnType
|
||||
val expression = if (returnValue != null && methodReturnType != null)
|
||||
codeConverter.convertExpression(returnValue, methodReturnType)
|
||||
@@ -260,7 +260,7 @@ class DefaultStatementConverter : JavaElementVisitor(), StatementConverter {
|
||||
|
||||
fun CodeConverter.convertStatementOrBlock(statement: PsiStatement?): Statement {
|
||||
return if (statement is PsiBlockStatement)
|
||||
convertBlock(statement.getCodeBlock())
|
||||
convertBlock(statement.codeBlock)
|
||||
else
|
||||
convertStatement(statement)
|
||||
}
|
||||
|
||||
@@ -18,11 +18,11 @@ package org.jetbrains.kotlin.j2k
|
||||
|
||||
import com.intellij.psi.*
|
||||
import org.jetbrains.kotlin.j2k.ast.*
|
||||
import java.util.ArrayList
|
||||
import java.util.*
|
||||
|
||||
class SwitchConverter(private val codeConverter: CodeConverter) {
|
||||
public fun convert(statement: PsiSwitchStatement): WhenStatement
|
||||
= WhenStatement(codeConverter.convertExpression(statement.getExpression()), switchBodyToWhenEntries(statement.getBody()))
|
||||
= WhenStatement(codeConverter.convertExpression(statement.expression), switchBodyToWhenEntries(statement.body))
|
||||
|
||||
private class Case(val label: PsiSwitchLabelStatement?, val statements: List<PsiStatement>)
|
||||
|
||||
@@ -59,7 +59,7 @@ class SwitchConverter(private val codeConverter: CodeConverter) {
|
||||
}
|
||||
}
|
||||
|
||||
for (statement in body.getStatements()) {
|
||||
for (statement in body.statements) {
|
||||
if (statement is PsiSwitchLabelStatement) {
|
||||
flushCurrentCase()
|
||||
currentLabel = statement
|
||||
@@ -78,10 +78,10 @@ class SwitchConverter(private val codeConverter: CodeConverter) {
|
||||
|
||||
private fun convertCaseStatements(statements: List<PsiStatement>, allowBlock: Boolean = true): List<Statement> {
|
||||
val statementsToKeep = statements.filter { !isSwitchBreak(it) }
|
||||
if (allowBlock && statementsToKeep.size() == 1) {
|
||||
if (allowBlock && statementsToKeep.size == 1) {
|
||||
val block = statementsToKeep.single() as? PsiBlockStatement
|
||||
if (block != null) {
|
||||
return listOf(codeConverter.convertBlock(block.getCodeBlock(), true, { !isSwitchBreak(it) }))
|
||||
return listOf(codeConverter.convertBlock(block.codeBlock, true, { !isSwitchBreak(it) }))
|
||||
}
|
||||
}
|
||||
return statementsToKeep.map { codeConverter.convertStatement(it) }
|
||||
@@ -94,7 +94,7 @@ class SwitchConverter(private val codeConverter: CodeConverter) {
|
||||
}
|
||||
else {
|
||||
val block = case.statements.singleOrNull() as? PsiBlockStatement
|
||||
val statements = if (block != null) block.getCodeBlock().getStatements().toList() else case.statements
|
||||
val statements = if (block != null) block.codeBlock.statements.toList() else case.statements
|
||||
!statements.any { it is PsiBreakStatement || it is PsiContinueStatement || it is PsiReturnStatement || it is PsiThrowStatement }
|
||||
}
|
||||
return if (fallsThrough) // we fall through into the next case
|
||||
@@ -105,11 +105,11 @@ class SwitchConverter(private val codeConverter: CodeConverter) {
|
||||
|
||||
private fun convertCaseStatementsToBody(cases: List<Case>, caseIndex: Int): Statement {
|
||||
val statements = convertCaseStatements(cases, caseIndex)
|
||||
return if (statements.size() == 1)
|
||||
return if (statements.size == 1)
|
||||
statements.single()
|
||||
else
|
||||
Block(statements, LBrace().assignNoPrototype(), RBrace().assignNoPrototype(), true).assignNoPrototype()
|
||||
}
|
||||
|
||||
private fun isSwitchBreak(statement: PsiStatement) = statement is PsiBreakStatement && statement.getLabelIdentifier() == null
|
||||
private fun isSwitchBreak(statement: PsiStatement) = statement is PsiBreakStatement && statement.labelIdentifier == null
|
||||
}
|
||||
|
||||
@@ -25,8 +25,7 @@ import org.jetbrains.kotlin.j2k.ast.*
|
||||
import org.jetbrains.kotlin.psi.KtCallableDeclaration
|
||||
import org.jetbrains.kotlin.resolve.DescriptorUtils
|
||||
import org.jetbrains.kotlin.types.TypeUtils
|
||||
import java.util.HashMap
|
||||
import java.util.HashSet
|
||||
import java.util.*
|
||||
|
||||
class TypeConverter(val converter: Converter) {
|
||||
private val typesBeingConverted = HashSet<PsiType>()
|
||||
@@ -64,13 +63,13 @@ class TypeConverter(val converter: Converter) {
|
||||
converter.settings).assignNoPrototype()
|
||||
}
|
||||
else {
|
||||
convertType(variable.getType(), variableNullability(variable), variableMutability(variable))
|
||||
convertType(variable.type, variableNullability(variable), variableMutability(variable))
|
||||
}
|
||||
return result.assignPrototype(variable.getTypeElement())
|
||||
return result.assignPrototype(variable.typeElement)
|
||||
}
|
||||
|
||||
public fun convertMethodReturnType(method: PsiMethod): Type
|
||||
= convertType(method.getReturnType(), methodNullability(method), methodMutability(method)).assignPrototype(method.getReturnTypeElement())
|
||||
= convertType(method.returnType, methodNullability(method), methodMutability(method)).assignPrototype(method.returnTypeElement)
|
||||
|
||||
public fun variableNullability(variable: PsiVariable): Nullability
|
||||
= nullabilityFlavor.forVariableType(variable)
|
||||
@@ -84,13 +83,13 @@ class TypeConverter(val converter: Converter) {
|
||||
public fun methodMutability(method: PsiMethod): Mutability
|
||||
= mutabilityFlavor.forMethodReturnType(method)
|
||||
|
||||
private fun PsiVariable.isMainMethodParameter() = this is PsiParameter && (getDeclarationScope() as? PsiMethod)?.isMainMethod() ?: false
|
||||
private fun PsiVariable.isMainMethodParameter() = this is PsiParameter && (declarationScope as? PsiMethod)?.isMainMethod() ?: false
|
||||
|
||||
private fun searchScope(element: PsiElement): PsiElement? {
|
||||
return when(element) {
|
||||
is PsiParameter -> element.getDeclarationScope()
|
||||
is PsiField -> if (element.hasModifierProperty(PsiModifier.PRIVATE)) element.getContainingClass() else element.getContainingFile()
|
||||
is PsiMethod -> if (element.hasModifierProperty(PsiModifier.PRIVATE)) element.getContainingClass() else element.getContainingFile()
|
||||
is PsiParameter -> element.declarationScope
|
||||
is PsiField -> if (element.hasModifierProperty(PsiModifier.PRIVATE)) element.containingClass else element.containingFile
|
||||
is PsiMethod -> if (element.hasModifierProperty(PsiModifier.PRIVATE)) element.containingClass else element.containingFile
|
||||
is PsiLocalVariable -> element.getContainingMethod()
|
||||
else -> null
|
||||
}
|
||||
@@ -100,7 +99,7 @@ class TypeConverter(val converter: Converter) {
|
||||
if (hasModifierProperty(PsiModifier.FINAL)) return true
|
||||
return when(this) {
|
||||
is PsiLocalVariable -> !hasWriteAccesses(converter.referenceSearcher, getContainingMethod())
|
||||
is PsiField -> if (hasModifierProperty(PsiModifier.PRIVATE)) !hasWriteAccesses(converter.referenceSearcher, getContainingClass()) else false
|
||||
is PsiField -> if (hasModifierProperty(PsiModifier.PRIVATE)) !hasWriteAccesses(converter.referenceSearcher, containingClass) else false
|
||||
else -> false
|
||||
}
|
||||
}
|
||||
@@ -129,7 +128,7 @@ class TypeConverter(val converter: Converter) {
|
||||
private fun forVariableTypeNoCache(variable: PsiVariable): T {
|
||||
if (variable is PsiEnumConstant) return forEnumConstant
|
||||
|
||||
val variableType = variable.getType()
|
||||
val variableType = variable.type
|
||||
var value = fromType(variableType)
|
||||
if (value != default) return value
|
||||
|
||||
@@ -137,14 +136,14 @@ class TypeConverter(val converter: Converter) {
|
||||
if (value != default) return value
|
||||
|
||||
if (variable is PsiParameter) {
|
||||
val scope = variable.getDeclarationScope()
|
||||
val scope = variable.declarationScope
|
||||
if (scope is PsiMethod) {
|
||||
val paramIndex = scope.getParameterList().getParameters().indexOf(variable)
|
||||
val paramIndex = scope.parameterList.parameters.indexOf(variable)
|
||||
assert(paramIndex >= 0)
|
||||
val superSignatures = scope.getHierarchicalMethodSignature().getSuperSignatures()
|
||||
val superSignatures = scope.hierarchicalMethodSignature.superSignatures
|
||||
value = superSignatures.map { signature ->
|
||||
val params = signature.getMethod().getParameterList().getParameters()
|
||||
if (paramIndex < params.size()) forVariableType(params[paramIndex]) else default
|
||||
val params = signature.method.parameterList.parameters
|
||||
if (paramIndex < params.size) forVariableType(params[paramIndex]) else default
|
||||
}.firstOrNull { it != default } ?: default
|
||||
if (value != default) return value
|
||||
}
|
||||
@@ -179,7 +178,7 @@ class TypeConverter(val converter: Converter) {
|
||||
}
|
||||
|
||||
private fun forMethodReturnTypeNoCache(method: PsiMethod): T {
|
||||
val returnType = method.getReturnType() ?: return default
|
||||
val returnType = method.returnType ?: return default
|
||||
|
||||
var value = fromType(returnType)
|
||||
if (value != default) return value
|
||||
@@ -187,8 +186,8 @@ class TypeConverter(val converter: Converter) {
|
||||
value = fromAnnotations(method)
|
||||
if (value != default) return value
|
||||
|
||||
val superSignatures = method.getHierarchicalMethodSignature().getSuperSignatures()
|
||||
value = superSignatures.map { forMethodReturnType(it.getMethod()) }.firstOrNull { it != default } ?: default
|
||||
val superSignatures = method.hierarchicalMethodSignature.superSignatures
|
||||
value = superSignatures.map { forMethodReturnType(it.method) }.firstOrNull { it != default } ?: default
|
||||
if (value != default) return value
|
||||
|
||||
value = fromTypeHeuristics(returnType)
|
||||
@@ -196,7 +195,7 @@ class TypeConverter(val converter: Converter) {
|
||||
|
||||
if (!converter.inConversionScope(method)) return default // do not analyze body and usages of methods out of our conversion scope
|
||||
|
||||
val body = method.getBody()
|
||||
val body = method.body
|
||||
if (body != null) {
|
||||
value = fromMethodBody(body)
|
||||
if (value != default) return value
|
||||
@@ -230,7 +229,7 @@ class TypeConverter(val converter: Converter) {
|
||||
override fun fromType(type: PsiType) = if (type is PsiPrimitiveType) Nullability.NotNull else Nullability.Default
|
||||
|
||||
override fun fromAnnotations(owner: PsiModifierListOwner): Nullability {
|
||||
val manager = NullableNotNullManager.getInstance(owner.getProject())
|
||||
val manager = NullableNotNullManager.getInstance(owner.project)
|
||||
return if (manager.isNotNull(owner, false/* we do not check bases because they are checked by callers of this method*/))
|
||||
Nullability.NotNull
|
||||
else if (manager.isNullable(owner, false))
|
||||
@@ -240,7 +239,7 @@ class TypeConverter(val converter: Converter) {
|
||||
}
|
||||
|
||||
override fun forVariableTypeBeforeUsageSearch(variable: PsiVariable): Nullability {
|
||||
val initializer = variable.getInitializer()
|
||||
val initializer = variable.initializer
|
||||
if (initializer != null) {
|
||||
val initializerNullability = initializer.nullability()
|
||||
if (initializerNullability != Nullability.Default) {
|
||||
@@ -259,8 +258,8 @@ class TypeConverter(val converter: Converter) {
|
||||
|
||||
if (variable is PsiParameter) {
|
||||
// Object.equals corresponds to Any.equals which has nullable parameter:
|
||||
val scope = variable.getDeclarationScope()
|
||||
if (scope is PsiMethod && scope.getName() == "equals" && scope.getContainingClass()?.getQualifiedName() == JAVA_LANG_OBJECT) {
|
||||
val scope = variable.declarationScope
|
||||
if (scope is PsiMethod && scope.name == "equals" && scope.containingClass?.qualifiedName == JAVA_LANG_OBJECT) {
|
||||
return Nullability.Nullable
|
||||
}
|
||||
}
|
||||
@@ -276,25 +275,25 @@ class TypeConverter(val converter: Converter) {
|
||||
}
|
||||
|
||||
// variables of types like Integer are most likely nullable
|
||||
override fun fromTypeHeuristics(type: PsiType) = if (type.getCanonicalText() in boxingTypes) Nullability.Nullable else Nullability.Default
|
||||
override fun fromTypeHeuristics(type: PsiType) = if (type.canonicalText in boxingTypes) Nullability.Nullable else Nullability.Default
|
||||
|
||||
override fun fromUsage(usage: PsiExpression): Nullability {
|
||||
return if (isNullableFromUsage(usage)) Nullability.Nullable else Nullability.Default
|
||||
}
|
||||
|
||||
private fun isNullableFromUsage(usage: PsiExpression): Boolean {
|
||||
val parent = usage.getParent()
|
||||
if (parent is PsiAssignmentExpression && parent.getOperationTokenType() == JavaTokenType.EQ && usage == parent.getLExpression()) {
|
||||
return parent.getRExpression()?.nullability() == Nullability.Nullable
|
||||
val parent = usage.parent
|
||||
if (parent is PsiAssignmentExpression && parent.operationTokenType == JavaTokenType.EQ && usage == parent.lExpression) {
|
||||
return parent.rExpression?.nullability() == Nullability.Nullable
|
||||
}
|
||||
else if (parent is PsiBinaryExpression) {
|
||||
val operationType = parent.getOperationTokenType()
|
||||
val operationType = parent.operationTokenType
|
||||
if (operationType == JavaTokenType.EQEQ || operationType == JavaTokenType.NE) {
|
||||
val otherOperand = if (usage == parent.getLOperand()) parent.getROperand() else parent.getLOperand()
|
||||
val otherOperand = if (usage == parent.lOperand) parent.rOperand else parent.lOperand
|
||||
return otherOperand?.isNullLiteral() ?: false
|
||||
}
|
||||
}
|
||||
else if (parent is PsiVariable && usage == parent.getInitializer() && parent.isEffectivelyFinal()) {
|
||||
else if (parent is PsiVariable && usage == parent.initializer && parent.isEffectivelyFinal()) {
|
||||
return variableNullability(parent) == Nullability.Nullable
|
||||
}
|
||||
return false
|
||||
@@ -302,15 +301,15 @@ class TypeConverter(val converter: Converter) {
|
||||
|
||||
override fun forVariableTypeAfterUsageSearch(variable: PsiVariable): Nullability {
|
||||
if (variable is PsiParameter) {
|
||||
val method = variable.getDeclarationScope() as? PsiMethod
|
||||
val method = variable.declarationScope as? PsiMethod
|
||||
if (method != null) {
|
||||
val scope = searchScope(method)
|
||||
if (scope != null) {
|
||||
val parameters = method.getParameterList().getParameters()
|
||||
val parameters = method.parameterList.parameters
|
||||
val parameterIndex = parameters.indexOf(variable)
|
||||
for (call in converter.referenceSearcher.findMethodCalls(method, scope)) {
|
||||
val args = call.getArgumentList().getExpressions()
|
||||
if (args.size() == parameters.size()) {
|
||||
val args = call.argumentList.expressions
|
||||
if (args.size == parameters.size) {
|
||||
if (args[parameterIndex].nullability() == Nullability.Nullable) {
|
||||
return Nullability.Nullable
|
||||
}
|
||||
@@ -326,7 +325,7 @@ class TypeConverter(val converter: Converter) {
|
||||
var isNullable = false
|
||||
body.accept(object: JavaRecursiveElementVisitor() {
|
||||
override fun visitReturnStatement(statement: PsiReturnStatement) {
|
||||
if (statement.getReturnValue()?.nullability() == Nullability.Nullable) {
|
||||
if (statement.returnValue?.nullability() == Nullability.Nullable) {
|
||||
isNullable = true
|
||||
}
|
||||
}
|
||||
@@ -340,20 +339,20 @@ class TypeConverter(val converter: Converter) {
|
||||
|
||||
private fun PsiExpression.nullability(): Nullability {
|
||||
return when (this) {
|
||||
is PsiLiteralExpression -> if (getType() != PsiType.NULL) Nullability.NotNull else Nullability.Nullable
|
||||
is PsiLiteralExpression -> if (type != PsiType.NULL) Nullability.NotNull else Nullability.Nullable
|
||||
|
||||
is PsiNewExpression -> Nullability.NotNull
|
||||
|
||||
is PsiConditionalExpression -> {
|
||||
val nullability1 = getThenExpression()?.nullability()
|
||||
val nullability1 = thenExpression?.nullability()
|
||||
if (nullability1 == Nullability.Nullable) return Nullability.Nullable
|
||||
val nullability2 = getElseExpression()?.nullability()
|
||||
val nullability2 = elseExpression?.nullability()
|
||||
if (nullability2 == Nullability.Nullable) return Nullability.Nullable
|
||||
if (nullability1 == Nullability.NotNull && nullability2 == Nullability.NotNull) return Nullability.NotNull
|
||||
Nullability.Default
|
||||
}
|
||||
|
||||
is PsiParenthesizedExpression -> getExpression()?.nullability() ?: Nullability.Default
|
||||
is PsiParenthesizedExpression -> expression?.nullability() ?: Nullability.Default
|
||||
|
||||
|
||||
//TODO: some other cases
|
||||
@@ -368,7 +367,7 @@ class TypeConverter(val converter: Converter) {
|
||||
|
||||
override fun fromType(type: PsiType): Mutability {
|
||||
val target = (type as? PsiClassType)?.resolve() ?: return Mutability.NonMutable
|
||||
if (target.getQualifiedName() !in TypeVisitor.toKotlinMutableTypesMap.keySet()) return Mutability.NonMutable
|
||||
if (!TypeVisitor.toKotlinMutableTypesMap.keys.containsRaw(target.qualifiedName)) return Mutability.NonMutable
|
||||
return Mutability.Default
|
||||
}
|
||||
|
||||
@@ -376,7 +375,7 @@ class TypeConverter(val converter: Converter) {
|
||||
if (owner is KtLightElement<*, *>) {
|
||||
val jetDeclaration = owner.getOrigin() as? KtCallableDeclaration ?: return Mutability.Default
|
||||
val descriptor = converter.services.resolverForConverter.resolveToDescriptor(jetDeclaration) as? CallableDescriptor ?: return Mutability.Default
|
||||
val type = descriptor.getReturnType() ?: return Mutability.Default
|
||||
val type = descriptor.returnType ?: return Mutability.Default
|
||||
val classDescriptor = TypeUtils.getClassDescriptor(type) ?: return Mutability.Default
|
||||
return if (DescriptorUtils.getFqName(classDescriptor).asString() in mutableKotlinClasses)
|
||||
Mutability.Mutable
|
||||
@@ -385,30 +384,30 @@ class TypeConverter(val converter: Converter) {
|
||||
}
|
||||
//TODO: Kotlin compiled elements
|
||||
|
||||
return super<TypeFlavor>.fromAnnotations(owner) //TODO: ReadOnly annotation
|
||||
return super.fromAnnotations(owner) //TODO: ReadOnly annotation
|
||||
}
|
||||
|
||||
override fun fromUsage(usage: PsiExpression)
|
||||
= if (isMutableFromUsage(usage)) Mutability.Mutable else Mutability.Default
|
||||
|
||||
private fun isMutableFromUsage(usage: PsiExpression): Boolean {
|
||||
val parent = usage.getParent()
|
||||
if (parent is PsiReferenceExpression && usage == parent.getQualifierExpression() && parent.getParent() is PsiMethodCallExpression) {
|
||||
return parent.getReferenceName() in modificationMethodNames
|
||||
val parent = usage.parent
|
||||
if (parent is PsiReferenceExpression && usage == parent.qualifierExpression && parent.parent is PsiMethodCallExpression) {
|
||||
return modificationMethodNames.containsRaw(parent.referenceName)
|
||||
}
|
||||
else if (parent is PsiExpressionList) {
|
||||
val call = parent.getParent() as? PsiCall ?: return false
|
||||
val call = parent.parent as? PsiCall ?: return false
|
||||
val method = call.resolveMethod() ?: return false
|
||||
val paramIndex = parent.getExpressions().indexOf(usage)
|
||||
val parameterList = method.getParameterList()
|
||||
if (paramIndex >= parameterList.getParametersCount()) return false
|
||||
return variableMutability(parameterList.getParameters()[paramIndex]) == Mutability.Mutable
|
||||
val paramIndex = parent.expressions.indexOf(usage)
|
||||
val parameterList = method.parameterList
|
||||
if (paramIndex >= parameterList.parametersCount) return false
|
||||
return variableMutability(parameterList.parameters[paramIndex]) == Mutability.Mutable
|
||||
}
|
||||
else if (parent is PsiVariable && usage == parent.getInitializer()) {
|
||||
else if (parent is PsiVariable && usage == parent.initializer) {
|
||||
return variableMutability(parent) == Mutability.Mutable
|
||||
}
|
||||
else if (parent is PsiAssignmentExpression && parent.getOperationTokenType() == JavaTokenType.EQ && usage == parent.getRExpression()) {
|
||||
val leftSideVar = (parent.getLExpression() as? PsiReferenceExpression)?.resolve() as? PsiVariable ?: return false
|
||||
else if (parent is PsiAssignmentExpression && parent.operationTokenType == JavaTokenType.EQ && usage == parent.rExpression) {
|
||||
val leftSideVar = (parent.lExpression as? PsiReferenceExpression)?.resolve() as? PsiVariable ?: return false
|
||||
return variableMutability(leftSideVar) == Mutability.Mutable
|
||||
}
|
||||
return false
|
||||
@@ -431,6 +430,6 @@ class TypeConverter(val converter: Converter) {
|
||||
"add", "remove", "set", "addAll", "removeAll", "retainAll", "clear", "put", "putAll"
|
||||
)
|
||||
|
||||
private val mutableKotlinClasses = TypeVisitor.toKotlinMutableTypesMap.values().toSet()
|
||||
private val mutableKotlinClasses = TypeVisitor.toKotlinMutableTypesMap.values.toSet()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -23,7 +23,7 @@ import org.jetbrains.kotlin.j2k.ast.*
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
import org.jetbrains.kotlin.resolve.jvm.JvmPrimitiveType
|
||||
|
||||
private val PRIMITIVE_TYPES_NAMES = JvmPrimitiveType.values().map { it.getJavaKeywordName() }
|
||||
private val PRIMITIVE_TYPES_NAMES = JvmPrimitiveType.values().map { it.javaKeywordName }
|
||||
|
||||
class TypeVisitor(
|
||||
private val converter: Converter,
|
||||
@@ -38,7 +38,7 @@ class TypeVisitor(
|
||||
override fun visitType(type: PsiType) = ErrorType()
|
||||
|
||||
override fun visitPrimitiveType(primitiveType: PsiPrimitiveType): Type {
|
||||
val name = primitiveType.getCanonicalText()
|
||||
val name = primitiveType.canonicalText
|
||||
return if (name == "void") {
|
||||
UnitType()
|
||||
}
|
||||
@@ -54,7 +54,7 @@ class TypeVisitor(
|
||||
}
|
||||
|
||||
override fun visitArrayType(arrayType: PsiArrayType): Type {
|
||||
return ArrayType(typeConverter.convertType(arrayType.getComponentType(), inAnnotationType = inAnnotationType), Nullability.Default, converter.settings)
|
||||
return ArrayType(typeConverter.convertType(arrayType.componentType, inAnnotationType = inAnnotationType), Nullability.Default, converter.settings)
|
||||
}
|
||||
|
||||
override fun visitClassType(classType: PsiClassType): Type {
|
||||
@@ -68,7 +68,7 @@ class TypeVisitor(
|
||||
|
||||
val psiClass = classType.resolve()
|
||||
if (psiClass != null) {
|
||||
val javaClassName = psiClass.getQualifiedName()
|
||||
val javaClassName = psiClass.qualifiedName
|
||||
val kotlinClassName = (if (mutability.isMutable(converter.settings)) toKotlinMutableTypesMap[javaClassName] else null)
|
||||
?: toKotlinTypesMap[javaClassName]
|
||||
if (kotlinClassName != null) {
|
||||
@@ -77,35 +77,35 @@ class TypeVisitor(
|
||||
|
||||
if (inAnnotationType && javaClassName == "java.lang.Class") {
|
||||
val fqName = FqName("kotlin.reflect.KClass")
|
||||
val identifier = Identifier(fqName.shortName().getIdentifier(), imports = listOf(fqName)).assignNoPrototype()
|
||||
val identifier = Identifier(fqName.shortName().identifier, imports = listOf(fqName)).assignNoPrototype()
|
||||
return ReferenceElement(identifier, typeArgs).assignNoPrototype()
|
||||
}
|
||||
}
|
||||
|
||||
if (classType is PsiClassReferenceType) {
|
||||
return converter.convertCodeReferenceElement(classType.getReference(), hasExternalQualifier = false, typeArgsConverted = typeArgs)
|
||||
return converter.convertCodeReferenceElement(classType.reference, hasExternalQualifier = false, typeArgsConverted = typeArgs)
|
||||
}
|
||||
|
||||
return ReferenceElement(Identifier(classType.getClassName() ?: "").assignNoPrototype(), typeArgs).assignNoPrototype()
|
||||
return ReferenceElement(Identifier(classType.className ?: "").assignNoPrototype(), typeArgs).assignNoPrototype()
|
||||
}
|
||||
|
||||
private fun getShortName(className: String): String = className.substringAfterLast('.', className)
|
||||
|
||||
private fun convertTypeArgs(classType: PsiClassType): List<Type> {
|
||||
if (classType.getParameterCount() == 0) {
|
||||
if (classType.parameterCount == 0) {
|
||||
return createTypeArgsForRawTypeUsage(classType, Mutability.Default)
|
||||
}
|
||||
else {
|
||||
return typeConverter.convertTypes(classType.getParameters())
|
||||
return typeConverter.convertTypes(classType.parameters)
|
||||
}
|
||||
}
|
||||
|
||||
private fun createTypeArgsForRawTypeUsage(classType: PsiClassType, mutability: Mutability): List<Type> {
|
||||
if (classType is PsiClassReferenceType) {
|
||||
val targetClass = classType.getReference().resolve() as? PsiClass
|
||||
val targetClass = classType.reference.resolve() as? PsiClass
|
||||
if (targetClass != null) {
|
||||
return targetClass.getTypeParameters().map {
|
||||
val superType = it.getSuperTypes().first() // there must be at least one super type always
|
||||
return targetClass.typeParameters.map {
|
||||
val superType = it.superTypes.first() // there must be at least one super type always
|
||||
typeConverter.convertType(superType, Nullability.Default, mutability, inAnnotationType).assignNoPrototype()
|
||||
}
|
||||
}
|
||||
@@ -115,14 +115,14 @@ class TypeVisitor(
|
||||
|
||||
override fun visitWildcardType(wildcardType: PsiWildcardType): Type {
|
||||
return when {
|
||||
wildcardType.isExtends() -> OutProjectionType(typeConverter.convertType(wildcardType.getExtendsBound()))
|
||||
wildcardType.isSuper() -> InProjectionType(typeConverter.convertType(wildcardType.getSuperBound()))
|
||||
wildcardType.isExtends -> OutProjectionType(typeConverter.convertType(wildcardType.extendsBound))
|
||||
wildcardType.isSuper -> InProjectionType(typeConverter.convertType(wildcardType.superBound))
|
||||
else -> StarProjectionType()
|
||||
}
|
||||
}
|
||||
|
||||
override fun visitEllipsisType(ellipsisType: PsiEllipsisType): Type {
|
||||
return VarArgType(typeConverter.convertType(ellipsisType.getComponentType(), inAnnotationType = inAnnotationType))
|
||||
return VarArgType(typeConverter.convertType(ellipsisType.componentType, inAnnotationType = inAnnotationType))
|
||||
}
|
||||
|
||||
companion object {
|
||||
|
||||
@@ -47,46 +47,46 @@ fun shouldGenerateDefaultInitializer(searcher: ReferenceSearcher, field: PsiFiel
|
||||
= field.initializer == null && (field.isVar(searcher) || !field.hasWriteAccesses(searcher, field.containingClass))
|
||||
|
||||
fun PsiReferenceExpression.isQualifierEmptyOrThis(): Boolean {
|
||||
val qualifier = getQualifierExpression()
|
||||
return qualifier == null || (qualifier is PsiThisExpression && qualifier.getQualifier() == null)
|
||||
val qualifier = qualifierExpression
|
||||
return qualifier == null || (qualifier is PsiThisExpression && qualifier.qualifier == null)
|
||||
}
|
||||
|
||||
fun PsiReferenceExpression.isQualifierEmptyOrClass(psiClass: PsiClass): Boolean {
|
||||
val qualifier = getQualifierExpression()
|
||||
val qualifier = qualifierExpression
|
||||
return qualifier == null || (qualifier is PsiReferenceExpression && qualifier.isReferenceTo(psiClass))
|
||||
}
|
||||
|
||||
fun PsiElement.isInSingleLine(): Boolean {
|
||||
if (this is PsiWhiteSpace) {
|
||||
val text = getText()!!
|
||||
val text = text!!
|
||||
return text.indexOf('\n') < 0 && text.indexOf('\r') < 0
|
||||
}
|
||||
|
||||
var child = getFirstChild()
|
||||
var child = firstChild
|
||||
while (child != null) {
|
||||
if (!child.isInSingleLine()) return false
|
||||
child = child.getNextSibling()
|
||||
child = child.nextSibling
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
//TODO: check for variables that are definitely assigned in constructors
|
||||
fun PsiElement.getContainingMethod(): PsiMethod? {
|
||||
var context = getContext()
|
||||
var context = context
|
||||
while (context != null) {
|
||||
val _context = context
|
||||
if (_context is PsiMethod) return _context
|
||||
context = _context.getContext()
|
||||
context = _context.context
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
||||
fun PsiElement.getContainingConstructor(): PsiMethod? {
|
||||
val method = getContainingMethod()
|
||||
return if (method?.isConstructor() == true) method else null
|
||||
return if (method?.isConstructor == true) method else null
|
||||
}
|
||||
|
||||
fun PsiMember.isConstructor(): Boolean = this is PsiMethod && this.isConstructor()
|
||||
fun PsiMember.isConstructor(): Boolean = this is PsiMethod && this.isConstructor
|
||||
|
||||
fun PsiModifierListOwner.accessModifier(): String = when {
|
||||
hasModifierProperty(PsiModifier.PUBLIC) -> PsiModifier.PUBLIC
|
||||
@@ -99,18 +99,18 @@ fun PsiMethod.isMainMethod(): Boolean = PsiMethodUtil.isMainMethod(this)
|
||||
|
||||
fun PsiMember.isImported(file: PsiJavaFile): Boolean {
|
||||
if (this is PsiClass) {
|
||||
val fqName = getQualifiedName()
|
||||
val fqName = qualifiedName
|
||||
val index = fqName?.lastIndexOf('.') ?: -1
|
||||
val parentName = if (index >= 0) fqName!!.substring(0, index) else null
|
||||
return file.getImportList()?.getAllImportStatements()?.any {
|
||||
it.getImportReference()?.getQualifiedName() == (if (it.isOnDemand()) parentName else fqName)
|
||||
return file.importList?.allImportStatements?.any {
|
||||
it.importReference?.qualifiedName == (if (it.isOnDemand) parentName else fqName)
|
||||
} ?: false
|
||||
}
|
||||
else {
|
||||
return getContainingClass() != null && file.getImportList()?.getImportStaticStatements()?.any {
|
||||
it.resolveTargetClass() == getContainingClass() && (it.isOnDemand() || it.getReferenceName() == getName())
|
||||
return containingClass != null && file.importList?.importStaticStatements?.any {
|
||||
it.resolveTargetClass() == containingClass && (it.isOnDemand || it.referenceName == name)
|
||||
} ?: false
|
||||
}
|
||||
}
|
||||
|
||||
fun PsiExpression.isNullLiteral() = this is PsiLiteralExpression && getType() == PsiType.NULL
|
||||
fun PsiExpression.isNullLiteral() = this is PsiLiteralExpression && type == PsiType.NULL
|
||||
|
||||
@@ -44,15 +44,15 @@ class ArrayWithoutInitializationExpression(val type: ArrayType, val expressions:
|
||||
}
|
||||
|
||||
fun constructInnerType(hostType: ArrayType, expressions: List<Expression>): CodeBuilder {
|
||||
if (expressions.size() == 1) {
|
||||
if (expressions.size == 1) {
|
||||
return oneDim(hostType, expressions[0])
|
||||
}
|
||||
|
||||
val innerType = hostType.elementType
|
||||
if (expressions.size() > 1 && innerType is ArrayType) {
|
||||
if (expressions.size > 1 && innerType is ArrayType) {
|
||||
return oneDim(hostType, expressions[0], {
|
||||
builder.append("{")
|
||||
constructInnerType(innerType, expressions.subList(1, expressions.size()))
|
||||
constructInnerType(innerType, expressions.subList(1, expressions.size))
|
||||
builder.append("}")
|
||||
})
|
||||
}
|
||||
|
||||
@@ -16,7 +16,8 @@
|
||||
|
||||
package org.jetbrains.kotlin.j2k.ast
|
||||
|
||||
import org.jetbrains.kotlin.j2k.*
|
||||
import org.jetbrains.kotlin.j2k.CodeBuilder
|
||||
import org.jetbrains.kotlin.j2k.append
|
||||
|
||||
class Block(val statements: List<Statement>, val lBrace: LBrace, val rBrace: RBrace, val notEmpty: Boolean = false) : Statement() {
|
||||
override val isEmpty: Boolean
|
||||
|
||||
@@ -59,7 +59,7 @@ open class Class(
|
||||
}
|
||||
|
||||
private fun baseClassSignatureWithParams(builder: CodeBuilder): List<() -> CodeBuilder> {
|
||||
if (keyword.equals("class") && extendsTypes.size() == 1 && baseClassParams != null) {
|
||||
if (keyword.equals("class") && extendsTypes.size == 1 && baseClassParams != null) {
|
||||
return listOf({
|
||||
builder append extendsTypes[0] append "("
|
||||
builder.append(baseClassParams, ", ")
|
||||
|
||||
@@ -16,8 +16,11 @@
|
||||
|
||||
package org.jetbrains.kotlin.j2k.ast
|
||||
|
||||
import org.jetbrains.kotlin.j2k.*
|
||||
import com.intellij.psi.PsiElement
|
||||
import org.jetbrains.kotlin.j2k.CodeBuilder
|
||||
import org.jetbrains.kotlin.j2k.CodeConverter
|
||||
import org.jetbrains.kotlin.j2k.Converter
|
||||
import org.jetbrains.kotlin.j2k.EmptyDocCommentConverter
|
||||
|
||||
fun <TElement: Element> TElement.assignPrototype(prototype: PsiElement?, inheritance: CommentsAndSpacesInheritance = CommentsAndSpacesInheritance()): TElement {
|
||||
prototypes = if (prototype != null) listOf(PrototypeInfo(prototype, inheritance)) else listOf()
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
|
||||
package org.jetbrains.kotlin.j2k.ast
|
||||
|
||||
import org.jetbrains.kotlin.j2k.*
|
||||
import org.jetbrains.kotlin.j2k.CodeBuilder
|
||||
|
||||
class Enum(
|
||||
name: Identifier,
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
|
||||
package org.jetbrains.kotlin.j2k.ast
|
||||
|
||||
import org.jetbrains.kotlin.j2k.*
|
||||
import org.jetbrains.kotlin.j2k.CodeBuilder
|
||||
|
||||
class EnumConstant(
|
||||
val identifier: Identifier,
|
||||
|
||||
@@ -17,7 +17,6 @@
|
||||
package org.jetbrains.kotlin.j2k.ast
|
||||
|
||||
import org.jetbrains.kotlin.j2k.CodeBuilder
|
||||
import org.jetbrains.kotlin.j2k.CodeConverter
|
||||
|
||||
abstract class Expression : Statement() {
|
||||
open val isNullable: Boolean get() = false
|
||||
|
||||
@@ -16,7 +16,8 @@
|
||||
|
||||
package org.jetbrains.kotlin.j2k.ast
|
||||
|
||||
import org.jetbrains.kotlin.j2k.*
|
||||
import org.jetbrains.kotlin.j2k.CodeBuilder
|
||||
import org.jetbrains.kotlin.j2k.append
|
||||
|
||||
class ExpressionList(val expressions: List<Expression>) : Expression() {
|
||||
override fun generateCode(builder: CodeBuilder) {
|
||||
|
||||
@@ -201,7 +201,7 @@ class LambdaExpression(val parameterList: ParameterList?, val block: Block) : Ex
|
||||
if (parameterList != null && !parameterList.parameters.isEmpty()) {
|
||||
builder.append(parameterList)
|
||||
.append("->")
|
||||
.append(if (block.statements.size() > 1) "\n" else " ")
|
||||
.append(if (block.statements.size > 1) "\n" else " ")
|
||||
.append(block.statements, "\n")
|
||||
}
|
||||
else {
|
||||
|
||||
@@ -23,8 +23,8 @@ import org.jetbrains.kotlin.lexer.KtTokens
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
|
||||
fun PsiNameIdentifierOwner.declarationIdentifier(): Identifier {
|
||||
val name = getName()
|
||||
return if (name != null) Identifier(name, false).assignPrototype(getNameIdentifier()!!) else Identifier.Empty
|
||||
val name = name
|
||||
return if (name != null) Identifier(name, false).assignPrototype(nameIdentifier!!) else Identifier.Empty
|
||||
}
|
||||
|
||||
class Identifier(
|
||||
@@ -51,14 +51,14 @@ class Identifier(
|
||||
imports.forEach { builder.addImport(it) }
|
||||
}
|
||||
|
||||
private fun quote(str: String): String = "`" + str + "`"
|
||||
private fun quote(str: String): String = "`$str`"
|
||||
|
||||
override fun toString() = if (isNullable) "$name?" else name
|
||||
|
||||
companion object {
|
||||
val Empty = Identifier("")
|
||||
|
||||
private val KEYWORDS = KtTokens.KEYWORDS.getTypes().map { (it as KtKeywordToken).getValue() }.toSet()
|
||||
private val KEYWORDS = KtTokens.KEYWORDS.types.map { (it as KtKeywordToken).value }.toSet()
|
||||
|
||||
fun toKotlin(name: String): String = Identifier(name).toKotlin()
|
||||
}
|
||||
|
||||
@@ -16,13 +16,16 @@
|
||||
|
||||
package org.jetbrains.kotlin.j2k.ast
|
||||
|
||||
import com.intellij.psi.PsiImportStatementBase
|
||||
import org.jetbrains.kotlin.j2k.*
|
||||
import com.intellij.psi.PsiImportList
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
import org.jetbrains.kotlin.platform.JavaToKotlinClassMap
|
||||
import com.intellij.psi.PsiImportStatementBase
|
||||
import com.intellij.psi.PsiJavaCodeReferenceElement
|
||||
import org.jetbrains.kotlin.asJava.KtLightClassForFacade
|
||||
import org.jetbrains.kotlin.j2k.CodeBuilder
|
||||
import org.jetbrains.kotlin.j2k.Converter
|
||||
import org.jetbrains.kotlin.j2k.append
|
||||
import org.jetbrains.kotlin.j2k.quoteKeywords
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
import org.jetbrains.kotlin.platform.JavaToKotlinClassMap
|
||||
|
||||
class Import(val name: String) : Element() {
|
||||
override fun generateCode(builder: CodeBuilder) {
|
||||
@@ -40,14 +43,13 @@ class ImportList(public var imports: List<Import>) : Element() {
|
||||
}
|
||||
|
||||
public fun Converter.convertImportList(importList: PsiImportList): ImportList =
|
||||
ImportList(importList.getAllImportStatements().mapNotNull { convertImport(it, true) }).assignPrototype(importList)
|
||||
ImportList(importList.allImportStatements.mapNotNull { convertImport(it, true) }).assignPrototype(importList)
|
||||
|
||||
public fun Converter.convertImport(anImport: PsiImportStatementBase, filter: Boolean): Import? {
|
||||
fun doConvert(): Import? {
|
||||
val reference = anImport.getImportReference()
|
||||
if (reference == null) return null
|
||||
val qualifiedName = quoteKeywords(reference.getQualifiedName()!!)
|
||||
if (anImport.isOnDemand()) {
|
||||
val reference = anImport.importReference ?: return null
|
||||
val qualifiedName = quoteKeywords(reference.qualifiedName!!)
|
||||
if (anImport.isOnDemand) {
|
||||
return Import(qualifiedName + ".*")
|
||||
}
|
||||
else {
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
|
||||
package org.jetbrains.kotlin.j2k.ast
|
||||
|
||||
import org.jetbrains.kotlin.j2k.*
|
||||
import org.jetbrains.kotlin.j2k.CodeBuilder
|
||||
|
||||
class Initializer(val body: DeferredElement<Block>, modifiers: Modifiers) : Member(Annotations.Empty, modifiers) {
|
||||
override fun generateCode(builder: CodeBuilder) {
|
||||
|
||||
@@ -16,7 +16,6 @@
|
||||
|
||||
package org.jetbrains.kotlin.j2k.ast
|
||||
|
||||
import org.jetbrains.kotlin.j2k.ConverterSettings
|
||||
import org.jetbrains.kotlin.j2k.CodeBuilder
|
||||
|
||||
class LocalVariable(
|
||||
|
||||
@@ -16,7 +16,8 @@
|
||||
|
||||
package org.jetbrains.kotlin.j2k.ast
|
||||
|
||||
import org.jetbrains.kotlin.j2k.*
|
||||
import org.jetbrains.kotlin.j2k.CodeBuilder
|
||||
import org.jetbrains.kotlin.j2k.append
|
||||
|
||||
class MethodCallExpression(
|
||||
val methodExpression: Expression,
|
||||
|
||||
@@ -43,7 +43,7 @@ class Modifiers(modifiers: Collection<Modifier>) : Element() {
|
||||
else
|
||||
modifiers.filter { it != Modifier.PUBLIC }
|
||||
val text = modifiersToInclude
|
||||
.sortedBy { it.ordinal() }
|
||||
.sortedBy { it.ordinal }
|
||||
.map { it.toKotlin() }
|
||||
.joinToString(" ")
|
||||
builder.append(text)
|
||||
|
||||
@@ -16,7 +16,8 @@
|
||||
|
||||
package org.jetbrains.kotlin.j2k.ast
|
||||
|
||||
import org.jetbrains.kotlin.j2k.*
|
||||
import org.jetbrains.kotlin.j2k.CodeBuilder
|
||||
import org.jetbrains.kotlin.j2k.append
|
||||
|
||||
class NewClassExpression(
|
||||
val name: ReferenceElement?,
|
||||
|
||||
@@ -16,7 +16,8 @@
|
||||
|
||||
package org.jetbrains.kotlin.j2k.ast
|
||||
|
||||
import org.jetbrains.kotlin.j2k.*
|
||||
import org.jetbrains.kotlin.j2k.CodeBuilder
|
||||
import org.jetbrains.kotlin.j2k.append
|
||||
|
||||
class ParameterList(val parameters: List<Parameter>) : Element() {
|
||||
override fun generateCode(builder: CodeBuilder) {
|
||||
|
||||
@@ -16,7 +16,8 @@
|
||||
|
||||
package org.jetbrains.kotlin.j2k.ast
|
||||
|
||||
import org.jetbrains.kotlin.j2k.*
|
||||
import org.jetbrains.kotlin.j2k.CodeBuilder
|
||||
import org.jetbrains.kotlin.j2k.append
|
||||
|
||||
class ReferenceElement(val name: Identifier, val typeArgs: List<Element>) : Element() {
|
||||
override fun generateCode(builder: CodeBuilder) {
|
||||
|
||||
@@ -16,7 +16,8 @@
|
||||
|
||||
package org.jetbrains.kotlin.j2k.ast
|
||||
|
||||
import org.jetbrains.kotlin.j2k.*
|
||||
import org.jetbrains.kotlin.j2k.CodeBuilder
|
||||
import org.jetbrains.kotlin.j2k.append
|
||||
|
||||
abstract class Statement : Element() {
|
||||
object Empty : Statement() {
|
||||
|
||||
@@ -17,11 +17,14 @@
|
||||
package org.jetbrains.kotlin.j2k.ast
|
||||
|
||||
import com.intellij.psi.PsiTypeParameter
|
||||
import org.jetbrains.kotlin.j2k.*
|
||||
import com.intellij.psi.PsiTypeParameterList
|
||||
import org.jetbrains.kotlin.j2k.CodeBuilder
|
||||
import org.jetbrains.kotlin.j2k.Converter
|
||||
import org.jetbrains.kotlin.j2k.append
|
||||
import org.jetbrains.kotlin.j2k.buildList
|
||||
|
||||
class TypeParameter(val name: Identifier, val extendsTypes: List<Type>) : Element() {
|
||||
fun hasWhere(): Boolean = extendsTypes.size() > 1
|
||||
fun hasWhere(): Boolean = extendsTypes.size > 1
|
||||
|
||||
fun whereToKotlin(builder: CodeBuilder) {
|
||||
if (hasWhere()) {
|
||||
@@ -64,12 +67,12 @@ class TypeParameterList(val parameters: List<TypeParameter>) : Element() {
|
||||
|
||||
private fun Converter.convertTypeParameter(typeParameter: PsiTypeParameter): TypeParameter {
|
||||
return TypeParameter(typeParameter.declarationIdentifier(),
|
||||
typeParameter.getExtendsListTypes().map { typeConverter.convertType(it) }).assignPrototype(typeParameter)
|
||||
typeParameter.extendsListTypes.map { typeConverter.convertType(it) }).assignPrototype(typeParameter)
|
||||
}
|
||||
|
||||
fun Converter.convertTypeParameterList(typeParameterList: PsiTypeParameterList?): TypeParameterList {
|
||||
return if (typeParameterList != null)
|
||||
TypeParameterList(typeParameterList.getTypeParameters()!!.toList().map { convertTypeParameter(it) }).assignPrototype(typeParameterList)
|
||||
TypeParameterList(typeParameterList.typeParameters!!.toList().map { convertTypeParameter(it) }).assignPrototype(typeParameterList)
|
||||
else
|
||||
TypeParameterList.Empty
|
||||
}
|
||||
|
||||
@@ -16,7 +16,8 @@
|
||||
|
||||
package org.jetbrains.kotlin.j2k.ast
|
||||
|
||||
import org.jetbrains.kotlin.j2k.*
|
||||
import org.jetbrains.kotlin.j2k.CodeBuilder
|
||||
import org.jetbrains.kotlin.j2k.ConverterSettings
|
||||
|
||||
fun Type.isUnit(): Boolean = this is UnitType
|
||||
|
||||
|
||||
@@ -18,9 +18,6 @@ package org.jetbrains.kotlin.j2k.ast
|
||||
|
||||
import org.jetbrains.kotlin.j2k.CodeBuilder
|
||||
|
||||
fun String.withSuffix(suffix: String): String = if (isEmpty()) "" else this + suffix
|
||||
fun String.withPrefix(prefix: String): String = if (isEmpty()) "" else prefix + this
|
||||
|
||||
fun CodeBuilder.appendWithPrefix(element: Element, prefix: String): CodeBuilder = if (!element.isEmpty) this append prefix append element else this
|
||||
fun CodeBuilder.appendWithSuffix(element: Element, suffix: String): CodeBuilder = if (!element.isEmpty) this append element append suffix else this
|
||||
|
||||
|
||||
@@ -114,9 +114,9 @@ private class PropertyDetector(
|
||||
|
||||
val propertyNameToGetterInfo = detectGetters(methodsToCheck, prohibitedPropertyNames, propertyNamesWithConflict)
|
||||
|
||||
val propertyNameToSetterInfo = detectSetters(methodsToCheck, prohibitedPropertyNames, propertyNameToGetterInfo.keySet(), propertyNamesWithConflict)
|
||||
val propertyNameToSetterInfo = detectSetters(methodsToCheck, prohibitedPropertyNames, propertyNameToGetterInfo.keys, propertyNamesWithConflict)
|
||||
|
||||
val propertyNames = propertyNameToGetterInfo.keySet() + propertyNameToSetterInfo.keySet()
|
||||
val propertyNames = propertyNameToGetterInfo.keys + propertyNameToSetterInfo.keys
|
||||
|
||||
val memberToPropertyInfo = HashMap<PsiMember, PropertyInfo>()
|
||||
for (propertyName in propertyNames) {
|
||||
@@ -246,7 +246,7 @@ private class PropertyDetector(
|
||||
}
|
||||
|
||||
private fun dropPropertiesWithConflictingAccessors(memberToPropertyInfo: MutableMap<PsiMember, PropertyInfo>) {
|
||||
val propertyInfos = memberToPropertyInfo.values().distinct()
|
||||
val propertyInfos = memberToPropertyInfo.values.distinct()
|
||||
|
||||
val mappedMethods = propertyInfos.mapNotNull { it.getMethod }.toSet() + propertyInfos.mapNotNull { it.setMethod }.toSet()
|
||||
|
||||
@@ -413,25 +413,25 @@ private class PropertyDetector(
|
||||
}
|
||||
|
||||
private fun fieldFromGetterBody(getter: PsiMethod): PsiField? {
|
||||
val body = getter.getBody() ?: return null
|
||||
val returnStatement = (body.getStatements().singleOrNull() as? PsiReturnStatement) ?: return null
|
||||
val body = getter.body ?: return null
|
||||
val returnStatement = (body.statements.singleOrNull() as? PsiReturnStatement) ?: return null
|
||||
val isStatic = getter.hasModifierProperty(PsiModifier.STATIC)
|
||||
val field = fieldByExpression(returnStatement.getReturnValue(), isStatic) ?: return null
|
||||
if (field.getType() != getter.getReturnType()) return null
|
||||
val field = fieldByExpression(returnStatement.returnValue, isStatic) ?: return null
|
||||
if (field.type != getter.returnType) return null
|
||||
if (converter.typeConverter.variableMutability(field) != converter.typeConverter.methodMutability(getter)) return null
|
||||
return field
|
||||
}
|
||||
|
||||
private fun fieldFromSetterBody(setter: PsiMethod): PsiField? {
|
||||
val body = setter.getBody() ?: return null
|
||||
val statement = (body.getStatements().singleOrNull() as? PsiExpressionStatement) ?: return null
|
||||
val assignment = statement.getExpression() as? PsiAssignmentExpression ?: return null
|
||||
if (assignment.getOperationTokenType() != JavaTokenType.EQ) return null
|
||||
val body = setter.body ?: return null
|
||||
val statement = (body.statements.singleOrNull() as? PsiExpressionStatement) ?: return null
|
||||
val assignment = statement.expression as? PsiAssignmentExpression ?: return null
|
||||
if (assignment.operationTokenType != JavaTokenType.EQ) return null
|
||||
val isStatic = setter.hasModifierProperty(PsiModifier.STATIC)
|
||||
val field = fieldByExpression(assignment.getLExpression(), isStatic) ?: return null
|
||||
val parameter = setter.getParameterList().getParameters().single()
|
||||
if ((assignment.getRExpression() as? PsiReferenceExpression)?.resolve() != parameter) return null
|
||||
if (field.getType() != parameter.getType()) return null
|
||||
val field = fieldByExpression(assignment.lExpression, isStatic) ?: return null
|
||||
val parameter = setter.parameterList.parameters.single()
|
||||
if ((assignment.rExpression as? PsiReferenceExpression)?.resolve() != parameter) return null
|
||||
if (field.type != parameter.type) return null
|
||||
return field
|
||||
}
|
||||
|
||||
@@ -444,7 +444,7 @@ private class PropertyDetector(
|
||||
if (!refExpr.isQualifierEmptyOrThis()) return null
|
||||
}
|
||||
val field = refExpr.resolve() as? PsiField ?: return null
|
||||
if (field.getContainingClass() != psiClass || field.hasModifierProperty(PsiModifier.STATIC) != static) return null
|
||||
if (field.containingClass != psiClass || field.hasModifierProperty(PsiModifier.STATIC) != static) return null
|
||||
return field
|
||||
}
|
||||
}
|
||||
@@ -29,18 +29,18 @@ class AccessorToPropertyProcessing(val accessorMethod: PsiMethod, val accessorKi
|
||||
override fun convertMethodUsage(methodCall: PsiMethodCallExpression, codeConverter: CodeConverter): Expression? {
|
||||
val isNullable = codeConverter.typeConverter.methodNullability(accessorMethod).isNullable(codeConverter.settings)
|
||||
|
||||
val methodExpr = methodCall.getMethodExpression()
|
||||
val arguments = methodCall.getArgumentList().getExpressions()
|
||||
val methodExpr = methodCall.methodExpression
|
||||
val arguments = methodCall.argumentList.expressions
|
||||
|
||||
val propertyName = Identifier(propertyName, isNullable).assignNoPrototype()
|
||||
val propertyAccess = QualifiedExpression(codeConverter.convertExpression(methodExpr.getQualifierExpression()), propertyName).assignNoPrototype()
|
||||
val propertyAccess = QualifiedExpression(codeConverter.convertExpression(methodExpr.qualifierExpression), propertyName).assignNoPrototype()
|
||||
|
||||
if (accessorKind == AccessorKind.GETTER) {
|
||||
if (arguments.size() != 0) return null // incorrect call
|
||||
if (arguments.size != 0) return null // incorrect call
|
||||
return propertyAccess
|
||||
}
|
||||
else {
|
||||
if (arguments.size() != 1) return null // incorrect call
|
||||
if (arguments.size != 1) return null // incorrect call
|
||||
val argument = codeConverter.convertExpression(arguments[0])
|
||||
return AssignmentExpression(propertyAccess, argument, Operator.EQ)
|
||||
}
|
||||
@@ -54,34 +54,34 @@ class AccessorToPropertyProcessing(val accessorMethod: PsiMethod, val accessorKi
|
||||
else
|
||||
object : ExternalCodeProcessor {
|
||||
override fun processUsage(reference: PsiReference): Array<PsiReference>? {
|
||||
val nameExpr = reference.getElement() as? KtSimpleNameExpression ?: return null
|
||||
val callExpr = nameExpr.getParent() as? KtCallExpression ?: return null
|
||||
val nameExpr = reference.element as? KtSimpleNameExpression ?: return null
|
||||
val callExpr = nameExpr.parent as? KtCallExpression ?: return null
|
||||
|
||||
val arguments = callExpr.getValueArguments()
|
||||
val arguments = callExpr.valueArguments
|
||||
|
||||
val factory = KtPsiFactory(nameExpr.getProject())
|
||||
val factory = KtPsiFactory(nameExpr.project)
|
||||
var propertyNameExpr = factory.createSimpleName(propertyName)
|
||||
if (accessorKind == AccessorKind.GETTER) {
|
||||
if (arguments.size() != 0) return null // incorrect call
|
||||
if (arguments.size != 0) return null // incorrect call
|
||||
propertyNameExpr = callExpr.replace(propertyNameExpr) as KtSimpleNameExpression
|
||||
return propertyNameExpr.getReferences()
|
||||
return propertyNameExpr.references
|
||||
}
|
||||
else {
|
||||
val value = arguments.singleOrNull()?.getArgumentExpression() ?: return null
|
||||
var assignment = factory.createExpression("a = b") as KtBinaryExpression
|
||||
assignment.getRight()!!.replace(value)
|
||||
assignment.right!!.replace(value)
|
||||
|
||||
val qualifiedExpression = callExpr.getParent() as? KtQualifiedExpression
|
||||
if (qualifiedExpression != null && qualifiedExpression.getSelectorExpression() == callExpr) {
|
||||
val qualifiedExpression = callExpr.parent as? KtQualifiedExpression
|
||||
if (qualifiedExpression != null && qualifiedExpression.selectorExpression == callExpr) {
|
||||
callExpr.replace(propertyNameExpr)
|
||||
assignment.getLeft()!!.replace(qualifiedExpression)
|
||||
assignment.left!!.replace(qualifiedExpression)
|
||||
assignment = qualifiedExpression.replace(assignment) as KtBinaryExpression
|
||||
return (assignment.getLeft() as KtQualifiedExpression).getSelectorExpression()!!.getReferences()
|
||||
return (assignment.left as KtQualifiedExpression).selectorExpression!!.references
|
||||
}
|
||||
else {
|
||||
assignment.getLeft()!!.replace(propertyNameExpr)
|
||||
assignment.left!!.replace(propertyNameExpr)
|
||||
assignment = callExpr.replace(assignment) as KtBinaryExpression
|
||||
return assignment.getLeft()!!.getReferences()
|
||||
return assignment.left!!.references
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -17,7 +17,6 @@
|
||||
package org.jetbrains.kotlin.j2k.usageProcessing
|
||||
|
||||
import com.intellij.psi.PsiReference
|
||||
import org.jetbrains.kotlin.j2k.ResolverForConverter
|
||||
|
||||
class ElementRenamedCodeProcessor(private val newName: String) : ExternalCodeProcessor {
|
||||
override fun processUsage(reference: PsiReference): Array<PsiReference>? {
|
||||
|
||||
@@ -21,37 +21,35 @@ import com.intellij.util.IncorrectOperationException
|
||||
import org.jetbrains.kotlin.j2k.AccessorKind
|
||||
import org.jetbrains.kotlin.j2k.CodeConverter
|
||||
import org.jetbrains.kotlin.j2k.ast.*
|
||||
import org.jetbrains.kotlin.psi.KtPsiFactory
|
||||
import org.jetbrains.kotlin.psi.KtSimpleNameExpression
|
||||
|
||||
class FieldToPropertyProcessing(val field: PsiField, val propertyName: String, val isNullable: Boolean) : UsageProcessing {
|
||||
override val targetElement: PsiElement get() = this.field
|
||||
|
||||
override val convertedCodeProcessor: ConvertedCodeProcessor? =
|
||||
if (field.getName() != propertyName) MyConvertedCodeProcessor() else null
|
||||
if (field.name != propertyName) MyConvertedCodeProcessor() else null
|
||||
|
||||
override var javaCodeProcessor = if (field.hasModifierProperty(PsiModifier.PRIVATE))
|
||||
null
|
||||
else if (!field.hasModifierProperty(PsiModifier.STATIC))
|
||||
UseAccessorsJavaCodeProcessor()
|
||||
else if (field.getName() != propertyName)
|
||||
else if (field.name != propertyName)
|
||||
ElementRenamedCodeProcessor(propertyName)
|
||||
else
|
||||
null
|
||||
|
||||
override val kotlinCodeProcessor = if (field.getName() != propertyName) ElementRenamedCodeProcessor(propertyName) else null
|
||||
override val kotlinCodeProcessor = if (field.name != propertyName) ElementRenamedCodeProcessor(propertyName) else null
|
||||
|
||||
private inner class MyConvertedCodeProcessor : ConvertedCodeProcessor {
|
||||
override fun convertVariableUsage(expression: PsiReferenceExpression, codeConverter: CodeConverter): Expression? {
|
||||
val identifier = Identifier(propertyName, isNullable).assignNoPrototype()
|
||||
|
||||
val qualifier = expression.getQualifierExpression()
|
||||
val qualifier = expression.qualifierExpression
|
||||
if (qualifier != null) {
|
||||
return QualifiedExpression(codeConverter.convertExpression(qualifier), identifier)
|
||||
}
|
||||
else {
|
||||
// check if field name is shadowed
|
||||
val elementFactory = PsiElementFactory.SERVICE.getInstance(expression.getProject())
|
||||
val elementFactory = PsiElementFactory.SERVICE.getInstance(expression.project)
|
||||
val refExpr = try {
|
||||
elementFactory.createExpressionFromText(propertyName, expression) as? PsiReferenceExpression ?: return identifier
|
||||
}
|
||||
@@ -67,25 +65,25 @@ class FieldToPropertyProcessing(val field: PsiField, val propertyName: String, v
|
||||
}
|
||||
|
||||
private inner class UseAccessorsJavaCodeProcessor : ExternalCodeProcessor {
|
||||
private val factory = PsiElementFactory.SERVICE.getInstance(field.getProject())
|
||||
private val factory = PsiElementFactory.SERVICE.getInstance(field.project)
|
||||
|
||||
override fun processUsage(reference: PsiReference): Array<PsiReference>? {
|
||||
val refExpr = reference.getElement() as? PsiReferenceExpression ?: return null
|
||||
val qualifier = refExpr.getQualifierExpression()
|
||||
val refExpr = reference.element as? PsiReferenceExpression ?: return null
|
||||
val qualifier = refExpr.qualifierExpression
|
||||
|
||||
val parent = refExpr.getParent()
|
||||
val parent = refExpr.parent
|
||||
when (parent) {
|
||||
is PsiAssignmentExpression -> {
|
||||
if (refExpr == parent.getLExpression()) {
|
||||
if (parent.getOperationTokenType() == JavaTokenType.EQ) {
|
||||
val callExpr = parent.replace(generateSetterCall(qualifier, parent.getRExpression() ?: return null)) as PsiMethodCallExpression
|
||||
return arrayOf(callExpr.getMethodExpression())
|
||||
if (refExpr == parent.lExpression) {
|
||||
if (parent.operationTokenType == JavaTokenType.EQ) {
|
||||
val callExpr = parent.replace(generateSetterCall(qualifier, parent.rExpression ?: return null)) as PsiMethodCallExpression
|
||||
return arrayOf(callExpr.methodExpression)
|
||||
}
|
||||
else {
|
||||
val assignmentOpText = parent.getOperationSign().getText()
|
||||
val assignmentOpText = parent.operationSign.text
|
||||
assert(assignmentOpText.endsWith("="))
|
||||
val opText = assignmentOpText.substring(0, assignmentOpText.length() - 1)
|
||||
return parent.replaceWithModificationCalls(qualifier, opText, parent.getRExpression() ?: return null)
|
||||
val opText = assignmentOpText.substring(0, assignmentOpText.length - 1)
|
||||
return parent.replaceWithModificationCalls(qualifier, opText, parent.rExpression ?: return null)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -93,9 +91,9 @@ class FieldToPropertyProcessing(val field: PsiField, val propertyName: String, v
|
||||
is PsiPrefixExpression, is PsiPostfixExpression -> {
|
||||
//TODO: what if it's used as value?
|
||||
val operationType = if (parent is PsiPrefixExpression)
|
||||
parent.getOperationTokenType()
|
||||
parent.operationTokenType
|
||||
else
|
||||
(parent as PsiPostfixExpression).getOperationTokenType()
|
||||
(parent as PsiPostfixExpression).operationTokenType
|
||||
val opText = when (operationType) {
|
||||
JavaTokenType.PLUSPLUS -> "+"
|
||||
JavaTokenType.MINUSMINUS -> "-"
|
||||
@@ -108,7 +106,7 @@ class FieldToPropertyProcessing(val field: PsiField, val propertyName: String, v
|
||||
}
|
||||
|
||||
val callExpr = refExpr.replace(generateGetterCall(qualifier)) as PsiMethodCallExpression
|
||||
return arrayOf(callExpr.getMethodExpression())
|
||||
return arrayOf(callExpr.methodExpression)
|
||||
}
|
||||
|
||||
//TODO: what if qualifier has side effects?
|
||||
@@ -116,31 +114,31 @@ class FieldToPropertyProcessing(val field: PsiField, val propertyName: String, v
|
||||
var getCall = generateGetterCall(qualifier)
|
||||
|
||||
var binary = factory.createExpressionFromText("x $op y", null) as PsiBinaryExpression
|
||||
binary.getLOperand().replace(getCall)
|
||||
binary.getROperand()!!.replace(value)
|
||||
binary.lOperand.replace(getCall)
|
||||
binary.rOperand!!.replace(value)
|
||||
|
||||
var setCall = generateSetterCall(qualifier, binary) as PsiMethodCallExpression
|
||||
setCall = this.replace(setCall) as PsiMethodCallExpression
|
||||
|
||||
binary = setCall.getArgumentList().getExpressions().single() as PsiBinaryExpression
|
||||
getCall = binary.getLOperand() as PsiMethodCallExpression
|
||||
binary = setCall.argumentList.expressions.single() as PsiBinaryExpression
|
||||
getCall = binary.lOperand as PsiMethodCallExpression
|
||||
|
||||
return arrayOf(getCall.getMethodExpression(), setCall.getMethodExpression())
|
||||
return arrayOf(getCall.methodExpression, setCall.methodExpression)
|
||||
}
|
||||
|
||||
private fun generateGetterCall(qualifier: PsiExpression?): PsiMethodCallExpression {
|
||||
val text = accessorName(AccessorKind.GETTER) + "()"
|
||||
val expressionText = if (qualifier != null)
|
||||
"${qualifier.getText()}.$text"
|
||||
"${qualifier.text}.$text"
|
||||
else
|
||||
text
|
||||
return factory.createExpressionFromText(expressionText, null) as PsiMethodCallExpression
|
||||
}
|
||||
|
||||
private fun generateSetterCall(qualifier: PsiExpression?, value: PsiExpression): PsiExpression {
|
||||
val text = accessorName(AccessorKind.SETTER) + "(" + value.getText() + ")"
|
||||
val text = accessorName(AccessorKind.SETTER) + "(" + value.text + ")"
|
||||
val expressionText = if (qualifier != null)
|
||||
"${qualifier.getText()}.$text"
|
||||
"${qualifier.text}.$text"
|
||||
else
|
||||
text
|
||||
return factory.createExpressionFromText(expressionText, null)
|
||||
|
||||
@@ -25,16 +25,16 @@ public class MethodIntoObjectProcessing(private val method: PsiMethod, private v
|
||||
|
||||
override val javaCodeProcessor = object: ExternalCodeProcessor {
|
||||
override fun processUsage(reference: PsiReference): Array<PsiReference>? {
|
||||
val refExpr = reference.getElement() as? PsiReferenceExpression ?: return null
|
||||
val qualifier = refExpr.getQualifierExpression()
|
||||
val factory = PsiElementFactory.SERVICE.getInstance(method.getProject())
|
||||
val refExpr = reference.element as? PsiReferenceExpression ?: return null
|
||||
val qualifier = refExpr.qualifierExpression
|
||||
val factory = PsiElementFactory.SERVICE.getInstance(method.project)
|
||||
if (qualifier != null) {
|
||||
val newQualifier = factory.createExpressionFromText(qualifier.getText() + "." + objectName, null)
|
||||
val newQualifier = factory.createExpressionFromText(qualifier.text + "." + objectName, null)
|
||||
qualifier.replace(newQualifier)
|
||||
return arrayOf(reference)
|
||||
}
|
||||
else {
|
||||
var qualifiedExpr = factory.createExpressionFromText(objectName + "." + refExpr.getText(), null) as PsiReferenceExpression
|
||||
var qualifiedExpr = factory.createExpressionFromText(objectName + "." + refExpr.text, null) as PsiReferenceExpression
|
||||
qualifiedExpr = refExpr.replace(qualifiedExpr) as PsiReferenceExpression
|
||||
return arrayOf(qualifiedExpr)
|
||||
}
|
||||
|
||||
+3
-3
@@ -26,9 +26,9 @@ class ToObjectWithOnlyMethodsProcessing(private val psiClass: PsiClass) : UsageP
|
||||
|
||||
override val javaCodeProcessor = object: ExternalCodeProcessor {
|
||||
override fun processUsage(reference: PsiReference): Array<PsiReference>? {
|
||||
val refExpr = reference.getElement() as? PsiReferenceExpression ?: return null
|
||||
val factory = PsiElementFactory.SERVICE.getInstance(psiClass.getProject())
|
||||
var qualifiedExpr = factory.createExpressionFromText(refExpr.getText() + "." + JvmAbi.INSTANCE_FIELD, null) as PsiReferenceExpression
|
||||
val refExpr = reference.element as? PsiReferenceExpression ?: return null
|
||||
val factory = PsiElementFactory.SERVICE.getInstance(psiClass.project)
|
||||
var qualifiedExpr = factory.createExpressionFromText(refExpr.text + "." + JvmAbi.INSTANCE_FIELD, null) as PsiReferenceExpression
|
||||
qualifiedExpr = refExpr.replace(qualifiedExpr) as PsiReferenceExpression
|
||||
return arrayOf(qualifiedExpr)
|
||||
}
|
||||
|
||||
@@ -16,7 +16,6 @@
|
||||
|
||||
package org.jetbrains.kotlin.j2k.usageProcessing
|
||||
|
||||
import com.google.common.collect.Multimap
|
||||
import com.intellij.psi.*
|
||||
import org.jetbrains.kotlin.j2k.CodeConverter
|
||||
import org.jetbrains.kotlin.j2k.SpecialExpressionConverter
|
||||
@@ -55,7 +54,7 @@ class UsageProcessingExpressionConverter(val processings: Map<PsiElement, Collec
|
||||
}
|
||||
|
||||
is PsiMethodCallExpression -> {
|
||||
val target = expression.getMethodExpression().resolve() as? PsiMethod ?: return null
|
||||
val target = expression.methodExpression.resolve() as? PsiMethod ?: return null
|
||||
val forTarget = processings[target] ?: return null
|
||||
for (processing in forTarget) {
|
||||
val converted = processing.convertedCodeProcessor?.convertMethodUsage(expression, codeConverter)
|
||||
|
||||
@@ -25,10 +25,12 @@ import com.intellij.core.JavaCoreProjectEnvironment
|
||||
import com.intellij.openapi.extensions.Extensions
|
||||
import com.intellij.openapi.extensions.ExtensionsArea
|
||||
import com.intellij.openapi.fileTypes.FileTypeExtensionPoint
|
||||
import junit.framework.TestCase
|
||||
import com.intellij.openapi.util.io.FileUtil
|
||||
import com.intellij.openapi.util.Disposer
|
||||
import com.intellij.psi.*
|
||||
import com.intellij.openapi.util.io.FileUtil
|
||||
import com.intellij.psi.FileContextProvider
|
||||
import com.intellij.psi.PsiElement
|
||||
import com.intellij.psi.PsiElementFinder
|
||||
import com.intellij.psi.PsiModifierListOwner
|
||||
import com.intellij.psi.augment.PsiAugmentProvider
|
||||
import com.intellij.psi.compiled.ClassFileDecompilers
|
||||
import com.intellij.psi.impl.JavaClassSupersImpl
|
||||
@@ -37,6 +39,7 @@ import com.intellij.psi.impl.compiled.ClsCustomNavigationPolicy
|
||||
import com.intellij.psi.meta.MetaDataContributor
|
||||
import com.intellij.psi.stubs.BinaryFileStubBuilders
|
||||
import com.intellij.psi.util.JavaClassSupers
|
||||
import junit.framework.TestCase
|
||||
import org.jetbrains.kotlin.utils.PathUtil
|
||||
import java.io.File
|
||||
import java.net.URLClassLoader
|
||||
@@ -48,7 +51,7 @@ public abstract class AbstractJavaToKotlinConverterForWebDemoTest : TestCase() {
|
||||
try {
|
||||
val fileContents = FileUtil.loadFile(File(javaPath), true)
|
||||
val javaCoreEnvironment: JavaCoreProjectEnvironment = setUpJavaCoreEnvironment()
|
||||
translateToKotlin(fileContents, javaCoreEnvironment.getProject())
|
||||
translateToKotlin(fileContents, javaCoreEnvironment.project)
|
||||
}
|
||||
finally {
|
||||
Disposer.dispose(DISPOSABLE)
|
||||
@@ -64,19 +67,19 @@ public abstract class AbstractJavaToKotlinConverterForWebDemoTest : TestCase() {
|
||||
val applicationEnvironment = JavaCoreApplicationEnvironment(DISPOSABLE)
|
||||
val javaCoreEnvironment = object : JavaCoreProjectEnvironment(DISPOSABLE, applicationEnvironment) {
|
||||
override fun preregisterServices() {
|
||||
val projectArea = Extensions.getArea(getProject())
|
||||
CoreApplicationEnvironment.registerExtensionPoint(projectArea, PsiTreeChangePreprocessor.EP_NAME, javaClass<PsiTreeChangePreprocessor>())
|
||||
CoreApplicationEnvironment.registerExtensionPoint(projectArea, PsiElementFinder.EP_NAME, javaClass<PsiElementFinder>())
|
||||
val projectArea = Extensions.getArea(project)
|
||||
CoreApplicationEnvironment.registerExtensionPoint(projectArea, PsiTreeChangePreprocessor.EP_NAME, PsiTreeChangePreprocessor::class.java)
|
||||
CoreApplicationEnvironment.registerExtensionPoint(projectArea, PsiElementFinder.EP_NAME, PsiElementFinder::class.java)
|
||||
}
|
||||
};
|
||||
|
||||
javaCoreEnvironment.getProject().registerService(javaClass<NullableNotNullManager>(), object : NullableNotNullManager() {
|
||||
javaCoreEnvironment.project.registerService(NullableNotNullManager::class.java, object : NullableNotNullManager() {
|
||||
override fun isNullable(owner: PsiModifierListOwner, checkBases: Boolean) = !isNotNull(owner, checkBases)
|
||||
override fun isNotNull(owner: PsiModifierListOwner, checkBases: Boolean) = true
|
||||
override fun hasHardcodedContracts(element: PsiElement): Boolean = false
|
||||
})
|
||||
|
||||
applicationEnvironment.getApplication().registerService(javaClass<JavaClassSupers>(), javaClass<JavaClassSupersImpl>())
|
||||
applicationEnvironment.application.registerService(JavaClassSupers::class.java, JavaClassSupersImpl::class.java)
|
||||
|
||||
for (root in PathUtil.getJdkClassesRoots()) {
|
||||
javaCoreEnvironment.addJarToClassPath(root)
|
||||
@@ -89,30 +92,30 @@ public abstract class AbstractJavaToKotlinConverterForWebDemoTest : TestCase() {
|
||||
}
|
||||
|
||||
private fun registerExtensionPoints(area: ExtensionsArea) {
|
||||
CoreApplicationEnvironment.registerExtensionPoint(area, BinaryFileStubBuilders.EP_NAME, javaClass<FileTypeExtensionPoint<Any>>())
|
||||
CoreApplicationEnvironment.registerExtensionPoint(area, FileContextProvider.EP_NAME, javaClass<FileContextProvider>())
|
||||
CoreApplicationEnvironment.registerExtensionPoint(area, BinaryFileStubBuilders.EP_NAME, FileTypeExtensionPoint::class.java)
|
||||
CoreApplicationEnvironment.registerExtensionPoint(area, FileContextProvider.EP_NAME, FileContextProvider::class.java)
|
||||
|
||||
CoreApplicationEnvironment.registerExtensionPoint(area, MetaDataContributor.EP_NAME, javaClass<MetaDataContributor>())
|
||||
CoreApplicationEnvironment.registerExtensionPoint(area, PsiAugmentProvider.EP_NAME, javaClass<PsiAugmentProvider>())
|
||||
CoreApplicationEnvironment.registerExtensionPoint(area, JavaMainMethodProvider.EP_NAME, javaClass<JavaMainMethodProvider>())
|
||||
CoreApplicationEnvironment.registerExtensionPoint(area, MetaDataContributor.EP_NAME, MetaDataContributor::class.java)
|
||||
CoreApplicationEnvironment.registerExtensionPoint(area, PsiAugmentProvider.EP_NAME, PsiAugmentProvider::class.java)
|
||||
CoreApplicationEnvironment.registerExtensionPoint(area, JavaMainMethodProvider.EP_NAME, JavaMainMethodProvider::class.java)
|
||||
|
||||
CoreApplicationEnvironment.registerExtensionPoint(area, ContainerProvider.EP_NAME, javaClass<ContainerProvider>())
|
||||
CoreApplicationEnvironment.registerExtensionPoint(area, ClsCustomNavigationPolicy.EP_NAME, javaClass<ClsCustomNavigationPolicy>())
|
||||
CoreApplicationEnvironment.registerExtensionPoint(area, ClassFileDecompilers.EP_NAME, javaClass<ClassFileDecompilers.Decompiler>())
|
||||
CoreApplicationEnvironment.registerExtensionPoint(area, ContainerProvider.EP_NAME, ContainerProvider::class.java)
|
||||
CoreApplicationEnvironment.registerExtensionPoint(area, ClsCustomNavigationPolicy.EP_NAME, ClsCustomNavigationPolicy::class.java)
|
||||
CoreApplicationEnvironment.registerExtensionPoint(area, ClassFileDecompilers.EP_NAME, ClassFileDecompilers.Decompiler::class.java)
|
||||
}
|
||||
|
||||
fun findAnnotations(): File? {
|
||||
var classLoader = javaClass<JavaToKotlinTranslator>().getClassLoader()
|
||||
var classLoader = JavaToKotlinTranslator::class.java.classLoader
|
||||
while (classLoader != null) {
|
||||
val loader = classLoader
|
||||
if (loader is URLClassLoader) {
|
||||
for (url in loader.getURLs()) {
|
||||
if ("file" == url.getProtocol() && url.getFile()!!.endsWith("/annotations.jar")) {
|
||||
return File(url.getFile()!!)
|
||||
for (url in loader.urLs) {
|
||||
if ("file" == url.protocol && url.file!!.endsWith("/annotations.jar")) {
|
||||
return File(url.file!!)
|
||||
}
|
||||
}
|
||||
}
|
||||
classLoader = classLoader.getParent()
|
||||
classLoader = classLoader.parent
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
||||
@@ -22,16 +22,14 @@ import com.intellij.psi.PsiJavaFile
|
||||
import com.intellij.psi.PsiManager
|
||||
import com.intellij.testFramework.LightPlatformTestCase
|
||||
import org.jetbrains.kotlin.idea.j2k.IdeaJavaToKotlinServices
|
||||
import org.jetbrains.kotlin.idea.test.KotlinWithJdkAndRuntimeLightProjectDescriptor
|
||||
import org.jetbrains.kotlin.idea.j2k.IdeaResolverForConverter
|
||||
import org.jetbrains.kotlin.idea.j2k.J2kPostProcessor
|
||||
import org.jetbrains.kotlin.idea.test.KotlinWithJdkAndRuntimeLightProjectDescriptor
|
||||
import org.jetbrains.kotlin.idea.test.dumpTextWithErrors
|
||||
import org.jetbrains.kotlin.idea.util.application.executeWriteCommand
|
||||
import org.jetbrains.kotlin.idea.util.application.runWriteAction
|
||||
import org.jetbrains.kotlin.psi.KtFile
|
||||
import org.jetbrains.kotlin.test.KotlinTestUtils
|
||||
import java.io.File
|
||||
import java.util.ArrayList
|
||||
import java.util.*
|
||||
|
||||
public abstract class AbstractJavaToKotlinConverterMultiFileTest : AbstractJavaToKotlinConverterTest() {
|
||||
public fun doTest(dirPath: String) {
|
||||
@@ -61,12 +59,12 @@ public abstract class AbstractJavaToKotlinConverterMultiFileTest : AbstractJavaT
|
||||
val process = externalCodeProcessor?.prepareWriteOperation(EmptyProgressIndicator())
|
||||
project.executeWriteCommand("") { process?.invoke() }
|
||||
|
||||
fun expectedResultFile(i: Int) = File(filesToConvert[i].getPath().replace(".java", ".kt"))
|
||||
fun expectedResultFile(i: Int) = File(filesToConvert[i].path.replace(".java", ".kt"))
|
||||
|
||||
val resultFiles = ArrayList<KtFile>()
|
||||
for ((i, javaFile) in psiFilesToConvert.withIndex()) {
|
||||
deleteFile(javaFile.getVirtualFile())
|
||||
val virtualFile = addFile(results[i], expectedResultFile(i).getName(), "test")
|
||||
deleteFile(javaFile.virtualFile)
|
||||
val virtualFile = addFile(results[i], expectedResultFile(i).name, "test")
|
||||
resultFiles.add(psiManager.findFile(virtualFile) as KtFile)
|
||||
}
|
||||
|
||||
@@ -75,13 +73,13 @@ public abstract class AbstractJavaToKotlinConverterMultiFileTest : AbstractJavaT
|
||||
}
|
||||
|
||||
for ((externalFile, externalPsiFile) in externalFiles.zip(externalPsiFiles)) {
|
||||
val expectedFile = File(externalFile.getPath() + ".expected")
|
||||
val expectedFile = File(externalFile.path + ".expected")
|
||||
var resultText = if (externalPsiFile is KtFile) {
|
||||
externalPsiFile.dumpTextWithErrors()
|
||||
}
|
||||
else {
|
||||
//TODO: errors dump for java files too
|
||||
externalPsiFile.getText()
|
||||
externalPsiFile.text
|
||||
}
|
||||
KotlinTestUtils.assertEqualsToFile(expectedFile, resultText)
|
||||
}
|
||||
|
||||
@@ -96,7 +96,7 @@ public abstract class AbstractJavaToKotlinConverterSingleFileTest : AbstractJava
|
||||
CodeStyleManager.getInstance(project)!!.reformat(convertedFile)
|
||||
}
|
||||
|
||||
val reformattedText = convertedFile.getText()!!
|
||||
val reformattedText = convertedFile.text!!
|
||||
|
||||
return if (inFunContext)
|
||||
reformattedText.removeFirstLine().removeLastLine().trimIndent()
|
||||
@@ -111,17 +111,17 @@ public abstract class AbstractJavaToKotlinConverterSingleFileTest : AbstractJava
|
||||
}
|
||||
|
||||
private fun methodToKotlin(text: String, settings: ConverterSettings, project: Project): String {
|
||||
val result = fileToKotlin("final class C {" + text + "}", settings, project).replace("internal class C {", "").replace("internal object C {", "")
|
||||
val result = fileToKotlin("final class C {$text}", settings, project).replace("internal class C {", "").replace("internal object C {", "")
|
||||
return result.substring(0, (result.lastIndexOf("}"))).trim()
|
||||
}
|
||||
|
||||
private fun statementToKotlin(text: String, settings: ConverterSettings, project: Project): String {
|
||||
val result = methodToKotlin("void main() {" + text + "}", settings, project)
|
||||
val result = methodToKotlin("void main() {$text}", settings, project)
|
||||
return result.substring(0, result.lastIndexOf("}")).replaceFirst("fun main() {", "").trim()
|
||||
}
|
||||
|
||||
private fun expressionToKotlin(code: String, settings: ConverterSettings, project: Project): String {
|
||||
val result = statementToKotlin("final Object o =" + code + "}", settings, project)
|
||||
val result = statementToKotlin("final Object o =$code}", settings, project)
|
||||
return result.replaceFirst("val o:Any? = ", "").replaceFirst("val o:Any = ", "").replaceFirst("val o = ", "").trim()
|
||||
}
|
||||
|
||||
|
||||
@@ -48,7 +48,7 @@ public abstract class AbstractJavaToKotlinConverterTest : LightCodeInsightFixtur
|
||||
}
|
||||
|
||||
protected fun addFile(file: File, dirName: String): VirtualFile {
|
||||
return addFile(FileUtil.loadFile(file, true), file.getName(), dirName)
|
||||
return addFile(FileUtil.loadFile(file, true), file.name, dirName)
|
||||
}
|
||||
|
||||
protected fun addFile(text: String, fileName: String, dirName: String): VirtualFile {
|
||||
|
||||
Reference in New Issue
Block a user