unique aggregate in Node::getEnclosingCallable()
I noticed while running tuple stats on JDK that the functionality of `Node::getEnclosingCallable()`
is not know to the QL compiler (possibly because it is defined recursively).
Here is an example pipeline before:
```
[2020-08-18 14:45:03] (29s) Starting to evaluate predicate DataFlowImpl::flowFwdIn#ffffffff#cur_delta/8[93]@efe539 (iteration 93)
[2020-08-18 14:45:04] (30s) Tuple counts for DataFlowImpl::flowFwdIn#ffffffff#cur_delta:
4034 ~4% {6} r1 = SCAN DataFlowImpl::flowFwd#ffffff#prev_delta AS I OUTPUT I.<0>, I.<5>, I.<1>, I.<2>, I.<3>, I.<4>
11410 ~4% {7} r2 = JOIN r1 WITH DataFlowImpl::flowIntoCallNodeCand2#ffffff_1502#join_rhs AS R ON FIRST 2 OUTPUT r1.<5>, r1.<2>, r1.<3>, r1.<4>, r1.<1>, R.<2>, R.<3>
11095 ~2% {7} r3 = JOIN r2 WITH DataFlowImpl::TNil#ff_1#join_rhs AS R ON FIRST 1 OUTPUT r2.<1>, r2.<2>, r2.<3>, r2.<0>, r2.<4>, r2.<5>, r2.<6>
11661 ~0% {10} r4 = JOIN r1 WITH DataFlowImpl::flowIntoCallNodeCand2#ffffff_150234#join_rhs AS R ON FIRST 2 OUTPUT r1.<0>, r1.<2>, r1.<3>, r1.<4>, r1.<5>, r1.<1>, R.<2>, R.<3>, R.<4>, R.<5>
1489 ~0% {10} r5 = SELECT r4 ON r4.<9> = true
1489 ~16% {7} r6 = SCAN r5 OUTPUT r5.<1>, r5.<2>, r5.<3>, r5.<4>, r5.<5>, r5.<6>, r5.<7>
12584 ~14% {7} r7 = r3 \/ r6
4966 ~6% {8} r8 = JOIN r7 WITH DataFlowImplCommon::Cached::TSpecificCall#ff_10#join_rhs AS R ON FIRST 1 OUTPUT r7.<5>, R.<1>, r7.<0>, r7.<1>, r7.<2>, r7.<3>, r7.<4>, r7.<6>
1115 ~6% {8} r9 = JOIN r8 WITH DataFlowImplCommon::Cached::DispatchWithCallContext::reducedViableImplInCallContext#fff_02#join_rhs AS R ON FIRST 2 OUTPUT r8.<0>, r8.<1>, r8.<2>, r8.<3>, r8.<4>, r8.<5>, r8.<6>, r8.<7>
1652 ~11% {8} r10 = JOIN r9 WITH DataFlowImplCommon::Cached::DispatchWithCallContext::prunedViableImplInCallContext#fff@staged_ext AS R ON FIRST 2 OUTPUT r9.<7>, R.<2>, r9.<2>, r9.<3>, r9.<4>, r9.<5>, r9.<6>, r9.<0>
4966 ~0% {8} r11 = JOIN r7 WITH DataFlowImplCommon::Cached::TSpecificCall#ff_10#join_rhs AS R ON FIRST 1 OUTPUT r7.<0>, r7.<1>, r7.<2>, r7.<3>, r7.<4>, r7.<5>, r7.<6>, R.<1>
3851 ~0% {8} r12 = r11 AND NOT DataFlowImplCommon::Cached::DispatchWithCallContext::reducedViableImplInCallContext#fff_02#join_rhs AS R(r11.<5>, r11.<7>)
3851 ~7% {7} r13 = SCAN r12 OUTPUT r12.<5>, r12.<0>, r12.<1>, r12.<2>, r12.<3>, r12.<4>, r12.<6>
3763916 ~0% {8} r14 = JOIN r13 WITH VirtualDispatch::viableCallable#ff AS R ON FIRST 1 OUTPUT r13.<6>, R.<1>, r13.<1>, r13.<2>, r13.<3>, r13.<4>, r13.<5>, r13.<0>
3765568 ~0% {8} r15 = r10 \/ r14
4604 ~20% {7} r16 = JOIN r7 WITH DataFlowImplCommon::Cached::TSomeCall#f@staged_ext AS R ON FIRST 1 OUTPUT r7.<5>, r7.<0>, r7.<1>, r7.<2>, r7.<3>, r7.<4>, r7.<6>
1383356 ~0% {8} r17 = JOIN r16 WITH VirtualDispatch::viableCallable#ff AS R ON FIRST 1 OUTPUT r16.<6>, R.<1>, r16.<1>, r16.<2>, r16.<3>, r16.<4>, r16.<5>, r16.<0>
5148924 ~0% {8} r18 = r15 \/ r17
1076 ~20% {7} r19 = JOIN r7 WITH DataFlowImplCommon::Cached::TAnyCallContext#f@staged_ext AS R ON FIRST 1 OUTPUT r7.<5>, r7.<0>, r7.<1>, r7.<2>, r7.<3>, r7.<4>, r7.<6>
660959 ~3% {8} r20 = JOIN r19 WITH VirtualDispatch::viableCallable#ff AS R ON FIRST 1 OUTPUT r19.<6>, R.<1>, r19.<1>, r19.<2>, r19.<3>, r19.<4>, r19.<5>, r19.<0>
5809883 ~0% {8} r21 = r18 \/ r20
1938 ~2% {7} r22 = JOIN r7 WITH DataFlowImplCommon::Cached::TReturn#fff_2#join_rhs AS R ON FIRST 1 OUTPUT r7.<5>, r7.<0>, r7.<1>, r7.<2>, r7.<3>, r7.<4>, r7.<6>
1184996 ~5% {8} r23 = JOIN r22 WITH VirtualDispatch::viableCallable#ff AS R ON FIRST 1 OUTPUT r22.<6>, R.<1>, r22.<1>, r22.<2>, r22.<3>, r22.<4>, r22.<5>, r22.<0>
6994879 ~0% {8} r24 = r21 \/ r23
11590 ~18% {8} r25 = JOIN r24 WITH DataFlowUtil::Node::getEnclosingCallable#ff AS R ON FIRST 2 OUTPUT r24.<0>, r24.<2>, r24.<3>, r24.<4>, r24.<5>, r24.<6>, r24.<7>, r24.<1>
11378 ~10% {9} r26 = JOIN r25 WITH project#DataFlowImpl::flowCand#fffff#10 AS R ON FIRST 1 OUTPUT r25.<1>, r25.<2>, r25.<3>, r25.<4>, r25.<5>, r25.<6>, r25.<0>, r25.<7>, R.<1>
11378 ~10% {9} r27 = SELECT r26 ON r26.<8> >= r26.<4>
11378 ~10% {9} r28 = SELECT r27 ON r27.<8> <= r27.<4>
11378 ~13% {8} r29 = SCAN r28 OUTPUT r28.<5>, r28.<7>, r28.<0>, r28.<1>, r28.<2>, r28.<3>, r28.<4>, r28.<6>
149 ~43% {7} r30 = JOIN r29 WITH DataFlowImplCommon::Cached::recordDataFlowCallSite#ff@staged_ext AS R ON FIRST 2 OUTPUT r29.<0>, r29.<2>, r29.<3>, r29.<4>, r29.<5>, r29.<6>, r29.<7>
149 ~45% {8} r31 = JOIN r30 WITH DataFlowImplCommon::Cached::TSpecificCall#ff@staged_ext AS R ON FIRST 1 OUTPUT r30.<1>, r30.<2>, r30.<3>, r30.<4>, r30.<5>, r30.<0>, r30.<6>, R.<1>
11378 ~10% {8} r32 = SCAN r28 OUTPUT r28.<0>, r28.<1>, r28.<2>, r28.<3>, r28.<4>, r28.<5>, r28.<6>, r28.<7>
11229 ~9% {8} r33 = r32 AND NOT DataFlowImplCommon::Cached::recordDataFlowCallSite#ff@staged_ext AS R(r32.<5>, r32.<7>)
11229 ~17% {7} r34 = SCAN r33 OUTPUT r33.<0>, r33.<1>, r33.<2>, r33.<3>, r33.<4>, r33.<5>, r33.<6>
11229 ~11% {8} r35 = JOIN r34 WITH DataFlowImplCommon::Cached::TSomeCall#f@staged_ext AS R CARTESIAN PRODUCT OUTPUT r34.<0>, r34.<1>, r34.<2>, r34.<3>, r34.<4>, r34.<5>, r34.<6>, R.<0>
11378 ~11% {8} r36 = r31 \/ r35
11378 ~11% {8} r37 = r36 AND NOT DataFlowImpl::flowFwdIn#ffffffff#prev AS R(r36.<5>, r36.<6>, r36.<0>, r36.<7>, r36.<1>, r36.<2>, r36.<3>, r36.<4>)
11378 ~9% {8} r38 = SCAN r37 OUTPUT r37.<5>, r37.<6>, r37.<0>, r37.<7>, r37.<1>, r37.<2>, r37.<3>, r37.<4>
return r38
```
And after:
```
[2020-08-18 15:02:55] (121s) Starting to evaluate predicate DataFlowImpl::flowFwdIn#ffffffff#cur_delta/8[93]@5ed760 (iteration 93)
[2020-08-18 15:02:55] (121s) Tuple counts for DataFlowImpl::flowFwdIn#ffffffff#cur_delta:
3918 ~2% {6} r1 = SCAN DataFlowImpl::flowFwd#ffffff#prev_delta AS I OUTPUT I.<0>, I.<5>, I.<1>, I.<2>, I.<3>, I.<4>
16820 ~0% {7} r2 = JOIN r1 WITH DataFlowImpl::flowIntoCallNodeCand2#fffff_1402#join_rhs AS R ON FIRST 2 OUTPUT r1.<5>, r1.<2>, r1.<3>, r1.<4>, r1.<1>, R.<2>, R.<3>
16525 ~1% {7} r3 = JOIN r2 WITH DataFlowImpl::TNil#ff_1#join_rhs AS R ON FIRST 1 OUTPUT r2.<6>, r2.<1>, r2.<2>, r2.<3>, r2.<0>, r2.<4>, r2.<5>
16820 ~0% {9} r4 = JOIN r1 WITH DataFlowImpl::flowIntoCallNodeCand2#fffff_14023#join_rhs AS R ON FIRST 2 OUTPUT r1.<0>, r1.<2>, r1.<3>, r1.<4>, r1.<5>, r1.<1>, R.<2>, R.<3>, R.<4>
1211 ~0% {9} r5 = SELECT r4 ON r4.<8> = true
1211 ~0% {7} r6 = SCAN r5 OUTPUT r5.<7>, r5.<1>, r5.<2>, r5.<3>, r5.<4>, r5.<5>, r5.<6>
17736 ~6% {7} r7 = r3 \/ r6
17736 ~4% {8} r8 = JOIN r7 WITH DataFlowUtil::Node::getEnclosingCallable_dispred#ff AS R ON FIRST 1 OUTPUT r7.<1>, r7.<2>, r7.<3>, r7.<4>, r7.<5>, r7.<6>, r7.<0>, R.<1>
6757 ~3% {9} r9 = JOIN r8 WITH DataFlowImplCommon::Cached::TSpecificCall#ff_10#join_rhs AS R ON FIRST 1 OUTPUT r8.<5>, R.<1>, r8.<7>, r8.<0>, r8.<1>, r8.<2>, r8.<3>, r8.<4>, r8.<6>
112 ~62% {9} r10 = JOIN r9 WITH DataFlowImplCommon::Cached::DispatchWithCallContext::prunedViableImplInCallContext#fff@staged_ext AS R ON FIRST 3 OUTPUT r9.<0>, r9.<1>, r9.<3>, r9.<4>, r9.<5>, r9.<6>, r9.<7>, r9.<8>, r9.<2>
112 ~62% {8} r11 = JOIN r10 WITH DataFlowImplCommon::Cached::DispatchWithCallContext::reducedViableImplInCallContext#fff_02#join_rhs AS R ON FIRST 2 OUTPUT r10.<7>, r10.<2>, r10.<3>, r10.<4>, r10.<5>, r10.<6>, r10.<0>, r10.<8>
6757 ~0% {9} r12 = JOIN r8 WITH DataFlowImplCommon::Cached::TSpecificCall#ff_10#join_rhs AS R ON FIRST 1 OUTPUT r8.<5>, r8.<7>, r8.<0>, r8.<1>, r8.<2>, r8.<3>, r8.<4>, r8.<6>, R.<1>
6757 ~0% {9} r13 = JOIN r12 WITH VirtualDispatch::viableCallable#ff AS R ON FIRST 2 OUTPUT r12.<2>, r12.<3>, r12.<4>, r12.<5>, r12.<6>, r12.<0>, r12.<7>, r12.<1>, r12.<8>
4945 ~0% {9} r14 = r13 AND NOT DataFlowImplCommon::Cached::DispatchWithCallContext::reducedViableImplInCallContext#fff_02#join_rhs AS R(r13.<5>, r13.<8>)
4945 ~4% {8} r15 = SCAN r14 OUTPUT r14.<6>, r14.<0>, r14.<1>, r14.<2>, r14.<3>, r14.<4>, r14.<5>, r14.<7>
5057 ~5% {8} r16 = r11 \/ r15
7628 ~12% {8} r17 = JOIN r8 WITH DataFlowImplCommon::Cached::TSomeCall#f@staged_ext AS R ON FIRST 1 OUTPUT r8.<5>, r8.<7>, r8.<0>, r8.<1>, r8.<2>, r8.<3>, r8.<4>, r8.<6>
7628 ~9% {8} r18 = JOIN r17 WITH VirtualDispatch::viableCallable#ff AS R ON FIRST 2 OUTPUT r17.<7>, r17.<2>, r17.<3>, r17.<4>, r17.<5>, r17.<6>, r17.<0>, r17.<1>
12685 ~14% {8} r19 = r16 \/ r18
1411 ~10% {8} r20 = JOIN r8 WITH DataFlowImplCommon::Cached::TAnyCallContext#f@staged_ext AS R ON FIRST 1 OUTPUT r8.<5>, r8.<7>, r8.<0>, r8.<1>, r8.<2>, r8.<3>, r8.<4>, r8.<6>
1411 ~11% {8} r21 = JOIN r20 WITH VirtualDispatch::viableCallable#ff AS R ON FIRST 2 OUTPUT r20.<7>, r20.<2>, r20.<3>, r20.<4>, r20.<5>, r20.<6>, r20.<0>, r20.<1>
14096 ~14% {8} r22 = r19 \/ r21
17736 ~10% {8} r23 = JOIN r7 WITH DataFlowUtil::Node::getEnclosingCallable_dispred#ff AS R ON FIRST 1 OUTPUT r7.<6>, R.<1>, r7.<1>, r7.<2>, r7.<3>, r7.<4>, r7.<5>, r7.<0>
17736 ~4% {8} r24 = JOIN r23 WITH VirtualDispatch::viableCallable#ff AS R ON FIRST 2 OUTPUT r23.<2>, r23.<3>, r23.<4>, r23.<5>, r23.<6>, r23.<0>, r23.<7>, r23.<1>
1940 ~0% {8} r25 = JOIN r24 WITH DataFlowImplCommon::Cached::TReturn#fff_2#join_rhs AS R ON FIRST 1 OUTPUT r24.<6>, r24.<0>, r24.<1>, r24.<2>, r24.<3>, r24.<4>, r24.<5>, r24.<7>
16036 ~13% {8} r26 = r22 \/ r25
14256 ~8% {9} r27 = JOIN r26 WITH project#DataFlowImpl::flowCand#fffff#10 AS R ON FIRST 1 OUTPUT r26.<1>, r26.<2>, r26.<3>, r26.<4>, r26.<5>, r26.<6>, r26.<0>, r26.<7>, R.<1>
14256 ~8% {9} r28 = SELECT r27 ON r27.<8> >= r27.<4>
14256 ~8% {9} r29 = SELECT r28 ON r28.<8> <= r28.<4>
14256 ~9% {8} r30 = SCAN r29 OUTPUT r29.<5>, r29.<7>, r29.<0>, r29.<1>, r29.<2>, r29.<3>, r29.<4>, r29.<6>
122 ~28% {7} r31 = JOIN r30 WITH DataFlowImplCommon::Cached::recordDataFlowCallSite#ff@staged_ext AS R ON FIRST 2 OUTPUT r30.<0>, r30.<2>, r30.<3>, r30.<4>, r30.<5>, r30.<6>, r30.<7>
122 ~30% {8} r32 = JOIN r31 WITH DataFlowImplCommon::Cached::TSpecificCall#ff@staged_ext AS R ON FIRST 1 OUTPUT r31.<1>, r31.<2>, r31.<3>, r31.<4>, r31.<5>, r31.<0>, r31.<6>, R.<1>
14256 ~3% {8} r33 = SCAN r29 OUTPUT r29.<0>, r29.<1>, r29.<2>, r29.<3>, r29.<4>, r29.<5>, r29.<6>, r29.<7>
14134 ~3% {8} r34 = r33 AND NOT DataFlowImplCommon::Cached::recordDataFlowCallSite#ff@staged_ext AS R(r33.<5>, r33.<7>)
14134 ~12% {7} r35 = SCAN r34 OUTPUT r34.<0>, r34.<1>, r34.<2>, r34.<3>, r34.<4>, r34.<5>, r34.<6>
14134 ~7% {8} r36 = JOIN r35 WITH DataFlowImplCommon::Cached::TSomeCall#f@staged_ext AS R CARTESIAN PRODUCT OUTPUT r35.<0>, r35.<1>, r35.<2>, r35.<3>, r35.<4>, r35.<5>, r35.<6>, R.<0>
14256 ~7% {8} r37 = r32 \/ r36
14256 ~7% {8} r38 = r37 AND NOT DataFlowImpl::flowFwdIn#ffffffff#prev AS R(r37.<5>, r37.<6>, r37.<0>, r37.<7>, r37.<1>, r37.<2>, r37.<3>, r37.<4>)
14256 ~9% {8} r39 = SCAN r38 OUTPUT r38.<5>, r38.<6>, r38.<0>, r38.<7>, r38.<1>, r38.<2>, r38.<3>, r38.<4>
return r39
```
CodeQL
This open source repository contains the standard CodeQL libraries and queries that power LGTM and the other CodeQL products that GitHub makes available to its customers worldwide. For the queries, libraries, and extractor that power Go analysis, visit the CodeQL for Go repository.
How do I learn CodeQL and run queries?
There is extensive documentation on getting started with writing CodeQL. You can use the interactive query console on LGTM.com or the CodeQL for Visual Studio Code extension to try out your queries on any open source project that's currently being analyzed.
Contributing
We welcome contributions to our standard library and standard checks. Do you have an idea for a new check, or how to improve an existing query? Then please go ahead and open a pull request! Before you do, though, please take the time to read our contributing guidelines. You can also consult our style guides to learn how to format your code for consistency and clarity, how to write query metadata, and how to write query help documentation for your query.
License
The code in this repository is licensed under the MIT License by GitHub.
Visual Studio Code integration
If you use Visual Studio Code to work in this repository, there are a few integration features to make development easier.
CodeQL for Visual Studio Code
You can install the CodeQL for Visual Studio Code extension to get syntax highlighting, IntelliSense, and code navigation for the QL language, as well as unit test support for testing CodeQL libraries and queries.
Tasks
The .vscode/tasks.json file defines custom tasks specific to working in this repository. To invoke one of these tasks, select the Terminal | Run Task... menu option, and then select the desired task from the dropdown. You can also invoke the Tasks: Run Task command from the command palette.