Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit ef2795c

Browse files
tamasvajkigfoo
authored andcommitted
Add ktLocalFunction relation and tests for local and anonymous classes
1 parent e0bf7d8 commit ef2795c

13 files changed

Lines changed: 238 additions & 0 deletions

File tree

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

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -662,6 +662,8 @@ open class KotlinFileExtractor(
662662
if (s.isLocalFunction()) {
663663
val classId = extractGeneratedClass(s, listOf(pluginContext.irBuiltIns.anyType))
664664
extractLocalTypeDeclStmt(classId, s, callable, parent, idx)
665+
val ids = getLocallyVisibleFunctionLabels(s)
666+
tw.writeKtLocalFunction(ids.function)
665667
} else {
666668
logger.warnElement(Severity.ErrorSevere, "Expected to find local function", s)
667669
}

java/ql/lib/config/semmlecode.dbscheme

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1143,3 +1143,7 @@ ktSyntheticBody(
11431143
// 1: ENUM_VALUES
11441144
// 2: ENUM_VALUEOF
11451145
)
1146+
1147+
ktLocalFunction(
1148+
unique int id: @method ref
1149+
)

java/ql/lib/semmle/code/java/Member.qll

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -463,6 +463,9 @@ class Method extends Callable, @method {
463463
not this.getDeclaringType().isFinal()
464464
}
465465

466+
/** Holds if this method is a Kotlin local function. */
467+
predicate isLocal() { ktLocalFunction(this) }
468+
466469
override string getAPrimaryQlClass() { result = "Method" }
467470
}
468471

