Skip to content

Commit 8bbb34a

Browse files
committed
Convert kotlin.Deprecated back into a no-arg java.lang.Deprecated if applicable
This at least maintains consistency with the Java extractor, although we lose its arguments if any were supplied Java-side.
1 parent 658c7a2 commit 8bbb34a

File tree

7 files changed

+99
-3
lines changed

7 files changed

+99
-3
lines changed

java/kotlin-extractor/src/main/kotlin/KotlinFileExtractor.kt

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -498,8 +498,19 @@ open class KotlinFileExtractor(
498498
extractEnumTypeAccesses: Boolean,
499499
contextLabel: String? = null
500500
): Label<out DbExpr> {
501+
val isConvertedJavaDeprecatedAnnotation = (constructorCall.type as? IrSimpleType)?.classFqName?.asString() == "kotlin.Deprecated" &&
502+
constructorCall.source is JavaSourceElement
503+
504+
val extractType =
505+
(
506+
if (isConvertedJavaDeprecatedAnnotation)
507+
pluginContext.referenceClass(FqName("java.lang.Deprecated"))?.defaultType
508+
else
509+
null
510+
) ?: erase(constructorCall.type)
511+
501512
// Erase the type here because the JVM lowering erases the annotation type, and so the Java extractor will see it in erased form.
502-
val t = useType(erase(constructorCall.type))
513+
val t = useType(extractType)
503514
val annotationContextLabel = contextLabel ?: "{${t.javaResult.id}}"
504515
val id = tw.getLabelFor<DbDeclannotation>("@\"annotation;{$parent};$annotationContextLabel\"")
505516
tw.writeExprs_declannotation(id, t.javaResult.id, parent, idx)
@@ -508,7 +519,11 @@ open class KotlinFileExtractor(
508519
val locId = tw.getLocation(constructorCall)
509520
tw.writeHasLocation(id, locId)
510521

511-
for (i in 0 until constructorCall.valueArgumentsCount) {
522+
// If this is `java.lang.Deprecated`, extract an annotation without parameters -- whatever the original source
523+
// may have supplied has been lost.
524+
val paramCount = if (isConvertedJavaDeprecatedAnnotation) 0 else constructorCall.valueArgumentsCount
525+
526+
for (i in 0 until paramCount) {
512527
val param = constructorCall.symbol.owner.valueParameters[i]
513528
val prop = constructorCall.symbol.owner.parentAsClass.declarations
514529
.filterIsInstance<IrProperty>()

java/ql/integration-tests/all-platforms/kotlin/annotation-id-consistency/PrintAst.expected

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,12 @@ User.java:
1818
# 4| 2: [ExprStmt] <Expr>;
1919
# 4| 0: [ClassInstanceExpr] new Annotated(...)
2020
# 4| -3: [TypeAccess] Annotated
21+
# 4| 3: [ExprStmt] <Expr>;
22+
# 4| 0: [ClassInstanceExpr] new HasJavaDeprecatedAnnotationUsedByJava(...)
23+
# 4| -3: [TypeAccess] HasJavaDeprecatedAnnotationUsedByJava
24+
# 4| 4: [ExprStmt] <Expr>;
25+
# 4| 0: [ClassInstanceExpr] new HasKotlinDeprecatedAnnotationUsedByJava(...)
26+
# 4| -3: [TypeAccess] HasKotlinDeprecatedAnnotationUsedByJava
2127
ktUser.kt:
2228
# 0| [CompilationUnit] ktUser
2329
# 1| 1: [Class] KtUser
@@ -32,6 +38,20 @@ ktUser.kt:
3238
# 4| 1: [LocalVariableDeclExpr] a
3339
# 4| 0: [ClassInstanceExpr] new AnnotatedUsedByKotlin(...)
3440
# 4| -3: [TypeAccess] AnnotatedUsedByKotlin
41+
# 5| 1: [LocalVariableDeclStmt] var ...;
42+
# 5| 1: [LocalVariableDeclExpr] b
43+
# 5| 0: [ClassInstanceExpr] new HasJavaDeprecatedAnnotationUsedByKotlin(...)
44+
# 5| -3: [TypeAccess] HasJavaDeprecatedAnnotationUsedByKotlin
45+
# 6| 2: [LocalVariableDeclStmt] var ...;
46+
# 6| 1: [LocalVariableDeclExpr] c
47+
# 6| 0: [ClassInstanceExpr] new HasKotlinDeprecatedAnnotationUsedByKotlin(...)
48+
# 6| -3: [TypeAccess] HasKotlinDeprecatedAnnotationUsedByKotlin
49+
# 8| 3: [ExprStmt] <Expr>;
50+
# 8| 0: [ImplicitCoercionToUnitExpr] <implicit coercion to unit>
51+
# 8| 0: [TypeAccess] Unit
52+
# 8| 1: [MethodAccess] isJavaLetter(...)
53+
# 8| -1: [TypeAccess] Character
54+
# 8| 0: [CharacterLiteral] a
3555
test.kt:
3656
# 0| [CompilationUnit] test
3757
# 4| 1: [Interface] Ann1
@@ -235,6 +255,36 @@ test.kt:
235255
# 27| 5: [BlockStmt] { ... }
236256
# 27| 0: [SuperConstructorInvocationStmt] super(...)
237257
# 35| 1: [BlockStmt] { ... }
258+
# 37| 10: [Class] HasJavaDeprecatedAnnotationUsedByJava
259+
#-----| -3: (Annotations)
260+
# 37| 1: [Annotation] Deprecated
261+
# 38| 1: [Constructor] HasJavaDeprecatedAnnotationUsedByJava
262+
# 37| 5: [BlockStmt] { ... }
263+
# 37| 0: [SuperConstructorInvocationStmt] super(...)
264+
# 38| 1: [BlockStmt] { ... }
265+
# 40| 11: [Class] HasKotlinDeprecatedAnnotationUsedByJava
266+
#-----| -3: (Annotations)
267+
# 40| 1: [Annotation] Deprecated
268+
# 0| 1: [StringLiteral] "Kotlin deprecation message 1"
269+
# 41| 1: [Constructor] HasKotlinDeprecatedAnnotationUsedByJava
270+
# 40| 5: [BlockStmt] { ... }
271+
# 40| 0: [SuperConstructorInvocationStmt] super(...)
272+
# 41| 1: [BlockStmt] { ... }
273+
# 43| 12: [Class] HasJavaDeprecatedAnnotationUsedByKotlin
274+
#-----| -3: (Annotations)
275+
# 43| 1: [Annotation] Deprecated
276+
# 44| 1: [Constructor] HasJavaDeprecatedAnnotationUsedByKotlin
277+
# 43| 5: [BlockStmt] { ... }
278+
# 43| 0: [SuperConstructorInvocationStmt] super(...)
279+
# 44| 1: [BlockStmt] { ... }
280+
# 46| 13: [Class] HasKotlinDeprecatedAnnotationUsedByKotlin
281+
#-----| -3: (Annotations)
282+
# 46| 1: [Annotation] Deprecated
283+
# 0| 1: [StringLiteral] "Kotlin deprecation message 2"
284+
# 47| 1: [Constructor] HasKotlinDeprecatedAnnotationUsedByKotlin
285+
# 46| 5: [BlockStmt] { ... }
286+
# 46| 0: [SuperConstructorInvocationStmt] super(...)
287+
# 47| 1: [BlockStmt] { ... }
238288
# 0| [TypeLiteral] String.class
239289
# 0| 0: [TypeAccess] String
240290
# 0| [ArrayInit] {...}
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
public class User {
22

33
public static void user(Ann1 a1, Ann2 a2) {
4-
a1.x(); a2.z(); new Annotated();
4+
a1.x(); a2.z(); new Annotated(); new HasJavaDeprecatedAnnotationUsedByJava(); new HasKotlinDeprecatedAnnotationUsedByJava();
55
}
66

77
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
| HasJavaDeprecatedAnnotationUsedByJava | java.lang.Deprecated |
2+
| HasJavaDeprecatedAnnotationUsedByKotlin | java.lang.Deprecated |
3+
| HasKotlinDeprecatedAnnotationUsedByJava | kotlin.Deprecated |
4+
| HasKotlinDeprecatedAnnotationUsedByKotlin | kotlin.Deprecated |
5+
| isJavaLetter | java.lang.Deprecated |
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
import java
2+
3+
from Annotatable a, Annotation ann
4+
where
5+
(
6+
a.(Method).hasQualifiedName("java.lang", "Character", "isJavaLetter") or
7+
a.(ClassOrInterface).fromSource()
8+
) and
9+
ann = a.getAnAnnotation() and
10+
ann.getType().getName() = "Deprecated"
11+
select a.toString(), a.getAnAnnotation().getType().getQualifiedName()

java/ql/integration-tests/all-platforms/kotlin/annotation-id-consistency/ktUser.kt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,10 @@ public class KtUser {
22

33
fun user() {
44
val a = AnnotatedUsedByKotlin()
5+
val b = HasJavaDeprecatedAnnotationUsedByKotlin()
6+
val c = HasKotlinDeprecatedAnnotationUsedByKotlin()
7+
// Use a Java-defined function carrying a java.lang.Deprecated annotation:
8+
java.lang.Character.isJavaLetter('a')
59
}
610

711
}

java/ql/integration-tests/all-platforms/kotlin/annotation-id-consistency/test.kt

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,3 +34,14 @@ class Annotated { }
3434
@AnnWithDefaults
3535
class AnnotatedUsedByKotlin { }
3636

37+
@java.lang.Deprecated
38+
class HasJavaDeprecatedAnnotationUsedByJava
39+
40+
@kotlin.Deprecated("Kotlin deprecation message 1")
41+
class HasKotlinDeprecatedAnnotationUsedByJava
42+
43+
@java.lang.Deprecated
44+
class HasJavaDeprecatedAnnotationUsedByKotlin
45+
46+
@kotlin.Deprecated("Kotlin deprecation message 2")
47+
class HasKotlinDeprecatedAnnotationUsedByKotlin

0 commit comments

Comments
 (0)