circle-ir 4.16.1 → 4.18.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/analysis/advisories.d.ts +186 -0
- package/dist/analysis/advisories.d.ts.map +1 -0
- package/dist/analysis/advisories.js +391 -0
- package/dist/analysis/advisories.js.map +1 -0
- package/dist/analysis/comment-lines.d.ts +14 -0
- package/dist/analysis/comment-lines.d.ts.map +1 -0
- package/dist/analysis/comment-lines.js +34 -0
- package/dist/analysis/comment-lines.js.map +1 -0
- package/dist/analysis/config-loader.d.ts.map +1 -1
- package/dist/analysis/config-loader.js +59 -5
- package/dist/analysis/config-loader.js.map +1 -1
- package/dist/analysis/constant-caller-gate.d.ts +2 -2
- package/dist/analysis/constant-caller-gate.d.ts.map +1 -1
- package/dist/analysis/constant-caller-gate.js +205 -29
- package/dist/analysis/constant-caller-gate.js.map +1 -1
- package/dist/analysis/constant-propagation/index.d.ts +2 -0
- package/dist/analysis/constant-propagation/index.d.ts.map +1 -1
- package/dist/analysis/constant-propagation/index.js +10 -0
- package/dist/analysis/constant-propagation/index.js.map +1 -1
- package/dist/analysis/constant-propagation/propagator.d.ts +15 -0
- package/dist/analysis/constant-propagation/propagator.d.ts.map +1 -1
- package/dist/analysis/constant-propagation/propagator.js +224 -20
- package/dist/analysis/constant-propagation/propagator.js.map +1 -1
- package/dist/analysis/constant-propagation/types.d.ts +2 -0
- package/dist/analysis/constant-propagation/types.d.ts.map +1 -1
- package/dist/analysis/constant-propagation.d.ts +1 -1
- package/dist/analysis/constant-propagation.d.ts.map +1 -1
- package/dist/analysis/constant-propagation.js +1 -1
- package/dist/analysis/constant-propagation.js.map +1 -1
- package/dist/analysis/entry-point-detection.d.ts.map +1 -1
- package/dist/analysis/entry-point-detection.js +72 -0
- package/dist/analysis/entry-point-detection.js.map +1 -1
- package/dist/analysis/interprocedural.d.ts.map +1 -1
- package/dist/analysis/interprocedural.js +75 -8
- package/dist/analysis/interprocedural.js.map +1 -1
- package/dist/analysis/maven-declared.d.ts +72 -0
- package/dist/analysis/maven-declared.d.ts.map +1 -0
- package/dist/analysis/maven-declared.js +216 -0
- package/dist/analysis/maven-declared.js.map +1 -0
- package/dist/analysis/maven-version.d.ts +28 -0
- package/dist/analysis/maven-version.d.ts.map +1 -0
- package/dist/analysis/maven-version.js +172 -0
- package/dist/analysis/maven-version.js.map +1 -0
- package/dist/analysis/passes/constant-propagation-pass.d.ts.map +1 -1
- package/dist/analysis/passes/constant-propagation-pass.js +29 -1
- package/dist/analysis/passes/constant-propagation-pass.js.map +1 -1
- package/dist/analysis/passes/cross-file-pass.d.ts.map +1 -1
- package/dist/analysis/passes/cross-file-pass.js +84 -2
- package/dist/analysis/passes/cross-file-pass.js.map +1 -1
- package/dist/analysis/passes/csharp-sanitizer-credit.d.ts +7 -0
- package/dist/analysis/passes/csharp-sanitizer-credit.d.ts.map +1 -1
- package/dist/analysis/passes/csharp-sanitizer-credit.js +44 -1
- package/dist/analysis/passes/csharp-sanitizer-credit.js.map +1 -1
- package/dist/analysis/passes/insecure-cookie-pass.d.ts +2 -0
- package/dist/analysis/passes/insecure-cookie-pass.d.ts.map +1 -1
- package/dist/analysis/passes/insecure-cookie-pass.js +25 -3
- package/dist/analysis/passes/insecure-cookie-pass.js.map +1 -1
- package/dist/analysis/passes/interprocedural-pass.d.ts +11 -14
- package/dist/analysis/passes/interprocedural-pass.d.ts.map +1 -1
- package/dist/analysis/passes/interprocedural-pass.js +562 -0
- package/dist/analysis/passes/interprocedural-pass.js.map +1 -1
- package/dist/analysis/passes/language-sources-pass.d.ts +18 -1
- package/dist/analysis/passes/language-sources-pass.d.ts.map +1 -1
- package/dist/analysis/passes/language-sources-pass.js +1079 -14
- package/dist/analysis/passes/language-sources-pass.js.map +1 -1
- package/dist/analysis/passes/param-source-flow-gate-pass.d.ts.map +1 -1
- package/dist/analysis/passes/param-source-flow-gate-pass.js +82 -3
- package/dist/analysis/passes/param-source-flow-gate-pass.js.map +1 -1
- package/dist/analysis/passes/sink-filter-pass.d.ts +44 -2
- package/dist/analysis/passes/sink-filter-pass.d.ts.map +1 -1
- package/dist/analysis/passes/sink-filter-pass.js +690 -12
- package/dist/analysis/passes/sink-filter-pass.js.map +1 -1
- package/dist/analysis/passes/taint-propagation-pass.d.ts.map +1 -1
- package/dist/analysis/passes/taint-propagation-pass.js +298 -19
- package/dist/analysis/passes/taint-propagation-pass.js.map +1 -1
- package/dist/analysis/passes/tls-verify-disabled-pass.d.ts +18 -0
- package/dist/analysis/passes/tls-verify-disabled-pass.d.ts.map +1 -1
- package/dist/analysis/passes/tls-verify-disabled-pass.js +161 -0
- package/dist/analysis/passes/tls-verify-disabled-pass.js.map +1 -1
- package/dist/analysis/passes/weak-random-pass.d.ts +6 -0
- package/dist/analysis/passes/weak-random-pass.d.ts.map +1 -1
- package/dist/analysis/passes/weak-random-pass.js +29 -0
- package/dist/analysis/passes/weak-random-pass.js.map +1 -1
- package/dist/analysis/promote-cross-file-flows.d.ts +17 -0
- package/dist/analysis/promote-cross-file-flows.d.ts.map +1 -0
- package/dist/analysis/promote-cross-file-flows.js +32 -0
- package/dist/analysis/promote-cross-file-flows.js.map +1 -0
- package/dist/analysis/rust-literal-guard.d.ts.map +1 -1
- package/dist/analysis/rust-literal-guard.js +100 -1
- package/dist/analysis/rust-literal-guard.js.map +1 -1
- package/dist/analysis/sbom.d.ts +100 -0
- package/dist/analysis/sbom.d.ts.map +1 -1
- package/dist/analysis/sbom.js +514 -3
- package/dist/analysis/sbom.js.map +1 -1
- package/dist/analysis/semver-version.d.ts +30 -0
- package/dist/analysis/semver-version.d.ts.map +1 -0
- package/dist/analysis/semver-version.js +76 -0
- package/dist/analysis/semver-version.js.map +1 -0
- package/dist/analysis/taint-matcher.d.ts +5 -0
- package/dist/analysis/taint-matcher.d.ts.map +1 -1
- package/dist/analysis/taint-matcher.js +226 -4
- package/dist/analysis/taint-matcher.js.map +1 -1
- package/dist/analyzer.d.ts +57 -0
- package/dist/analyzer.d.ts.map +1 -1
- package/dist/analyzer.js +69 -6
- package/dist/analyzer.js.map +1 -1
- package/dist/browser/circle-ir.js +3360 -314
- package/dist/core/circle-ir-core.cjs +783 -220
- package/dist/core/circle-ir-core.js +783 -220
- package/dist/core/extractors/dfg.js +205 -2
- package/dist/core/extractors/dfg.js.map +1 -1
- package/dist/core/extractors/ts-declaration-detail.d.ts +39 -0
- package/dist/core/extractors/ts-declaration-detail.d.ts.map +1 -0
- package/dist/core/extractors/ts-declaration-detail.js +266 -0
- package/dist/core/extractors/ts-declaration-detail.js.map +1 -0
- package/dist/core/extractors/types.js +53 -9
- package/dist/core/extractors/types.js.map +1 -1
- package/dist/graph/analysis-pass.d.ts +4 -1
- package/dist/graph/analysis-pass.d.ts.map +1 -1
- package/dist/graph/analysis-pass.js +4 -1
- package/dist/graph/analysis-pass.js.map +1 -1
- package/dist/graph-facts/dead-code.d.ts +62 -0
- package/dist/graph-facts/dead-code.d.ts.map +1 -0
- package/dist/graph-facts/dead-code.js +90 -0
- package/dist/graph-facts/dead-code.js.map +1 -0
- package/dist/graph-facts/dependency-calls.d.ts +86 -0
- package/dist/graph-facts/dependency-calls.d.ts.map +1 -0
- package/dist/graph-facts/dependency-calls.js +93 -0
- package/dist/graph-facts/dependency-calls.js.map +1 -0
- package/dist/graph-facts/index.d.ts +10 -0
- package/dist/graph-facts/index.d.ts.map +1 -0
- package/dist/graph-facts/index.js +10 -0
- package/dist/graph-facts/index.js.map +1 -0
- package/dist/graph-facts/maven-packages.d.ts +42 -0
- package/dist/graph-facts/maven-packages.d.ts.map +1 -0
- package/dist/graph-facts/maven-packages.js +133 -0
- package/dist/graph-facts/maven-packages.js.map +1 -0
- package/dist/graph-facts/reach.d.ts +203 -0
- package/dist/graph-facts/reach.d.ts.map +1 -0
- package/dist/graph-facts/reach.js +219 -0
- package/dist/graph-facts/reach.js.map +1 -0
- package/dist/graph-facts/removal-reach.d.ts +73 -0
- package/dist/graph-facts/removal-reach.d.ts.map +1 -0
- package/dist/graph-facts/removal-reach.js +64 -0
- package/dist/graph-facts/removal-reach.js.map +1 -0
- package/dist/index.d.ts +21 -6
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +20 -3
- package/dist/index.js.map +1 -1
- package/dist/navigation/go-graph.d.ts +68 -0
- package/dist/navigation/go-graph.d.ts.map +1 -0
- package/dist/navigation/go-graph.js +753 -0
- package/dist/navigation/go-graph.js.map +1 -0
- package/dist/navigation/index.d.ts +7 -1
- package/dist/navigation/index.d.ts.map +1 -1
- package/dist/navigation/index.js +6 -0
- package/dist/navigation/index.js.map +1 -1
- package/dist/navigation/java-entry-tables.d.ts +43 -0
- package/dist/navigation/java-entry-tables.d.ts.map +1 -0
- package/dist/navigation/java-entry-tables.js +56 -0
- package/dist/navigation/java-entry-tables.js.map +1 -0
- package/dist/navigation/java-graph.d.ts +64 -0
- package/dist/navigation/java-graph.d.ts.map +1 -0
- package/dist/navigation/java-graph.js +466 -0
- package/dist/navigation/java-graph.js.map +1 -0
- package/dist/navigation/navigation-index.d.ts +91 -2
- package/dist/navigation/navigation-index.d.ts.map +1 -1
- package/dist/navigation/navigation-index.js +372 -45
- package/dist/navigation/navigation-index.js.map +1 -1
- package/dist/navigation/python-graph.d.ts +73 -0
- package/dist/navigation/python-graph.d.ts.map +1 -0
- package/dist/navigation/python-graph.js +867 -0
- package/dist/navigation/python-graph.js.map +1 -0
- package/dist/navigation/ts-call-edges.d.ts +193 -0
- package/dist/navigation/ts-call-edges.d.ts.map +1 -0
- package/dist/navigation/ts-call-edges.js +2089 -0
- package/dist/navigation/ts-call-edges.js.map +1 -0
- package/dist/navigation/ts-entry-tables.d.ts +88 -0
- package/dist/navigation/ts-entry-tables.d.ts.map +1 -0
- package/dist/navigation/ts-entry-tables.js +50 -0
- package/dist/navigation/ts-entry-tables.js.map +1 -0
- package/dist/path-set/branches.d.ts +52 -0
- package/dist/path-set/branches.d.ts.map +1 -0
- package/dist/path-set/branches.js +124 -0
- package/dist/path-set/branches.js.map +1 -0
- package/dist/path-set/finding-diff.d.ts +63 -0
- package/dist/path-set/finding-diff.d.ts.map +1 -0
- package/dist/path-set/finding-diff.js +150 -0
- package/dist/path-set/finding-diff.js.map +1 -0
- package/dist/path-set/index.d.ts +18 -0
- package/dist/path-set/index.d.ts.map +1 -0
- package/dist/path-set/index.js +12 -0
- package/dist/path-set/index.js.map +1 -0
- package/dist/path-set/line-diff.d.ts +19 -0
- package/dist/path-set/line-diff.d.ts.map +1 -0
- package/dist/path-set/line-diff.js +98 -0
- package/dist/path-set/line-diff.js.map +1 -0
- package/dist/path-set/path-set.d.ts +88 -0
- package/dist/path-set/path-set.d.ts.map +1 -0
- package/dist/path-set/path-set.js +716 -0
- package/dist/path-set/path-set.js.map +1 -0
- package/dist/path-set/templates.d.ts +42 -0
- package/dist/path-set/templates.d.ts.map +1 -0
- package/dist/path-set/templates.js +119 -0
- package/dist/path-set/templates.js.map +1 -0
- package/dist/path-set/types.d.ts +195 -0
- package/dist/path-set/types.d.ts.map +1 -0
- package/dist/path-set/types.js +8 -0
- package/dist/path-set/types.js.map +1 -0
- package/dist/remedy-class/index.d.ts +12 -0
- package/dist/remedy-class/index.d.ts.map +1 -0
- package/dist/remedy-class/index.js +9 -0
- package/dist/remedy-class/index.js.map +1 -0
- package/dist/remedy-class/match.d.ts +165 -0
- package/dist/remedy-class/match.d.ts.map +1 -0
- package/dist/remedy-class/match.js +705 -0
- package/dist/remedy-class/match.js.map +1 -0
- package/dist/remedy-class/output-context.d.ts +25 -0
- package/dist/remedy-class/output-context.d.ts.map +1 -0
- package/dist/remedy-class/output-context.js +150 -0
- package/dist/remedy-class/output-context.js.map +1 -0
- package/dist/remedy-class/sha256.d.ts +18 -0
- package/dist/remedy-class/sha256.d.ts.map +1 -0
- package/dist/remedy-class/sha256.js +89 -0
- package/dist/remedy-class/sha256.js.map +1 -0
- package/dist/remedy-class/table.d.ts +130 -0
- package/dist/remedy-class/table.d.ts.map +1 -0
- package/dist/remedy-class/table.js +457 -0
- package/dist/remedy-class/table.js.map +1 -0
- package/dist/resolution/cross-file.d.ts +18 -0
- package/dist/resolution/cross-file.d.ts.map +1 -1
- package/dist/resolution/cross-file.js +194 -5
- package/dist/resolution/cross-file.js.map +1 -1
- package/dist/stable-ids/builder.d.ts +20 -0
- package/dist/stable-ids/builder.d.ts.map +1 -0
- package/dist/stable-ids/builder.js +65 -0
- package/dist/stable-ids/builder.js.map +1 -0
- package/dist/stable-ids/diff.d.ts +18 -0
- package/dist/stable-ids/diff.d.ts.map +1 -0
- package/dist/stable-ids/diff.js +37 -0
- package/dist/stable-ids/diff.js.map +1 -0
- package/dist/stable-ids/go.d.ts +28 -0
- package/dist/stable-ids/go.d.ts.map +1 -0
- package/dist/stable-ids/go.js +160 -0
- package/dist/stable-ids/go.js.map +1 -0
- package/dist/stable-ids/hash.d.ts +22 -0
- package/dist/stable-ids/hash.d.ts.map +1 -0
- package/dist/stable-ids/hash.js +167 -0
- package/dist/stable-ids/hash.js.map +1 -0
- package/dist/stable-ids/index.d.ts +30 -0
- package/dist/stable-ids/index.d.ts.map +1 -0
- package/dist/stable-ids/index.js +59 -0
- package/dist/stable-ids/index.js.map +1 -0
- package/dist/stable-ids/java.d.ts +28 -0
- package/dist/stable-ids/java.d.ts.map +1 -0
- package/dist/stable-ids/java.js +224 -0
- package/dist/stable-ids/java.js.map +1 -0
- package/dist/stable-ids/moves.d.ts +87 -0
- package/dist/stable-ids/moves.d.ts.map +1 -0
- package/dist/stable-ids/moves.js +222 -0
- package/dist/stable-ids/moves.js.map +1 -0
- package/dist/stable-ids/nodes.d.ts +32 -0
- package/dist/stable-ids/nodes.d.ts.map +1 -0
- package/dist/stable-ids/nodes.js +92 -0
- package/dist/stable-ids/nodes.js.map +1 -0
- package/dist/stable-ids/normalize.d.ts +35 -0
- package/dist/stable-ids/normalize.d.ts.map +1 -0
- package/dist/stable-ids/normalize.js +174 -0
- package/dist/stable-ids/normalize.js.map +1 -0
- package/dist/stable-ids/parse-errors.d.ts +24 -0
- package/dist/stable-ids/parse-errors.d.ts.map +1 -0
- package/dist/stable-ids/parse-errors.js +46 -0
- package/dist/stable-ids/parse-errors.js.map +1 -0
- package/dist/stable-ids/python.d.ts +27 -0
- package/dist/stable-ids/python.d.ts.map +1 -0
- package/dist/stable-ids/python.js +212 -0
- package/dist/stable-ids/python.js.map +1 -0
- package/dist/stable-ids/ts-parse-errors.d.ts +27 -0
- package/dist/stable-ids/ts-parse-errors.d.ts.map +1 -0
- package/dist/stable-ids/ts-parse-errors.js +75 -0
- package/dist/stable-ids/ts-parse-errors.js.map +1 -0
- package/dist/stable-ids/types.d.ts +106 -0
- package/dist/stable-ids/types.d.ts.map +1 -0
- package/dist/stable-ids/types.js +16 -0
- package/dist/stable-ids/types.js.map +1 -0
- package/dist/stable-ids/typescript.d.ts +30 -0
- package/dist/stable-ids/typescript.d.ts.map +1 -0
- package/dist/stable-ids/typescript.js +362 -0
- package/dist/stable-ids/typescript.js.map +1 -0
- package/dist/types/config.d.ts +9 -0
- package/dist/types/config.d.ts.map +1 -1
- package/dist/types/index.d.ts +53 -0
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/index.js.map +1 -1
- package/package.json +3 -3
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"navigation-index.d.ts","sourceRoot":"","sources":["../../src/navigation/navigation-index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgDG;AAEH,OAAO,KAAK,EAAE,QAAQ,EAAoC,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AACvG,OAAO,KAAK,EAGV,gBAAgB,EAChB,KAAK,EACL,SAAS,EACT,YAAY,
|
|
1
|
+
{"version":3,"file":"navigation-index.d.ts","sourceRoot":"","sources":["../../src/navigation/navigation-index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgDG;AAEH,OAAO,KAAK,EAAE,QAAQ,EAAoC,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AACvG,OAAO,KAAK,EAGV,gBAAgB,EAChB,KAAK,EACL,SAAS,EACT,YAAY,EAEZ,IAAI,EAEJ,gBAAgB,EACjB,MAAM,YAAY,CAAC;AAEpB,2FAA2F;AAC3F,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,iBAAiB,CAAC;IAC5B,EAAE,EAAE,QAAQ,CAAC;IACb,mEAAmE;IACnE,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB;;;OAGG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,YAAY;IAC3B;;;;;OAKG;IACH,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,uFAAuF;IACvF,QAAQ,CAAC,EAAE,KAAK,CAAC;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IACtD,8EAA8E;IAC9E,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AA0FD,wEAAwE;AACxE,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,iFAAiF;IACjF,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,GAAG,EAAE,MAAM,CAAC;IACZ,yEAAyE;IACzE,IAAI,CAAC,EAAE,IAAI,CAAC;CACb;AAED,iDAAiD;AACjD,MAAM,MAAM,eAAe,GACvB;IAAE,IAAI,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,GAAG,EAAE,MAAM,CAAA;KAAE,CAAC;IAAC,UAAU,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,OAAO,CAAC;IAAC,IAAI,EAAE,IAAI,CAAC;IAAC,SAAS,EAAE,aAAa,CAAC;IAAC,MAAM,EAAE,aAAa,EAAE,CAAA;CAAE,GACvJ;IACE,IAAI,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,GAAG,EAAE,MAAM,CAAA;KAAE,CAAC;IAClD,UAAU,EAAE,MAAM,CAAC;IACnB,IAAI,EAAE,YAAY,CAAC;IACnB,MAAM,EAAE,gBAAgB,CAAC;IACzB,0HAA0H;IAC1H,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB,CAAC;AAoKN,wBAAgB,oBAAoB,CAClC,KAAK,EAAE,cAAc,EAAE,EACvB,OAAO,GAAE,YAAiB,GACzB,eAAe,CAEjB;AAED,qBAAa,eAAe;IAC1B,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAiC;IACvD,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAiC;IAC5D,OAAO,CAAC,QAAQ,CAAC,iBAAiB,CAAmC;IACrE,yFAAyF;IACzF,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAqB;IACnD,4DAA4D;IAC5D,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAgB;IAChD,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAQ;IAC9B,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAS;IACjC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAS;IACjC,yCAAyC;IACzC,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAkC;IAC3D,mFAAmF;IACnF,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAuC;IAChE,4DAA4D;IAC5D,OAAO,CAAC,QAAQ,CAAC,OAAO,CAA8C;IAEtE,YAAY,KAAK,EAAE,cAAc,EAAE,EAAE,OAAO,EAAE,YAAY,EA4DzD;IAID;;;;;;;;;;;;OAYG;IACH,cAAc,CAAC,KAAK,EAAE,KAAK,EAAE,IAAI,GAAE,YAAiB,GAAG,gBAAgB,CA0HtE;IAED,uEAAuE;IACvE,cAAc,CAAC,KAAK,EAAE,KAAK,EAAE,IAAI,GAAE,YAAiB,GAAG,gBAAgB,CA8CtE;IAED;;;;;;;;;;;OAWG;IACH,SAAS,IAAI,eAAe,EAAE,CA8B7B;IAED,6HAA6H;IAC7H,OAAO,CAAC,aAAa;IAarB,OAAO,CAAC,QAAQ;IAQhB;;;;;;;;;;;;;;;OAeG;IACH,QAAQ,CACN,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,MAAM,EACZ,UAAU,EAAE,MAAM,EAClB,IAAI,EAAE,SAAS,GACd,MAAM,GAAG,SAAS,CAapB;IAID,wEAAwE;IACxE,OAAO,CAAC,YAAY;IASpB;;;;;;;;OAQG;IACH,OAAO,CAAC,QAAQ;IAUhB,OAAO,CAAC,YAAY;IAwEpB,uFAAuF;IACvF,OAAO,CAAC,UAAU;IA+BlB;;;;;;;;;;;;;;OAcG;IACH,OAAO,CAAC,OAAO;IA6Bf,2FAA2F;IAC3F,OAAO,CAAC,eAAe;IAqCvB;;;OAGG;IACH,OAAO,CAAC,gBAAgB;IAwBxB,8EAA8E;IAC9E,OAAO,CAAC,iBAAiB;IAKzB;;;;;;;;;;;OAWG;IACH,OAAO,CAAC,cAAc;IAsDtB,mFAAmF;IACnF,OAAO,CAAC,UAAU;IAmBlB,mFAAmF;IACnF,OAAO,CAAC,YAAY;IAQpB;;;OAGG;IACH,OAAO,CAAC,IAAI;IAgEZ,uFAAuF;IACvF,OAAO,CAAC,OAAO;IA2Cf,iDAAiD;IACjD,OAAO,CAAC,iBAAiB;IAKzB,2CAA2C;IAC3C,OAAO,CAAC,YAAY;IAIpB,8FAA8F;IAC9F,OAAO,CAAC,YAAY;IAiCpB,mEAAmE;IACnE,OAAO,CAAC,cAAc;IAStB;;;;;OAKG;IACH,OAAO,CAAC,YAAY;IA+BpB;;;OAGG;IACH,OAAO,CAAC,mBAAmB;IAwB3B;;;;;;;OAOG;IACH,OAAO,CAAC,UAAU;IA4ClB,6EAA6E;IAC7E,OAAO,CAAC,MAAM;IAad,8DAA8D;IAC9D,OAAO,CAAC,OAAO;IA0Bf,8EAA8E;IAC9E,OAAO,CAAC,gBAAgB;IAcxB,kEAAkE;IAClE,OAAO,CAAC,aAAa;IAKrB;;;;;;;;;;;OAWG;IACH,OAAO,CAAC,WAAW;IAyBnB,iGAAiG;IACjG,OAAO,CAAC,uBAAuB;IAoB/B,8EAA8E;IAC9E,OAAO,CAAC,SAAS;IAIjB;;;;;;OAMG;IACH,OAAO,CAAC,aAAa;IAcrB;;;OAGG;IACH,OAAO,CAAC,WAAW;IAcnB,8FAA8F;IAC9F,OAAO,CAAC,QAAQ;IAQhB,+FAA+F;IAC/F,OAAO,CAAC,WAAW;IAUnB,uFAAuF;IACvF,OAAO,CAAC,OAAO;IAaf;;;;OAIG;IACH,OAAO,CAAC,gBAAgB;IAsBxB,4EAA4E;IAC5E,OAAO,CAAC,cAAc;IAiCtB,kEAAkE;IAClE,OAAO,CAAC,SAAS;IAmBjB,yEAAyE;IACzE,OAAO,CAAC,aAAa;IAuBrB;;;;;;;OAOG;IACH,OAAO,CAAC,cAAc;IAqCtB;;;;;;;;OAQG;IACH,OAAO,CAAC,gBAAgB;IAkDxB;;;OAGG;IACH,OAAO,CAAC,YAAY;IAOpB,gEAAgE;IAChE,OAAO,CAAC,cAAc;IAiBtB,OAAO,CAAC,eAAe;IAIvB,iEAAiE;IACjE,OAAO,CAAC,eAAe;IASvB,6FAA6F;IAC7F,OAAO,CAAC,QAAQ;IAahB,uEAAuE;IACvE,OAAO,CAAC,sBAAsB;IAoB9B;;;;;;;;;;;;;OAaG;IACH,OAAO,CAAC,UAAU;IASlB;;;;;;;;;OASG;IACH,OAAO,CAAC,gBAAgB;IAkBxB,iFAAiF;IACjF,OAAO,CAAC,YAAY;IASpB,+EAA+E;IAC/E,OAAO,CAAC,iBAAiB;IAKzB,OAAO,CAAC,eAAe;IAsBvB;;;;;;;OAOG;IACH,OAAO,CAAC,SAAS;IAuCjB,oEAAoE;IACpE,OAAO,CAAC,gBAAgB;IA+BxB,2EAA2E;IAC3E,OAAO,CAAC,yBAAyB;IASjC,OAAO,CAAC,YAAY;IAIpB,OAAO,CAAC,MAAM;IAMd,2DAA2D;IAC3D,OAAO,CAAC,cAAc;IAQtB,OAAO,CAAC,WAAW;IAqBnB,OAAO,CAAC,MAAM;IAYd,OAAO,CAAC,MAAM;CA6Cf"}
|
|
@@ -56,6 +56,8 @@ const REFLECTIVE_METHODS = new Set([
|
|
|
56
56
|
'getDeclaredConstructor', 'newProxyInstance', 'getAnnotation',
|
|
57
57
|
'getAnnotationsByType', 'isAnnotationPresent', 'getGenericReturnType',
|
|
58
58
|
]);
|
|
59
|
+
/** What every class inherits from `java.lang.Object`. */
|
|
60
|
+
const OBJECT_METHODS = new Set(['toString', 'hashCode', 'equals', 'getClass', 'clone', 'finalize', 'notify', 'notifyAll', 'wait']);
|
|
59
61
|
const LOMBOK_ACCESSOR = new Set(['Getter', 'Setter', 'Data', 'Value']);
|
|
60
62
|
const LOMBOK_BUILDER = new Set(['Builder', 'SuperBuilder']);
|
|
61
63
|
const PRIMITIVES = new Set(['byte', 'short', 'char', 'int', 'long', 'float', 'double', 'boolean']);
|
|
@@ -114,7 +116,7 @@ const JAVA_LANG = new Set([
|
|
|
114
116
|
'Object', 'Number', 'Class', 'StringBuilder', 'CharSequence', 'Comparable', 'Iterable', 'Enum',
|
|
115
117
|
]);
|
|
116
118
|
/** Bumped when the shape of a cached per-file record changes. */
|
|
117
|
-
const CACHE_VERSION = 'nav-
|
|
119
|
+
const CACHE_VERSION = 'nav-4';
|
|
118
120
|
const fileCache = new Map();
|
|
119
121
|
export function buildNavigationIndex(files, options = {}) {
|
|
120
122
|
return new NavigationIndex(files, options);
|
|
@@ -231,6 +233,15 @@ export class NavigationIndex {
|
|
|
231
233
|
`declared: ${declared.map(o => `${q.base}${signatureOf(o)}`).join(', ')}`;
|
|
232
234
|
return this.finish('callers', query, answers, unresolved, t0, opts, extra);
|
|
233
235
|
}
|
|
236
|
+
if (target && declared.length === 0 && q.name !== '<init>' && this.visibleOverloads(target.fqn, q.name).length === 0) {
|
|
237
|
+
// `MapIterator.toString()`: the type is in the tree, the method is
|
|
238
|
+
// not — it is inherited from outside, so no call site can bind to the
|
|
239
|
+
// query's target, and "no callers" would read as a finding.
|
|
240
|
+
extra.note =
|
|
241
|
+
`${q.owner} declares no method ${q.name}, and no supertype in the searched tree does: it is inherited from ` +
|
|
242
|
+
`${OBJECT_METHODS.has(q.name) ? 'java.lang.Object' : 'a type outside the tree'}, so no call site here binds to ${q.base}. ` +
|
|
243
|
+
`A call reached only through string conversion or library code has no call site at all.`;
|
|
244
|
+
}
|
|
234
245
|
const wantedSet = new Set(wanted);
|
|
235
246
|
const dispatchOpen = target !== undefined && q.name !== '<init>' && wanted.some(o => this.dispatchIsOpen(target, o));
|
|
236
247
|
for (const rec of this.files.values()) {
|
|
@@ -371,6 +382,78 @@ export class NavigationIndex {
|
|
|
371
382
|
}
|
|
372
383
|
return this.finish('callees', query, answers, unresolved, t0, opts);
|
|
373
384
|
}
|
|
385
|
+
/**
|
|
386
|
+
* Every call site in the index, bound — the whole-program view of what
|
|
387
|
+
* `resolveCallees` answers one method at a time, with each target located
|
|
388
|
+
* by file and declaration line so a caller can key it to its own
|
|
389
|
+
* declaration ids. Additive: no query path changes.
|
|
390
|
+
*
|
|
391
|
+
* A `bound` site names the member its receiver's static type declares
|
|
392
|
+
* (`declaring`) and, on `polymorphic`, every body that could run
|
|
393
|
+
* (`bodies`, the overload with the declaring member's signature where it
|
|
394
|
+
* has one). Anything else is `unresolved` with the same reason a query
|
|
395
|
+
* would give.
|
|
396
|
+
*/
|
|
397
|
+
callSites() {
|
|
398
|
+
const out = [];
|
|
399
|
+
const files = [...this.files.values()].sort((a, b) => (a.path < b.path ? -1 : a.path > b.path ? 1 : 0));
|
|
400
|
+
for (const rec of files) {
|
|
401
|
+
for (const call of rec.calls) {
|
|
402
|
+
const site = { file: rec.path, line: call.location.line, col: call.location.column };
|
|
403
|
+
const b = this.bindCall(call, rec);
|
|
404
|
+
if (b?.kind === 'bound') {
|
|
405
|
+
const bodies = [];
|
|
406
|
+
if (b.result.tier === 'polymorphic') {
|
|
407
|
+
const sig = b.overload ? signatureOf(b.overload) : null;
|
|
408
|
+
for (const c of b.result.candidates ?? []) {
|
|
409
|
+
const dot = c.lastIndexOf('.');
|
|
410
|
+
const t = this.typesByFqn.get(c.slice(0, dot));
|
|
411
|
+
const name = c.slice(dot + 1);
|
|
412
|
+
if (!t)
|
|
413
|
+
continue;
|
|
414
|
+
const all = this.declaredOverloads(t, name);
|
|
415
|
+
const pick = sig ? all.filter(o => signatureOf(o) === sig) : all;
|
|
416
|
+
for (const o of pick.length > 0 ? pick : all)
|
|
417
|
+
bodies.push({ file: t.file, line: o.startLine, name, fqn: c });
|
|
418
|
+
}
|
|
419
|
+
}
|
|
420
|
+
out.push({ site, methodName: call.method_name, kind: 'bound', tier: b.result.tier, declaring: this.targetOf(b.owner, b.name, b.overload), bodies });
|
|
421
|
+
}
|
|
422
|
+
else {
|
|
423
|
+
const reason = b?.kind === 'ambiguous' ? 'overload-ambiguous' : this.reasonFor(call, rec);
|
|
424
|
+
const receiver = reason === 'external' ? this.foreignTypeOf(call, rec) : undefined;
|
|
425
|
+
out.push({ site, methodName: call.method_name, kind: 'unresolved', reason, ...(receiver ? { receiver } : {}) });
|
|
426
|
+
}
|
|
427
|
+
}
|
|
428
|
+
}
|
|
429
|
+
return out;
|
|
430
|
+
}
|
|
431
|
+
/** The type outside the tree an `external` site lands on: its receiver, the constructed type, or a static import's owner. */
|
|
432
|
+
foreignTypeOf(call, rec) {
|
|
433
|
+
let name;
|
|
434
|
+
if (call.is_constructor)
|
|
435
|
+
name = call.receiver_type_fqn ?? call.receiver_type ?? call.method_name;
|
|
436
|
+
else if (call.receiver === null && !call.receiver_type)
|
|
437
|
+
name = rec.staticImports.get(call.method_name);
|
|
438
|
+
else {
|
|
439
|
+
const t = this.receiverTypeOf(call, rec);
|
|
440
|
+
if (t?.kind === 'foreign')
|
|
441
|
+
name = t.name;
|
|
442
|
+
}
|
|
443
|
+
const bare = name?.replace(/<.*>$/, '').replace(/\[\]$/, '').trim();
|
|
444
|
+
if (!bare)
|
|
445
|
+
return undefined;
|
|
446
|
+
return bare.includes('.') ? bare : rec.imports.get(bare) ?? bare;
|
|
447
|
+
}
|
|
448
|
+
targetOf(owner, name, overload) {
|
|
449
|
+
if (overload)
|
|
450
|
+
return { file: owner.file, line: overload.startLine, name: overload.isConstructor ? '<init>' : name, fqn: memberName(owner, overload) };
|
|
451
|
+
const m = name === '<init>' ? undefined : owner.methods.get(name);
|
|
452
|
+
if (m)
|
|
453
|
+
return { file: owner.file, line: m.startLine, name, fqn: `${owner.fqn}.${name}` };
|
|
454
|
+
// A constructor the type does not declare: the type itself.
|
|
455
|
+
return { file: owner.file, line: owner.startLine, name: owner.simpleName, fqn: owner.fqn, type: true };
|
|
456
|
+
}
|
|
374
457
|
/**
|
|
375
458
|
* The symbol a call site names, so a caller holding a line of code can ask
|
|
376
459
|
* the same question as a caller holding a name.
|
|
@@ -454,7 +537,7 @@ export class NavigationIndex {
|
|
|
454
537
|
const encl = this.enclosingTypeOf(call, rec);
|
|
455
538
|
const sup = encl?.extendsName ? this.resolveTypeName(encl.extendsName, rec) : undefined;
|
|
456
539
|
if (sup && this.typesByFqn.has(sup)) {
|
|
457
|
-
return this.bindInType(sup, call, rec, depth, `super call inside ${encl.fqn}`, sup);
|
|
540
|
+
return this.bindInType(sup, call, rec, depth, `super call inside ${encl.fqn}`, sup, true);
|
|
458
541
|
}
|
|
459
542
|
return undefined;
|
|
460
543
|
}
|
|
@@ -500,7 +583,7 @@ export class NavigationIndex {
|
|
|
500
583
|
return undefined;
|
|
501
584
|
}
|
|
502
585
|
/** Bind `call` to a member of `fqn` or of a supertype of it, choosing the overload. */
|
|
503
|
-
bindInType(fqn, call, rec, depth, evidence, receiver) {
|
|
586
|
+
bindInType(fqn, call, rec, depth, evidence, receiver, nonVirtual = false) {
|
|
504
587
|
const cands = this.visibleOverloads(fqn, call.method_name);
|
|
505
588
|
if (cands.length === 0)
|
|
506
589
|
return undefined;
|
|
@@ -520,8 +603,8 @@ export class NavigationIndex {
|
|
|
520
603
|
overload,
|
|
521
604
|
receiver,
|
|
522
605
|
result: overloaded
|
|
523
|
-
? this.tierFor(owner, call.method_name, overload, `${evidence}; ${sel.how}`, true)
|
|
524
|
-
: this.tierFor(owner, call.method_name, overload, evidence),
|
|
606
|
+
? this.tierFor(owner, call.method_name, overload, `${evidence}; ${sel.how}`, true, nonVirtual)
|
|
607
|
+
: this.tierFor(owner, call.method_name, overload, evidence, false, nonVirtual),
|
|
525
608
|
};
|
|
526
609
|
}
|
|
527
610
|
/**
|
|
@@ -535,11 +618,14 @@ export class NavigationIndex {
|
|
|
535
618
|
* the first; what runs there is a subclass's body or a lambda, never the
|
|
536
619
|
* member named. The target stays the declaring member, which is what a
|
|
537
620
|
* static resolver answers; only the tier changes.
|
|
621
|
+
*
|
|
622
|
+
* A `super.m()` call is not dispatched: it runs the body it names, whatever
|
|
623
|
+
* overrides it below.
|
|
538
624
|
*/
|
|
539
|
-
tierFor(owner, method, overload, evidence, overloaded = false) {
|
|
625
|
+
tierFor(owner, method, overload, evidence, overloaded = false, nonVirtual = false) {
|
|
540
626
|
const impls = this.implementorsWith(owner.fqn, overload);
|
|
541
627
|
const bodyless = this.isBodyless(owner, overload);
|
|
542
|
-
if (impls.length > 1 || bodyless) {
|
|
628
|
+
if ((impls.length > 1 && !nonVirtual) || bodyless) {
|
|
543
629
|
return {
|
|
544
630
|
target: `${owner.fqn}.${method}`,
|
|
545
631
|
tier: 'polymorphic',
|
|
@@ -652,11 +738,16 @@ export class NavigationIndex {
|
|
|
652
738
|
if (byArity.length === 0)
|
|
653
739
|
return { kind: 'none' };
|
|
654
740
|
const args = call.arguments.map(a => this.argumentType(a, call, rec, depth));
|
|
741
|
+
// An implicit, `this.` or `super.` receiver is the enclosing type itself,
|
|
742
|
+
// which fixes what the declaring type's variables are.
|
|
743
|
+
const self = call.receiver === null || call.receiver === 'this' || call.receiver === 'super'
|
|
744
|
+
? this.enclosingTypeOf(call, rec)
|
|
745
|
+
: undefined;
|
|
655
746
|
if (byArity.length === 1) {
|
|
656
747
|
// The only declaration in the tree at this arity, but the argument
|
|
657
748
|
// types certainly rule it out: what is called is an overload this
|
|
658
749
|
// index cannot see, inherited from a library type. Not ours.
|
|
659
|
-
if ([1, 2, 3].every(p => this.applicable(byArity[0], args, p) === 'no'))
|
|
750
|
+
if ([1, 2, 3].every(p => this.applicable(byArity[0], args, p, self) === 'no'))
|
|
660
751
|
return { kind: 'none' };
|
|
661
752
|
return {
|
|
662
753
|
kind: 'one',
|
|
@@ -666,7 +757,7 @@ export class NavigationIndex {
|
|
|
666
757
|
}
|
|
667
758
|
const fit = new Map();
|
|
668
759
|
for (const c of byArity)
|
|
669
|
-
fit.set(c, [1, 2, 3].map(p => this.applicable(c, args, p)));
|
|
760
|
+
fit.set(c, [1, 2, 3].map(p => this.applicable(c, args, p, self)));
|
|
670
761
|
const possible = byArity.filter(c => fit.get(c).some(f => f !== 'no'));
|
|
671
762
|
if (possible.length === 1) {
|
|
672
763
|
return {
|
|
@@ -686,7 +777,7 @@ export class NavigationIndex {
|
|
|
686
777
|
const C = P.filter(c => fit.get(c)[phase - 1] === 'yes');
|
|
687
778
|
if (C.length === 0)
|
|
688
779
|
return { kind: 'ambiguous', candidates: possible };
|
|
689
|
-
const best = C.find(m => P.every(o => o === m || this.moreSpecific(m, o, phase)));
|
|
780
|
+
const best = C.find(m => P.every(o => o === m || this.moreSpecific(m, o, phase, self)));
|
|
690
781
|
if (best) {
|
|
691
782
|
return {
|
|
692
783
|
kind: 'one',
|
|
@@ -699,10 +790,9 @@ export class NavigationIndex {
|
|
|
699
790
|
return { kind: 'ambiguous', candidates: possible };
|
|
700
791
|
}
|
|
701
792
|
/** Whether `c` applies to arguments of these types in compiler phase 1, 2 or 3. */
|
|
702
|
-
applicable(c, args, phase) {
|
|
793
|
+
applicable(c, args, phase, self) {
|
|
703
794
|
const o = c.overload;
|
|
704
|
-
const
|
|
705
|
-
const params = o.params.map(p => this.typeRef(p, declRec));
|
|
795
|
+
const params = this.paramRefsFrom(c, self);
|
|
706
796
|
let worst = 'yes';
|
|
707
797
|
const meet = (f) => {
|
|
708
798
|
if (f === 'no')
|
|
@@ -718,17 +808,16 @@ export class NavigationIndex {
|
|
|
718
808
|
}
|
|
719
809
|
if (!o.varargs || args.length < params.length - 1)
|
|
720
810
|
return 'no';
|
|
721
|
-
const
|
|
722
|
-
const elem = { ...last, dims: Math.max(0, last.dims - 1) };
|
|
811
|
+
const elem = elementOf(params[params.length - 1]);
|
|
723
812
|
args.forEach((a, i) => meet(this.fits(a, i < params.length - 1 ? params[i] : elem, 2)));
|
|
724
813
|
return worst;
|
|
725
814
|
}
|
|
726
815
|
/** `m` is more specific than `o`: each of its parameter types fits the other's. */
|
|
727
|
-
moreSpecific(m, o, phase) {
|
|
816
|
+
moreSpecific(m, o, phase, self) {
|
|
728
817
|
if (phase === 3)
|
|
729
818
|
return false;
|
|
730
|
-
const mp =
|
|
731
|
-
const op =
|
|
819
|
+
const mp = this.paramRefsFrom(m, self);
|
|
820
|
+
const op = this.paramRefsFrom(o, self);
|
|
732
821
|
if (mp.length !== op.length)
|
|
733
822
|
return false;
|
|
734
823
|
return mp.every((t, i) => this.fits(t, op[i], 1) === 'yes');
|
|
@@ -740,12 +829,42 @@ export class NavigationIndex {
|
|
|
740
829
|
fits(a, p, phase) {
|
|
741
830
|
if (!a)
|
|
742
831
|
return 'maybe';
|
|
743
|
-
if (p.
|
|
832
|
+
if (p.opaque) {
|
|
833
|
+
if (a.simple === 'null' && a.dims === 0)
|
|
834
|
+
return 'yes';
|
|
835
|
+
if (a.typeVar)
|
|
836
|
+
return a.varName !== undefined && a.varName === p.varName && a.dims === p.dims ? 'yes' : 'maybe';
|
|
837
|
+
// Nothing but the variable itself is a subtype of it.
|
|
838
|
+
return a.prim || a.fqn ? 'no' : 'maybe';
|
|
839
|
+
}
|
|
840
|
+
if (p.typeVar) {
|
|
841
|
+
// Whatever fills a type variable is a subtype of its erasure, so an
|
|
842
|
+
// argument the erasure rules out is ruled out. One it admits is
|
|
843
|
+
// certainly admitted only where the compiler infers the variable from
|
|
844
|
+
// the arguments.
|
|
845
|
+
if (p.erasure) {
|
|
846
|
+
const f = this.fits(a, p.erasure, phase);
|
|
847
|
+
return f === 'no' ? 'no' : p.certain ? f : 'maybe';
|
|
848
|
+
}
|
|
744
849
|
return a.prim && a.dims === 0 && phase === 1 ? 'no' : 'maybe';
|
|
850
|
+
}
|
|
745
851
|
if (a.simple === 'null' && a.dims === 0)
|
|
746
852
|
return p.prim && p.dims === 0 ? 'no' : 'yes';
|
|
747
|
-
if (a.typeVar)
|
|
853
|
+
if (a.typeVar) {
|
|
854
|
+
// A value of a type variable is a value of its erasure, and maybe of
|
|
855
|
+
// something narrower.
|
|
856
|
+
// A type variable's supertypes are its bound's; what a generic call
|
|
857
|
+
// infers is only known to be below the erasure.
|
|
858
|
+
if (a.erasure) {
|
|
859
|
+
// An unbounded variable's only supertype is Object.
|
|
860
|
+
if (!a.inferred && a.erasure.fqn === 'java.lang.Object' && a.erasure.dims === 0) {
|
|
861
|
+
return !p.prim && p.dims === 0 && p.simple === 'Object' && (!p.fqn || p.fqn === 'java.lang.Object') ? 'yes' : 'no';
|
|
862
|
+
}
|
|
863
|
+
const f = this.fits(a.erasure, p, phase);
|
|
864
|
+
return a.inferred && f !== 'yes' ? 'maybe' : f;
|
|
865
|
+
}
|
|
748
866
|
return 'maybe';
|
|
867
|
+
}
|
|
749
868
|
if (a.dims > 0 || p.dims > 0) {
|
|
750
869
|
if (a.dims === p.dims) {
|
|
751
870
|
const ae = { ...a, dims: 0 };
|
|
@@ -895,7 +1014,7 @@ export class NavigationIndex {
|
|
|
895
1014
|
*/
|
|
896
1015
|
argumentType(arg, call, rec, depth) {
|
|
897
1016
|
if (arg.type)
|
|
898
|
-
return this.
|
|
1017
|
+
return this.callSiteRef(arg.type, call, rec);
|
|
899
1018
|
if (!arg.location || depth >= 4)
|
|
900
1019
|
return null;
|
|
901
1020
|
const name = outerCallName(arg.expression);
|
|
@@ -908,6 +1027,11 @@ export class NavigationIndex {
|
|
|
908
1027
|
let returned;
|
|
909
1028
|
let receiver;
|
|
910
1029
|
if (b?.kind === 'bound' && b.overload?.returnType) {
|
|
1030
|
+
// `<M extends Map<K, V>> M invert(…)` returns whatever the call infers
|
|
1031
|
+
// for `M`: known only to be some subtype of the erasure.
|
|
1032
|
+
const own = this.paramRef(b.overload.returnType, { owner: b.owner, overload: b.overload });
|
|
1033
|
+
if (own.varName && b.overload.typeParams.includes(own.varName))
|
|
1034
|
+
return { ...own, inferred: true };
|
|
911
1035
|
returned = { text: b.overload.returnType, owner: b.owner };
|
|
912
1036
|
receiver = b.receiver;
|
|
913
1037
|
}
|
|
@@ -1068,37 +1192,165 @@ export class NavigationIndex {
|
|
|
1068
1192
|
signatureMatches(o, params, owner) {
|
|
1069
1193
|
if (o.params.length !== params.length)
|
|
1070
1194
|
return false;
|
|
1071
|
-
const
|
|
1072
|
-
return
|
|
1195
|
+
const have = this.paramRefs({ owner, overload: o });
|
|
1196
|
+
return have.every((h, i) => {
|
|
1073
1197
|
const want = this.typeRef(params[i], undefined);
|
|
1074
|
-
|
|
1075
|
-
if (want.dims !== have.dims)
|
|
1198
|
+
if (want.dims !== h.dims)
|
|
1076
1199
|
return false;
|
|
1077
1200
|
const wantBare = eraseType(params[i].replace(/\.\.\.$/, '').replace(/(\[\])+$/, ''));
|
|
1078
|
-
|
|
1079
|
-
|
|
1080
|
-
|
|
1081
|
-
return
|
|
1082
|
-
|
|
1083
|
-
return have.simple === want.simple;
|
|
1201
|
+
// A type variable is named as written (`K`) or by its erasure (`Object`,
|
|
1202
|
+
// `java.lang.Object`), the way the compiler and bytecode name it.
|
|
1203
|
+
if (h.varName && wantBare === h.varName)
|
|
1204
|
+
return true;
|
|
1205
|
+
return this.sameAsWritten(h, want, wantBare);
|
|
1084
1206
|
});
|
|
1085
1207
|
}
|
|
1086
|
-
/**
|
|
1208
|
+
/** Whether a declared parameter type is the one a query wrote. */
|
|
1209
|
+
sameAsWritten(have, want, wantBare) {
|
|
1210
|
+
if (wantBare.includes('.') && have.fqn && !have.prim)
|
|
1211
|
+
return have.fqn === wantBare;
|
|
1212
|
+
return have.simple === want.simple;
|
|
1213
|
+
}
|
|
1214
|
+
/**
|
|
1215
|
+
* Same name and same parameter types: one overrides the other, as the
|
|
1216
|
+
* compiler decides it. Within one type that is the erasure, which the
|
|
1217
|
+
* compiler requires to differ between two declarations. Between a type and
|
|
1218
|
+
* its supertype, the supertype's parameter types are first read through the
|
|
1219
|
+
* subtype's supertype clauses — `Fn<T>.apply(T)` is `apply(String)` to a
|
|
1220
|
+
* class implementing `Fn<String>`, and `apply(T)` to one implementing
|
|
1221
|
+
* `Fn<T>`, which then does not override it with `apply(Collection<T>)` —
|
|
1222
|
+
* and the erasures compared. Between types neither of which is known to
|
|
1223
|
+
* extend the other, a type variable still matches whatever its erasure
|
|
1224
|
+
* admits.
|
|
1225
|
+
*/
|
|
1087
1226
|
sameErasure(a, b) {
|
|
1088
|
-
|
|
1089
|
-
const pb = b.overload.params;
|
|
1090
|
-
if (a.overload.name !== b.overload.name || pa.length !== pb.length)
|
|
1227
|
+
if (a.overload.name !== b.overload.name || a.overload.params.length !== b.overload.params.length)
|
|
1091
1228
|
return false;
|
|
1092
|
-
|
|
1093
|
-
|
|
1094
|
-
|
|
1095
|
-
|
|
1096
|
-
|
|
1097
|
-
|
|
1098
|
-
|
|
1099
|
-
|
|
1229
|
+
if (a.owner !== b.owner) {
|
|
1230
|
+
const sub = this.isSubtype(a.owner.fqn, b.owner.fqn) ? a : this.isSubtype(b.owner.fqn, a.owner.fqn) ? b : undefined;
|
|
1231
|
+
if (sub)
|
|
1232
|
+
return this.overridesBySubstitution(sub, sub === a ? b : a);
|
|
1233
|
+
}
|
|
1234
|
+
const pa = this.paramRefs(a);
|
|
1235
|
+
const pb = this.paramRefs(b);
|
|
1236
|
+
const across = a.owner !== b.owner;
|
|
1237
|
+
const open = (t, c) => across && t.typeVar && (!t.varName || !c.overload.typeParams.includes(t.varName));
|
|
1238
|
+
return pa.every((x, i) => {
|
|
1239
|
+
const y = pb[i];
|
|
1240
|
+
if (x.dims !== y.dims)
|
|
1241
|
+
return false;
|
|
1242
|
+
const xo = open(x, a);
|
|
1243
|
+
const yo = open(y, b);
|
|
1244
|
+
if (xo && yo)
|
|
1245
|
+
return true;
|
|
1246
|
+
if (xo)
|
|
1247
|
+
return !x.erasure || this.fits({ ...y, dims: 0 }, { ...x.erasure, dims: 0 }, 1) !== 'no';
|
|
1248
|
+
if (yo)
|
|
1249
|
+
return !y.erasure || this.fits({ ...x, dims: 0 }, { ...y.erasure, dims: 0 }, 1) !== 'no';
|
|
1250
|
+
// A type variable no declaration in scope names: as lenient as before.
|
|
1251
|
+
if ((x.typeVar && !x.erasure) || (y.typeVar && !y.erasure))
|
|
1252
|
+
return true;
|
|
1253
|
+
return x.simple === y.simple;
|
|
1254
|
+
});
|
|
1255
|
+
}
|
|
1256
|
+
/** Whether `sub`'s declaration has `sup`'s parameter types as `sub`'s type sees them, erased. */
|
|
1257
|
+
overridesBySubstitution(sub, sup) {
|
|
1258
|
+
const mine = this.paramRefs(sub);
|
|
1259
|
+
const scope = this.scopeOf(sub.owner, sub.overload);
|
|
1260
|
+
return sup.overload.params.every((written, i) => {
|
|
1261
|
+
const own = sup.overload.vars[i];
|
|
1262
|
+
// The supertype method's own type variable: its erasure.
|
|
1263
|
+
const s = own && sup.overload.typeParams.includes(own.name) ? undefined : this.substitute(written, sup.owner, sub.owner.fqn);
|
|
1264
|
+
// No binding read for the variable (a raw supertype, or a clause this
|
|
1265
|
+
// index cannot resolve): the supertype's own erasure.
|
|
1266
|
+
const theirs = s
|
|
1267
|
+
? this.withErasure(s.text, eraseWritten(s.text, scope), s.rec)
|
|
1268
|
+
: this.paramRef(written, sup);
|
|
1269
|
+
const m = mine[i];
|
|
1270
|
+
if (m.dims !== theirs.dims)
|
|
1271
|
+
return false;
|
|
1272
|
+
if (m.typeVar && !m.erasure)
|
|
1273
|
+
return true;
|
|
1274
|
+
if (theirs.typeVar && !theirs.erasure)
|
|
1275
|
+
return true;
|
|
1276
|
+
return m.simple === theirs.simple;
|
|
1100
1277
|
});
|
|
1101
1278
|
}
|
|
1279
|
+
/** A candidate's parameter types, each type variable carrying its erasure. */
|
|
1280
|
+
paramRefs(c) {
|
|
1281
|
+
return c.overload.params.map(p => this.paramRef(p, c));
|
|
1282
|
+
}
|
|
1283
|
+
/**
|
|
1284
|
+
* `c`'s parameter types as a call on `self` — the enclosing type, as an
|
|
1285
|
+
* implicit, `this.` or `super.` receiver — sees them: a variable of the
|
|
1286
|
+
* declaring type is that of `self` when `self` declares it, and what
|
|
1287
|
+
* `self`'s supertype clauses fill it with when it is inherited
|
|
1288
|
+
* (`Lru extends Base<String>` makes `Base<K>.put(K)` a `put(String)`).
|
|
1289
|
+
*/
|
|
1290
|
+
paramRefsFrom(c, self) {
|
|
1291
|
+
const refs = this.paramRefs(c);
|
|
1292
|
+
if (!self)
|
|
1293
|
+
return refs;
|
|
1294
|
+
return refs.map((r, i) => {
|
|
1295
|
+
if (!r.typeVar || !r.varName || c.overload.typeParams.includes(r.varName))
|
|
1296
|
+
return r;
|
|
1297
|
+
if (c.owner === self)
|
|
1298
|
+
return { ...r, opaque: true };
|
|
1299
|
+
const sub = this.substitute(c.overload.params[i], c.owner, self.fqn);
|
|
1300
|
+
if (!sub)
|
|
1301
|
+
return r;
|
|
1302
|
+
const e = eraseWritten(sub.text, this.scopeOf(self, undefined));
|
|
1303
|
+
if (e)
|
|
1304
|
+
return { ...this.withErasure(sub.text, e, sub.rec), opaque: true };
|
|
1305
|
+
return this.typeRef(sub.text, sub.rec);
|
|
1306
|
+
});
|
|
1307
|
+
}
|
|
1308
|
+
/**
|
|
1309
|
+
* An argument's written type at a call site: a type variable of the
|
|
1310
|
+
* enclosing method or type carries its erasure.
|
|
1311
|
+
*/
|
|
1312
|
+
callSiteRef(written, call, rec) {
|
|
1313
|
+
const encl = this.enclosingTypeOf(call, rec);
|
|
1314
|
+
if (!encl)
|
|
1315
|
+
return this.typeRef(written, rec);
|
|
1316
|
+
const line = call.location.line;
|
|
1317
|
+
let method;
|
|
1318
|
+
for (const list of encl.overloads.values()) {
|
|
1319
|
+
for (const o of list) {
|
|
1320
|
+
if (line < o.startLine || line > o.endLine)
|
|
1321
|
+
continue;
|
|
1322
|
+
if (!method || o.endLine - o.startLine < method.endLine - method.startLine)
|
|
1323
|
+
method = o;
|
|
1324
|
+
}
|
|
1325
|
+
}
|
|
1326
|
+
return this.withErasure(written, eraseWritten(written, this.scopeOf(encl, method)), rec);
|
|
1327
|
+
}
|
|
1328
|
+
/** One written parameter (or return) type of `c`, from its declaring file's point of view. */
|
|
1329
|
+
paramRef(written, c) {
|
|
1330
|
+
const i = c.overload.params.indexOf(written);
|
|
1331
|
+
const e = i !== -1 && c.overload.vars[i]
|
|
1332
|
+
? { ...c.overload.vars[i], text: c.overload.erased[i] }
|
|
1333
|
+
: eraseWritten(written, this.scopeOf(c.owner, c.overload));
|
|
1334
|
+
return this.withErasure(written, e, this.files.get(c.owner.file));
|
|
1335
|
+
}
|
|
1336
|
+
/** A written type, with the erasure `eraseWritten` found for it when it is a type variable. */
|
|
1337
|
+
withErasure(written, e, rec) {
|
|
1338
|
+
if (!e)
|
|
1339
|
+
return this.typeRef(written, rec);
|
|
1340
|
+
const erased = this.typeRef(e.text, rec);
|
|
1341
|
+
return { ...erased, typeVar: true, varName: e.name, erasure: erased, certain: e.certain };
|
|
1342
|
+
}
|
|
1343
|
+
/** The type variables visible in a member of `owner` (`overload`), innermost first. */
|
|
1344
|
+
scopeOf(owner, overload) {
|
|
1345
|
+
const types = [];
|
|
1346
|
+
let t = owner;
|
|
1347
|
+
while (t) {
|
|
1348
|
+
types.push(t);
|
|
1349
|
+
const outer = this.typesByFqn.get(stripLast(t.fqn));
|
|
1350
|
+
t = outer && outer.file === owner.file ? outer : undefined;
|
|
1351
|
+
}
|
|
1352
|
+
return { method: overload ?? null, types };
|
|
1353
|
+
}
|
|
1102
1354
|
// --------------------------------------------------------------- dispatch
|
|
1103
1355
|
/**
|
|
1104
1356
|
* How a site bound to `owner.overload` reaches `target`'s overload, if it
|
|
@@ -1728,6 +1980,10 @@ function buildFileRecord(f) {
|
|
|
1728
1980
|
startLine: m.start_line,
|
|
1729
1981
|
endLine: m.end_line,
|
|
1730
1982
|
modifiers: m.modifiers ?? [],
|
|
1983
|
+
typeParams: m.type_parameters ?? [],
|
|
1984
|
+
typeBounds: m.type_parameter_bounds ?? {},
|
|
1985
|
+
erased: params,
|
|
1986
|
+
vars: params.map(() => null),
|
|
1731
1987
|
});
|
|
1732
1988
|
}
|
|
1733
1989
|
types.push({
|
|
@@ -1742,6 +1998,7 @@ function buildFileRecord(f) {
|
|
|
1742
1998
|
fieldNames: (t.fields ?? []).map(x => x.name),
|
|
1743
1999
|
fieldTypes: new Map((t.fields ?? []).filter(x => x.type).map(x => [x.name, x.type])),
|
|
1744
2000
|
typeParams: t.type_parameters ?? [],
|
|
2001
|
+
typeBounds: t.type_parameter_bounds ?? {},
|
|
1745
2002
|
getterFields: lombokFields(f.source, 'Getter'),
|
|
1746
2003
|
setterFields: lombokFields(f.source, 'Setter'),
|
|
1747
2004
|
methods,
|
|
@@ -1750,6 +2007,22 @@ function buildFileRecord(f) {
|
|
|
1750
2007
|
endLine: t.end_line,
|
|
1751
2008
|
});
|
|
1752
2009
|
}
|
|
2010
|
+
// Erase each parameter's type variables. Everything a declaration's
|
|
2011
|
+
// variables can name — the method, its type, the types enclosing it — is in
|
|
2012
|
+
// this file, so the result is per file and cached with it.
|
|
2013
|
+
for (const t of types) {
|
|
2014
|
+
const chain = [];
|
|
2015
|
+
for (let c = t; c; c = types.find(x => x.fqn === stripLast(c.fqn)))
|
|
2016
|
+
chain.push(c);
|
|
2017
|
+
for (const list of t.overloads.values()) {
|
|
2018
|
+
for (const o of list) {
|
|
2019
|
+
const scope = { method: o, types: chain };
|
|
2020
|
+
const es = o.params.map(p => eraseWritten(p, scope));
|
|
2021
|
+
o.erased = o.params.map((p, i) => es[i]?.text ?? p);
|
|
2022
|
+
o.vars = es.map(e => (e ? { name: e.name, certain: e.certain } : null));
|
|
2023
|
+
}
|
|
2024
|
+
}
|
|
2025
|
+
}
|
|
1753
2026
|
return {
|
|
1754
2027
|
path: f.path,
|
|
1755
2028
|
language: f.language,
|
|
@@ -1806,9 +2079,13 @@ function splitTopLevel(text) {
|
|
|
1806
2079
|
out.push(buf);
|
|
1807
2080
|
return out;
|
|
1808
2081
|
}
|
|
1809
|
-
/**
|
|
2082
|
+
/**
|
|
2083
|
+
* `(Long,String)` — simple names, generics erased, `String...` for varargs, a
|
|
2084
|
+
* type variable shown as its erasure: `getNumber(Map,Object)` for
|
|
2085
|
+
* `<K> getNumber(Map<? super K, ?>, K)`, as javadoc and bytecode name it.
|
|
2086
|
+
*/
|
|
1810
2087
|
function signatureOf(o) {
|
|
1811
|
-
return `(${o.
|
|
2088
|
+
return `(${o.erased.map(p => {
|
|
1812
2089
|
const varargs = p.endsWith('...');
|
|
1813
2090
|
let t = eraseType(p.replace(/@[\w.]+(\([^)]*\))?\s*/g, '').replace(/\bfinal\s+/g, '').replace(/\.\.\.$/, '').trim());
|
|
1814
2091
|
let dims = '';
|
|
@@ -1823,6 +2100,51 @@ function signatureOf(o) {
|
|
|
1823
2100
|
function memberName(owner, o) {
|
|
1824
2101
|
return o.isConstructor ? `${owner.fqn}.<init>` : `${owner.fqn}.${o.name}`;
|
|
1825
2102
|
}
|
|
2103
|
+
/**
|
|
2104
|
+
* What a written type that is a type variable erases to, the way the compiler
|
|
2105
|
+
* erases it: its leftmost bound, erased in turn when the bound is itself a
|
|
2106
|
+
* variable (`W extends U`), else `Object`; array and varargs suffixes kept.
|
|
2107
|
+
* Nothing when it is not a type variable in scope. The innermost declaration
|
|
2108
|
+
* of a name hides the outer ones.
|
|
2109
|
+
*
|
|
2110
|
+
* `certain` says whether an argument that fits the erasure certainly fits the
|
|
2111
|
+
* variable: so for a method's own variable, which the compiler infers from
|
|
2112
|
+
* the arguments, unless its bound names the variable itself
|
|
2113
|
+
* (`T extends Comparable<T>`); never for a type's, which the receiver fixes.
|
|
2114
|
+
*/
|
|
2115
|
+
function eraseWritten(written, scope, seen = new Set()) {
|
|
2116
|
+
let t = written.replace(/@[\w.]+(\([^)]*\))?\s*/g, '').replace(/\bfinal\s+/g, '').trim();
|
|
2117
|
+
let suffix = '';
|
|
2118
|
+
if (t.endsWith('...')) {
|
|
2119
|
+
suffix = '...';
|
|
2120
|
+
t = t.slice(0, -3).trim();
|
|
2121
|
+
}
|
|
2122
|
+
t = eraseType(t);
|
|
2123
|
+
while (t.endsWith('[]')) {
|
|
2124
|
+
suffix = `[]${suffix}`;
|
|
2125
|
+
t = t.slice(0, -2).trim();
|
|
2126
|
+
}
|
|
2127
|
+
if (!/^[A-Za-z_$][\w$]*$/.test(t) || seen.has(t))
|
|
2128
|
+
return undefined;
|
|
2129
|
+
let v;
|
|
2130
|
+
if (scope.method?.typeParams.includes(t))
|
|
2131
|
+
v = { bound: scope.method.typeBounds[t] ?? null, kind: 'method' };
|
|
2132
|
+
else {
|
|
2133
|
+
const owner = scope.types.find(x => x.typeParams.includes(t));
|
|
2134
|
+
if (owner)
|
|
2135
|
+
v = { bound: owner.typeBounds[t] ?? null, kind: 'type' };
|
|
2136
|
+
}
|
|
2137
|
+
if (!v)
|
|
2138
|
+
return undefined;
|
|
2139
|
+
if (v.bound === null)
|
|
2140
|
+
return { name: t, text: `Object${suffix}`, certain: v.kind === 'method' };
|
|
2141
|
+
const inner = eraseWritten(v.bound, scope, new Set([...seen, t]));
|
|
2142
|
+
if (inner)
|
|
2143
|
+
return { name: t, text: `${inner.text}${suffix}`, certain: v.kind === 'method' && inner.certain };
|
|
2144
|
+
const args = v.bound.includes('<') ? v.bound.slice(v.bound.indexOf('<') + 1) : '';
|
|
2145
|
+
const selfBounded = new RegExp(`\\b${t}\\b`).test(args);
|
|
2146
|
+
return { name: t, text: `${eraseType(v.bound)}${suffix}`, certain: v.kind === 'method' && !selfBounded };
|
|
2147
|
+
}
|
|
1826
2148
|
/** Remove every `<...>` from a written type. */
|
|
1827
2149
|
function eraseType(t) {
|
|
1828
2150
|
let out = '';
|
|
@@ -1841,6 +2163,11 @@ function eraseType(t) {
|
|
|
1841
2163
|
}
|
|
1842
2164
|
return out.trim();
|
|
1843
2165
|
}
|
|
2166
|
+
/** A varargs parameter's element type. */
|
|
2167
|
+
function elementOf(t) {
|
|
2168
|
+
const dims = Math.max(0, t.dims - 1);
|
|
2169
|
+
return { ...t, dims, ...(t.erasure ? { erasure: { ...t.erasure, dims } } : {}) };
|
|
2170
|
+
}
|
|
1844
2171
|
/** Whether a call with `n` arguments can reach overload `o` at all. */
|
|
1845
2172
|
function fitsArity(o, n) {
|
|
1846
2173
|
if (o.params.length === n)
|