java/ql/test/kotlin/library-tests/classes/PrintAst.expected

Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -433,6 +433,109 @@ classes.kt:
433433
# 127| 1: [ExprStmt] <Expr>;
434434
# 127| 0: [ClassInstanceExpr] new (...)
435435
# 127| -3: [TypeAccess] Object
436+
local_anonymous.kt:
437+
# 0| [CompilationUnit] local_anonymous
438+
# 0| 1: [Class] Local_anonymousKt
439+
# 3| 2: [Class] Class1
440+
# 3| 1: [Constructor] Class1
441+
# 3| 5: [BlockStmt] { ... }
442+
# 3| 0: [SuperConstructorInvocationStmt] super(...)
443+
# 3| 1: [ExprStmt] <Expr>;
444+
# 3| 0: [MethodAccess] <obinit>(...)
445+
# 4| 3: [Method] fn1
446+
# 4| 5: [BlockStmt] { ... }
447+
# 5| 0: [ReturnStmt] return ...
448+
# 5| 0: [StmtExpr] <Stmt>
449+
# 5| 0: [BlockStmt] { ... }
450+
# 5| 0: [LocalTypeDeclStmt] class ...
451+
# 5| 0: [AnonymousClass,LocalClass] new Object(...) { ... }
452+
# 5| 1: [Constructor]
453+
# 5| 5: [BlockStmt] { ... }
454+
# 5| 0: [SuperConstructorInvocationStmt] super(...)
455+
# 5| 1: [ExprStmt] <Expr>;
456+
# 5| 0: [MethodAccess] <obinit>(...)
457+
# 6| 3: [Method] fn
458+
# 6| 5: [BlockStmt] { ... }
459+
# 5| 1: [ExprStmt] <Expr>;
460+
# 5| 0: [ClassInstanceExpr] new (...)
461+
# 5| -3: [TypeAccess] Object
462+
# 10| 4: [Method] fn2
463+
# 10| 5: [BlockStmt] { ... }
464+
# 11| 0: [LocalTypeDeclStmt] class ...
465+
# 11| 0: [AnonymousClass,LocalClass] new Object(...) { ... }
466+
# 11| 1: [Constructor]
467+
# 11| 5: [BlockStmt] { ... }
468+
# 11| 0: [SuperConstructorInvocationStmt] super(...)
469+
# 11| 1: [Method] fnLocal
470+
# 11| 5: [BlockStmt] { ... }
471+
# 12| 1: [ExprStmt] <Expr>;
472+
# 12| 0: [MethodAccess] fnLocal(...)
473+
# 12| -1: [ClassInstanceExpr] new (...)
474+
# 12| -3: [TypeAccess] Object
475+
# 15| 5: [Method] fn3
476+
# 15| 5: [BlockStmt] { ... }
477+
# 16| 0: [LocalVariableDeclStmt] var ...;
478+
# 16| 1: [LocalVariableDeclExpr] lambda1
479+
# 16| 0: [LambdaExpr] ...->...
480+
# 16| -4: [AnonymousClass] new Function2<Integer,Integer,Integer>(...) { ... }
481+
# 16| 1: [Constructor]
482+
# 16| 5: [BlockStmt] { ... }
483+
# 16| 0: [SuperConstructorInvocationStmt] super(...)
484+
# 16| 1: [Method] invoke
485+
#-----| 4: (Parameters)
486+
# 16| 0: [Parameter] a
487+
# 16| 1: [Parameter] b
488+
# 16| 5: [BlockStmt] { ... }
489+
# 16| 0: [ReturnStmt] return ...
490+
# 16| 0: [AddExpr] ... + ...
491+
# 16| 0: [VarAccess] a
492+
# 16| 1: [VarAccess] b
493+
# 16| -3: [TypeAccess] Function2<Integer,Integer,Integer>
494+
# 17| 1: [LocalVariableDeclStmt] var ...;
495+
# 17| 1: [LocalVariableDeclExpr] lambda2
496+
# 17| 0: [LambdaExpr] ...->...
497+
# 17| -4: [AnonymousClass] new Function2<Integer,Integer,Integer>(...) { ... }
498+
# 17| 1: [Constructor]
499+
# 17| 5: [BlockStmt] { ... }
500+
# 17| 0: [SuperConstructorInvocationStmt] super(...)
501+
# 17| 1: [Method] invoke
502+
#-----| 4: (Parameters)
503+
# 17| 0: [Parameter] a
504+
# 17| 1: [Parameter] b
505+
# 17| 5: [BlockStmt] { ... }
506+
# 17| 0: [ReturnStmt] return ...
507+
# 17| 0: [AddExpr] ... + ...
508+
# 17| 0: [VarAccess] a
509+
# 17| 1: [VarAccess] b
510+
# 17| -3: [TypeAccess] Function2<Integer,Integer,Integer>
511+
# 20| 6: [Method] fn4
512+
# 20| 5: [BlockStmt] { ... }
513+
# 21| 0: [LocalVariableDeclStmt] var ...;
514+
# 21| 1: [LocalVariableDeclExpr] fnRef
515+
# 21| 0: [MemberRefExpr] ...::...
516+
# 21| -4: [AnonymousClass] new Function0<Unit>(...) { ... }
517+
# 21| 1: [Constructor]
518+
# 21| 5: [BlockStmt] { ... }
519+
# 21| 0: [SuperConstructorInvocationStmt] super(...)
520+
# 21| 1: [Method] invoke
521+
# 21| 5: [BlockStmt] { ... }
522+
# 21| 0: [ReturnStmt] return ...
523+
# 21| 0: [MethodAccess] fn3(...)
524+
# 21| -3: [TypeAccess] Function0<Unit>
525+
# 24| 7: [Method] fn5
526+
# 24| 5: [BlockStmt] { ... }
527+
# 25| 0: [LocalTypeDeclStmt] class ...
528+
# 25| 0: [LocalClass] LocalClass
529+
# 25| 1: [Constructor] LocalClass
530+
# 25| 5: [BlockStmt] { ... }
531+
# 25| 0: [SuperConstructorInvocationStmt] super(...)
532+
# 25| 1: [ExprStmt] <Expr>;
533+
# 25| 0: [MethodAccess] <obinit>(...)
534+
# 26| 1: [ExprStmt] <Expr>;
535+
# 26| 0: [CastExpr] (...)...
536+
# 26| 0: [TypeAccess] Unit
537+
# 26| 1: [ClassInstanceExpr] new LocalClass(...)
538+
# 26| -3: [TypeAccess] LocalClass
436539
superChain.kt:
437540
# 0| [CompilationUnit] superChain
438541
# 0| 1: [Class] SuperChainKt

