Kapt3: Ignore declarations with illegal Java identifiers (KT-16153)
This commit is contained in:
+23
-10
@@ -172,7 +172,7 @@ class ClassFileToSourceStubConverter(
|
|||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
|
|
||||||
val simpleName = getClassName(clazz, descriptor, isDefaultImpls, packageFqName)
|
val simpleName = getValidIdentifierName(getClassName(clazz, descriptor, isDefaultImpls, packageFqName)) ?: return null
|
||||||
|
|
||||||
val interfaces = mapJList(clazz.interfaces) {
|
val interfaces = mapJList(clazz.interfaces) {
|
||||||
if (isAnnotation && it == "java/lang/annotation/Annotation") return@mapJList null
|
if (isAnnotation && it == "java/lang/annotation/Annotation") return@mapJList null
|
||||||
@@ -245,7 +245,7 @@ class ClassFileToSourceStubConverter(
|
|||||||
|
|
||||||
return treeMaker.ClassDef(
|
return treeMaker.ClassDef(
|
||||||
modifiers,
|
modifiers,
|
||||||
treeMaker.name(getNonKeywordName(simpleName)),
|
treeMaker.name(simpleName),
|
||||||
genericType.typeParameters,
|
genericType.typeParameters,
|
||||||
if (hasSuperClass) genericType.superClass else null,
|
if (hasSuperClass) genericType.superClass else null,
|
||||||
genericType.interfaces,
|
genericType.interfaces,
|
||||||
@@ -279,7 +279,7 @@ class ClassFileToSourceStubConverter(
|
|||||||
val descriptor = kaptContext.origins[field]?.descriptor
|
val descriptor = kaptContext.origins[field]?.descriptor
|
||||||
|
|
||||||
val modifiers = convertModifiers(field.access, ElementKind.FIELD, packageFqName, field.visibleAnnotations, field.invisibleAnnotations)
|
val modifiers = convertModifiers(field.access, ElementKind.FIELD, packageFqName, field.visibleAnnotations, field.invisibleAnnotations)
|
||||||
val name = treeMaker.name(getNonKeywordName(field.name))
|
val name = getValidIdentifierName(field.name) ?: return null
|
||||||
val type = Type.getType(field.desc)
|
val type = Type.getType(field.desc)
|
||||||
|
|
||||||
// Enum type must be an identifier (Javac requirement)
|
// Enum type must be an identifier (Javac requirement)
|
||||||
@@ -298,7 +298,7 @@ class ClassFileToSourceStubConverter(
|
|||||||
?: convertValueOfPrimitiveTypeOrString(value)
|
?: convertValueOfPrimitiveTypeOrString(value)
|
||||||
?: if (isFinal(field.access)) convertLiteralExpression(getDefaultValue(type)) else null
|
?: if (isFinal(field.access)) convertLiteralExpression(getDefaultValue(type)) else null
|
||||||
|
|
||||||
return treeMaker.VarDef(modifiers, name, typeExpression, initializer)
|
return treeMaker.VarDef(modifiers, treeMaker.name(name), typeExpression, initializer)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun convertMethod(method: MethodNode, containingClass: ClassNode, packageFqName: String): JCMethodDecl? {
|
private fun convertMethod(method: MethodNode, containingClass: ClassNode, packageFqName: String): JCMethodDecl? {
|
||||||
@@ -318,7 +318,7 @@ class ClassFileToSourceStubConverter(
|
|||||||
}
|
}
|
||||||
|
|
||||||
val isConstructor = method.name == "<init>"
|
val isConstructor = method.name == "<init>"
|
||||||
val name = treeMaker.name(getNonKeywordName(method.name))
|
val name = getValidIdentifierName(method.name, canBeConstructor = true) ?: return null
|
||||||
|
|
||||||
val modifiers = convertModifiers(
|
val modifiers = convertModifiers(
|
||||||
if (containingClass.isEnum() && isConstructor)
|
if (containingClass.isEnum() && isConstructor)
|
||||||
@@ -344,7 +344,7 @@ class ClassFileToSourceStubConverter(
|
|||||||
info.visibleAnnotations,
|
info.visibleAnnotations,
|
||||||
info.invisibleAnnotations)
|
info.invisibleAnnotations)
|
||||||
|
|
||||||
val name = treeMaker.name(getNonKeywordName(info.name))
|
val name = treeMaker.name(getValidIdentifierName(info.name) ?: "p${index}_" + info.name.hashCode())
|
||||||
val type = treeMaker.Type(info.type)
|
val type = treeMaker.Type(info.type)
|
||||||
treeMaker.VarDef(modifiers, name, type, null)
|
treeMaker.VarDef(modifiers, name, type, null)
|
||||||
}
|
}
|
||||||
@@ -388,7 +388,7 @@ class ClassFileToSourceStubConverter(
|
|||||||
}
|
}
|
||||||
|
|
||||||
return treeMaker.MethodDef(
|
return treeMaker.MethodDef(
|
||||||
modifiers, name, returnType, genericSignature.typeParameters,
|
modifiers, treeMaker.name(name), returnType, genericSignature.typeParameters,
|
||||||
genericSignature.parameterTypes, genericSignature.exceptionTypes,
|
genericSignature.parameterTypes, genericSignature.exceptionTypes,
|
||||||
body, defaultValue)
|
body, defaultValue)
|
||||||
}
|
}
|
||||||
@@ -452,9 +452,21 @@ class ClassFileToSourceStubConverter(
|
|||||||
return ifNonError()
|
return ifNonError()
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun getNonKeywordName(name: String): String {
|
fun getValidIdentifierName(name: String, canBeConstructor: Boolean = false): String? {
|
||||||
|
if (canBeConstructor && name == "<init>") {
|
||||||
|
return name
|
||||||
|
}
|
||||||
|
|
||||||
// In theory, this could lead to member/parameter name clashes, though it's supposed to be extremely rare.
|
// In theory, this could lead to member/parameter name clashes, though it's supposed to be extremely rare.
|
||||||
if (name in JAVA_KEYWORDS) return '_' + name + '_'
|
if (name in JAVA_KEYWORDS) return '_' + name + '_'
|
||||||
|
|
||||||
|
if (name.isEmpty()
|
||||||
|
|| !Character.isJavaIdentifierStart(name[0])
|
||||||
|
|| name.drop(1).any { !Character.isJavaIdentifierPart(it) }
|
||||||
|
) {
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
|
||||||
return name
|
return name
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -532,7 +544,8 @@ class ClassFileToSourceStubConverter(
|
|||||||
val useSimpleName = '.' in fqName && fqName.substringBeforeLast('.', "") == packageFqName
|
val useSimpleName = '.' in fqName && fqName.substringBeforeLast('.', "") == packageFqName
|
||||||
val name = if (useSimpleName) treeMaker.FqName(fqName.substring(packageFqName!!.length + 1)) else treeMaker.Type(annotationType)
|
val name = if (useSimpleName) treeMaker.FqName(fqName.substring(packageFqName!!.length + 1)) else treeMaker.Type(annotationType)
|
||||||
val values = mapPairedValuesJList<JCExpression>(annotation.values) { key, value ->
|
val values = mapPairedValuesJList<JCExpression>(annotation.values) { key, value ->
|
||||||
treeMaker.Assign(treeMaker.SimpleName(key), convertLiteralExpression(value))
|
val name = getValidIdentifierName(key) ?: return@mapPairedValuesJList null
|
||||||
|
treeMaker.Assign(treeMaker.SimpleName(name), convertLiteralExpression(value))
|
||||||
}
|
}
|
||||||
return treeMaker.Annotation(name, values)
|
return treeMaker.Annotation(name, values)
|
||||||
}
|
}
|
||||||
@@ -564,7 +577,7 @@ class ClassFileToSourceStubConverter(
|
|||||||
is Array<*> -> { // Two-element String array for enumerations ([desc, fieldName])
|
is Array<*> -> { // Two-element String array for enumerations ([desc, fieldName])
|
||||||
assert(value.size == 2)
|
assert(value.size == 2)
|
||||||
val enumType = Type.getType(value[0] as String)
|
val enumType = Type.getType(value[0] as String)
|
||||||
val valueName = value[1] as String
|
val valueName = getValidIdentifierName(value[1] as String) ?: "InvalidFieldName"
|
||||||
treeMaker.Select(treeMaker.Type(enumType), treeMaker.name(valueName))
|
treeMaker.Select(treeMaker.Type(enumType), treeMaker.name(valueName))
|
||||||
}
|
}
|
||||||
is List<*> -> treeMaker.NewArray(null, JavacList.nil(), mapJList(value) { convertLiteralExpression(it) })
|
is List<*> -> treeMaker.NewArray(null, JavacList.nil(), mapJList(value) { convertLiteralExpression(it) })
|
||||||
|
|||||||
+6
@@ -222,6 +222,12 @@ public class ClassFileToSourceStubConverterTestGenerated extends AbstractClassFi
|
|||||||
doTest(fileName);
|
doTest(fileName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("strangeIdentifiers.kt")
|
||||||
|
public void testStrangeIdentifiers() throws Exception {
|
||||||
|
String fileName = KotlinTestUtils.navigationMetadata("plugins/kapt3/testData/converter/strangeIdentifiers.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("strangeNames.kt")
|
@TestMetadata("strangeNames.kt")
|
||||||
public void testStrangeNames() throws Exception {
|
public void testStrangeNames() throws Exception {
|
||||||
String fileName = KotlinTestUtils.navigationMetadata("plugins/kapt3/testData/converter/strangeNames.kt");
|
String fileName = KotlinTestUtils.navigationMetadata("plugins/kapt3/testData/converter/strangeNames.kt");
|
||||||
|
|||||||
@@ -0,0 +1,38 @@
|
|||||||
|
class `:)` {
|
||||||
|
lateinit val f: String
|
||||||
|
}
|
||||||
|
|
||||||
|
// Commented declarations won't compile with the current Kotlin
|
||||||
|
class Test {
|
||||||
|
class `(^_^)`
|
||||||
|
|
||||||
|
lateinit val simpleName: String
|
||||||
|
lateinit val `strange name`: String
|
||||||
|
// lateinit val strangeType: List<`!A@`>
|
||||||
|
|
||||||
|
fun simpleFun() {}
|
||||||
|
|
||||||
|
@Anno(name = "Woofwoof", size = StrangeEnum.`60x60`, `A B` = "S")
|
||||||
|
fun simpleFun2(a: String, b: String) {}
|
||||||
|
|
||||||
|
fun `strange!Fun`() {}
|
||||||
|
// fun strangeFun2(a: String, b: `A()B()`) {}
|
||||||
|
// fun strangeFun3(a: String, b: `A B`) {}
|
||||||
|
fun strangeFun4(a: String, `A()B()`: String) {}
|
||||||
|
// fun strangeFun5(a: `A B`.C) {}
|
||||||
|
}
|
||||||
|
|
||||||
|
enum class StrangeEnum(val size: String) {
|
||||||
|
`60x60`("60x60"),
|
||||||
|
`70x70`("70x70"),
|
||||||
|
`80x80`("80x80"),
|
||||||
|
InvalidFieldName("0x0") // Workaround to pass javac analysis
|
||||||
|
}
|
||||||
|
|
||||||
|
annotation class Anno(val size: StrangeEnum, val name: String, val `A B`: String)
|
||||||
|
|
||||||
|
class `!A@`
|
||||||
|
class `A()B()`
|
||||||
|
class `A B` {
|
||||||
|
class C
|
||||||
|
}
|
||||||
@@ -0,0 +1,56 @@
|
|||||||
|
@java.lang.annotation.Retention(value = java.lang.annotation.RetentionPolicy.RUNTIME)
|
||||||
|
public abstract @interface Anno {
|
||||||
|
|
||||||
|
public abstract StrangeEnum size();
|
||||||
|
|
||||||
|
public abstract java.lang.String name();
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////
|
||||||
|
|
||||||
|
|
||||||
|
public enum StrangeEnum {
|
||||||
|
/*public static final*/ InvalidFieldName /* = new InvalidFieldName(null) */;
|
||||||
|
@org.jetbrains.annotations.NotNull()
|
||||||
|
private final java.lang.String size = null;
|
||||||
|
|
||||||
|
@org.jetbrains.annotations.NotNull()
|
||||||
|
public final java.lang.String getSize() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
StrangeEnum(@org.jetbrains.annotations.NotNull()
|
||||||
|
java.lang.String size) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////
|
||||||
|
|
||||||
|
|
||||||
|
public final class Test {
|
||||||
|
@org.jetbrains.annotations.NotNull()
|
||||||
|
public java.lang.String simpleName;
|
||||||
|
|
||||||
|
@org.jetbrains.annotations.NotNull()
|
||||||
|
public final java.lang.String getSimpleName() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public final void simpleFun() {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Anno(name = "Woofwoof", size = StrangeEnum.InvalidFieldName)
|
||||||
|
public final void simpleFun2(@org.jetbrains.annotations.NotNull()
|
||||||
|
java.lang.String a, @org.jetbrains.annotations.NotNull()
|
||||||
|
java.lang.String b) {
|
||||||
|
}
|
||||||
|
|
||||||
|
public final void strangeFun4(@org.jetbrains.annotations.NotNull()
|
||||||
|
java.lang.String a, @org.jetbrains.annotations.NotNull()
|
||||||
|
java.lang.String p1_1899121793) {
|
||||||
|
}
|
||||||
|
|
||||||
|
public Test() {
|
||||||
|
super();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,26 +1 @@
|
|||||||
public final class My $ name {
|
|
||||||
@org.jetbrains.annotations.NotNull()
|
|
||||||
private final java.lang.String (@\u2022@) = "";
|
|
||||||
@org.jetbrains.annotations.NotNull()
|
|
||||||
private final java.lang.String \u041a\u043e\u0442\u043b\u0438\u043d-\u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0442\u043e\u0440 = "";
|
|
||||||
|
|
||||||
public final void (^_^)(int )))))) {
|
|
||||||
}
|
|
||||||
|
|
||||||
@org.jetbrains.annotations.NotNull()
|
|
||||||
public final java.lang.String get(@\u2022@)() {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@org.jetbrains.annotations.NotNull()
|
|
||||||
public final java.lang.String get\u041a\u043e\u0442\u043b\u0438\u043d-\u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0442\u043e\u0440() {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public final void \u3053\u3000\u3068\u3000\u308a\u3000\u3093\uff01() {
|
|
||||||
}
|
|
||||||
|
|
||||||
public My $ name() {
|
|
||||||
super();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|||||||
Reference in New Issue
Block a user