Java class with static-only methods can contain 'protected' members (#1257)

#KT-19651 Fixed
This commit is contained in:
Toshiaki Kameyama
2017-09-14 21:47:10 +09:00
committed by Simon Ogorodnik
parent 0f9d31c9d1
commit cd6201c5df
9 changed files with 94 additions and 15 deletions
@@ -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)
+18 -8
View File
@@ -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>()
+11
View File
@@ -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() {}
}
+11
View File
@@ -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() {}
}
+11
View File
@@ -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() {}
}
+11
View File
@@ -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")