java/ql/test/kotlin/library-tests/classes/anonymousClasses.expected

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,3 +6,5 @@
66
| classes.kt:85:16:85:25 | new Object(...) { ... } | classes.kt:85:16:85:25 | new (...) | | classes.kt:85:16:85:25 | Object | classes.kt:85:16:85:25 | class ... |
77
| classes.kt:89:16:89:44 | new Interface3<Integer>(...) { ... } | classes.kt:89:16:89:44 | new (...) | | classes.kt:89:16:89:44 | Interface3<Integer> | classes.kt:89:16:89:44 | class ... |
88
| classes.kt:127:16:134:9 | new Object(...) { ... } | classes.kt:127:16:134:9 | new (...) | | classes.kt:127:16:134:9 | Object | classes.kt:127:16:134:9 | class ... |
9+
| local_anonymous.kt:5:16:7:9 | new Object(...) { ... } | local_anonymous.kt:5:16:7:9 | new (...) | | local_anonymous.kt:5:16:7:9 | Object | local_anonymous.kt:5:16:7:9 | class ... |
10+
| local_anonymous.kt:11:9:11:24 | new Object(...) { ... } | local_anonymous.kt:12:9:12:17 | new (...) | | local_anonymous.kt:12:9:12:17 | Object | local_anonymous.kt:11:9:11:24 | class ... |

java/ql/test/kotlin/library-tests/classes/classes.expected

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,14 @@
3434
| classes.kt:119:13:121:13 | Local2 | C1$Local2 | final |
3535
| classes.kt:127:16:134:9 | new Object(...) { ... } | <anonymous class> | final |
3636
| classes.kt:129:17:131:17 | Local3 | C1$$Local3 | final |
37+
| local_anonymous.kt:0:0:0:0 | Local_anonymousKt | LocalAnonymous.Local_anonymousKt | |
38+
| local_anonymous.kt:3:1:28:1 | Class1 | LocalAnonymous.Class1 | final, public |
39+
| local_anonymous.kt:5:16:7:9 | new Object(...) { ... } | <anonymous class> | final |
40+
| local_anonymous.kt:11:9:11:24 | new Object(...) { ... } | <anonymous class> | final, public, static |
41+
| local_anonymous.kt:16:23:16:49 | new Function2<Integer,Integer,Integer>(...) { ... } | <anonymous class> | final, public, static |
42+
| local_anonymous.kt:17:23:17:49 | new Function2<Integer,Integer,Integer>(...) { ... } | <anonymous class> | final, public, static |
43+
| local_anonymous.kt:21:21:21:31 | new Function0<Unit>(...) { ... } | <anonymous class> | final, public, static |
44+
| local_anonymous.kt:25:9:25:27 | LocalClass | LocalAnonymous.Class1$LocalClass | final |
3745
| superChain.kt:0:0:0:0 | SuperChainKt | SuperChainKt | |
3846
| superChain.kt:1:1:1:33 | SuperChain1 | SuperChain1 | public |
3947
| superChain.kt:2:1:2:60 | SuperChain2 | SuperChain2 | public |

java/ql/test/kotlin/library-tests/classes/ctorCalls.expected

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,13 @@ superCall
3434
| classes.kt:119:13:121:13 | super(...) |
3535
| classes.kt:127:16:134:9 | super(...) |
3636
| classes.kt:129:17:131:17 | super(...) |
37+
| local_anonymous.kt:3:1:28:1 | super(...) |
38+
| local_anonymous.kt:5:16:7:9 | super(...) |
39+
| local_anonymous.kt:11:9:11:24 | super(...) |
40+
| local_anonymous.kt:16:23:16:49 | super(...) |
41+
| local_anonymous.kt:17:23:17:49 | super(...) |
42+
| local_anonymous.kt:21:21:21:31 | super(...) |
43+
| local_anonymous.kt:25:9:25:27 | super(...) |
3744
| superChain.kt:1:1:1:33 | super(...) |
3845
| superChain.kt:2:33:2:57 | super(...) |
3946
| superChain.kt:3:33:3:57 | super(...) |

