Don't use PsiElement.getReference() on JetElement

This commit is contained in:
Valentin Kipyatkov
2015-07-10 16:50:27 +03:00
parent d8d00a83bb
commit 283c8668f5
47 changed files with 214 additions and 177 deletions
@@ -265,7 +265,7 @@ class ConstructorConverter(
if (expression is PsiReferenceExpression && expression.getQualifier() == null) {
val replacement = parameterUsageReplacementMap[expression.getReferenceName()]
if (replacement != null) {
val target = expression.getReference()?.resolve()
val target = expression.resolve()
if (target is PsiParameter) {
val scope = target.getDeclarationScope()
// we do not check for exactly this constructor because default values reference parameters in other constructors
@@ -397,7 +397,7 @@ class DefaultExpressionConverter : JavaElementVisitor(), ExpressionConverter {
}
val referenceName = expression.getReferenceName()!!
val target = expression.getReference()?.resolve()
val target = expression.resolve()
val isNullable = target is PsiVariable && typeConverter.variableNullability(target).isNullable(codeConverter.settings)
val qualifier = expression.getQualifierExpression()
@@ -59,10 +59,12 @@ public interface PostProcessor {
}
Errors.VAL_REASSIGNMENT -> { ->
val property = (psiElement as? JetSimpleNameExpression)?.getReference()?.resolve() as? JetProperty
if (property != null && !property.isVar()) {
val factory = JetPsiFactory(psiElement.getProject())
property.getValOrVarKeyword().replace(factory.createVarKeyword())
if (psiElement is JetSimpleNameExpression) {
val property = simpleNameReference(psiElement).resolve() as? JetProperty
if (property != null && !property.isVar()) {
val factory = JetPsiFactory(psiElement.getProject())
property.getValOrVarKeyword().replace(factory.createVarKeyword())
}
}
}
@@ -71,6 +73,8 @@ public interface PostProcessor {
}
public fun doAdditionalProcessing(file: JetFile, rangeMarker: RangeMarker?)
public fun simpleNameReference(nameExpression: JetSimpleNameExpression): PsiReference
}
public enum class ParseContext {
@@ -233,7 +237,7 @@ public class JavaToKotlinConverter(
var references = listOf(reference)
for (processor in processors) {
references = references.flatMap { processor.processUsage(it) ?: listOf(it) }
references = references.flatMap { processor.processUsage(it)?.toList() ?: listOf(it) }
references.forEach { checkReferenceValid(it) }
}
}
@@ -19,6 +19,7 @@ package org.jetbrains.kotlin.j2k.usageProcessing
import com.intellij.psi.*
import org.jetbrains.kotlin.j2k.AccessorKind
import org.jetbrains.kotlin.j2k.CodeConverter
import org.jetbrains.kotlin.j2k.ResolverForConverter
import org.jetbrains.kotlin.j2k.ast.*
import org.jetbrains.kotlin.psi.*
@@ -53,7 +54,7 @@ class AccessorToPropertyProcessing(val accessorMethod: PsiMethod, val accessorKi
null
else
object : ExternalCodeProcessor {
override fun processUsage(reference: PsiReference): Collection<PsiReference>? {
override fun processUsage(reference: PsiReference): Array<PsiReference>? {
val nameExpr = reference.getElement() as? JetSimpleNameExpression ?: return null
val callExpr = nameExpr.getParent() as? JetCallExpression ?: return null
@@ -64,7 +65,7 @@ class AccessorToPropertyProcessing(val accessorMethod: PsiMethod, val accessorKi
if (accessorKind == AccessorKind.GETTER) {
if (arguments.size() != 0) return null // incorrect call
propertyNameExpr = callExpr.replace(propertyNameExpr) as JetSimpleNameExpression
return listOf(propertyNameExpr.getReference()!!)
return propertyNameExpr.getReferences()
}
else {
val value = arguments.singleOrNull()?.getArgumentExpression() ?: return null
@@ -76,12 +77,12 @@ class AccessorToPropertyProcessing(val accessorMethod: PsiMethod, val accessorKi
callExpr.replace(propertyNameExpr)
assignment.getLeft()!!.replace(qualifiedExpression)
assignment = qualifiedExpression.replace(assignment) as JetBinaryExpression
return listOf((assignment.getLeft() as JetQualifiedExpression).getSelectorExpression()!!.getReference()!!)
return (assignment.getLeft() as JetQualifiedExpression).getSelectorExpression()!!.getReferences()
}
else {
assignment.getLeft()!!.replace(propertyNameExpr)
assignment = callExpr.replace(assignment) as JetBinaryExpression
return listOf(assignment.getLeft()!!.getReference()!!)
return assignment.getLeft()!!.getReferences()
}
}
@@ -17,10 +17,10 @@
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): Collection<PsiReference>? {
val newReference = reference.handleElementRename(newName).getReference()!!
return listOf(newReference)
override fun processUsage(reference: PsiReference): Array<PsiReference>? {
return reference.handleElementRename(newName).getReferences()
}
}
@@ -68,7 +68,7 @@ class FieldToPropertyProcessing(val field: PsiField, val propertyName: String, v
private inner class UseAccessorsJavaCodeProcessor : ExternalCodeProcessor {
private val factory = PsiElementFactory.SERVICE.getInstance(field.getProject())
override fun processUsage(reference: PsiReference): Collection<PsiReference>? {
override fun processUsage(reference: PsiReference): Array<PsiReference>? {
val refExpr = reference.getElement() as? PsiReferenceExpression ?: return null
val qualifier = refExpr.getQualifierExpression()
@@ -78,7 +78,7 @@ class FieldToPropertyProcessing(val field: PsiField, val propertyName: String, v
if (refExpr == parent.getLExpression()) {
if (parent.getOperationTokenType() == JavaTokenType.EQ) {
val callExpr = parent.replace(generateSetterCall(qualifier, parent.getRExpression() ?: return null)) as PsiMethodCallExpression
return listOf(callExpr.getMethodExpression())
return arrayOf(callExpr.getMethodExpression())
}
else {
val assignmentOpText = parent.getOperationSign().getText()
@@ -107,11 +107,11 @@ class FieldToPropertyProcessing(val field: PsiField, val propertyName: String, v
}
val callExpr = refExpr.replace(generateGetterCall(qualifier)) as PsiMethodCallExpression
return listOf(callExpr.getMethodExpression())
return arrayOf(callExpr.getMethodExpression())
}
//TODO: what if qualifier has side effects?
private fun PsiExpression.replaceWithModificationCalls(qualifier: PsiExpression?, op: String, value: PsiExpression): Collection<PsiReference> {
private fun PsiExpression.replaceWithModificationCalls(qualifier: PsiExpression?, op: String, value: PsiExpression): Array<PsiReference> {
var getCall = generateGetterCall(qualifier)
var binary = factory.createExpressionFromText("x $op y", null) as PsiBinaryExpression
@@ -124,7 +124,7 @@ class FieldToPropertyProcessing(val field: PsiField, val propertyName: String, v
binary = setCall.getArgumentList().getExpressions().single() as PsiBinaryExpression
getCall = binary.getLOperand() as PsiMethodCallExpression
return listOf(getCall.getMethodExpression().getReference()!!, setCall.getMethodExpression().getReference()!!)
return arrayOf(getCall.getMethodExpression(), setCall.getMethodExpression())
}
private fun generateGetterCall(qualifier: PsiExpression?): PsiMethodCallExpression {
@@ -24,19 +24,19 @@ public class MethodIntoObjectProcessing(private val method: PsiMethod, private v
override val convertedCodeProcessor: ConvertedCodeProcessor? get() = null
override val javaCodeProcessor = object: ExternalCodeProcessor {
override fun processUsage(reference: PsiReference): Collection<PsiReference>? {
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())
if (qualifier != null) {
val newQualifier = factory.createExpressionFromText(qualifier.getText() + "." + objectName, null)
qualifier.replace(newQualifier)
return listOf(reference)
return arrayOf(reference)
}
else {
var qualifiedExpr = factory.createExpressionFromText(objectName + "." + refExpr.getText(), null) as PsiReferenceExpression
qualifiedExpr = refExpr.replace(qualifiedExpr) as PsiReferenceExpression
return listOf(qualifiedExpr.getReference()!!)
return arrayOf(qualifiedExpr)
}
}
}
@@ -25,12 +25,12 @@ class ToObjectWithOnlyMethodsProcessing(private val psiClass: PsiClass) : UsageP
override val convertedCodeProcessor: ConvertedCodeProcessor? get() = null
override val javaCodeProcessor = object: ExternalCodeProcessor {
override fun processUsage(reference: PsiReference): Collection<PsiReference>? {
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
qualifiedExpr = refExpr.replace(qualifiedExpr) as PsiReferenceExpression
return listOf(qualifiedExpr.getReference()!!)
return arrayOf(qualifiedExpr)
}
}
@@ -36,7 +36,7 @@ trait ConvertedCodeProcessor {
}
trait ExternalCodeProcessor {
fun processUsage(reference: PsiReference): Collection<PsiReference>?
fun processUsage(reference: PsiReference): Array<PsiReference>?
}
class UsageProcessingExpressionConverter(val processings: Map<PsiElement, Collection<UsageProcessing>>) : SpecialExpressionConverter {