Adjust J2K to latest protected visibility fixes

This commit is contained in:
Denis Zharkov
2016-03-30 11:55:22 +03:00
parent 92be4aee9c
commit 1bc45fb9cf
8 changed files with 58 additions and 42 deletions
+28 -19
View File
@@ -19,8 +19,10 @@ package org.jetbrains.kotlin.j2k
import com.intellij.openapi.project.Project
import com.intellij.psi.*
import com.intellij.psi.CommonClassNames.*
import com.intellij.psi.util.InheritanceUtil
import com.intellij.psi.util.PsiMethodUtil
import com.intellij.psi.util.PsiTreeUtil
import com.intellij.psi.util.PsiUtil
import org.jetbrains.kotlin.j2k.ast.*
import org.jetbrains.kotlin.j2k.ast.Annotation
import org.jetbrains.kotlin.j2k.ast.Enum
@@ -29,6 +31,7 @@ import org.jetbrains.kotlin.j2k.usageProcessing.FieldToPropertyProcessing
import org.jetbrains.kotlin.j2k.usageProcessing.UsageProcessing
import org.jetbrains.kotlin.j2k.usageProcessing.UsageProcessingExpressionConverter
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.psi.psiUtil.parentsWithSelf
import org.jetbrains.kotlin.types.expressions.OperatorConventions.*
import org.jetbrains.kotlin.utils.addToStdlib.singletonOrEmptyList
import java.util.*
@@ -714,28 +717,34 @@ class Converter private constructor(
val originalClass = member.containingClass ?: return this
// Search for usages only in Java because java-protected member cannot be used in Kotlin from same package
val usages = referenceSearcher.findUsagesForExternalCodeProcessing(member, true, false)
for (usage in usages) {
val element = usage.element
var allowProtected = false
var parent: PsiElement? = element
while (parent != null) {
if (parent is PsiClass && allowProtected(parent, originalClass)) {
allowProtected = true
break
}
parent = parent.parent
}
if (!allowProtected) {
return without(Modifier.PROTECTED).with(Modifier.PUBLIC)
}
}
return this
return if (usages.any { !allowProtected(it.element, member, originalClass) })
without(Modifier.PROTECTED).with(Modifier.PUBLIC)
else this
}
private fun allowProtected(containingClass: PsiClass, originalClass: PsiClass): Boolean {
return originalClass == containingClass || containingClass.isInheritor(originalClass, true)
private fun allowProtected(element: PsiElement, member: PsiMember, originalClass: PsiClass): Boolean {
if (element.parent is PsiNewExpression && member is PsiMethod && member.isConstructor) {
// calls to for protected constructors are allowed only within same class or as super calls
return element.parentsWithSelf.contains(originalClass)
}
return element.parentsWithSelf.filterIsInstance<PsiClass>().any { accessContainingClass ->
if (!InheritanceUtil.isInheritorOrSelf(accessContainingClass, originalClass, true)) return@any false
if (element !is PsiReferenceExpression) return@any true
val qualifierExpression = element.qualifierExpression ?: return@any true
// super.foo is allowed if 'foo' is protected
if (qualifierExpression is PsiSuperExpression) return@any true
val receiverType = qualifierExpression.type ?: return@any true
val resolvedClass = PsiUtil.resolveGenericsClassInType(receiverType).element ?: return@any true
// receiver type should be subtype of containing class
InheritanceUtil.isInheritorOrSelf(resolvedClass, accessContainingClass, true)
}
}
fun convertAnonymousClassBody(anonymousClass: PsiAnonymousClass): AnonymousClassBody {
@@ -1,6 +1,5 @@
open class Base internal constructor(x: Int) {
var x = 42
protected set
init {
this.x = x
@@ -5,10 +5,14 @@ public class BaseInheritorSamePackage {
}
protected void foo() {
protected BaseInheritorSamePackage(int x) {
}
protected void foo() {
new BaseInheritorSamePackage(1);
}
protected int i = 1;
}
@@ -1,12 +1,19 @@
package test
open class BaseInheritorSamePackage protected constructor() {
protected fun foo() {
open class BaseInheritorSamePackage {
constructor() {
}
protected var i = 1
protected constructor(x: Int) {
}
fun foo() {
BaseInheritorSamePackage(1)
}
var i = 1
}
internal class DerivedInheritorSamePackage : BaseInheritorSamePackage() {
@@ -3,9 +3,9 @@ package test2;
import test.*;
public class DerivedOtherPackage extends BaseOtherPackage {
public void usage1() {
BaseOtherPackage base = new BaseOtherPackage();
base.foo();
int i = base.i;
protected DerivedOtherPackage() {
super();
foo();
int i = this.i;
}
}
@@ -2,10 +2,9 @@ package test2
import test.*
class DerivedOtherPackage : BaseOtherPackage() {
fun usage1() {
val base = BaseOtherPackage()
base.foo()
val i = base.i
class DerivedOtherPackage protected constructor() : BaseOtherPackage() {
init {
foo()
val i = this.i
}
}
@@ -3,9 +3,8 @@ package test3
import test.*
class DerivedOtherPackageKotlin : BaseOtherPackage() {
fun usage1() {
val base = BaseOtherPackage()
base.foo()
val i = base.i
init {
foo()
val i = this.i
}
}
@@ -3,9 +3,8 @@ package test3
import test.*
class DerivedOtherPackageKotlin : BaseOtherPackage() {
fun usage1() {
val base = BaseOtherPackage()
base.foo()
val i = base.i
init {
foo()
val i = this.i
}
}