Java class with static-only methods can contain 'protected' members (#1257)
#KT-19651 Fixed
This commit is contained in:
committed by
Simon Ogorodnik
parent
0f9d31c9d1
commit
cd6201c5df
@@ -83,7 +83,7 @@ class CodeConverter(
|
||||
val explicitType = type.takeIf { settings.specifyLocalVariableTypeByDefault || converter.shouldDeclareVariableType(variable, type, isVal) }
|
||||
return LocalVariable(variable.declarationIdentifier(),
|
||||
converter.convertAnnotations(variable),
|
||||
converter.convertModifiers(variable, false),
|
||||
converter.convertModifiers(variable, false, false),
|
||||
explicitType,
|
||||
convertExpression(variable.initializer, variable.type),
|
||||
isVal).assignPrototype(variable)
|
||||
|
||||
@@ -162,7 +162,7 @@ class Converter private constructor(
|
||||
}
|
||||
|
||||
val annotations = convertAnnotations(psiClass)
|
||||
var modifiers = convertModifiers(psiClass, false)
|
||||
var modifiers = convertModifiers(psiClass, false, false)
|
||||
val typeParameters = convertTypeParameterList(psiClass.typeParameterList)
|
||||
val extendsTypes = convertToNotNullableTypes(psiClass.extendsList)
|
||||
val implementsTypes = convertToNotNullableTypes(psiClass.implementsList)
|
||||
@@ -222,7 +222,7 @@ class Converter private constructor(
|
||||
settings.openByDefault || referenceSearcher.hasInheritors(psiClass)
|
||||
}
|
||||
|
||||
private fun shouldConvertIntoObject(psiClass: PsiClass): Boolean {
|
||||
fun shouldConvertIntoObject(psiClass: PsiClass): Boolean {
|
||||
val methods = psiClass.methods
|
||||
val fields = psiClass.fields
|
||||
val classes = psiClass.innerClasses
|
||||
@@ -295,7 +295,7 @@ class Converter private constructor(
|
||||
|
||||
return Class(psiClass.declarationIdentifier(),
|
||||
convertAnnotations(psiClass),
|
||||
convertModifiers(psiClass, false).with(Modifier.ANNOTATION).without(Modifier.ABSTRACT),
|
||||
convertModifiers(psiClass, false, false).with(Modifier.ANNOTATION).without(Modifier.ABSTRACT),
|
||||
TypeParameterList.Empty,
|
||||
listOf(),
|
||||
null,
|
||||
@@ -305,7 +305,7 @@ class Converter private constructor(
|
||||
|
||||
fun convertInitializer(initializer: PsiClassInitializer): Initializer {
|
||||
return Initializer(deferredElement { codeConverter -> codeConverter.convertBlock(initializer.body) },
|
||||
convertModifiers(initializer, false)).assignPrototype(initializer)
|
||||
convertModifiers(initializer, false, false)).assignPrototype(initializer)
|
||||
}
|
||||
|
||||
fun convertProperty(propertyInfo: PropertyInfo, classKind: ClassKind): Member {
|
||||
@@ -544,7 +544,7 @@ class Converter private constructor(
|
||||
|
||||
val annotations = convertAnnotations(method) + convertThrows(method)
|
||||
|
||||
var modifiers = convertModifiers(method, classKind.isOpen())
|
||||
var modifiers = convertModifiers(method, classKind.isOpen(), classKind == ClassKind.OBJECT)
|
||||
|
||||
val statementsToInsert = ArrayList<Statement>()
|
||||
for (parameter in method.parameterList.parameters) {
|
||||
@@ -735,7 +735,7 @@ class Converter private constructor(
|
||||
return Identifier(identifier.text!!).assignPrototype(identifier)
|
||||
}
|
||||
|
||||
fun convertModifiers(owner: PsiModifierListOwner, isMethodInOpenClass: Boolean): Modifiers {
|
||||
fun convertModifiers(owner: PsiModifierListOwner, isMethodInOpenClass: Boolean, isInObject: Boolean): Modifiers {
|
||||
var modifiers = Modifiers(MODIFIERS_MAP.filter { owner.hasModifierProperty(it.first) }.map { it.second })
|
||||
.assignPrototype(owner.modifierList, CommentsAndSpacesInheritance.NO_SPACES)
|
||||
|
||||
@@ -752,10 +752,14 @@ class Converter private constructor(
|
||||
if (owner.hasModifierProperty(PsiModifier.NATIVE))
|
||||
modifiers = modifiers.with(Modifier.EXTERNAL)
|
||||
|
||||
modifiers = modifiers.adaptForContainingClassVisibility(owner.containingClass).adaptProtectedVisibility(owner)
|
||||
modifiers = modifiers.adaptForObject(isInObject)
|
||||
.adaptForContainingClassVisibility(owner.containingClass)
|
||||
.adaptProtectedVisibility(owner)
|
||||
}
|
||||
else if (owner is PsiField) {
|
||||
modifiers = modifiers.adaptForContainingClassVisibility(owner.containingClass).adaptProtectedVisibility(owner)
|
||||
modifiers = modifiers.adaptForObject(isInObject)
|
||||
.adaptForContainingClassVisibility(owner.containingClass)
|
||||
.adaptProtectedVisibility(owner)
|
||||
}
|
||||
else if (owner is PsiClass && owner.scope is PsiMethod) {
|
||||
// Local class should not have visibility modifiers
|
||||
@@ -765,6 +769,12 @@ class Converter private constructor(
|
||||
return modifiers
|
||||
}
|
||||
|
||||
private fun Modifiers.adaptForObject(isInObject: Boolean): Modifiers {
|
||||
if (!isInObject) return this
|
||||
if (!modifiers.contains(Modifier.PROTECTED)) return this
|
||||
return without(Modifier.PROTECTED).with(Modifier.INTERNAL)
|
||||
}
|
||||
|
||||
// to convert package local members in package local class into public member (when it's not override, open or abstract)
|
||||
private fun Modifiers.adaptForContainingClassVisibility(containingClass: PsiClass?): Modifiers {
|
||||
if (containingClass == null || !containingClass.hasModifierProperty(PsiModifier.PACKAGE_LOCAL)) return this
|
||||
|
||||
@@ -85,7 +85,8 @@ class PropertyInfo(
|
||||
companion object {
|
||||
fun fromFieldWithNoAccessors(field: PsiField, converter: Converter): PropertyInfo {
|
||||
val isVar = field.isVar(converter.referenceSearcher)
|
||||
val modifiers = converter.convertModifiers(field, false)
|
||||
val isInObject = field.containingClass?.let { converter.shouldConvertIntoObject(it) } == true
|
||||
val modifiers = converter.convertModifiers(field, false, isInObject)
|
||||
return PropertyInfo(field.declarationIdentifier(), isVar, field.type, field, null, null, false, false, modifiers, null, null)
|
||||
}
|
||||
}
|
||||
@@ -221,9 +222,9 @@ private class PropertyDetector(
|
||||
|
||||
val propertyAccess = modifiers.accessModifier()
|
||||
val setterAccess = if (setterInfo != null)
|
||||
converter.convertModifiers(setterInfo.method, false).accessModifier()
|
||||
converter.convertModifiers(setterInfo.method, false, false).accessModifier()
|
||||
else if (field != null && field.isVar(converter.referenceSearcher))
|
||||
converter.convertModifiers(field, false).accessModifier()
|
||||
converter.convertModifiers(field, false, false).accessModifier()
|
||||
else
|
||||
propertyAccess
|
||||
val specialSetterAccess = setterAccess?.takeIf { it != propertyAccess }
|
||||
@@ -366,9 +367,9 @@ private class PropertyDetector(
|
||||
}
|
||||
|
||||
private fun convertModifiers(field: PsiField?, getMethod: PsiMethod?, setMethod: PsiMethod?, isOverride: Boolean): Modifiers {
|
||||
val fieldModifiers = field?.let { converter.convertModifiers(it, false) } ?: Modifiers.Empty
|
||||
val getterModifiers = getMethod?.let { converter.convertModifiers(it, isOpenClass) } ?: Modifiers.Empty
|
||||
val setterModifiers = setMethod?.let { converter.convertModifiers(it, isOpenClass) } ?: Modifiers.Empty
|
||||
val fieldModifiers = field?.let { converter.convertModifiers(it, false, false) } ?: Modifiers.Empty
|
||||
val getterModifiers = getMethod?.let { converter.convertModifiers(it, isOpenClass, false) } ?: Modifiers.Empty
|
||||
val setterModifiers = setMethod?.let { converter.convertModifiers(it, isOpenClass, false) } ?: Modifiers.Empty
|
||||
|
||||
val modifiers = ArrayList<Modifier>()
|
||||
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
class Util {
|
||||
public static final String publicStr = "";
|
||||
protected static final String protectedStr = "";
|
||||
static final String packageStr = "";
|
||||
private static final String privateStr = "";
|
||||
|
||||
public static void publicMethod() {}
|
||||
protected static void protectedMethod() {}
|
||||
static void packageMethod() {}
|
||||
private static void privateMethod() {}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
internal object Util {
|
||||
val publicStr = ""
|
||||
val protectedStr = ""
|
||||
val packageStr = ""
|
||||
private val privateStr = ""
|
||||
|
||||
fun publicMethod() {}
|
||||
fun protectedMethod() {}
|
||||
fun packageMethod() {}
|
||||
private fun privateMethod() {}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
public class Util {
|
||||
public static final String publicStr = "";
|
||||
protected static final String protectedStr = "";
|
||||
static final String packageStr = "";
|
||||
private static final String privateStr = "";
|
||||
|
||||
public static void publicMethod() {}
|
||||
protected static void protectedMethod() {}
|
||||
static void packageMethod() {}
|
||||
private static void privateMethod() {}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
object Util {
|
||||
val publicStr = ""
|
||||
internal val protectedStr = ""
|
||||
internal val packageStr = ""
|
||||
private val privateStr = ""
|
||||
|
||||
fun publicMethod() {}
|
||||
internal fun protectedMethod() {}
|
||||
internal fun packageMethod() {}
|
||||
private fun privateMethod() {}
|
||||
}
|
||||
@@ -1018,6 +1018,18 @@ public class JavaToKotlinConverterForWebDemoTestGenerated extends AbstractJavaTo
|
||||
String fileName = KotlinTestUtils.navigationMetadata("j2k/testData/fileOrElement/class/utilityClass3.java");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("utilityClass4.java")
|
||||
public void testUtilityClass4() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("j2k/testData/fileOrElement/class/utilityClass4.java");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("utilityClass5.java")
|
||||
public void testUtilityClass5() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("j2k/testData/fileOrElement/class/utilityClass5.java");
|
||||
doTest(fileName);
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("j2k/testData/fileOrElement/classExpression")
|
||||
|
||||
@@ -1018,6 +1018,18 @@ public class JavaToKotlinConverterSingleFileTestGenerated extends AbstractJavaTo
|
||||
String fileName = KotlinTestUtils.navigationMetadata("j2k/testData/fileOrElement/class/utilityClass3.java");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("utilityClass4.java")
|
||||
public void testUtilityClass4() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("j2k/testData/fileOrElement/class/utilityClass4.java");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("utilityClass5.java")
|
||||
public void testUtilityClass5() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("j2k/testData/fileOrElement/class/utilityClass5.java");
|
||||
doTest(fileName);
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("j2k/testData/fileOrElement/classExpression")
|
||||
|
||||
Reference in New Issue
Block a user