pi-lens 3.8.73 → 4.0.0
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/CHANGELOG.md +2614 -12
- package/README.md +50 -21
- package/dist/clients/actionable-warnings.js +73 -18
- package/dist/clients/agent-behavior-client.js +21 -4
- package/dist/clients/ast-grep-client.js +68 -16
- package/dist/clients/ast-grep-types.js +0 -1
- package/dist/clients/ast-grep-yaml-synth.js +37 -10
- package/dist/clients/atomic-write-staging.js +63 -0
- package/dist/clients/atomic-write.js +116 -16
- package/dist/clients/bash-file-access.js +193 -23
- package/dist/clients/biome-client.js +29 -25
- package/dist/clients/bootstrap.js +11 -2
- package/dist/clients/bounded-cache.js +34 -0
- package/dist/clients/bounded-pid-file-lock.js +192 -0
- package/dist/clients/bus-events-logger.js +5 -1
- package/dist/clients/bus-publish.js +10 -3
- package/dist/clients/cache/rule-cache.js +89 -6
- package/dist/clients/cache-manager.js +97 -9
- package/dist/clients/cache-observability.js +498 -0
- package/dist/clients/call-graph.js +460 -108
- package/dist/clients/cascade-logger.js +5 -1
- package/dist/clients/child-unref.js +85 -0
- package/dist/clients/codebase-model.js +52 -23
- package/dist/clients/collateral-test-role.js +40 -0
- package/dist/clients/complexity-client.js +6 -8
- package/dist/clients/console-guard-install.js +14 -0
- package/dist/clients/cooperative-budget.js +42 -0
- package/dist/clients/dead-code-client.js +2 -1
- package/dist/clients/debug-handles.js +206 -0
- package/dist/clients/debug-heap.js +167 -0
- package/dist/clients/degradation-ledger.js +153 -0
- package/dist/clients/dependency-checker.js +466 -63
- package/dist/clients/diagnostic-dispositions.js +83 -13
- package/dist/clients/diagnostics-publish.js +10 -3
- package/dist/clients/dispatch/auxiliary-lsp.js +34 -0
- package/dist/clients/dispatch/dispatcher.js +71 -13
- package/dist/clients/dispatch/fact-store.js +11 -0
- package/dist/clients/dispatch/facts/function-facts.js +37 -7
- package/dist/clients/dispatch/facts/import-facts.js +108 -119
- package/dist/clients/dispatch/facts/tree-sitter-facts.js +12 -12
- package/dist/clients/dispatch/facts/try-catch-facts.js +13 -0
- package/dist/clients/dispatch/indent-detect.js +35 -0
- package/dist/clients/dispatch/inline-suppressions.js +17 -8
- package/dist/clients/dispatch/integration.js +1094 -611
- package/dist/clients/dispatch/lazy.js +14 -0
- package/dist/clients/dispatch/plan.js +11 -1
- package/dist/clients/dispatch/rule-id-normalize.js +50 -0
- package/dist/clients/dispatch/rule-policy.js +135 -0
- package/dist/clients/dispatch/rules/async-noise.js +1 -0
- package/dist/clients/dispatch/rules/unsafe-boundary.js +7 -0
- package/dist/clients/dispatch/runners/ast-grep-napi.js +47 -6
- package/dist/clients/dispatch/runners/biome-check.js +5 -9
- package/dist/clients/dispatch/runners/detekt.js +3 -2
- package/dist/clients/dispatch/runners/hadolint.js +2 -1
- package/dist/clients/dispatch/runners/helm-lint.js +154 -0
- package/dist/clients/dispatch/runners/htmlhint.js +3 -2
- package/dist/clients/dispatch/runners/index.js +5 -1
- package/dist/clients/dispatch/runners/lsp.js +14 -6
- package/dist/clients/dispatch/runners/markdownlint.js +4 -9
- package/dist/clients/dispatch/runners/psscriptanalyzer.js +10 -1
- package/dist/clients/dispatch/runners/pyright.js +9 -5
- package/dist/clients/dispatch/runners/ruff.js +4 -8
- package/dist/clients/dispatch/runners/shellcheck.js +2 -3
- package/dist/clients/dispatch/runners/shfmt.js +2 -3
- package/dist/clients/dispatch/runners/spotbugs.js +2 -1
- package/dist/clients/dispatch/runners/taplo.js +2 -1
- package/dist/clients/dispatch/runners/terragrunt.js +163 -0
- package/dist/clients/dispatch/runners/tflint.js +37 -5
- package/dist/clients/dispatch/runners/tree-sitter.js +155 -166
- package/dist/clients/dispatch/runners/trivy-config.js +13 -7
- package/dist/clients/dispatch/runners/utils/lazy-installer.js +3 -0
- package/dist/clients/dispatch/runners/utils/runner-helpers.js +284 -34
- package/dist/clients/dispatch/runners/utils/spawn-outcome.js +22 -0
- package/dist/clients/dispatch/runners/yaml-rule-parser.js +5 -4
- package/dist/clients/disposition-publish.js +10 -3
- package/dist/clients/durable-store.js +97 -0
- package/dist/clients/event-loop-monitor.js +94 -3
- package/dist/clients/extension-log.js +139 -0
- package/dist/clients/extension-mode.js +73 -0
- package/dist/clients/feature-hints.js +53 -7
- package/dist/clients/file-kinds.js +143 -31
- package/dist/clients/file-role.js +18 -3
- package/dist/clients/file-utils.js +56 -34
- package/dist/clients/fix-worklog.js +14 -2
- package/dist/clients/format-events-publish.js +16 -3
- package/dist/clients/format-service.js +24 -8
- package/dist/clients/formatters-lazy.js +8 -0
- package/dist/clients/formatters.js +358 -61
- package/dist/clients/generated-artifacts.js +169 -15
- package/dist/clients/git-guard.js +681 -11
- package/dist/clients/git-tracked-ignore.js +4 -0
- package/dist/clients/go-client.js +2 -1
- package/dist/clients/govulncheck-client.js +8 -0
- package/dist/clients/grammar-source.js +12 -4
- package/dist/clients/gzip-stage-write.js +102 -0
- package/dist/clients/host-ports.js +31 -0
- package/dist/clients/installer/index.js +733 -213
- package/dist/clients/instance-reaper.js +142 -172
- package/dist/clients/jscpd-client.js +31 -54
- package/dist/clients/knip-client.js +78 -36
- package/dist/clients/language-policy.js +14 -2
- package/dist/clients/language-profile.js +72 -77
- package/dist/clients/latency-logger.js +28 -16
- package/dist/clients/lens-config.js +140 -166
- package/dist/clients/lens-engine.js +124 -21
- package/dist/clients/lens-events.js +27 -4
- package/dist/clients/lens-flag-registry.js +293 -0
- package/dist/clients/lens-map.js +96 -26
- package/dist/clients/live-bus-emitter.js +30 -0
- package/dist/clients/log-cleanup.js +8 -18
- package/dist/clients/lsp/cascade-tier.js +23 -3
- package/dist/clients/lsp/client.js +566 -57
- package/dist/clients/lsp/config.js +74 -10
- package/dist/clients/lsp/diagnostic-binding.js +86 -0
- package/dist/clients/lsp/edits.js +1012 -121
- package/dist/clients/lsp/index.js +1840 -803
- package/dist/clients/lsp/language.js +4 -1
- package/dist/clients/lsp/launch.js +40 -32
- package/dist/clients/lsp/path-utils.js +1 -1
- package/dist/clients/lsp/ruby-drive-dirs.js +83 -0
- package/dist/clients/lsp/server.js +279 -60
- package/dist/clients/lsp/workspace-diagnostics-cache.js +28 -4
- package/dist/clients/lsp-document-symbols.js +112 -0
- package/dist/clients/lsp-lazy.js +8 -0
- package/dist/clients/lsp-mutation.js +248 -0
- package/dist/clients/mcp/analyze.js +128 -36
- package/dist/clients/mcp/ipc.js +157 -24
- package/dist/clients/mcp/review.js +36 -3
- package/dist/clients/mcp/session.js +216 -8
- package/dist/clients/memory-sampler.js +115 -0
- package/dist/clients/metrics-client.js +2 -1
- package/dist/clients/metrics-history.js +2 -1
- package/dist/clients/module-report-lsp.js +5 -0
- package/dist/clients/module-report.js +267 -82
- package/dist/clients/ndjson-logger.js +334 -103
- package/dist/clients/opengrep-client.js +1 -1
- package/dist/clients/partial-edit-apply.js +120 -5
- package/dist/clients/path-keyed-map.js +76 -0
- package/dist/clients/path-utils.js +141 -5
- package/dist/clients/performance-report.js +327 -0
- package/dist/clients/pipeline.js +54 -13
- package/dist/clients/print-mode.js +21 -0
- package/dist/clients/project-changes.js +117 -4
- package/dist/clients/project-diagnostics/cache.js +3 -2
- package/dist/clients/project-diagnostics/extractors.js +26 -115
- package/dist/clients/project-diagnostics/fresh-fetch.js +149 -19
- package/dist/clients/project-diagnostics/runner-adapters/call-graph-impact.js +117 -0
- package/dist/clients/project-diagnostics/runner-adapters/runner-findings.js +37 -5
- package/dist/clients/project-diagnostics/scanner.js +268 -128
- package/dist/clients/project-lens-config.js +138 -34
- package/dist/clients/project-report.js +64 -25
- package/dist/clients/project-scale.js +8 -10
- package/dist/clients/project-snapshot-persist-worker.js +6 -0
- package/dist/clients/project-snapshot.js +767 -8
- package/dist/clients/project-trust.js +181 -0
- package/dist/clients/quiet-window.js +27 -5
- package/dist/clients/read-bridge.js +147 -0
- package/dist/clients/read-expansion.js +22 -12
- package/dist/clients/read-guard-logger.js +159 -1
- package/dist/clients/read-guard-tool-lines.js +150 -29
- package/dist/clients/read-guard.js +262 -3
- package/dist/clients/redact/secrets.js +449 -0
- package/dist/clients/resource-sampler.js +144 -39
- package/dist/clients/reverse-deps.js +48 -0
- package/dist/clients/review-graph/builder.js +2570 -326
- package/dist/clients/review-graph/git-identity.js +2 -1
- package/dist/clients/review-graph/import-resolvers.js +21 -10
- package/dist/clients/review-graph/persist-worker.js +10 -0
- package/dist/clients/review-graph/query.js +5 -0
- package/dist/clients/review-graph/shared-extraction-ir.js +90 -0
- package/dist/clients/review-graph/symbol-id.js +46 -0
- package/dist/clients/review-graph/tsconfig-paths.js +57 -6
- package/dist/clients/review-graph/workspace-modules.js +51 -3
- package/dist/clients/review-graph-logger.js +53 -0
- package/dist/clients/ruff-client.js +27 -44
- package/dist/clients/runtime-agent-end.js +111 -75
- package/dist/clients/runtime-context.js +36 -12
- package/dist/clients/runtime-coordinator.js +76 -8
- package/dist/clients/runtime-session.js +799 -137
- package/dist/clients/runtime-tool-call.js +117 -62
- package/dist/clients/runtime-tool-result.js +218 -23
- package/dist/clients/runtime-turn.js +284 -40
- package/dist/clients/rust-client.js +2 -1
- package/dist/clients/safe-spawn.js +873 -71
- package/dist/clients/security-scan-client.js +2 -1
- package/dist/clients/session-start-observability.js +15 -0
- package/dist/clients/session-state-store.js +5 -3
- package/dist/clients/sessionstart-logger.js +18 -0
- package/dist/clients/sg-runner.js +284 -159
- package/dist/clients/slow-fs.js +2 -1
- package/dist/clients/smells-rollup.js +224 -0
- package/dist/clients/source-filter.js +231 -43
- package/dist/clients/source-walker.js +66 -10
- package/dist/clients/startup-scan.js +15 -16
- package/dist/clients/startup-timing.js +9 -0
- package/dist/clients/test-runner-client.js +38 -8
- package/dist/clients/todo-scanner.js +30 -3
- package/dist/clients/tool-event.js +35 -0
- package/dist/clients/tool-policy.js +388 -39
- package/dist/clients/tool-render.js +155 -0
- package/dist/clients/tree-sitter-cache.js +153 -140
- package/dist/clients/tree-sitter-client.js +1722 -80
- package/dist/clients/tree-sitter-logger.js +64 -1
- package/dist/clients/tree-sitter-query-loader.js +117 -12
- package/dist/clients/tree-sitter-shared.js +48 -19
- package/dist/clients/tree-sitter-symbol-extractor.js +115 -11
- package/dist/clients/user-notify.js +51 -0
- package/dist/clients/vanished-instance-marker.js +57 -0
- package/dist/clients/warm-attach.js +33 -13
- package/dist/clients/widget-state.js +342 -49
- package/dist/clients/word-index-logger.js +44 -0
- package/dist/clients/word-index.js +612 -68
- package/dist/clients/workspace-topology.js +100 -7
- package/dist/index.js +65923 -47161
- package/dist/mcp/analyze-cli.js +185 -29
- package/dist/mcp/cli.js +110 -0
- package/dist/mcp/server.js +272 -50
- package/dist/tools/ast-grep-search.js +93 -27
- package/dist/tools/lens-diagnostics.js +247 -41
- package/dist/tools/lsp-diagnostics.js +153 -40
- package/dist/tools/lsp-navigation.js +51 -31
- package/dist/tools/module-report.js +9 -0
- package/dist/tools/symbol-search.js +21 -2
- package/docs/agent-guide.md +247 -0
- package/docs/agent-tools.md +21 -10
- package/docs/analysisall.md +192 -0
- package/docs/api-ports-inventory.md +165 -0
- package/docs/ast-grep_rules_catalog.md +5 -2
- package/docs/astplayground.md +3 -4
- package/docs/audit1.md +5 -5
- package/docs/durable-store-audit-1202.md +32 -0
- package/docs/environment-variables.md +197 -11
- package/docs/fable.md +27 -0
- package/docs/features.md +35 -5
- package/docs/globalconfig.md +101 -5
- package/docs/language-coverage.md +6 -5
- package/docs/lsp-capability-matrix.md +2 -2
- package/docs/mcp.md +54 -20
- package/docs/servercapabilities.md +7 -4
- package/docs/settings.md +192 -0
- package/docs/tools.md +18 -1
- package/docs/tree-sitter_rules_catalog.md +11 -31
- package/docs/usage.md +31 -0
- package/package.json +139 -138
- package/rules/ast-grep-rules/rule-tests/hardcoded-url-js-test.yml +1 -0
- package/rules/ast-grep-rules/rule-tests/hardcoded-url-test.yml +2 -0
- package/rules/ast-grep-rules/rule-tests/no-bare-except-test.yml +49 -0
- package/rules/ast-grep-rules/rule-tests/no-bare-host-path-in-win32-branch-test.yml +87 -0
- package/rules/ast-grep-rules/rule-tests/no-case-declarations-js-test.yml +10 -0
- package/rules/ast-grep-rules/rule-tests/no-case-declarations-test.yml +10 -0
- package/rules/ast-grep-rules/rule-tests/no-javascript-url-js-test.yml +10 -0
- package/rules/ast-grep-rules/rule-tests/no-javascript-url-test.yml +10 -0
- package/rules/ast-grep-rules/rule-tests/no-nested-links-test.yml +11 -1
- package/rules/ast-grep-rules/rule-tests/no-raw-json-store-write-test.yml +17 -0
- package/rules/ast-grep-rules/rule-tests/no-win32-isabsolute-for-qualification-test.yml +16 -0
- package/rules/ast-grep-rules/rule-tests/strict-equality-js-test.yml +3 -0
- package/rules/ast-grep-rules/rule-tests/strict-equality-test.yml +3 -0
- package/rules/ast-grep-rules/rule-tests/strict-inequality-js-test.yml +3 -0
- package/rules/ast-grep-rules/rule-tests/strict-inequality-test.yml +4 -0
- package/rules/ast-grep-rules/rules/hardcoded-url-js.yml +22 -4
- package/rules/ast-grep-rules/rules/hardcoded-url.yml +22 -4
- package/rules/ast-grep-rules/rules/no-bare-except.yml +3 -15
- package/rules/ast-grep-rules/rules/no-bare-host-path-in-win32-branch.yml +25 -0
- package/rules/ast-grep-rules/rules/no-case-declarations-js.yml +4 -3
- package/rules/ast-grep-rules/rules/no-case-declarations.yml +4 -3
- package/rules/ast-grep-rules/rules/no-console-except-error-js.yml +10 -0
- package/rules/ast-grep-rules/rules/no-console-except-error.yml +10 -0
- package/rules/ast-grep-rules/rules/no-javascript-url-js.yml +42 -6
- package/rules/ast-grep-rules/rules/no-javascript-url.yml +42 -6
- package/rules/ast-grep-rules/rules/no-nested-links.yml +7 -0
- package/rules/ast-grep-rules/rules/no-raw-json-store-write.yml +30 -0
- package/rules/ast-grep-rules/rules/no-win32-isabsolute-for-qualification.yml +23 -0
- package/rules/ast-grep-rules/rules/strict-equality-js.yml +14 -1
- package/rules/ast-grep-rules/rules/strict-equality.yml +14 -1
- package/rules/ast-grep-rules/rules/strict-inequality-js.yml +14 -1
- package/rules/ast-grep-rules/rules/strict-inequality.yml +14 -1
- package/rules/tree-sitter-queries/cpp/no-memset-sensitive-data.yml +9 -3
- package/rules/tree-sitter-queries/cpp/no-scoped-lock-without-args.yml +6 -6
- package/rules/tree-sitter-queries/css/calc-spacing.yml +8 -6
- package/rules/tree-sitter-queries/go/go-mutex-copy.yml +21 -18
- package/rules/tree-sitter-queries/go/go-shared-map-write-goroutine.yml +3 -3
- package/rules/tree-sitter-queries/java/infinite-loop-java.yml +3 -3
- package/rules/tree-sitter-queries/java/junit-call-super.yml +6 -4
- package/rules/tree-sitter-queries/java/no-double-checked-locking.yml +10 -8
- package/rules/tree-sitter-queries/java/no-field-shadowing.yml +1 -1
- package/rules/tree-sitter-queries/java/prepared-statement-valid-indices.yml +2 -3
- package/rules/tree-sitter-queries/java/resources-closed.yml +2 -2
- package/rules/tree-sitter-queries/java/springboot-default-package.yml +6 -3
- package/rules/tree-sitter-queries/java/switch-fall-through.yml +6 -4
- package/rules/tree-sitter-queries/java/switch-non-case-labels.yml +4 -3
- package/rules/tree-sitter-queries/java/tests-include-assertions.yml +6 -5
- package/rules/tree-sitter-queries/javascript/switch-case-termination-js.yml +5 -8
- package/rules/tree-sitter-queries/javascript/switch-non-case-labels.yml +3 -2
- package/rules/tree-sitter-queries/kotlin/prepared-statement-indices.yml +9 -5
- package/rules/tree-sitter-queries/php/this-in-static-context.yml +5 -5
- package/rules/tree-sitter-queries/python/exit-signature-check.yml +2 -9
- package/rules/tree-sitter-queries/python/in-operator-unsupported.yml +3 -4
- package/rules/tree-sitter-queries/python/no-super-torchscript.yml +4 -8
- package/rules/tree-sitter-queries/python/notimplemented-boolean-context.yml +1 -5
- package/rules/tree-sitter-queries/python/python-empty-except.yml +1 -1
- package/rules/tree-sitter-queries/python/return-in-init.yml +0 -2
- package/rules/tree-sitter-queries/python/yield-return-outside-function.yml +0 -3
- package/rules/tree-sitter-queries/ruby/ruby-command-injection.yml +1 -12
- package/rules/tree-sitter-queries/ruby/ruby-eval.yml +1 -1
- package/rules/tree-sitter-queries/ruby/ruby-insecure-deserialization.yml +4 -4
- package/rules/tree-sitter-queries/ruby/ruby-insecure-random.yml +4 -11
- package/rules/tree-sitter-queries/ruby/ruby-open-struct.yml +1 -1
- package/rules/tree-sitter-queries/ruby/ruby-string-eval.yml +2 -3
- package/rules/tree-sitter-queries/ruby/ruby-weak-hash.yml +4 -4
- package/rules/tree-sitter-queries/rust/rust-lock-held-across-await.yml +4 -3
- package/rules/tree-sitter-queries/tsx/no-nested-links.yml +4 -6
- package/rules/tree-sitter-queries/typescript/console-statement.yml +11 -0
- package/rules/tree-sitter-queries/typescript/duplicate-function-arg.yml +4 -9
- package/rules/tree-sitter-queries/typescript/empty-switch-case.yml +13 -9
- package/rules/tree-sitter-queries/typescript/infinite-loop.yml +2 -2
- package/rules/tree-sitter-queries/typescript/mixed-async-styles.yml +10 -1
- package/rules/tree-sitter-queries/typescript/switch-case-termination.yml +5 -8
- package/rules/tree-sitter-queries/typescript/ts-insecure-random.yml +7 -10
- package/rules/tree-sitter-queries/typescript/unsafe-regex.yml +4 -2
- package/rules/typos/_typos.toml +17 -0
- package/scripts/analyze-pi-lens-logs.mjs +55 -2
- package/skills/pi-lens-write-tree-sitter-rule/SKILL.md +5 -0
- package/dist/clients/ast-grep-parser.js +0 -86
- package/dist/clients/config-enabled-shape.js +0 -39
- package/dist/clients/lsp/interactive-install.js +0 -367
- package/dist/clients/lsp/lsp-index.js +0 -10
- package/dist/clients/lsp/server-strategies.js +0 -5
- package/dist/clients/project-metadata.js +0 -690
- package/dist/clients/source-groups.js +0 -96
- package/dist/clients/types.js +0 -11
- package/docs/env_variables.md +0 -10
- package/rules/tree-sitter-queries/abap-disabled/delete-where.yml +0 -46
- package/rules/tree-sitter-queries/cpp/no-confused-move-forward.yml +0 -59
- package/rules/tree-sitter-queries/cpp/noexcept-functions.yml +0 -58
- package/rules/tree-sitter-queries/java/mockito-initialized.yml +0 -66
- package/rules/tree-sitter-queries/java/no-wait-notify-on-thread.yml +0 -58
- package/rules/tree-sitter-queries/java/short-circuit-logic.yml +0 -57
- package/rules/tree-sitter-queries/java/spring-session-attributes-setcomplete.yml +0 -75
- package/rules/tree-sitter-queries/plsql-disabled/delete-update-where.yml +0 -56
- package/rules/tree-sitter-queries/plsql-disabled/end-loop-semicolon.yml +0 -51
- package/rules/tree-sitter-queries/plsql-disabled/fetch-bulk-collect-limit.yml +0 -47
- package/rules/tree-sitter-queries/plsql-disabled/forallsave-exceptions.yml +0 -51
- package/rules/tree-sitter-queries/plsql-disabled/nchar-nvarchar2-bytes.yml +0 -54
- package/rules/tree-sitter-queries/plsql-disabled/not-null-initialization.yml +0 -59
- package/rules/tree-sitter-queries/plsql-disabled/raise-application-error-codes.yml +0 -50
- package/rules/tree-sitter-queries/typescript-disabled/ts-path-traversal.yml +0 -71
|
@@ -1,96 +0,0 @@
|
|
|
1
|
-
export function partitionSourceFiles(sourceRoot, files, maxFiles = 12) {
|
|
2
|
-
if (maxFiles <= 0) {
|
|
3
|
-
throw new Error("maxFiles must be greater than zero");
|
|
4
|
-
}
|
|
5
|
-
return partitionAt(sourceRoot.replace(/\\/g, "/"), normalizeFiles(files), maxFiles, 0);
|
|
6
|
-
}
|
|
7
|
-
function normalizeFiles(files) {
|
|
8
|
-
return [...new Set(files.map((file) => file.replace(/\\/g, "/")))].sort((a, b) => a.localeCompare(b));
|
|
9
|
-
}
|
|
10
|
-
function partitionAt(sourceRoot, files, maxFiles, depth) {
|
|
11
|
-
if (files.length === 0)
|
|
12
|
-
return [];
|
|
13
|
-
if (files.length <= maxFiles) {
|
|
14
|
-
return [{ label: commonLabel(sourceRoot, files, depth), files }];
|
|
15
|
-
}
|
|
16
|
-
const directFiles = [];
|
|
17
|
-
const buckets = new Map();
|
|
18
|
-
for (const file of files) {
|
|
19
|
-
const relativePath = file.startsWith(`${sourceRoot}/`)
|
|
20
|
-
? file.slice(sourceRoot.length + 1)
|
|
21
|
-
: file;
|
|
22
|
-
const parts = relativePath.split("/");
|
|
23
|
-
if (parts.length <= depth + 1) {
|
|
24
|
-
directFiles.push(file);
|
|
25
|
-
continue;
|
|
26
|
-
}
|
|
27
|
-
const segment = parts[depth];
|
|
28
|
-
if (!segment) {
|
|
29
|
-
directFiles.push(file);
|
|
30
|
-
continue;
|
|
31
|
-
}
|
|
32
|
-
const bucket = buckets.get(segment) ?? [];
|
|
33
|
-
bucket.push(file);
|
|
34
|
-
buckets.set(segment, bucket);
|
|
35
|
-
}
|
|
36
|
-
if (buckets.size === 0) {
|
|
37
|
-
return chunkFiles(currentLabel(sourceRoot, files, depth), files, maxFiles);
|
|
38
|
-
}
|
|
39
|
-
const groups = chunkFiles(currentLabel(sourceRoot, files, depth), directFiles, maxFiles);
|
|
40
|
-
for (const [segment, bucketFiles] of [...buckets.entries()].sort(([left], [right]) => left.localeCompare(right))) {
|
|
41
|
-
if (bucketFiles.length <= maxFiles) {
|
|
42
|
-
groups.push({
|
|
43
|
-
label: `${sourceRoot}/${bucketPrefix(bucketFiles, sourceRoot, depth, segment)}`,
|
|
44
|
-
files: bucketFiles,
|
|
45
|
-
});
|
|
46
|
-
}
|
|
47
|
-
else {
|
|
48
|
-
groups.push(...partitionAt(sourceRoot, bucketFiles, maxFiles, depth + 1));
|
|
49
|
-
}
|
|
50
|
-
}
|
|
51
|
-
return groups;
|
|
52
|
-
}
|
|
53
|
-
function chunkFiles(label, files, maxFiles) {
|
|
54
|
-
if (files.length === 0)
|
|
55
|
-
return [];
|
|
56
|
-
if (files.length <= maxFiles)
|
|
57
|
-
return [{ label, files }];
|
|
58
|
-
const chunks = [];
|
|
59
|
-
for (let index = 0; index < files.length; index += maxFiles) {
|
|
60
|
-
const part = Math.floor(index / maxFiles) + 1;
|
|
61
|
-
chunks.push({
|
|
62
|
-
label: `${label}#${part}`,
|
|
63
|
-
files: files.slice(index, index + maxFiles),
|
|
64
|
-
});
|
|
65
|
-
}
|
|
66
|
-
return chunks;
|
|
67
|
-
}
|
|
68
|
-
function currentLabel(sourceRoot, files, depth) {
|
|
69
|
-
if (depth === 0)
|
|
70
|
-
return sourceRoot;
|
|
71
|
-
const first = files[0];
|
|
72
|
-
if (!first)
|
|
73
|
-
return sourceRoot;
|
|
74
|
-
const relativePath = first.startsWith(`${sourceRoot}/`)
|
|
75
|
-
? first.slice(sourceRoot.length + 1)
|
|
76
|
-
: first;
|
|
77
|
-
const parts = relativePath.split("/").slice(0, depth);
|
|
78
|
-
return parts.length === 0 ? sourceRoot : `${sourceRoot}/${parts.join("/")}`;
|
|
79
|
-
}
|
|
80
|
-
function commonLabel(sourceRoot, files, depth) {
|
|
81
|
-
if (depth === 0)
|
|
82
|
-
return sourceRoot;
|
|
83
|
-
if (files.length === 1)
|
|
84
|
-
return files[0] ?? sourceRoot;
|
|
85
|
-
return currentLabel(sourceRoot, files, depth);
|
|
86
|
-
}
|
|
87
|
-
function bucketPrefix(files, sourceRoot, depth, segment) {
|
|
88
|
-
const first = files[0];
|
|
89
|
-
if (!first || depth === 0)
|
|
90
|
-
return segment;
|
|
91
|
-
const relativePath = first.startsWith(`${sourceRoot}/`)
|
|
92
|
-
? first.slice(sourceRoot.length + 1)
|
|
93
|
-
: first;
|
|
94
|
-
const parts = relativePath.split("/").slice(0, depth);
|
|
95
|
-
return [...parts, segment].join("/");
|
|
96
|
-
}
|
package/dist/clients/types.js
DELETED
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* LSP Types - Core types for the pi-local LSP client
|
|
3
|
-
* Simplified from the full LSP spec to what we actually need
|
|
4
|
-
*/
|
|
5
|
-
export var DiagnosticSeverity;
|
|
6
|
-
(function (DiagnosticSeverity) {
|
|
7
|
-
DiagnosticSeverity[DiagnosticSeverity["Error"] = 1] = "Error";
|
|
8
|
-
DiagnosticSeverity[DiagnosticSeverity["Warning"] = 2] = "Warning";
|
|
9
|
-
DiagnosticSeverity[DiagnosticSeverity["Information"] = 3] = "Information";
|
|
10
|
-
DiagnosticSeverity[DiagnosticSeverity["Hint"] = 4] = "Hint";
|
|
11
|
-
})(DiagnosticSeverity || (DiagnosticSeverity = {}));
|
package/docs/env_variables.md
DELETED
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
# Environment Variables
|
|
2
|
-
|
|
3
|
-
See [`environment-variables.md`](environment-variables.md) for the full reference.
|
|
4
|
-
|
|
5
|
-
Common variables:
|
|
6
|
-
|
|
7
|
-
- `PILENS_DATA_DIR` — redirect per-project persistent state outside the workspace.
|
|
8
|
-
- `PI_LENS_STARTUP_MODE` — choose `full`, `minimal`, or `quick` startup mode.
|
|
9
|
-
- `PI_LENS_NO_CONTEXT_INJECTION=1` — keep tools, LSP, read-guard, and formatting
|
|
10
|
-
active while disabling automatic turn-end/session-start context injection.
|
|
@@ -1,46 +0,0 @@
|
|
|
1
|
-
# ABAP DELETE Without WHERE
|
|
2
|
-
# Detects DELETE statements without WHERE in ABAP
|
|
3
|
-
id: delete-where
|
|
4
|
-
name: DELETE FROM Should Have WHERE Clause
|
|
5
|
-
severity: error
|
|
6
|
-
category: reliability
|
|
7
|
-
defect_class: correctness
|
|
8
|
-
inline_tier: blocking
|
|
9
|
-
language: abap
|
|
10
|
-
|
|
11
|
-
message: "DELETE FROM statement should have a WHERE clause"
|
|
12
|
-
|
|
13
|
-
description: |
|
|
14
|
-
DELETE FROM without WHERE deletes ALL rows. Almost always a bug.
|
|
15
|
-
|
|
16
|
-
✅ FIX: Add WHERE clause
|
|
17
|
-
|
|
18
|
-
```abap
|
|
19
|
-
DELETE FROM employees WHERE id = lv_id. " GOOD
|
|
20
|
-
```
|
|
21
|
-
|
|
22
|
-
query: |
|
|
23
|
-
(delete_statement
|
|
24
|
-
(delete) @DELETE
|
|
25
|
-
(from_clause)
|
|
26
|
-
(where_clause)? @WHERE)
|
|
27
|
-
|
|
28
|
-
metavars:
|
|
29
|
-
- DELETE
|
|
30
|
-
- WHERE
|
|
31
|
-
|
|
32
|
-
post_filter: missing_where
|
|
33
|
-
|
|
34
|
-
tags:
|
|
35
|
-
- reliability
|
|
36
|
-
- abap
|
|
37
|
-
- data-loss
|
|
38
|
-
|
|
39
|
-
examples:
|
|
40
|
-
bad: |
|
|
41
|
-
DELETE FROM employees. " BAD
|
|
42
|
-
|
|
43
|
-
good: |
|
|
44
|
-
DELETE FROM employees WHERE id = 123. " GOOD
|
|
45
|
-
|
|
46
|
-
has_fix: false
|
|
@@ -1,59 +0,0 @@
|
|
|
1
|
-
# No Confused std::move/std::forward
|
|
2
|
-
# Detects potential confusion between std::move and std::forward
|
|
3
|
-
id: no-confused-move-forward
|
|
4
|
-
name: std::move and std::forward Should Not Be Confused
|
|
5
|
-
severity: error
|
|
6
|
-
category: reliability
|
|
7
|
-
defect_class: correctness
|
|
8
|
-
inline_tier: blocking
|
|
9
|
-
language: cpp
|
|
10
|
-
|
|
11
|
-
message: "std::move and std::forward should not be confused"
|
|
12
|
-
|
|
13
|
-
description: |
|
|
14
|
-
std::move unconditionally casts to rvalue, while std::forward
|
|
15
|
-
conditionally casts based on template parameter. Using the wrong
|
|
16
|
-
one can lead to subtle bugs and unexpected copies/moves.
|
|
17
|
-
|
|
18
|
-
✅ FIX: Use std::move for known objects, std::forward for templates
|
|
19
|
-
|
|
20
|
-
```cpp
|
|
21
|
-
template<typename T>
|
|
22
|
-
void process(T&& t) {
|
|
23
|
-
other(std::forward<T>(t)); // Correct - preserve value category
|
|
24
|
-
}
|
|
25
|
-
```
|
|
26
|
-
|
|
27
|
-
query: |
|
|
28
|
-
(call_expression
|
|
29
|
-
function: (qualified_identifier
|
|
30
|
-
name: (identifier) @FUNC
|
|
31
|
-
(#match? @FUNC "^(move|forward)$"))
|
|
32
|
-
arguments: (argument_list) @ARGS)
|
|
33
|
-
|
|
34
|
-
post_filter: confused_move_forward
|
|
35
|
-
|
|
36
|
-
metavars:
|
|
37
|
-
- FUNC
|
|
38
|
-
- ARGS
|
|
39
|
-
|
|
40
|
-
tags:
|
|
41
|
-
- reliability
|
|
42
|
-
- cpp
|
|
43
|
-
- move-semantics
|
|
44
|
-
- cppcoreguidelines
|
|
45
|
-
|
|
46
|
-
examples:
|
|
47
|
-
bad: |
|
|
48
|
-
template<typename T>
|
|
49
|
-
void wrapper(T&& t) {
|
|
50
|
-
return foo(std::move(t)); // BAD - breaks perfect forwarding
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
good: |
|
|
54
|
-
template<typename T>
|
|
55
|
-
void wrapper(T&& t) {
|
|
56
|
-
return foo(std::forward<T>(t)); // GOOD - preserves category
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
has_fix: false
|
|
@@ -1,58 +0,0 @@
|
|
|
1
|
-
# Noexcept Functions
|
|
2
|
-
# Detects functions that should be noexcept
|
|
3
|
-
id: noexcept-functions
|
|
4
|
-
name: Exception-Unfriendly Functions Should Be noexcept
|
|
5
|
-
severity: error
|
|
6
|
-
category: reliability
|
|
7
|
-
defect_class: correctness
|
|
8
|
-
inline_tier: blocking
|
|
9
|
-
language: cpp
|
|
10
|
-
|
|
11
|
-
message: "Function should be declared noexcept"
|
|
12
|
-
|
|
13
|
-
description: |
|
|
14
|
-
Functions that don't throw exceptions should be marked noexcept.
|
|
15
|
-
This enables compiler optimizations and better error handling.
|
|
16
|
-
This is a MISRA C++ 2023 rule.
|
|
17
|
-
|
|
18
|
-
✅ FIX: Add noexcept specifier
|
|
19
|
-
|
|
20
|
-
```cpp
|
|
21
|
-
int add(int a, int b) noexcept { // GOOD - noexcept
|
|
22
|
-
return a + b;
|
|
23
|
-
}
|
|
24
|
-
```
|
|
25
|
-
|
|
26
|
-
query: |
|
|
27
|
-
(function_definition
|
|
28
|
-
type: (primitive_type) @RET
|
|
29
|
-
(function_declarator
|
|
30
|
-
name: (identifier) @NAME)
|
|
31
|
-
body: (compound_statement) @BODY)
|
|
32
|
-
|
|
33
|
-
metavars:
|
|
34
|
-
- RET
|
|
35
|
-
- NAME
|
|
36
|
-
- BODY
|
|
37
|
-
|
|
38
|
-
post_filter: should_be_noexcept
|
|
39
|
-
|
|
40
|
-
tags:
|
|
41
|
-
- reliability
|
|
42
|
-
- cpp
|
|
43
|
-
- misra-cpp2023
|
|
44
|
-
- performance
|
|
45
|
-
|
|
46
|
-
examples:
|
|
47
|
-
bad: |
|
|
48
|
-
int add(int a, int b) { // BAD - missing noexcept
|
|
49
|
-
return a + b;
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
good: |
|
|
53
|
-
int add(int a, int b) noexcept { // GOOD
|
|
54
|
-
return a + b;
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
has_fix: true
|
|
58
|
-
fix_action: add_noexcept
|
|
@@ -1,66 +0,0 @@
|
|
|
1
|
-
# Mockito Initialized
|
|
2
|
-
# Detects annotated Mockito objects that may not be initialized
|
|
3
|
-
id: mockito-initialized
|
|
4
|
-
name: Annotated Mockito Objects Should Be Initialized
|
|
5
|
-
severity: error
|
|
6
|
-
category: reliability
|
|
7
|
-
defect_class: correctness
|
|
8
|
-
inline_tier: blocking
|
|
9
|
-
language: java
|
|
10
|
-
|
|
11
|
-
message: "@Mock/@InjectMocks object should be initialized with MockitoAnnotations.openMocks()"
|
|
12
|
-
|
|
13
|
-
description: |
|
|
14
|
-
@Mock, @Spy, @Captor, @InjectMocks fields must be initialized
|
|
15
|
-
before use. Call MockitoAnnotations.openMocks(this) in @Before
|
|
16
|
-
or use MockitoJUnitRunner.
|
|
17
|
-
|
|
18
|
-
✅ FIX: Add initialization in @Before method
|
|
19
|
-
|
|
20
|
-
```java
|
|
21
|
-
@Before
|
|
22
|
-
public void setUp() {
|
|
23
|
-
MockitoAnnotations.openMocks(this); // GOOD
|
|
24
|
-
}
|
|
25
|
-
```
|
|
26
|
-
|
|
27
|
-
query: |
|
|
28
|
-
(field_declaration
|
|
29
|
-
(modifiers
|
|
30
|
-
(annotation
|
|
31
|
-
name: (identifier) @ANNOT (#match? @ANNOT "^(Mock|Spy|Captor|InjectMocks)$")))
|
|
32
|
-
(variable_declarator
|
|
33
|
-
name: (identifier) @FIELD))
|
|
34
|
-
|
|
35
|
-
metavars:
|
|
36
|
-
- ANNOT
|
|
37
|
-
- FIELD
|
|
38
|
-
|
|
39
|
-
post_filter: missing_mockito_init
|
|
40
|
-
|
|
41
|
-
tags:
|
|
42
|
-
- reliability
|
|
43
|
-
- java
|
|
44
|
-
- mockito
|
|
45
|
-
- testing
|
|
46
|
-
|
|
47
|
-
examples:
|
|
48
|
-
bad: |
|
|
49
|
-
@Mock
|
|
50
|
-
private Service service; // BAD - not initialized
|
|
51
|
-
|
|
52
|
-
@Test
|
|
53
|
-
public void test() {
|
|
54
|
-
service.doSomething(); // NullPointerException!
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
good: |
|
|
58
|
-
@Mock
|
|
59
|
-
private Service service;
|
|
60
|
-
|
|
61
|
-
@Before
|
|
62
|
-
public void setUp() {
|
|
63
|
-
MockitoAnnotations.openMocks(this); // GOOD
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
has_fix: false
|
|
@@ -1,58 +0,0 @@
|
|
|
1
|
-
# No Wait/Notify on Thread
|
|
2
|
-
# Detects wait(), notify(), notifyAll() called on Thread instances
|
|
3
|
-
id: no-wait-notify-on-thread
|
|
4
|
-
name: Wait/Notify Should Not Be Called on Thread Instances
|
|
5
|
-
severity: error
|
|
6
|
-
category: reliability
|
|
7
|
-
defect_class: correctness
|
|
8
|
-
inline_tier: blocking
|
|
9
|
-
language: java
|
|
10
|
-
|
|
11
|
-
message: "{{METHOD}}() should not be called on Thread instances"
|
|
12
|
-
|
|
13
|
-
description: |
|
|
14
|
-
Calling wait(), notify(), or notifyAll() on Thread objects can
|
|
15
|
-
conflict with the Thread's internal join mechanism, causing
|
|
16
|
-
unexpected behavior. Use them on a separate lock object.
|
|
17
|
-
|
|
18
|
-
✅ FIX: Use a dedicated lock object
|
|
19
|
-
|
|
20
|
-
```java
|
|
21
|
-
private final Object lock = new Object();
|
|
22
|
-
|
|
23
|
-
synchronized (lock) {
|
|
24
|
-
lock.wait(); // GOOD - separate lock
|
|
25
|
-
}
|
|
26
|
-
```
|
|
27
|
-
|
|
28
|
-
query: |
|
|
29
|
-
(method_invocation
|
|
30
|
-
object: (identifier) @OBJ
|
|
31
|
-
name: (identifier) @METHOD
|
|
32
|
-
(#match? @METHOD "^(wait|notify|notifyAll)$"))
|
|
33
|
-
|
|
34
|
-
metavars:
|
|
35
|
-
- METHOD
|
|
36
|
-
- OBJ
|
|
37
|
-
|
|
38
|
-
post_filter: called_on_thread_instance
|
|
39
|
-
|
|
40
|
-
tags:
|
|
41
|
-
- reliability
|
|
42
|
-
- java
|
|
43
|
-
- multi-threading
|
|
44
|
-
- bugs
|
|
45
|
-
|
|
46
|
-
examples:
|
|
47
|
-
bad: |
|
|
48
|
-
Thread thread = new Thread(runnable);
|
|
49
|
-
thread.wait(); // BAD - on Thread instance
|
|
50
|
-
thread.notify(); // BAD
|
|
51
|
-
|
|
52
|
-
good: |
|
|
53
|
-
Object lock = new Object();
|
|
54
|
-
synchronized (lock) {
|
|
55
|
-
lock.wait(); // GOOD - on separate lock
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
has_fix: false
|
|
@@ -1,57 +0,0 @@
|
|
|
1
|
-
# Short Circuit Logic
|
|
2
|
-
# Detects non-short-circuit operators in boolean contexts
|
|
3
|
-
id: short-circuit-logic
|
|
4
|
-
name: Short-Circuit Logic Should Be Used in Boolean Contexts
|
|
5
|
-
severity: error
|
|
6
|
-
category: maintainability
|
|
7
|
-
defect_class: correctness
|
|
8
|
-
inline_tier: blocking
|
|
9
|
-
language: java
|
|
10
|
-
|
|
11
|
-
message: "Use '{{OP}}' instead of '{{BAD_OP}}' for short-circuit evaluation"
|
|
12
|
-
|
|
13
|
-
description: |
|
|
14
|
-
Use && and || for boolean logic (short-circuit). & and | are
|
|
15
|
-
bitwise operators that evaluate both sides, causing unnecessary
|
|
16
|
-
computation and potential errors.
|
|
17
|
-
|
|
18
|
-
✅ FIX: Use && or ||
|
|
19
|
-
|
|
20
|
-
```java
|
|
21
|
-
if (obj != null && obj.isValid()) { // GOOD - short-circuit
|
|
22
|
-
```
|
|
23
|
-
|
|
24
|
-
query: |
|
|
25
|
-
(binary_expression
|
|
26
|
-
(identifier) @LEFT
|
|
27
|
-
"&" @BAD_OP
|
|
28
|
-
(identifier) @RIGHT)
|
|
29
|
-
(binary_expression
|
|
30
|
-
(identifier) @LEFT
|
|
31
|
-
"|" @BAD_OP
|
|
32
|
-
(identifier) @RIGHT)
|
|
33
|
-
|
|
34
|
-
metavars:
|
|
35
|
-
- LEFT
|
|
36
|
-
- BAD_OP
|
|
37
|
-
- RIGHT
|
|
38
|
-
|
|
39
|
-
post_filter: boolean_operands
|
|
40
|
-
|
|
41
|
-
tags:
|
|
42
|
-
- maintainability
|
|
43
|
-
- java
|
|
44
|
-
- cert
|
|
45
|
-
- performance
|
|
46
|
-
|
|
47
|
-
examples:
|
|
48
|
-
bad: |
|
|
49
|
-
if (a & b) { } // BAD - bitwise AND
|
|
50
|
-
if (x | y) { } // BAD - bitwise OR
|
|
51
|
-
|
|
52
|
-
good: |
|
|
53
|
-
if (a && b) { } // GOOD - short-circuit
|
|
54
|
-
if (x || y) { } // GOOD - short-circuit
|
|
55
|
-
|
|
56
|
-
has_fix: true
|
|
57
|
-
fix_action: replace_with_short_circuit
|
|
@@ -1,75 +0,0 @@
|
|
|
1
|
-
# Spring SessionAttributes setComplete
|
|
2
|
-
# Detects @Controller classes with @SessionAttributes that don't call setComplete
|
|
3
|
-
id: spring-session-attributes-setcomplete
|
|
4
|
-
name: SessionAttributes Controllers Must Call setComplete
|
|
5
|
-
severity: error
|
|
6
|
-
category: reliability
|
|
7
|
-
defect_class: correctness
|
|
8
|
-
inline_tier: blocking
|
|
9
|
-
language: java
|
|
10
|
-
|
|
11
|
-
message: "@Controller with @SessionAttributes must call setComplete on SessionStatus"
|
|
12
|
-
|
|
13
|
-
description: |
|
|
14
|
-
Controllers using @SessionAttributes must call setComplete() on the SessionStatus
|
|
15
|
-
parameter to clean up session attributes. Otherwise, session data leaks
|
|
16
|
-
and causes memory issues.
|
|
17
|
-
|
|
18
|
-
✅ FIX: Call setComplete() when done with session attributes
|
|
19
|
-
|
|
20
|
-
```java
|
|
21
|
-
@Controller
|
|
22
|
-
@SessionAttributes("user")
|
|
23
|
-
public class UserController {
|
|
24
|
-
@RequestMapping("/complete")
|
|
25
|
-
public String complete(SessionStatus status) {
|
|
26
|
-
status.setComplete(); // Clear session attributes
|
|
27
|
-
return "done";
|
|
28
|
-
}
|
|
29
|
-
}
|
|
30
|
-
```
|
|
31
|
-
|
|
32
|
-
query: |
|
|
33
|
-
(class_declaration
|
|
34
|
-
(modifiers
|
|
35
|
-
(annotation
|
|
36
|
-
name: (identifier) @ANNOT1 (#eq? @ANNOT1 "Controller"))
|
|
37
|
-
(annotation
|
|
38
|
-
name: (identifier) @ANNOT2 (#eq? @ANNOT2 "SessionAttributes"))))
|
|
39
|
-
|
|
40
|
-
metavars:
|
|
41
|
-
- ANNOT1
|
|
42
|
-
- ANNOT2
|
|
43
|
-
|
|
44
|
-
post_filter: missing_setcomplete_call
|
|
45
|
-
|
|
46
|
-
tags:
|
|
47
|
-
- reliability
|
|
48
|
-
- java
|
|
49
|
-
- spring
|
|
50
|
-
- session
|
|
51
|
-
- memory-leak
|
|
52
|
-
|
|
53
|
-
examples:
|
|
54
|
-
bad: |
|
|
55
|
-
@Controller
|
|
56
|
-
@SessionAttributes("data")
|
|
57
|
-
public class MyController {
|
|
58
|
-
@PostMapping("/submit")
|
|
59
|
-
public String submit(SessionStatus status) { // Missing setComplete()
|
|
60
|
-
return "done";
|
|
61
|
-
}
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
good: |
|
|
65
|
-
@Controller
|
|
66
|
-
@SessionAttributes("data")
|
|
67
|
-
public class MyController {
|
|
68
|
-
@PostMapping("/submit")
|
|
69
|
-
public String submit(SessionStatus status) {
|
|
70
|
-
status.setComplete(); // GOOD - clean up
|
|
71
|
-
return "done";
|
|
72
|
-
}
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
has_fix: false
|
|
@@ -1,56 +0,0 @@
|
|
|
1
|
-
# DELETE and UPDATE Without WHERE
|
|
2
|
-
# Detects DELETE and UPDATE statements without WHERE clauses in PL/SQL
|
|
3
|
-
id: delete-update-where
|
|
4
|
-
name: DELETE and UPDATE Should Contain WHERE Clauses
|
|
5
|
-
severity: error
|
|
6
|
-
category: reliability
|
|
7
|
-
defect_class: correctness
|
|
8
|
-
inline_tier: blocking
|
|
9
|
-
language: plsql
|
|
10
|
-
|
|
11
|
-
message: "{{STATEMENT}} statement should contain a WHERE clause"
|
|
12
|
-
|
|
13
|
-
description: |
|
|
14
|
-
DELETE and UPDATE without WHERE clauses affect ALL rows in the table.
|
|
15
|
-
This is almost always a bug and can cause data loss.
|
|
16
|
-
|
|
17
|
-
✅ FIX: Add a WHERE clause to limit affected rows
|
|
18
|
-
|
|
19
|
-
```sql
|
|
20
|
-
DELETE FROM employees WHERE id = emp_id; -- GOOD
|
|
21
|
-
UPDATE employees SET status = 'inactive' WHERE id = emp_id; -- GOOD
|
|
22
|
-
```
|
|
23
|
-
|
|
24
|
-
query: |
|
|
25
|
-
(delete_statement
|
|
26
|
-
(delete) @DELETE
|
|
27
|
-
(from_clause)
|
|
28
|
-
(where_clause)? @WHERE)
|
|
29
|
-
(update_statement
|
|
30
|
-
(update) @UPDATE
|
|
31
|
-
(table_reference)
|
|
32
|
-
(where_clause)? @WHERE)
|
|
33
|
-
|
|
34
|
-
metavars:
|
|
35
|
-
- DELETE
|
|
36
|
-
- UPDATE
|
|
37
|
-
- WHERE
|
|
38
|
-
|
|
39
|
-
post_filter: missing_where_clause
|
|
40
|
-
|
|
41
|
-
tags:
|
|
42
|
-
- reliability
|
|
43
|
-
- plsql
|
|
44
|
-
- sql
|
|
45
|
-
- data-loss
|
|
46
|
-
|
|
47
|
-
examples:
|
|
48
|
-
bad: |
|
|
49
|
-
DELETE FROM employees; -- BAD - deletes all rows!
|
|
50
|
-
UPDATE employees SET salary = 0; -- BAD - updates all rows!
|
|
51
|
-
|
|
52
|
-
good: |
|
|
53
|
-
DELETE FROM employees WHERE id = 123; -- GOOD
|
|
54
|
-
UPDATE employees SET salary = 0 WHERE department = 'TEMP'; -- GOOD
|
|
55
|
-
|
|
56
|
-
has_fix: false
|
|
@@ -1,51 +0,0 @@
|
|
|
1
|
-
# END LOOP Semicolon
|
|
2
|
-
# Detects END LOOP without following semicolon
|
|
3
|
-
id: end-loop-semicolon
|
|
4
|
-
name: END LOOP Should Be Followed By Semicolon
|
|
5
|
-
severity: error
|
|
6
|
-
category: reliability
|
|
7
|
-
defect_class: correctness
|
|
8
|
-
inline_tier: blocking
|
|
9
|
-
language: plsql
|
|
10
|
-
|
|
11
|
-
message: "END LOOP should be followed by a semicolon"
|
|
12
|
-
|
|
13
|
-
description: |
|
|
14
|
-
The END LOOP keyword must be followed by a semicolon.
|
|
15
|
-
Missing semicolon causes a syntax error.
|
|
16
|
-
|
|
17
|
-
✅ FIX: Add semicolon after END LOOP
|
|
18
|
-
|
|
19
|
-
```sql
|
|
20
|
-
LOOP
|
|
21
|
-
EXIT WHEN condition;
|
|
22
|
-
END LOOP; -- GOOD - has semicolon
|
|
23
|
-
```
|
|
24
|
-
|
|
25
|
-
query: |
|
|
26
|
-
(loop_statement
|
|
27
|
-
(end_loop) @ENDLOOP)
|
|
28
|
-
|
|
29
|
-
metavars:
|
|
30
|
-
- ENDLOOP
|
|
31
|
-
|
|
32
|
-
post_filter: missing_following_semicolon
|
|
33
|
-
|
|
34
|
-
tags:
|
|
35
|
-
- reliability
|
|
36
|
-
- plsql
|
|
37
|
-
- syntax
|
|
38
|
-
|
|
39
|
-
examples:
|
|
40
|
-
bad: |
|
|
41
|
-
LOOP
|
|
42
|
-
EXIT WHEN x > 10;
|
|
43
|
-
END LOOP -- BAD - missing semicolon
|
|
44
|
-
|
|
45
|
-
good: |
|
|
46
|
-
LOOP
|
|
47
|
-
EXIT WHEN x > 10;
|
|
48
|
-
END LOOP; -- GOOD
|
|
49
|
-
|
|
50
|
-
has_fix: true
|
|
51
|
-
fix_action: add_semicolon
|
|
@@ -1,47 +0,0 @@
|
|
|
1
|
-
# FETCH BULK COLLECT With LIMIT
|
|
2
|
-
# Detects FETCH ... BULK COLLECT without LIMIT clause
|
|
3
|
-
id: fetch-bulk-collect-limit
|
|
4
|
-
name: FETCH BULK COLLECT INTO Should Use LIMIT Clause
|
|
5
|
-
severity: error
|
|
6
|
-
category: reliability
|
|
7
|
-
defect_class: correctness
|
|
8
|
-
inline_tier: blocking
|
|
9
|
-
language: plsql
|
|
10
|
-
|
|
11
|
-
message: "FETCH ... BULK COLLECT INTO should not be used without a LIMIT clause"
|
|
12
|
-
|
|
13
|
-
description: |
|
|
14
|
-
FETCH ... BULK COLLECT without LIMIT fetches ALL rows into memory.
|
|
15
|
-
This can cause out-of-memory errors for large result sets.
|
|
16
|
-
|
|
17
|
-
✅ FIX: Add LIMIT clause to control batch size
|
|
18
|
-
|
|
19
|
-
```sql
|
|
20
|
-
FETCH cursor BULK COLLECT INTO collection LIMIT 1000; -- GOOD
|
|
21
|
-
```
|
|
22
|
-
|
|
23
|
-
query: |
|
|
24
|
-
(fetch_statement
|
|
25
|
-
(fetch) @FETCH
|
|
26
|
-
(bulk_collect_into_clause) @BULK)
|
|
27
|
-
|
|
28
|
-
metavars:
|
|
29
|
-
- FETCH
|
|
30
|
-
- BULK
|
|
31
|
-
|
|
32
|
-
post_filter: missing_limit_clause
|
|
33
|
-
|
|
34
|
-
tags:
|
|
35
|
-
- reliability
|
|
36
|
-
- plsql
|
|
37
|
-
- performance
|
|
38
|
-
- memory
|
|
39
|
-
|
|
40
|
-
examples:
|
|
41
|
-
bad: |
|
|
42
|
-
FETCH cursor BULK COLLECT INTO employees; -- BAD - no LIMIT
|
|
43
|
-
|
|
44
|
-
good: |
|
|
45
|
-
FETCH cursor BULK COLLECT INTO employees LIMIT 1000; -- GOOD
|
|
46
|
-
|
|
47
|
-
has_fix: false
|