java/ql/test/kotlin/library-tests/classes/initBlocks.expected

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,9 @@ initBlocks
3838
| classes.kt:119:13:121:13 | <obinit> |
3939
| classes.kt:127:16:134:9 | <obinit> |
4040
| classes.kt:129:17:131:17 | <obinit> |
41+
| local_anonymous.kt:3:1:28:1 | <obinit> |
42+
| local_anonymous.kt:5:16:7:9 | <obinit> |
43+
| local_anonymous.kt:25:9:25:27 | <obinit> |
4144
| superChain.kt:1:1:1:33 | <obinit> |
4245
| superChain.kt:2:1:2:60 | <obinit> |
4346
| superChain.kt:3:1:3:60 | <obinit> |
@@ -76,6 +79,9 @@ initCall
7679
| classes.kt:119:13:121:13 | <obinit>(...) |
7780
| classes.kt:127:16:134:9 | <obinit>(...) |
7881
| classes.kt:129:17:131:17 | <obinit>(...) |
82+
| local_anonymous.kt:3:1:28:1 | <obinit>(...) |
83+
| local_anonymous.kt:5:16:7:9 | <obinit>(...) |
84+
| local_anonymous.kt:25:9:25:27 | <obinit>(...) |
7985
| superChain.kt:1:1:1:33 | <obinit>(...) |
8086
| superChain.kt:2:1:2:60 | <obinit>(...) |
8187
| superChain.kt:3:1:3:60 | <obinit>(...) |

java/ql/test/kotlin/library-tests/classes/localClass.expected

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,3 +2,4 @@
22
| classes.kt:118:9:123:9 | class ... | classes.kt:118:9:123:9 | | classes.kt:117:5:124:5 | fn2 | classes.kt:109:1:136:1 | C1 |
33
| classes.kt:119:13:121:13 | class ... | classes.kt:119:13:121:13 | Local2 | classes.kt:118:9:123:9 | localFn | classes.kt:109:1:136:1 | C1 |
44
| classes.kt:129:17:131:17 | class ... | classes.kt:129:17:131:17 | Local3 | classes.kt:128:13:133:13 | fn | classes.kt:127:16:134:9 | new Object(...) { ... } |
5+
| local_anonymous.kt:25:9:25:27 | class ... | local_anonymous.kt:25:9:25:27 | LocalClass | local_anonymous.kt:24:5:27:5 | fn5 | local_anonymous.kt:3:1:28:1 | Class1 |
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
anonymousObjects
2+
| local_anonymous.kt:5:16:7:9 | new (...) | local_anonymous.kt:5:16:7:9 | new Object(...) { ... } | anonymous | local |
3+
localFunctions
4+
| local_anonymous.kt:11:9:11:24 | fnLocal | local_anonymous.kt:11:9:11:24 | new Object(...) { ... } | anonymous | local |
5+
lambdas
6+
| local_anonymous.kt:16:23:16:49 | ...->... | local_anonymous.kt:16:23:16:49 | new Function2<Integer,Integer,Integer>(...) { ... } | anonymous | not local |
7+
| local_anonymous.kt:17:23:17:49 | ...->... | local_anonymous.kt:17:23:17:49 | new Function2<Integer,Integer,Integer>(...) { ... } | anonymous | not local |
8+
memberRefs
9+
| local_anonymous.kt:21:21:21:31 | ...::... | local_anonymous.kt:21:21:21:31 | new Function0<Unit>(...) { ... } | anonymous | not local |
10+
localClasses
11+
| local_anonymous.kt:25:9:25:27 | LocalClass | not anonymous | local |

0 commit comments

Comments
 (0)