@@ -172,7 +172,7 @@ class ClassFileToSourceStubConverter(
172
172
return null
173
173
}
174
174
175
- val simpleName = getClassName(clazz, descriptor, isDefaultImpls, packageFqName)
175
+ val simpleName = getValidIdentifierName( getClassName(clazz, descriptor, isDefaultImpls, packageFqName)) ? : return null
176
176
177
177
val interfaces = mapJList(clazz.interfaces) {
178
178
if (isAnnotation && it == " java/lang/annotation/Annotation" ) return @mapJList null
@@ -245,7 +245,7 @@ class ClassFileToSourceStubConverter(
245
245
246
246
return treeMaker.ClassDef (
247
247
modifiers,
248
- treeMaker.name(getNonKeywordName( simpleName) ),
248
+ treeMaker.name(simpleName),
249
249
genericType.typeParameters,
250
250
if (hasSuperClass) genericType.superClass else null ,
251
251
genericType.interfaces,
@@ -279,7 +279,7 @@ class ClassFileToSourceStubConverter(
279
279
val descriptor = kaptContext.origins[field]?.descriptor
280
280
281
281
val modifiers = convertModifiers(field.access, ElementKind .FIELD , packageFqName, field.visibleAnnotations, field.invisibleAnnotations)
282
- val name = treeMaker.name(getNonKeywordName( field.name))
282
+ val name = getValidIdentifierName( field.name) ? : return null
283
283
val type = Type .getType(field.desc)
284
284
285
285
// Enum type must be an identifier (Javac requirement)
@@ -298,7 +298,7 @@ class ClassFileToSourceStubConverter(
298
298
? : convertValueOfPrimitiveTypeOrString(value)
299
299
? : if (isFinal(field.access)) convertLiteralExpression(getDefaultValue(type)) else null
300
300
301
- return treeMaker.VarDef (modifiers, name, typeExpression, initializer)
301
+ return treeMaker.VarDef (modifiers, treeMaker. name(name) , typeExpression, initializer)
302
302
}
303
303
304
304
private fun convertMethod (method : MethodNode , containingClass : ClassNode , packageFqName : String ): JCMethodDecl ? {
@@ -318,7 +318,7 @@ class ClassFileToSourceStubConverter(
318
318
}
319
319
320
320
val isConstructor = method.name == " <init>"
321
- val name = treeMaker.name(getNonKeywordName( method.name))
321
+ val name = getValidIdentifierName( method.name, canBeConstructor = true ) ? : return null
322
322
323
323
val modifiers = convertModifiers(
324
324
if (containingClass.isEnum() && isConstructor)
@@ -344,7 +344,7 @@ class ClassFileToSourceStubConverter(
344
344
info.visibleAnnotations,
345
345
info.invisibleAnnotations)
346
346
347
- val name = treeMaker.name(getNonKeywordName (info.name))
347
+ val name = treeMaker.name(getValidIdentifierName (info.name) ? : " p ${index} _ " + info.name.hashCode( ))
348
348
val type = treeMaker.Type (info.type)
349
349
treeMaker.VarDef (modifiers, name, type, null )
350
350
}
@@ -388,7 +388,7 @@ class ClassFileToSourceStubConverter(
388
388
}
389
389
390
390
return treeMaker.MethodDef (
391
- modifiers, name, returnType, genericSignature.typeParameters,
391
+ modifiers, treeMaker. name(name) , returnType, genericSignature.typeParameters,
392
392
genericSignature.parameterTypes, genericSignature.exceptionTypes,
393
393
body, defaultValue)
394
394
}
@@ -452,9 +452,21 @@ class ClassFileToSourceStubConverter(
452
452
return ifNonError()
453
453
}
454
454
455
- private fun getNonKeywordName (name : String ): String {
455
+ fun getValidIdentifierName (name : String , canBeConstructor : Boolean = false): String? {
456
+ if (canBeConstructor && name == " <init>" ) {
457
+ return name
458
+ }
459
+
456
460
// In theory, this could lead to member/parameter name clashes, though it's supposed to be extremely rare.
457
461
if (name in JAVA_KEYWORDS ) return ' _' + name + ' _'
462
+
463
+ if (name.isEmpty()
464
+ || ! Character .isJavaIdentifierStart(name[0 ])
465
+ || name.drop(1 ).any { ! Character .isJavaIdentifierPart(it) }
466
+ ) {
467
+ return null
468
+ }
469
+
458
470
return name
459
471
}
460
472
@@ -532,7 +544,8 @@ class ClassFileToSourceStubConverter(
532
544
val useSimpleName = ' .' in fqName && fqName.substringBeforeLast(' .' , " " ) == packageFqName
533
545
val name = if (useSimpleName) treeMaker.FqName (fqName.substring(packageFqName!! .length + 1 )) else treeMaker.Type (annotationType)
534
546
val values = mapPairedValuesJList<JCExpression >(annotation.values) { key, value ->
535
- treeMaker.Assign (treeMaker.SimpleName (key), convertLiteralExpression(value))
547
+ val name = getValidIdentifierName(key) ? : return @mapPairedValuesJList null
548
+ treeMaker.Assign (treeMaker.SimpleName (name), convertLiteralExpression(value))
536
549
}
537
550
return treeMaker.Annotation (name, values)
538
551
}
@@ -564,7 +577,7 @@ class ClassFileToSourceStubConverter(
564
577
is Array <* > -> { // Two-element String array for enumerations ([desc, fieldName])
565
578
assert (value.size == 2 )
566
579
val enumType = Type .getType(value[0 ] as String )
567
- val valueName = value[1 ] as String
580
+ val valueName = getValidIdentifierName( value[1 ] as String ) ? : " InvalidFieldName "
568
581
treeMaker.Select (treeMaker.Type (enumType), treeMaker.name(valueName))
569
582
}
570
583
is List <* > -> treeMaker.NewArray (null , JavacList .nil(), mapJList(value) { convertLiteralExpression(it) })
0 commit comments