deep-slop 1.5.0 → 1.6.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/dist/{ast-slop-BGdr58wZ.js → ast-slop-B6Y39w1U.js} +1 -1
- package/dist/{dead-flow-DHRkyxZT.js → dead-flow-BgowgQ-_.js} +1 -1
- package/dist/deep-slop-bundled.js +1109 -1033
- package/dist/{import-intelligence-SK4F7XpL.js → import-intelligence-B7R90PWJ.js} +1 -1
- package/dist/index.js +5 -3
- package/dist/mcp.js +191 -113
- package/dist/{tree-sitter-CM-cP0nl.js → tree-sitter-CBpekmYc.js} +99 -26
- package/package.json +1 -1
|
@@ -3899,636 +3899,192 @@ var init_file_cache = __esm({
|
|
|
3899
3899
|
}
|
|
3900
3900
|
});
|
|
3901
3901
|
|
|
3902
|
-
// src/
|
|
3903
|
-
|
|
3904
|
-
|
|
3905
|
-
|
|
3906
|
-
|
|
3907
|
-
|
|
3908
|
-
|
|
3902
|
+
// src/utils/tree-sitter.ts
|
|
3903
|
+
function clearParseCache() {
|
|
3904
|
+
parseCache.clear();
|
|
3905
|
+
}
|
|
3906
|
+
async function initParser() {
|
|
3907
|
+
if (initDone) return initOk;
|
|
3908
|
+
if (initPromise) return initPromise;
|
|
3909
|
+
initPromise = (async () => {
|
|
3910
|
+
try {
|
|
3911
|
+
const wt = await import("web-tree-sitter");
|
|
3912
|
+
const { dirname: dirname9 } = await import("node:path");
|
|
3913
|
+
const wasmDir = dirname9(
|
|
3914
|
+
__require.resolve("web-tree-sitter/tree-sitter.wasm")
|
|
3915
|
+
);
|
|
3916
|
+
await wt.Parser.init({
|
|
3917
|
+
locateFile: (name) => `${wasmDir}/${name}`
|
|
3918
|
+
});
|
|
3919
|
+
const parser = new wt.Parser();
|
|
3920
|
+
parserInstance = parser;
|
|
3921
|
+
const tsWasm = __require.resolve(
|
|
3922
|
+
"tree-sitter-typescript/tree-sitter-typescript.wasm"
|
|
3923
|
+
);
|
|
3924
|
+
tsLang = await wt.Language.load(tsWasm);
|
|
3925
|
+
const tsxWasm = __require.resolve(
|
|
3926
|
+
"tree-sitter-typescript/tree-sitter-tsx.wasm"
|
|
3927
|
+
);
|
|
3928
|
+
tsxLang = await wt.Language.load(tsxWasm);
|
|
3929
|
+
initDone = true;
|
|
3930
|
+
initOk = true;
|
|
3931
|
+
return true;
|
|
3932
|
+
} catch (err) {
|
|
3933
|
+
initDone = true;
|
|
3934
|
+
initOk = false;
|
|
3935
|
+
return false;
|
|
3909
3936
|
}
|
|
3910
|
-
|
|
3911
|
-
|
|
3937
|
+
})();
|
|
3938
|
+
return initPromise;
|
|
3939
|
+
}
|
|
3940
|
+
async function initPythonParser() {
|
|
3941
|
+
if (pyInitDone) return pyInitOk;
|
|
3942
|
+
if (!initOk) {
|
|
3943
|
+
const baseOk = await initParser();
|
|
3944
|
+
if (!baseOk) {
|
|
3945
|
+
pyInitDone = true;
|
|
3946
|
+
pyInitOk = false;
|
|
3947
|
+
return false;
|
|
3912
3948
|
}
|
|
3913
|
-
|
|
3949
|
+
}
|
|
3950
|
+
try {
|
|
3951
|
+
const pyWasm = __require.resolve(
|
|
3952
|
+
"tree-sitter-python/python.wasm"
|
|
3953
|
+
);
|
|
3954
|
+
const wt = await import("web-tree-sitter");
|
|
3955
|
+
pyLang = await wt.Language.load(pyWasm);
|
|
3956
|
+
pyInitDone = true;
|
|
3957
|
+
pyInitOk = true;
|
|
3958
|
+
return true;
|
|
3914
3959
|
} catch {
|
|
3915
|
-
|
|
3960
|
+
pyInitDone = true;
|
|
3961
|
+
pyInitOk = false;
|
|
3962
|
+
return false;
|
|
3916
3963
|
}
|
|
3917
3964
|
}
|
|
3918
|
-
async function
|
|
3919
|
-
|
|
3920
|
-
|
|
3921
|
-
|
|
3922
|
-
|
|
3923
|
-
|
|
3924
|
-
|
|
3925
|
-
|
|
3965
|
+
async function initGoParser() {
|
|
3966
|
+
if (goInitDone) return goInitOk;
|
|
3967
|
+
if (!initOk) {
|
|
3968
|
+
const baseOk = await initParser();
|
|
3969
|
+
if (!baseOk) {
|
|
3970
|
+
goInitDone = true;
|
|
3971
|
+
goInitOk = false;
|
|
3972
|
+
return false;
|
|
3926
3973
|
}
|
|
3927
3974
|
}
|
|
3928
|
-
|
|
3929
|
-
|
|
3930
|
-
|
|
3931
|
-
|
|
3932
|
-
|
|
3975
|
+
try {
|
|
3976
|
+
const goWasm = __require.resolve(
|
|
3977
|
+
"tree-sitter-go/go.wasm"
|
|
3978
|
+
);
|
|
3979
|
+
const wt = await import("web-tree-sitter");
|
|
3980
|
+
goLang = await wt.Language.load(goWasm);
|
|
3981
|
+
goInitDone = true;
|
|
3982
|
+
goInitOk = true;
|
|
3983
|
+
return true;
|
|
3984
|
+
} catch {
|
|
3985
|
+
goInitDone = true;
|
|
3986
|
+
goInitOk = false;
|
|
3987
|
+
return false;
|
|
3933
3988
|
}
|
|
3934
|
-
});
|
|
3935
|
-
|
|
3936
|
-
// src/plugins/registry.ts
|
|
3937
|
-
var registry_exports = {};
|
|
3938
|
-
__export(registry_exports, {
|
|
3939
|
-
PLUGIN_DIR: () => PLUGIN_DIR,
|
|
3940
|
-
discoverAndLoadPlugins: () => discoverAndLoadPlugins,
|
|
3941
|
-
getPluginDir: () => getPluginDir,
|
|
3942
|
-
pluginRegistry: () => pluginRegistry
|
|
3943
|
-
});
|
|
3944
|
-
import { join as join2 } from "node:path";
|
|
3945
|
-
import { readdir } from "node:fs/promises";
|
|
3946
|
-
import { existsSync as existsSync2 } from "node:fs";
|
|
3947
|
-
function getPluginDir(rootDir) {
|
|
3948
|
-
return join2(rootDir, PLUGIN_DIR);
|
|
3949
3989
|
}
|
|
3950
|
-
async function
|
|
3951
|
-
if (
|
|
3952
|
-
|
|
3990
|
+
async function initRustParser() {
|
|
3991
|
+
if (rustInitDone) return rustInitOk;
|
|
3992
|
+
if (!initOk) {
|
|
3993
|
+
const baseOk = await initParser();
|
|
3994
|
+
if (!baseOk) {
|
|
3995
|
+
rustInitDone = true;
|
|
3996
|
+
rustInitOk = false;
|
|
3997
|
+
return false;
|
|
3998
|
+
}
|
|
3953
3999
|
}
|
|
3954
|
-
|
|
3955
|
-
|
|
3956
|
-
|
|
3957
|
-
|
|
4000
|
+
try {
|
|
4001
|
+
const rustWasm = __require.resolve(
|
|
4002
|
+
"tree-sitter-rust/rust.wasm"
|
|
4003
|
+
);
|
|
4004
|
+
const wt = await import("web-tree-sitter");
|
|
4005
|
+
rustLang = await wt.Language.load(rustWasm);
|
|
4006
|
+
rustInitDone = true;
|
|
4007
|
+
rustInitOk = true;
|
|
4008
|
+
return true;
|
|
4009
|
+
} catch {
|
|
4010
|
+
rustInitDone = true;
|
|
4011
|
+
rustInitOk = false;
|
|
4012
|
+
return false;
|
|
4013
|
+
}
|
|
4014
|
+
}
|
|
4015
|
+
async function initPhpParser() {
|
|
4016
|
+
if (phpInitDone) return phpInitOk;
|
|
4017
|
+
if (!initOk) {
|
|
4018
|
+
const baseOk = await initParser();
|
|
4019
|
+
if (!baseOk) {
|
|
4020
|
+
phpInitDone = true;
|
|
4021
|
+
phpInitOk = false;
|
|
4022
|
+
return false;
|
|
4023
|
+
}
|
|
3958
4024
|
}
|
|
3959
4025
|
try {
|
|
3960
|
-
const
|
|
3961
|
-
|
|
3962
|
-
|
|
3963
|
-
|
|
3964
|
-
|
|
3965
|
-
|
|
3966
|
-
|
|
3967
|
-
|
|
3968
|
-
|
|
3969
|
-
|
|
3970
|
-
|
|
4026
|
+
const phpWasm = __require.resolve(
|
|
4027
|
+
"tree-sitter-php/php.wasm"
|
|
4028
|
+
);
|
|
4029
|
+
const wt = await import("web-tree-sitter");
|
|
4030
|
+
phpLang = await wt.Language.load(phpWasm);
|
|
4031
|
+
phpInitDone = true;
|
|
4032
|
+
phpInitOk = true;
|
|
4033
|
+
return true;
|
|
4034
|
+
} catch {
|
|
4035
|
+
phpInitDone = true;
|
|
4036
|
+
phpInitOk = false;
|
|
4037
|
+
return false;
|
|
4038
|
+
}
|
|
4039
|
+
}
|
|
4040
|
+
async function initCsharpParser() {
|
|
4041
|
+
if (csharpInitDone) return csharpInitOk;
|
|
4042
|
+
if (!initOk) {
|
|
4043
|
+
const baseOk = await initParser();
|
|
4044
|
+
if (!baseOk) {
|
|
4045
|
+
csharpInitDone = true;
|
|
4046
|
+
csharpInitOk = false;
|
|
4047
|
+
return false;
|
|
3971
4048
|
}
|
|
3972
|
-
|
|
3973
|
-
|
|
3974
|
-
|
|
3975
|
-
|
|
3976
|
-
|
|
3977
|
-
|
|
3978
|
-
|
|
3979
|
-
|
|
3980
|
-
|
|
3981
|
-
|
|
3982
|
-
|
|
3983
|
-
|
|
3984
|
-
|
|
3985
|
-
|
|
3986
|
-
|
|
4049
|
+
}
|
|
4050
|
+
try {
|
|
4051
|
+
const csharpWasm = __require.resolve(
|
|
4052
|
+
"tree-sitter-c-sharp/c_sharp.wasm"
|
|
4053
|
+
);
|
|
4054
|
+
const wt = await import("web-tree-sitter");
|
|
4055
|
+
csharpLang = await wt.Language.load(csharpWasm);
|
|
4056
|
+
csharpInitDone = true;
|
|
4057
|
+
csharpInitOk = true;
|
|
4058
|
+
return true;
|
|
4059
|
+
} catch {
|
|
4060
|
+
csharpInitDone = true;
|
|
4061
|
+
csharpInitOk = false;
|
|
4062
|
+
return false;
|
|
4063
|
+
}
|
|
4064
|
+
}
|
|
4065
|
+
async function initSwiftParser() {
|
|
4066
|
+
if (swiftInitDone) return swiftInitOk;
|
|
4067
|
+
if (!initOk) {
|
|
4068
|
+
const baseOk = await initParser();
|
|
4069
|
+
if (!baseOk) {
|
|
4070
|
+
swiftInitDone = true;
|
|
4071
|
+
swiftInitOk = false;
|
|
4072
|
+
return false;
|
|
3987
4073
|
}
|
|
3988
|
-
|
|
3989
|
-
|
|
4074
|
+
}
|
|
4075
|
+
try {
|
|
4076
|
+
const swiftWasm = __require.resolve(
|
|
4077
|
+
"tree-sitter-swift/swift.wasm"
|
|
4078
|
+
);
|
|
4079
|
+
const wt = await import("web-tree-sitter");
|
|
4080
|
+
swiftLang = await wt.Language.load(swiftWasm);
|
|
4081
|
+
swiftInitDone = true;
|
|
4082
|
+
swiftInitOk = true;
|
|
4083
|
+
return true;
|
|
3990
4084
|
} catch {
|
|
3991
|
-
|
|
3992
|
-
|
|
3993
|
-
|
|
3994
|
-
}
|
|
3995
|
-
var PluginRegistry, pluginRegistry, PLUGIN_DIR;
|
|
3996
|
-
var init_registry = __esm({
|
|
3997
|
-
"src/plugins/registry.ts"() {
|
|
3998
|
-
"use strict";
|
|
3999
|
-
init_loader();
|
|
4000
|
-
PluginRegistry = class {
|
|
4001
|
-
entries = /* @__PURE__ */ new Map();
|
|
4002
|
-
loaded = false;
|
|
4003
|
-
/** Get all registered plugins */
|
|
4004
|
-
getAll() {
|
|
4005
|
-
return [...this.entries.values()];
|
|
4006
|
-
}
|
|
4007
|
-
/** Get all successfully loaded engines */
|
|
4008
|
-
getEngines() {
|
|
4009
|
-
return [...this.entries.values()].filter((e) => e.loaded).map((e) => e.engine);
|
|
4010
|
-
}
|
|
4011
|
-
/** Get a specific plugin by id */
|
|
4012
|
-
get(id) {
|
|
4013
|
-
return this.entries.get(id);
|
|
4014
|
-
}
|
|
4015
|
-
/** Get a loaded engine by name */
|
|
4016
|
-
getEngine(name) {
|
|
4017
|
-
const entry = this.entries.get(name);
|
|
4018
|
-
return entry?.loaded ? entry.engine : void 0;
|
|
4019
|
-
}
|
|
4020
|
-
/** Register a plugin entry */
|
|
4021
|
-
register(entry) {
|
|
4022
|
-
this.entries.set(entry.id, entry);
|
|
4023
|
-
}
|
|
4024
|
-
/** Remove a plugin by id */
|
|
4025
|
-
remove(id) {
|
|
4026
|
-
return this.entries.delete(id);
|
|
4027
|
-
}
|
|
4028
|
-
/** Check if a plugin is registered */
|
|
4029
|
-
has(id) {
|
|
4030
|
-
return this.entries.has(id);
|
|
4031
|
-
}
|
|
4032
|
-
/** Number of registered plugins */
|
|
4033
|
-
get size() {
|
|
4034
|
-
return this.entries.size;
|
|
4035
|
-
}
|
|
4036
|
-
/** Whether the registry has been loaded from disk */
|
|
4037
|
-
get isLoaded() {
|
|
4038
|
-
return this.loaded;
|
|
4039
|
-
}
|
|
4040
|
-
/** Mark the registry as loaded */
|
|
4041
|
-
setLoaded(loaded) {
|
|
4042
|
-
this.loaded = loaded;
|
|
4043
|
-
}
|
|
4044
|
-
/** Clear all entries */
|
|
4045
|
-
clear() {
|
|
4046
|
-
this.entries.clear();
|
|
4047
|
-
this.loaded = false;
|
|
4048
|
-
}
|
|
4049
|
-
};
|
|
4050
|
-
pluginRegistry = new PluginRegistry();
|
|
4051
|
-
PLUGIN_DIR = ".deep-slop/plugins";
|
|
4052
|
-
}
|
|
4053
|
-
});
|
|
4054
|
-
|
|
4055
|
-
// src/utils/suppress.ts
|
|
4056
|
-
import { join as join3 } from "node:path";
|
|
4057
|
-
import { readFileSync as readFileSync2 } from "node:fs";
|
|
4058
|
-
function parseSuppressDirectives(content) {
|
|
4059
|
-
const entries = [];
|
|
4060
|
-
const lines = content.split("\n");
|
|
4061
|
-
for (let i = 0; i < lines.length; i++) {
|
|
4062
|
-
const line = lines[i].trim();
|
|
4063
|
-
const lineNum = i + 1;
|
|
4064
|
-
const ignoreNextMatch = line.match(
|
|
4065
|
-
/\/\/\s*deep-slop-ignore-next(?:\s+(.+))?$/
|
|
4066
|
-
);
|
|
4067
|
-
if (ignoreNextMatch) {
|
|
4068
|
-
entries.push({
|
|
4069
|
-
directiveLine: lineNum,
|
|
4070
|
-
targetLine: lineNum + 1,
|
|
4071
|
-
rules: parseRuleList(ignoreNextMatch[1]),
|
|
4072
|
-
type: "next-line"
|
|
4073
|
-
});
|
|
4074
|
-
continue;
|
|
4075
|
-
}
|
|
4076
|
-
const ignoreLineMatch = line.match(
|
|
4077
|
-
/\/\/\s*deep-slop-ignore-line(?:\s+(.+))?$/
|
|
4078
|
-
);
|
|
4079
|
-
if (ignoreLineMatch) {
|
|
4080
|
-
entries.push({
|
|
4081
|
-
directiveLine: lineNum,
|
|
4082
|
-
targetLine: lineNum,
|
|
4083
|
-
rules: parseRuleList(ignoreLineMatch[1]),
|
|
4084
|
-
type: "line"
|
|
4085
|
-
});
|
|
4086
|
-
continue;
|
|
4087
|
-
}
|
|
4088
|
-
const ignoreRuleMatch = line.match(
|
|
4089
|
-
/\/\/\s*deep-slop-ignore(?:\s+(.+))?$/
|
|
4090
|
-
);
|
|
4091
|
-
if (ignoreRuleMatch) {
|
|
4092
|
-
const rulePart = ignoreRuleMatch[1];
|
|
4093
|
-
if (rulePart !== "start" && rulePart !== "end") {
|
|
4094
|
-
entries.push({
|
|
4095
|
-
directiveLine: lineNum,
|
|
4096
|
-
targetLine: lineNum + 1,
|
|
4097
|
-
rules: parseRuleList(rulePart),
|
|
4098
|
-
type: "next-line"
|
|
4099
|
-
});
|
|
4100
|
-
continue;
|
|
4101
|
-
}
|
|
4102
|
-
}
|
|
4103
|
-
const ignoreStartMatch = line.match(
|
|
4104
|
-
/\/\/\s*deep-slop-ignore-start(?:\s+(.+))?$/
|
|
4105
|
-
);
|
|
4106
|
-
if (ignoreStartMatch) {
|
|
4107
|
-
entries.push({
|
|
4108
|
-
directiveLine: lineNum,
|
|
4109
|
-
targetLine: lineNum,
|
|
4110
|
-
rules: parseRuleList(ignoreStartMatch[1]),
|
|
4111
|
-
type: "block-start"
|
|
4112
|
-
});
|
|
4113
|
-
continue;
|
|
4114
|
-
}
|
|
4115
|
-
const ignoreEndMatch = line.match(
|
|
4116
|
-
/\/\/\s*deep-slop-ignore-end/
|
|
4117
|
-
);
|
|
4118
|
-
if (ignoreEndMatch) {
|
|
4119
|
-
entries.push({
|
|
4120
|
-
directiveLine: lineNum,
|
|
4121
|
-
targetLine: lineNum,
|
|
4122
|
-
rules: /* @__PURE__ */ new Set(),
|
|
4123
|
-
type: "block-end"
|
|
4124
|
-
});
|
|
4125
|
-
continue;
|
|
4126
|
-
}
|
|
4127
|
-
const nextLineMatch = line.match(
|
|
4128
|
-
/\/\/\s*deep-slop-disable-next-line(?:\s+(.+))?$/
|
|
4129
|
-
);
|
|
4130
|
-
if (nextLineMatch) {
|
|
4131
|
-
entries.push({
|
|
4132
|
-
directiveLine: lineNum,
|
|
4133
|
-
targetLine: lineNum + 1,
|
|
4134
|
-
rules: parseRuleList(nextLineMatch[1]),
|
|
4135
|
-
type: "next-line"
|
|
4136
|
-
});
|
|
4137
|
-
continue;
|
|
4138
|
-
}
|
|
4139
|
-
const lineMatch = line.match(
|
|
4140
|
-
/\/\/\s*deep-slop-disable-line(?:\s+(.+))?$/
|
|
4141
|
-
);
|
|
4142
|
-
if (lineMatch) {
|
|
4143
|
-
entries.push({
|
|
4144
|
-
directiveLine: lineNum,
|
|
4145
|
-
targetLine: lineNum,
|
|
4146
|
-
rules: parseRuleList(lineMatch[1]),
|
|
4147
|
-
type: "line"
|
|
4148
|
-
});
|
|
4149
|
-
continue;
|
|
4150
|
-
}
|
|
4151
|
-
const blockStart = line.match(
|
|
4152
|
-
/\/\*\s*deep-slop-disable(?:\s+(.+))?\s*\//
|
|
4153
|
-
);
|
|
4154
|
-
if (blockStart) {
|
|
4155
|
-
entries.push({
|
|
4156
|
-
directiveLine: lineNum,
|
|
4157
|
-
targetLine: lineNum,
|
|
4158
|
-
rules: parseRuleList(blockStart[1]),
|
|
4159
|
-
type: "block-start"
|
|
4160
|
-
});
|
|
4161
|
-
continue;
|
|
4162
|
-
}
|
|
4163
|
-
const blockEnd = line.match(/\/\*\s*deep-slop-enable\s*\//);
|
|
4164
|
-
if (blockEnd) {
|
|
4165
|
-
entries.push({
|
|
4166
|
-
directiveLine: lineNum,
|
|
4167
|
-
targetLine: lineNum,
|
|
4168
|
-
rules: /* @__PURE__ */ new Set(),
|
|
4169
|
-
type: "block-end"
|
|
4170
|
-
});
|
|
4171
|
-
}
|
|
4172
|
-
}
|
|
4173
|
-
return entries;
|
|
4174
|
-
}
|
|
4175
|
-
function parseRuleList(rulesStr) {
|
|
4176
|
-
if (!rulesStr) return /* @__PURE__ */ new Set();
|
|
4177
|
-
const rules = rulesStr.split(/[,\\s]+/).map((r) => r.trim()).filter(Boolean);
|
|
4178
|
-
return new Set(rules);
|
|
4179
|
-
}
|
|
4180
|
-
function buildSuppressChecker(entries) {
|
|
4181
|
-
const blockRanges = [];
|
|
4182
|
-
let currentStart = null;
|
|
4183
|
-
for (const entry of entries) {
|
|
4184
|
-
if (entry.type === "block-start") {
|
|
4185
|
-
currentStart = { line: entry.directiveLine, rules: entry.rules };
|
|
4186
|
-
} else if (entry.type === "block-end" && currentStart) {
|
|
4187
|
-
blockRanges.push({
|
|
4188
|
-
startLine: currentStart.line,
|
|
4189
|
-
endLine: entry.directiveLine,
|
|
4190
|
-
rules: currentStart.rules
|
|
4191
|
-
});
|
|
4192
|
-
currentStart = null;
|
|
4193
|
-
}
|
|
4194
|
-
}
|
|
4195
|
-
if (currentStart) {
|
|
4196
|
-
blockRanges.push({
|
|
4197
|
-
startLine: currentStart.line,
|
|
4198
|
-
endLine: 999999,
|
|
4199
|
-
rules: currentStart.rules
|
|
4200
|
-
});
|
|
4201
|
-
}
|
|
4202
|
-
return (line, rule) => {
|
|
4203
|
-
for (const entry of entries) {
|
|
4204
|
-
if (entry.type === "next-line" || entry.type === "line") {
|
|
4205
|
-
if (entry.targetLine === line) {
|
|
4206
|
-
if (entry.rules.size === 0 || entry.rules.has(rule)) {
|
|
4207
|
-
return true;
|
|
4208
|
-
}
|
|
4209
|
-
}
|
|
4210
|
-
}
|
|
4211
|
-
}
|
|
4212
|
-
for (const range2 of blockRanges) {
|
|
4213
|
-
if (line >= range2.startLine && line <= range2.endLine) {
|
|
4214
|
-
if (range2.rules.size === 0 || range2.rules.has(rule)) {
|
|
4215
|
-
return true;
|
|
4216
|
-
}
|
|
4217
|
-
}
|
|
4218
|
-
}
|
|
4219
|
-
return false;
|
|
4220
|
-
};
|
|
4221
|
-
}
|
|
4222
|
-
function buildSuppressMap(content) {
|
|
4223
|
-
const entries = parseSuppressDirectives(content);
|
|
4224
|
-
const isSuppressed = buildSuppressChecker(entries);
|
|
4225
|
-
return { entries, isSuppressed };
|
|
4226
|
-
}
|
|
4227
|
-
function loadIgnoreFile(rootDir) {
|
|
4228
|
-
const ignorePath = join3(rootDir, ".deep-slop", ".deep-slop-ignore");
|
|
4229
|
-
try {
|
|
4230
|
-
const content = readFileSync2(ignorePath, "utf-8");
|
|
4231
|
-
return content.split("\n").map((line) => line.split("#")[0].trim()).filter((line) => line && !line.startsWith("file:"));
|
|
4232
|
-
} catch {
|
|
4233
|
-
return [];
|
|
4234
|
-
}
|
|
4235
|
-
}
|
|
4236
|
-
function applySuppressDirectives(diagnostics, fileContents, globallySuppressed = /* @__PURE__ */ new Set()) {
|
|
4237
|
-
const suppressMaps = /* @__PURE__ */ new Map();
|
|
4238
|
-
for (const [filePath, content] of fileContents) {
|
|
4239
|
-
suppressMaps.set(filePath, buildSuppressMap(content));
|
|
4240
|
-
}
|
|
4241
|
-
const filtered = [];
|
|
4242
|
-
let suppressedCount = 0;
|
|
4243
|
-
for (const diag8 of diagnostics) {
|
|
4244
|
-
if (globallySuppressed.has(diag8.rule)) {
|
|
4245
|
-
suppressedCount++;
|
|
4246
|
-
continue;
|
|
4247
|
-
}
|
|
4248
|
-
const map = suppressMaps.get(diag8.filePath);
|
|
4249
|
-
if (map && map.isSuppressed(diag8.line, diag8.rule)) {
|
|
4250
|
-
suppressedCount++;
|
|
4251
|
-
} else {
|
|
4252
|
-
filtered.push(diag8);
|
|
4253
|
-
}
|
|
4254
|
-
}
|
|
4255
|
-
return { filtered, suppressedCount };
|
|
4256
|
-
}
|
|
4257
|
-
var init_suppress = __esm({
|
|
4258
|
-
"src/utils/suppress.ts"() {
|
|
4259
|
-
"use strict";
|
|
4260
|
-
}
|
|
4261
|
-
});
|
|
4262
|
-
|
|
4263
|
-
// src/utils/file-utils.ts
|
|
4264
|
-
import { readFile as readFile2 } from "node:fs/promises";
|
|
4265
|
-
async function readFileContent(filePath) {
|
|
4266
|
-
const buffer = await readFile2(filePath);
|
|
4267
|
-
let content = buffer.toString("utf-8");
|
|
4268
|
-
if (content.charCodeAt(0) === 65279) {
|
|
4269
|
-
content = content.slice(1);
|
|
4270
|
-
}
|
|
4271
|
-
return content;
|
|
4272
|
-
}
|
|
4273
|
-
function detectEncodingAnomalies(content) {
|
|
4274
|
-
const hasBom = content.charCodeAt(0) === 65279;
|
|
4275
|
-
const hasCrlf = content.includes("\r\n");
|
|
4276
|
-
const hasZwnbsp = content.includes("\uFEFF");
|
|
4277
|
-
const lfOnly = (content.match(/(?<!\r)\n/g) ?? []).length;
|
|
4278
|
-
const crlfCount = (content.match(/\r\n/g) ?? []).length;
|
|
4279
|
-
const lineEnding = crlfCount > 0 && lfOnly > crlfCount ? "mixed" : crlfCount > 0 ? "crlf" : "lf";
|
|
4280
|
-
return { hasBom, hasCrlf, hasZwnbsp, lineEnding };
|
|
4281
|
-
}
|
|
4282
|
-
function toLines(content) {
|
|
4283
|
-
return content.split("\n").map((text, i) => ({ num: i + 1, text }));
|
|
4284
|
-
}
|
|
4285
|
-
function extractImports(content, language) {
|
|
4286
|
-
const imports = [];
|
|
4287
|
-
const lines = toLines(content);
|
|
4288
|
-
for (const { num, text } of lines) {
|
|
4289
|
-
const trimmed = text.trim();
|
|
4290
|
-
if (language === "typescript" || language === "javascript") {
|
|
4291
|
-
const jsMatch = trimmed.match(
|
|
4292
|
-
/^import\s+(?:type\s+)?(?:\{[^}]*\}|\*\s+as\s+\w+|\w+)\s+from\s+['"]([^'"]+)['"]/
|
|
4293
|
-
);
|
|
4294
|
-
if (jsMatch) {
|
|
4295
|
-
imports.push({
|
|
4296
|
-
line: num,
|
|
4297
|
-
source: jsMatch[1],
|
|
4298
|
-
raw: trimmed,
|
|
4299
|
-
isTypeOnly: trimmed.includes("import type"),
|
|
4300
|
-
isDefault: !trimmed.includes("{")
|
|
4301
|
-
});
|
|
4302
|
-
}
|
|
4303
|
-
const dynMatch = trimmed.match(/import\s*\(\s*['"]([^'"]+)['"]\s*\)/);
|
|
4304
|
-
if (dynMatch) {
|
|
4305
|
-
imports.push({
|
|
4306
|
-
line: num,
|
|
4307
|
-
source: dynMatch[1],
|
|
4308
|
-
raw: trimmed,
|
|
4309
|
-
isTypeOnly: false,
|
|
4310
|
-
isDynamic: true
|
|
4311
|
-
});
|
|
4312
|
-
}
|
|
4313
|
-
const reqMatch = trimmed.match(/(?:const|let|var)\s+[^=]*=\s*require\s*\(\s*['"]([^'"]+)['"]\s*\)/);
|
|
4314
|
-
if (reqMatch) {
|
|
4315
|
-
imports.push({
|
|
4316
|
-
line: num,
|
|
4317
|
-
source: reqMatch[1],
|
|
4318
|
-
raw: trimmed,
|
|
4319
|
-
isTypeOnly: false,
|
|
4320
|
-
isRequire: true
|
|
4321
|
-
});
|
|
4322
|
-
}
|
|
4323
|
-
}
|
|
4324
|
-
if (language === "python") {
|
|
4325
|
-
const pyMatch = trimmed.match(/^from\s+([^\s]+)\s+import/);
|
|
4326
|
-
if (pyMatch) {
|
|
4327
|
-
imports.push({ line: num, source: pyMatch[1], raw: trimmed, isTypeOnly: false });
|
|
4328
|
-
}
|
|
4329
|
-
const pyImport = trimmed.match(/^import\s+([^\s]+)/);
|
|
4330
|
-
if (pyImport) {
|
|
4331
|
-
imports.push({ line: num, source: pyImport[1], raw: trimmed, isTypeOnly: false });
|
|
4332
|
-
}
|
|
4333
|
-
}
|
|
4334
|
-
if (language === "go") {
|
|
4335
|
-
const goMatch = trimmed.match(/"([^"]+)"/);
|
|
4336
|
-
if (trimmed.startsWith("import") && goMatch) {
|
|
4337
|
-
imports.push({ line: num, source: goMatch[1], raw: trimmed, isTypeOnly: false });
|
|
4338
|
-
}
|
|
4339
|
-
}
|
|
4340
|
-
}
|
|
4341
|
-
return imports;
|
|
4342
|
-
}
|
|
4343
|
-
var init_file_utils = __esm({
|
|
4344
|
-
"src/utils/file-utils.ts"() {
|
|
4345
|
-
"use strict";
|
|
4346
|
-
}
|
|
4347
|
-
});
|
|
4348
|
-
|
|
4349
|
-
// src/utils/tree-sitter.ts
|
|
4350
|
-
async function initParser() {
|
|
4351
|
-
if (initDone) return initOk;
|
|
4352
|
-
if (initPromise) return initPromise;
|
|
4353
|
-
initPromise = (async () => {
|
|
4354
|
-
try {
|
|
4355
|
-
const wt = await import("web-tree-sitter");
|
|
4356
|
-
const { dirname: dirname9 } = await import("node:path");
|
|
4357
|
-
const wasmDir = dirname9(
|
|
4358
|
-
__require.resolve("web-tree-sitter/tree-sitter.wasm")
|
|
4359
|
-
);
|
|
4360
|
-
await wt.Parser.init({
|
|
4361
|
-
locateFile: (name) => `${wasmDir}/${name}`
|
|
4362
|
-
});
|
|
4363
|
-
const parser = new wt.Parser();
|
|
4364
|
-
parserInstance = parser;
|
|
4365
|
-
const tsWasm = __require.resolve(
|
|
4366
|
-
"tree-sitter-typescript/tree-sitter-typescript.wasm"
|
|
4367
|
-
);
|
|
4368
|
-
tsLang = await wt.Language.load(tsWasm);
|
|
4369
|
-
const tsxWasm = __require.resolve(
|
|
4370
|
-
"tree-sitter-typescript/tree-sitter-tsx.wasm"
|
|
4371
|
-
);
|
|
4372
|
-
tsxLang = await wt.Language.load(tsxWasm);
|
|
4373
|
-
initDone = true;
|
|
4374
|
-
initOk = true;
|
|
4375
|
-
return true;
|
|
4376
|
-
} catch (err) {
|
|
4377
|
-
initDone = true;
|
|
4378
|
-
initOk = false;
|
|
4379
|
-
return false;
|
|
4380
|
-
}
|
|
4381
|
-
})();
|
|
4382
|
-
return initPromise;
|
|
4383
|
-
}
|
|
4384
|
-
async function initPythonParser() {
|
|
4385
|
-
if (pyInitDone) return pyInitOk;
|
|
4386
|
-
if (!initOk) {
|
|
4387
|
-
const baseOk = await initParser();
|
|
4388
|
-
if (!baseOk) {
|
|
4389
|
-
pyInitDone = true;
|
|
4390
|
-
pyInitOk = false;
|
|
4391
|
-
return false;
|
|
4392
|
-
}
|
|
4393
|
-
}
|
|
4394
|
-
try {
|
|
4395
|
-
const pyWasm = __require.resolve(
|
|
4396
|
-
"tree-sitter-python/python.wasm"
|
|
4397
|
-
);
|
|
4398
|
-
const wt = await import("web-tree-sitter");
|
|
4399
|
-
pyLang = await wt.Language.load(pyWasm);
|
|
4400
|
-
pyInitDone = true;
|
|
4401
|
-
pyInitOk = true;
|
|
4402
|
-
return true;
|
|
4403
|
-
} catch {
|
|
4404
|
-
pyInitDone = true;
|
|
4405
|
-
pyInitOk = false;
|
|
4406
|
-
return false;
|
|
4407
|
-
}
|
|
4408
|
-
}
|
|
4409
|
-
async function initGoParser() {
|
|
4410
|
-
if (goInitDone) return goInitOk;
|
|
4411
|
-
if (!initOk) {
|
|
4412
|
-
const baseOk = await initParser();
|
|
4413
|
-
if (!baseOk) {
|
|
4414
|
-
goInitDone = true;
|
|
4415
|
-
goInitOk = false;
|
|
4416
|
-
return false;
|
|
4417
|
-
}
|
|
4418
|
-
}
|
|
4419
|
-
try {
|
|
4420
|
-
const goWasm = __require.resolve(
|
|
4421
|
-
"tree-sitter-go/go.wasm"
|
|
4422
|
-
);
|
|
4423
|
-
const wt = await import("web-tree-sitter");
|
|
4424
|
-
goLang = await wt.Language.load(goWasm);
|
|
4425
|
-
goInitDone = true;
|
|
4426
|
-
goInitOk = true;
|
|
4427
|
-
return true;
|
|
4428
|
-
} catch {
|
|
4429
|
-
goInitDone = true;
|
|
4430
|
-
goInitOk = false;
|
|
4431
|
-
return false;
|
|
4432
|
-
}
|
|
4433
|
-
}
|
|
4434
|
-
async function initRustParser() {
|
|
4435
|
-
if (rustInitDone) return rustInitOk;
|
|
4436
|
-
if (!initOk) {
|
|
4437
|
-
const baseOk = await initParser();
|
|
4438
|
-
if (!baseOk) {
|
|
4439
|
-
rustInitDone = true;
|
|
4440
|
-
rustInitOk = false;
|
|
4441
|
-
return false;
|
|
4442
|
-
}
|
|
4443
|
-
}
|
|
4444
|
-
try {
|
|
4445
|
-
const rustWasm = __require.resolve(
|
|
4446
|
-
"tree-sitter-rust/rust.wasm"
|
|
4447
|
-
);
|
|
4448
|
-
const wt = await import("web-tree-sitter");
|
|
4449
|
-
rustLang = await wt.Language.load(rustWasm);
|
|
4450
|
-
rustInitDone = true;
|
|
4451
|
-
rustInitOk = true;
|
|
4452
|
-
return true;
|
|
4453
|
-
} catch {
|
|
4454
|
-
rustInitDone = true;
|
|
4455
|
-
rustInitOk = false;
|
|
4456
|
-
return false;
|
|
4457
|
-
}
|
|
4458
|
-
}
|
|
4459
|
-
async function initPhpParser() {
|
|
4460
|
-
if (phpInitDone) return phpInitOk;
|
|
4461
|
-
if (!initOk) {
|
|
4462
|
-
const baseOk = await initParser();
|
|
4463
|
-
if (!baseOk) {
|
|
4464
|
-
phpInitDone = true;
|
|
4465
|
-
phpInitOk = false;
|
|
4466
|
-
return false;
|
|
4467
|
-
}
|
|
4468
|
-
}
|
|
4469
|
-
try {
|
|
4470
|
-
const phpWasm = __require.resolve(
|
|
4471
|
-
"tree-sitter-php/php.wasm"
|
|
4472
|
-
);
|
|
4473
|
-
const wt = await import("web-tree-sitter");
|
|
4474
|
-
phpLang = await wt.Language.load(phpWasm);
|
|
4475
|
-
phpInitDone = true;
|
|
4476
|
-
phpInitOk = true;
|
|
4477
|
-
return true;
|
|
4478
|
-
} catch {
|
|
4479
|
-
phpInitDone = true;
|
|
4480
|
-
phpInitOk = false;
|
|
4481
|
-
return false;
|
|
4482
|
-
}
|
|
4483
|
-
}
|
|
4484
|
-
async function initCsharpParser() {
|
|
4485
|
-
if (csharpInitDone) return csharpInitOk;
|
|
4486
|
-
if (!initOk) {
|
|
4487
|
-
const baseOk = await initParser();
|
|
4488
|
-
if (!baseOk) {
|
|
4489
|
-
csharpInitDone = true;
|
|
4490
|
-
csharpInitOk = false;
|
|
4491
|
-
return false;
|
|
4492
|
-
}
|
|
4493
|
-
}
|
|
4494
|
-
try {
|
|
4495
|
-
const csharpWasm = __require.resolve(
|
|
4496
|
-
"tree-sitter-c-sharp/c_sharp.wasm"
|
|
4497
|
-
);
|
|
4498
|
-
const wt = await import("web-tree-sitter");
|
|
4499
|
-
csharpLang = await wt.Language.load(csharpWasm);
|
|
4500
|
-
csharpInitDone = true;
|
|
4501
|
-
csharpInitOk = true;
|
|
4502
|
-
return true;
|
|
4503
|
-
} catch {
|
|
4504
|
-
csharpInitDone = true;
|
|
4505
|
-
csharpInitOk = false;
|
|
4506
|
-
return false;
|
|
4507
|
-
}
|
|
4508
|
-
}
|
|
4509
|
-
async function initSwiftParser() {
|
|
4510
|
-
if (swiftInitDone) return swiftInitOk;
|
|
4511
|
-
if (!initOk) {
|
|
4512
|
-
const baseOk = await initParser();
|
|
4513
|
-
if (!baseOk) {
|
|
4514
|
-
swiftInitDone = true;
|
|
4515
|
-
swiftInitOk = false;
|
|
4516
|
-
return false;
|
|
4517
|
-
}
|
|
4518
|
-
}
|
|
4519
|
-
try {
|
|
4520
|
-
const swiftWasm = __require.resolve(
|
|
4521
|
-
"tree-sitter-swift/swift.wasm"
|
|
4522
|
-
);
|
|
4523
|
-
const wt = await import("web-tree-sitter");
|
|
4524
|
-
swiftLang = await wt.Language.load(swiftWasm);
|
|
4525
|
-
swiftInitDone = true;
|
|
4526
|
-
swiftInitOk = true;
|
|
4527
|
-
return true;
|
|
4528
|
-
} catch {
|
|
4529
|
-
swiftInitDone = true;
|
|
4530
|
-
swiftInitOk = false;
|
|
4531
|
-
return false;
|
|
4085
|
+
swiftInitDone = true;
|
|
4086
|
+
swiftInitOk = false;
|
|
4087
|
+
return false;
|
|
4532
4088
|
}
|
|
4533
4089
|
}
|
|
4534
4090
|
function isAvailable() {
|
|
@@ -4538,14 +4094,19 @@ function isPythonAvailable() {
|
|
|
4538
4094
|
return pyInitOk && pyLang !== null;
|
|
4539
4095
|
}
|
|
4540
4096
|
async function parseFile(content, isTsx = false, filePath) {
|
|
4097
|
+
if (filePath) {
|
|
4098
|
+
const cacheKey = `${filePath}:${isTsx ? "tsx" : "ts"}`;
|
|
4099
|
+
const cached = parseCache.get(cacheKey);
|
|
4100
|
+
if (cached !== void 0) return cached;
|
|
4101
|
+
}
|
|
4541
4102
|
if (filePath) {
|
|
4542
4103
|
const ext2 = filePath.toLowerCase();
|
|
4543
|
-
if (ext2.endsWith(".go")) return parseGoFile(content);
|
|
4544
|
-
if (ext2.endsWith(".rs")) return parseRustFile(content);
|
|
4545
|
-
if (ext2.endsWith(".php")) return parsePhpFile(content);
|
|
4546
|
-
if (ext2.endsWith(".cs")) return parseCsharpFile(content);
|
|
4547
|
-
if (ext2.endsWith(".swift")) return parseSwiftFile(content);
|
|
4548
|
-
if (ext2.endsWith(".py")) return parsePython(content);
|
|
4104
|
+
if (ext2.endsWith(".go")) return parseGoFile(content, filePath);
|
|
4105
|
+
if (ext2.endsWith(".rs")) return parseRustFile(content, filePath);
|
|
4106
|
+
if (ext2.endsWith(".php")) return parsePhpFile(content, filePath);
|
|
4107
|
+
if (ext2.endsWith(".cs")) return parseCsharpFile(content, filePath);
|
|
4108
|
+
if (ext2.endsWith(".swift")) return parseSwiftFile(content, filePath);
|
|
4109
|
+
if (ext2.endsWith(".py")) return parsePython(content, filePath);
|
|
4549
4110
|
}
|
|
4550
4111
|
if (!parserInstance || !tsLang && !tsxLang) {
|
|
4551
4112
|
const ok = await initParser();
|
|
@@ -4556,12 +4117,21 @@ async function parseFile(content, isTsx = false, filePath) {
|
|
|
4556
4117
|
parserInstance.setLanguage(lang);
|
|
4557
4118
|
const tree = parserInstance.parse(content);
|
|
4558
4119
|
if (!tree) return null;
|
|
4559
|
-
|
|
4120
|
+
const result = convertNode(tree.rootNode, null);
|
|
4121
|
+
if (filePath) {
|
|
4122
|
+
parseCache.set(`${filePath}:${isTsx ? "tsx" : "ts"}`, result);
|
|
4123
|
+
}
|
|
4124
|
+
return result;
|
|
4560
4125
|
} catch {
|
|
4126
|
+
if (filePath) parseCache.set(`${filePath}:${isTsx ? "tsx" : "ts"}`, null);
|
|
4561
4127
|
return null;
|
|
4562
4128
|
}
|
|
4563
4129
|
}
|
|
4564
|
-
async function parsePython(content) {
|
|
4130
|
+
async function parsePython(content, filePath) {
|
|
4131
|
+
if (filePath) {
|
|
4132
|
+
const cached = parseCache.get(`py:${filePath}`);
|
|
4133
|
+
if (cached !== void 0) return cached;
|
|
4134
|
+
}
|
|
4565
4135
|
if (!pyLang) {
|
|
4566
4136
|
const ok = await initPythonParser();
|
|
4567
4137
|
if (!ok) return null;
|
|
@@ -4573,480 +4143,984 @@ async function parsePython(content) {
|
|
|
4573
4143
|
try {
|
|
4574
4144
|
parserInstance.setLanguage(pyLang);
|
|
4575
4145
|
const tree = parserInstance.parse(content);
|
|
4576
|
-
if (!tree)
|
|
4577
|
-
|
|
4146
|
+
if (!tree) {
|
|
4147
|
+
if (filePath) parseCache.set(`py:${filePath}`, null);
|
|
4148
|
+
return null;
|
|
4149
|
+
}
|
|
4150
|
+
const result = convertNode(tree.rootNode, null);
|
|
4151
|
+
if (filePath) parseCache.set(`py:${filePath}`, result);
|
|
4152
|
+
return result;
|
|
4153
|
+
} catch {
|
|
4154
|
+
if (filePath) parseCache.set(`py:${filePath}`, null);
|
|
4155
|
+
return null;
|
|
4156
|
+
}
|
|
4157
|
+
}
|
|
4158
|
+
async function parseGoFile(content, filePath) {
|
|
4159
|
+
if (filePath) {
|
|
4160
|
+
const cached = parseCache.get(`go:${filePath}`);
|
|
4161
|
+
if (cached !== void 0) return cached;
|
|
4162
|
+
}
|
|
4163
|
+
if (!goLang) {
|
|
4164
|
+
const ok = await initGoParser();
|
|
4165
|
+
if (!ok) return null;
|
|
4166
|
+
}
|
|
4167
|
+
if (!parserInstance) {
|
|
4168
|
+
const ok = await initParser();
|
|
4169
|
+
if (!ok) return null;
|
|
4170
|
+
}
|
|
4171
|
+
try {
|
|
4172
|
+
parserInstance.setLanguage(goLang);
|
|
4173
|
+
const tree = parserInstance.parse(content);
|
|
4174
|
+
if (!tree) {
|
|
4175
|
+
if (filePath) parseCache.set(`go:${filePath}`, null);
|
|
4176
|
+
return null;
|
|
4177
|
+
}
|
|
4178
|
+
const result = convertNode(tree.rootNode, null);
|
|
4179
|
+
if (filePath) parseCache.set(`go:${filePath}`, result);
|
|
4180
|
+
return result;
|
|
4181
|
+
} catch {
|
|
4182
|
+
if (filePath) parseCache.set(`go:${filePath}`, null);
|
|
4183
|
+
return null;
|
|
4184
|
+
}
|
|
4185
|
+
}
|
|
4186
|
+
async function parseRustFile(content, filePath) {
|
|
4187
|
+
if (filePath) {
|
|
4188
|
+
const cached = parseCache.get(`rs:${filePath}`);
|
|
4189
|
+
if (cached !== void 0) return cached;
|
|
4190
|
+
}
|
|
4191
|
+
if (!rustLang) {
|
|
4192
|
+
const ok = await initRustParser();
|
|
4193
|
+
if (!ok) return null;
|
|
4194
|
+
}
|
|
4195
|
+
if (!parserInstance) {
|
|
4196
|
+
const ok = await initParser();
|
|
4197
|
+
if (!ok) return null;
|
|
4198
|
+
}
|
|
4199
|
+
try {
|
|
4200
|
+
parserInstance.setLanguage(rustLang);
|
|
4201
|
+
const tree = parserInstance.parse(content);
|
|
4202
|
+
if (!tree) {
|
|
4203
|
+
if (filePath) parseCache.set(`rs:${filePath}`, null);
|
|
4204
|
+
return null;
|
|
4205
|
+
}
|
|
4206
|
+
const result = convertNode(tree.rootNode, null);
|
|
4207
|
+
if (filePath) parseCache.set(`rs:${filePath}`, result);
|
|
4208
|
+
return result;
|
|
4209
|
+
} catch {
|
|
4210
|
+
if (filePath) parseCache.set(`rs:${filePath}`, null);
|
|
4211
|
+
return null;
|
|
4212
|
+
}
|
|
4213
|
+
}
|
|
4214
|
+
async function parsePhpFile(content, filePath) {
|
|
4215
|
+
if (filePath) {
|
|
4216
|
+
const cached = parseCache.get(`php:${filePath}`);
|
|
4217
|
+
if (cached !== void 0) return cached;
|
|
4218
|
+
}
|
|
4219
|
+
if (!phpLang) {
|
|
4220
|
+
const ok = await initPhpParser();
|
|
4221
|
+
if (!ok) return null;
|
|
4222
|
+
}
|
|
4223
|
+
if (!parserInstance) {
|
|
4224
|
+
const ok = await initParser();
|
|
4225
|
+
if (!ok) return null;
|
|
4226
|
+
}
|
|
4227
|
+
try {
|
|
4228
|
+
parserInstance.setLanguage(phpLang);
|
|
4229
|
+
const tree = parserInstance.parse(content);
|
|
4230
|
+
if (!tree) {
|
|
4231
|
+
if (filePath) parseCache.set(`php:${filePath}`, null);
|
|
4232
|
+
return null;
|
|
4233
|
+
}
|
|
4234
|
+
const result = convertNode(tree.rootNode, null);
|
|
4235
|
+
if (filePath) parseCache.set(`php:${filePath}`, result);
|
|
4236
|
+
return result;
|
|
4237
|
+
} catch {
|
|
4238
|
+
if (filePath) parseCache.set(`php:${filePath}`, null);
|
|
4239
|
+
return null;
|
|
4240
|
+
}
|
|
4241
|
+
}
|
|
4242
|
+
async function parseCsharpFile(content, filePath) {
|
|
4243
|
+
if (filePath) {
|
|
4244
|
+
const cached = parseCache.get(`cs:${filePath}`);
|
|
4245
|
+
if (cached !== void 0) return cached;
|
|
4246
|
+
}
|
|
4247
|
+
if (!csharpLang) {
|
|
4248
|
+
const ok = await initCsharpParser();
|
|
4249
|
+
if (!ok) return null;
|
|
4250
|
+
}
|
|
4251
|
+
if (!parserInstance) {
|
|
4252
|
+
const ok = await initParser();
|
|
4253
|
+
if (!ok) return null;
|
|
4254
|
+
}
|
|
4255
|
+
try {
|
|
4256
|
+
parserInstance.setLanguage(csharpLang);
|
|
4257
|
+
const tree = parserInstance.parse(content);
|
|
4258
|
+
if (!tree) {
|
|
4259
|
+
if (filePath) parseCache.set(`cs:${filePath}`, null);
|
|
4260
|
+
return null;
|
|
4261
|
+
}
|
|
4262
|
+
const result = convertNode(tree.rootNode, null);
|
|
4263
|
+
if (filePath) parseCache.set(`cs:${filePath}`, result);
|
|
4264
|
+
return result;
|
|
4265
|
+
} catch {
|
|
4266
|
+
if (filePath) parseCache.set(`cs:${filePath}`, null);
|
|
4267
|
+
return null;
|
|
4268
|
+
}
|
|
4269
|
+
}
|
|
4270
|
+
async function parseSwiftFile(content, filePath) {
|
|
4271
|
+
if (filePath) {
|
|
4272
|
+
const cached = parseCache.get(`swift:${filePath}`);
|
|
4273
|
+
if (cached !== void 0) return cached;
|
|
4274
|
+
}
|
|
4275
|
+
if (!swiftLang) {
|
|
4276
|
+
const ok = await initSwiftParser();
|
|
4277
|
+
if (!ok) return null;
|
|
4278
|
+
}
|
|
4279
|
+
if (!parserInstance) {
|
|
4280
|
+
const ok = await initParser();
|
|
4281
|
+
if (!ok) return null;
|
|
4282
|
+
}
|
|
4283
|
+
try {
|
|
4284
|
+
parserInstance.setLanguage(swiftLang);
|
|
4285
|
+
const tree = parserInstance.parse(content);
|
|
4286
|
+
if (!tree) {
|
|
4287
|
+
if (filePath) parseCache.set(`swift:${filePath}`, null);
|
|
4288
|
+
return null;
|
|
4289
|
+
}
|
|
4290
|
+
const result = convertNode(tree.rootNode, null);
|
|
4291
|
+
if (filePath) parseCache.set(`swift:${filePath}`, result);
|
|
4292
|
+
return result;
|
|
4578
4293
|
} catch {
|
|
4294
|
+
if (filePath) parseCache.set(`swift:${filePath}`, null);
|
|
4295
|
+
return null;
|
|
4296
|
+
}
|
|
4297
|
+
}
|
|
4298
|
+
function findNodesOfType(root, type) {
|
|
4299
|
+
const results = [];
|
|
4300
|
+
function walk(node) {
|
|
4301
|
+
if (node.type === type) results.push(node);
|
|
4302
|
+
for (const child of node.children) walk(child);
|
|
4303
|
+
}
|
|
4304
|
+
walk(root);
|
|
4305
|
+
return results;
|
|
4306
|
+
}
|
|
4307
|
+
function findNodesOfTypes(root, types3) {
|
|
4308
|
+
const typeSet = new Set(types3);
|
|
4309
|
+
const results = [];
|
|
4310
|
+
function walk(node) {
|
|
4311
|
+
if (typeSet.has(node.type)) results.push(node);
|
|
4312
|
+
for (const child of node.children) walk(child);
|
|
4313
|
+
}
|
|
4314
|
+
walk(root);
|
|
4315
|
+
return results;
|
|
4316
|
+
}
|
|
4317
|
+
function walkAST(root, visitor) {
|
|
4318
|
+
function walk(node) {
|
|
4319
|
+
const result = visitor(node);
|
|
4320
|
+
if (result !== false) {
|
|
4321
|
+
for (const child of node.children) walk(child);
|
|
4322
|
+
}
|
|
4323
|
+
}
|
|
4324
|
+
walk(root);
|
|
4325
|
+
}
|
|
4326
|
+
function findAncestor(node, predicate) {
|
|
4327
|
+
let current = node.parent;
|
|
4328
|
+
while (current) {
|
|
4329
|
+
if (predicate(current)) return current;
|
|
4330
|
+
current = current.parent;
|
|
4331
|
+
}
|
|
4332
|
+
return null;
|
|
4333
|
+
}
|
|
4334
|
+
function isInsideCatch(node) {
|
|
4335
|
+
return findAncestor(node, (n) => n.type === "catch_clause") !== null;
|
|
4336
|
+
}
|
|
4337
|
+
function findAncestorOfType(node, type) {
|
|
4338
|
+
return findAncestor(node, (n) => n.type === type);
|
|
4339
|
+
}
|
|
4340
|
+
function isCatchBodyEmpty(catchNode) {
|
|
4341
|
+
if (catchNode.type !== "catch_clause") return false;
|
|
4342
|
+
const body = catchNode.children.find(
|
|
4343
|
+
(c) => c.type === "statement_block" || c.type === "block"
|
|
4344
|
+
);
|
|
4345
|
+
if (!body) return true;
|
|
4346
|
+
const nonTrivial = body.children.filter(
|
|
4347
|
+
(c) => c.type !== "comment" && c.type !== "//" && c.type !== "/*" && c.type !== "{" && c.type !== "}" && c.text.trim() !== ""
|
|
4348
|
+
);
|
|
4349
|
+
return nonTrivial.length === 0;
|
|
4350
|
+
}
|
|
4351
|
+
function getAsExpressionType(node) {
|
|
4352
|
+
if (node.type !== "as_expression") return null;
|
|
4353
|
+
const typeChild = node.children.find((c) => c.fieldName === "type");
|
|
4354
|
+
return typeChild?.text ?? null;
|
|
4355
|
+
}
|
|
4356
|
+
function getAsExpressionContext(node) {
|
|
4357
|
+
if (isInsideCatch(node)) return "catch";
|
|
4358
|
+
const funcAncestor = findAncestor(
|
|
4359
|
+
node,
|
|
4360
|
+
(n) => ["function_declaration", "arrow_function", "method_definition"].includes(n.type)
|
|
4361
|
+
);
|
|
4362
|
+
if (funcAncestor) {
|
|
4363
|
+
const text = funcAncestor.text.toLowerCase();
|
|
4364
|
+
if (/prisma|drizzle|sequelize|mongoose|typeorm|knex|supabase/.test(text))
|
|
4365
|
+
return "orm";
|
|
4366
|
+
if (/json\.parse|parse\(/.test(text)) return "json";
|
|
4367
|
+
}
|
|
4368
|
+
return "unknown";
|
|
4369
|
+
}
|
|
4370
|
+
function extractImportFromNode(node) {
|
|
4371
|
+
if (node.type !== "import_statement" && node.type !== "import_declaration")
|
|
4579
4372
|
return null;
|
|
4373
|
+
const sourceNode = node.children.find(
|
|
4374
|
+
(c) => c.type === "string" || c.fieldName === "source"
|
|
4375
|
+
);
|
|
4376
|
+
if (!sourceNode) return null;
|
|
4377
|
+
const source = sourceNode.text.replace(/^['"]|['"]$/g, "");
|
|
4378
|
+
const isTypeOnly = node.text.includes("import type ");
|
|
4379
|
+
const symbols = [];
|
|
4380
|
+
const namedImport = node.children.find(
|
|
4381
|
+
(c) => c.type === "named_imports" || c.type === "import_clause"
|
|
4382
|
+
);
|
|
4383
|
+
if (namedImport) {
|
|
4384
|
+
for (const child of namedImport.children) {
|
|
4385
|
+
if (child.type === "identifier" || child.type === "type_identifier" || child.type === "import_specifier") {
|
|
4386
|
+
symbols.push(child.text);
|
|
4387
|
+
}
|
|
4388
|
+
}
|
|
4389
|
+
}
|
|
4390
|
+
return { source, symbols, line: node.startRow + 1, isTypeOnly };
|
|
4391
|
+
}
|
|
4392
|
+
function findPythonFunctions(root) {
|
|
4393
|
+
const funcNodes = findNodesOfTypes(root, [
|
|
4394
|
+
"function_definition",
|
|
4395
|
+
"decorated_definition"
|
|
4396
|
+
]);
|
|
4397
|
+
const results = [];
|
|
4398
|
+
for (const node of funcNodes) {
|
|
4399
|
+
if (node.type === "decorated_definition") {
|
|
4400
|
+
const inner = node.children.find(
|
|
4401
|
+
(c) => c.type === "function_definition"
|
|
4402
|
+
);
|
|
4403
|
+
if (inner) {
|
|
4404
|
+
results.push(extractPythonFunctionInfo(inner, node));
|
|
4405
|
+
}
|
|
4406
|
+
} else {
|
|
4407
|
+
results.push(extractPythonFunctionInfo(node));
|
|
4408
|
+
}
|
|
4409
|
+
}
|
|
4410
|
+
return results;
|
|
4411
|
+
}
|
|
4412
|
+
function findPythonClasses(root) {
|
|
4413
|
+
const classNodes = findNodesOfTypes(root, [
|
|
4414
|
+
"class_definition",
|
|
4415
|
+
"decorated_definition"
|
|
4416
|
+
]);
|
|
4417
|
+
const results = [];
|
|
4418
|
+
for (const node of classNodes) {
|
|
4419
|
+
if (node.type === "decorated_definition") {
|
|
4420
|
+
const inner = node.children.find(
|
|
4421
|
+
(c) => c.type === "class_definition"
|
|
4422
|
+
);
|
|
4423
|
+
if (inner) {
|
|
4424
|
+
results.push(extractPythonClassInfo(inner, node));
|
|
4425
|
+
}
|
|
4426
|
+
} else {
|
|
4427
|
+
results.push(extractPythonClassInfo(node));
|
|
4428
|
+
}
|
|
4580
4429
|
}
|
|
4430
|
+
return results;
|
|
4431
|
+
}
|
|
4432
|
+
function findPythonImports(root) {
|
|
4433
|
+
const importNodes = findNodesOfTypes(root, [
|
|
4434
|
+
"import_statement",
|
|
4435
|
+
"import_from_statement"
|
|
4436
|
+
]);
|
|
4437
|
+
return importNodes.map(extractPythonImportInfo);
|
|
4581
4438
|
}
|
|
4582
|
-
|
|
4583
|
-
|
|
4584
|
-
|
|
4585
|
-
|
|
4439
|
+
function isPythonFunctionStub(funcInfo) {
|
|
4440
|
+
const text = funcInfo.text;
|
|
4441
|
+
const bodyLines = text.split("\n").slice(1).join("\n").trim();
|
|
4442
|
+
if (/^(\s*(pass|\.\.\.)\s*)$/.test(bodyLines)) return true;
|
|
4443
|
+
const docstringOnly = bodyLines.replace(/"""[\s\S]*?"""/g, "").replace(/'''[\s\S]*?'''/g, "").trim();
|
|
4444
|
+
if (docstringOnly === "" || docstringOnly === "pass" || docstringOnly === "...") {
|
|
4445
|
+
return true;
|
|
4586
4446
|
}
|
|
4587
|
-
|
|
4588
|
-
|
|
4589
|
-
|
|
4447
|
+
return false;
|
|
4448
|
+
}
|
|
4449
|
+
function detectPythonAIPatterns(root) {
|
|
4450
|
+
const findings = [];
|
|
4451
|
+
const functions = findPythonFunctions(root);
|
|
4452
|
+
for (const fn of functions) {
|
|
4453
|
+
if (isPythonFunctionStub(fn)) {
|
|
4454
|
+
findings.push({
|
|
4455
|
+
type: "python-stub-function",
|
|
4456
|
+
message: `Function '${fn.name}' is a stub (only pass/ellipsis)`,
|
|
4457
|
+
line: fn.line
|
|
4458
|
+
});
|
|
4459
|
+
}
|
|
4590
4460
|
}
|
|
4591
|
-
|
|
4592
|
-
|
|
4593
|
-
const
|
|
4594
|
-
|
|
4595
|
-
|
|
4596
|
-
|
|
4597
|
-
|
|
4461
|
+
const tryNodes = findNodesOfType(root, "try_statement");
|
|
4462
|
+
for (const tryNode of tryNodes) {
|
|
4463
|
+
const exceptNodes = tryNode.children.filter(
|
|
4464
|
+
(c) => c.type === "except_clause"
|
|
4465
|
+
);
|
|
4466
|
+
for (const exceptNode of exceptNodes) {
|
|
4467
|
+
const hasSpecificType = exceptNode.children.some(
|
|
4468
|
+
(c) => c.type === "identifier" || c.type === "tuple"
|
|
4469
|
+
);
|
|
4470
|
+
if (!hasSpecificType) {
|
|
4471
|
+
const bareExcept = exceptNode.children.find(
|
|
4472
|
+
(c) => c.text && c.text.includes("except")
|
|
4473
|
+
);
|
|
4474
|
+
findings.push({
|
|
4475
|
+
type: "python-bare-except",
|
|
4476
|
+
message: "Bare except clause catches all exceptions",
|
|
4477
|
+
line: exceptNode.startRow + 1
|
|
4478
|
+
});
|
|
4479
|
+
}
|
|
4480
|
+
}
|
|
4598
4481
|
}
|
|
4599
|
-
|
|
4600
|
-
|
|
4601
|
-
|
|
4602
|
-
|
|
4603
|
-
|
|
4482
|
+
const commentNodes = findNodesOfType(root, "comment");
|
|
4483
|
+
for (const comment of commentNodes) {
|
|
4484
|
+
const text = comment.text.toLowerCase();
|
|
4485
|
+
if (/todo|fixme|hack|xxx/.test(text)) {
|
|
4486
|
+
findings.push({
|
|
4487
|
+
type: "python-todo-stub",
|
|
4488
|
+
message: `TODO/FIXME comment: ${comment.text.trim()}`,
|
|
4489
|
+
line: comment.startRow + 1
|
|
4490
|
+
});
|
|
4491
|
+
}
|
|
4604
4492
|
}
|
|
4605
|
-
|
|
4606
|
-
|
|
4607
|
-
|
|
4493
|
+
const callNodes = findNodesOfType(root, "call");
|
|
4494
|
+
for (const call of callNodes) {
|
|
4495
|
+
const func = call.children[0];
|
|
4496
|
+
if (func && func.text === "print") {
|
|
4497
|
+
findings.push({
|
|
4498
|
+
type: "python-print-leftover",
|
|
4499
|
+
message: "print() statement \u2014 likely debug leftover",
|
|
4500
|
+
line: call.startRow + 1
|
|
4501
|
+
});
|
|
4502
|
+
}
|
|
4608
4503
|
}
|
|
4609
|
-
|
|
4610
|
-
|
|
4611
|
-
|
|
4612
|
-
|
|
4613
|
-
|
|
4614
|
-
|
|
4615
|
-
|
|
4504
|
+
return findings;
|
|
4505
|
+
}
|
|
4506
|
+
function extractPythonFunctionInfo(funcNode, decoratedParent) {
|
|
4507
|
+
const nameNode = funcNode.children.find((c) => c.fieldName === "name") ?? funcNode.children.find((c) => c.type === "identifier");
|
|
4508
|
+
const name = nameNode?.text ?? "(anonymous)";
|
|
4509
|
+
const params = funcNode.children.find(
|
|
4510
|
+
(c) => c.type === "parameters"
|
|
4511
|
+
);
|
|
4512
|
+
const parameters = params ? params.children.filter((c) => c.type === "identifier" || c.type === "typed_parameter" || c.type === "default_parameter").map((c) => c.children[0]?.text ?? c.text) : [];
|
|
4513
|
+
const isAsync = funcNode.children.some(
|
|
4514
|
+
(c) => c.type === "async"
|
|
4515
|
+
);
|
|
4516
|
+
const decorators = [];
|
|
4517
|
+
if (decoratedParent) {
|
|
4518
|
+
for (const child of decoratedParent.children) {
|
|
4519
|
+
if (child.type === "decorator") {
|
|
4520
|
+
decorators.push(child.text.replace("@", ""));
|
|
4521
|
+
}
|
|
4522
|
+
}
|
|
4616
4523
|
}
|
|
4524
|
+
return {
|
|
4525
|
+
name,
|
|
4526
|
+
decorators,
|
|
4527
|
+
parameters,
|
|
4528
|
+
isAsync,
|
|
4529
|
+
line: funcNode.startRow + 1,
|
|
4530
|
+
endLine: funcNode.endRow + 1,
|
|
4531
|
+
text: funcNode.text
|
|
4532
|
+
};
|
|
4617
4533
|
}
|
|
4618
|
-
|
|
4619
|
-
|
|
4620
|
-
|
|
4621
|
-
|
|
4534
|
+
function extractPythonClassInfo(classNode, decoratedParent) {
|
|
4535
|
+
const nameNode = classNode.children.find((c) => c.fieldName === "name") ?? classNode.children.find((c) => c.type === "identifier");
|
|
4536
|
+
const name = nameNode?.text ?? "(anonymous)";
|
|
4537
|
+
const argList = classNode.children.find(
|
|
4538
|
+
(c) => c.type === "argument_list"
|
|
4539
|
+
);
|
|
4540
|
+
const bases = argList ? argList.children.filter((c) => c.type === "identifier" || c.type === "attribute").map((c) => c.text) : [];
|
|
4541
|
+
const decorators = [];
|
|
4542
|
+
if (decoratedParent) {
|
|
4543
|
+
for (const child of decoratedParent.children) {
|
|
4544
|
+
if (child.type === "decorator") {
|
|
4545
|
+
decorators.push(child.text.replace("@", ""));
|
|
4546
|
+
}
|
|
4547
|
+
}
|
|
4622
4548
|
}
|
|
4623
|
-
|
|
4624
|
-
|
|
4625
|
-
|
|
4549
|
+
const body = classNode.children.find(
|
|
4550
|
+
(c) => c.type === "block"
|
|
4551
|
+
);
|
|
4552
|
+
const methods = [];
|
|
4553
|
+
if (body) {
|
|
4554
|
+
for (const child of body.children) {
|
|
4555
|
+
if (child.type === "function_definition") {
|
|
4556
|
+
methods.push(extractPythonFunctionInfo(child));
|
|
4557
|
+
} else if (child.type === "decorated_definition") {
|
|
4558
|
+
const inner = child.children.find(
|
|
4559
|
+
(c) => c.type === "function_definition"
|
|
4560
|
+
);
|
|
4561
|
+
if (inner) {
|
|
4562
|
+
methods.push(extractPythonFunctionInfo(inner, child));
|
|
4563
|
+
}
|
|
4564
|
+
}
|
|
4565
|
+
}
|
|
4626
4566
|
}
|
|
4627
|
-
|
|
4628
|
-
|
|
4629
|
-
|
|
4630
|
-
|
|
4631
|
-
|
|
4632
|
-
|
|
4633
|
-
|
|
4567
|
+
return {
|
|
4568
|
+
name,
|
|
4569
|
+
bases,
|
|
4570
|
+
decorators,
|
|
4571
|
+
methods,
|
|
4572
|
+
line: classNode.startRow + 1,
|
|
4573
|
+
endLine: classNode.endRow + 1,
|
|
4574
|
+
text: classNode.text
|
|
4575
|
+
};
|
|
4576
|
+
}
|
|
4577
|
+
function extractPythonImportInfo(importNode) {
|
|
4578
|
+
const isFromImport = importNode.type === "import_from_statement";
|
|
4579
|
+
let module = "";
|
|
4580
|
+
const symbols = [];
|
|
4581
|
+
if (isFromImport) {
|
|
4582
|
+
const moduleNode = importNode.children.find(
|
|
4583
|
+
(c) => c.fieldName === "module_name" || c.type === "dotted_name" && c.fieldName !== "name" || c.type === "identifier" && c.fieldName !== "name"
|
|
4584
|
+
);
|
|
4585
|
+
module = moduleNode?.text ?? "";
|
|
4586
|
+
const nameList = importNode.children.find(
|
|
4587
|
+
(c) => c.type === "dotted_name" && c !== moduleNode
|
|
4588
|
+
);
|
|
4589
|
+
const identifierChildren = importNode.children.filter(
|
|
4590
|
+
(c) => c.type === "identifier" && c !== moduleNode
|
|
4591
|
+
);
|
|
4592
|
+
if (nameList) {
|
|
4593
|
+
symbols.push(nameList.text);
|
|
4594
|
+
}
|
|
4595
|
+
for (const id of identifierChildren) {
|
|
4596
|
+
if (id.text !== "from" && id.text !== "import" && id.text !== module) {
|
|
4597
|
+
symbols.push(id.text);
|
|
4598
|
+
}
|
|
4599
|
+
}
|
|
4600
|
+
} else {
|
|
4601
|
+
const dottedNames = importNode.children.filter(
|
|
4602
|
+
(c) => c.type === "dotted_name"
|
|
4603
|
+
);
|
|
4604
|
+
const identifiers = importNode.children.filter(
|
|
4605
|
+
(c) => c.type === "identifier"
|
|
4606
|
+
);
|
|
4607
|
+
for (const dn of dottedNames) {
|
|
4608
|
+
symbols.push(dn.text);
|
|
4609
|
+
}
|
|
4610
|
+
for (const id of identifiers) {
|
|
4611
|
+
if (id.text !== "import") {
|
|
4612
|
+
symbols.push(id.text);
|
|
4613
|
+
}
|
|
4614
|
+
}
|
|
4615
|
+
module = symbols[0] ?? "";
|
|
4634
4616
|
}
|
|
4617
|
+
return {
|
|
4618
|
+
module,
|
|
4619
|
+
symbols,
|
|
4620
|
+
isFromImport,
|
|
4621
|
+
line: importNode.startRow + 1,
|
|
4622
|
+
text: importNode.text
|
|
4623
|
+
};
|
|
4635
4624
|
}
|
|
4636
|
-
|
|
4637
|
-
|
|
4638
|
-
|
|
4639
|
-
|
|
4625
|
+
function convertNode(node, parent) {
|
|
4626
|
+
const children = [];
|
|
4627
|
+
const astNode = {
|
|
4628
|
+
type: node.type,
|
|
4629
|
+
text: node.text,
|
|
4630
|
+
startRow: node.startPosition.row,
|
|
4631
|
+
startCol: node.startPosition.column,
|
|
4632
|
+
endRow: node.endPosition.row,
|
|
4633
|
+
endCol: node.endPosition.column,
|
|
4634
|
+
children,
|
|
4635
|
+
parent,
|
|
4636
|
+
fieldName: null
|
|
4637
|
+
};
|
|
4638
|
+
for (let i = 0; i < node.childCount; i++) {
|
|
4639
|
+
const child = node.child(i);
|
|
4640
|
+
if (child) {
|
|
4641
|
+
const converted = convertNode(child, astNode);
|
|
4642
|
+
converted.fieldName = node.fieldNameForChild(i) ?? null;
|
|
4643
|
+
children.push(converted);
|
|
4644
|
+
}
|
|
4640
4645
|
}
|
|
4641
|
-
|
|
4642
|
-
|
|
4643
|
-
|
|
4646
|
+
return astNode;
|
|
4647
|
+
}
|
|
4648
|
+
var parseCache, parserInstance, tsLang, tsxLang, initPromise, initDone, initOk, pyLang, pyInitDone, pyInitOk, goLang, goInitDone, goInitOk, rustLang, rustInitDone, rustInitOk, phpLang, phpInitDone, phpInitOk, csharpLang, csharpInitDone, csharpInitOk, swiftLang, swiftInitDone, swiftInitOk;
|
|
4649
|
+
var init_tree_sitter = __esm({
|
|
4650
|
+
"src/utils/tree-sitter.ts"() {
|
|
4651
|
+
"use strict";
|
|
4652
|
+
parseCache = /* @__PURE__ */ new Map();
|
|
4653
|
+
parserInstance = null;
|
|
4654
|
+
tsLang = null;
|
|
4655
|
+
tsxLang = null;
|
|
4656
|
+
initPromise = null;
|
|
4657
|
+
initDone = false;
|
|
4658
|
+
initOk = false;
|
|
4659
|
+
pyLang = null;
|
|
4660
|
+
pyInitDone = false;
|
|
4661
|
+
pyInitOk = false;
|
|
4662
|
+
goLang = null;
|
|
4663
|
+
goInitDone = false;
|
|
4664
|
+
goInitOk = false;
|
|
4665
|
+
rustLang = null;
|
|
4666
|
+
rustInitDone = false;
|
|
4667
|
+
rustInitOk = false;
|
|
4668
|
+
phpLang = null;
|
|
4669
|
+
phpInitDone = false;
|
|
4670
|
+
phpInitOk = false;
|
|
4671
|
+
csharpLang = null;
|
|
4672
|
+
csharpInitDone = false;
|
|
4673
|
+
csharpInitOk = false;
|
|
4674
|
+
swiftLang = null;
|
|
4675
|
+
swiftInitDone = false;
|
|
4676
|
+
swiftInitOk = false;
|
|
4644
4677
|
}
|
|
4678
|
+
});
|
|
4679
|
+
|
|
4680
|
+
// src/plugins/loader.ts
|
|
4681
|
+
async function loadPlugin(pluginPath) {
|
|
4645
4682
|
try {
|
|
4646
|
-
|
|
4647
|
-
const
|
|
4648
|
-
if (!
|
|
4649
|
-
|
|
4650
|
-
|
|
4683
|
+
const mod = await import(pluginPath);
|
|
4684
|
+
const engine = mod.default;
|
|
4685
|
+
if (!engine || typeof engine !== "object") {
|
|
4686
|
+
return null;
|
|
4687
|
+
}
|
|
4688
|
+
if (typeof engine.name === "string" && typeof engine.description === "string" && Array.isArray(engine.supportedLanguages) && typeof engine.run === "function") {
|
|
4689
|
+
return engine;
|
|
4690
|
+
}
|
|
4651
4691
|
return null;
|
|
4652
|
-
}
|
|
4653
|
-
}
|
|
4654
|
-
async function parseSwiftFile(content) {
|
|
4655
|
-
if (!swiftLang) {
|
|
4656
|
-
const ok = await initSwiftParser();
|
|
4657
|
-
if (!ok) return null;
|
|
4658
|
-
}
|
|
4659
|
-
if (!parserInstance) {
|
|
4660
|
-
const ok = await initParser();
|
|
4661
|
-
if (!ok) return null;
|
|
4662
|
-
}
|
|
4663
|
-
try {
|
|
4664
|
-
parserInstance.setLanguage(swiftLang);
|
|
4665
|
-
const tree = parserInstance.parse(content);
|
|
4666
|
-
if (!tree) return null;
|
|
4667
|
-
return convertNode(tree.rootNode, null);
|
|
4668
4692
|
} catch {
|
|
4669
4693
|
return null;
|
|
4670
4694
|
}
|
|
4671
4695
|
}
|
|
4672
|
-
function
|
|
4673
|
-
const results =
|
|
4674
|
-
|
|
4675
|
-
|
|
4676
|
-
|
|
4677
|
-
|
|
4678
|
-
|
|
4679
|
-
|
|
4680
|
-
}
|
|
4681
|
-
function findNodesOfTypes(root, types3) {
|
|
4682
|
-
const typeSet = new Set(types3);
|
|
4683
|
-
const results = [];
|
|
4684
|
-
function walk(node) {
|
|
4685
|
-
if (typeSet.has(node.type)) results.push(node);
|
|
4686
|
-
for (const child of node.children) walk(child);
|
|
4687
|
-
}
|
|
4688
|
-
walk(root);
|
|
4689
|
-
return results;
|
|
4690
|
-
}
|
|
4691
|
-
function walkAST(root, visitor) {
|
|
4692
|
-
function walk(node) {
|
|
4693
|
-
const result = visitor(node);
|
|
4694
|
-
if (result !== false) {
|
|
4695
|
-
for (const child of node.children) walk(child);
|
|
4696
|
+
async function loadPlugins(paths) {
|
|
4697
|
+
const results = await Promise.allSettled(
|
|
4698
|
+
paths.map((p) => loadPlugin(p))
|
|
4699
|
+
);
|
|
4700
|
+
const engines = [];
|
|
4701
|
+
for (const r of results) {
|
|
4702
|
+
if (r.status === "fulfilled" && r.value !== null) {
|
|
4703
|
+
engines.push(r.value);
|
|
4696
4704
|
}
|
|
4697
4705
|
}
|
|
4698
|
-
|
|
4706
|
+
return engines;
|
|
4699
4707
|
}
|
|
4700
|
-
|
|
4701
|
-
|
|
4702
|
-
|
|
4703
|
-
if (predicate(current)) return current;
|
|
4704
|
-
current = current.parent;
|
|
4708
|
+
var init_loader = __esm({
|
|
4709
|
+
"src/plugins/loader.ts"() {
|
|
4710
|
+
"use strict";
|
|
4705
4711
|
}
|
|
4706
|
-
|
|
4707
|
-
|
|
4708
|
-
|
|
4709
|
-
|
|
4710
|
-
|
|
4711
|
-
|
|
4712
|
-
|
|
4713
|
-
|
|
4714
|
-
|
|
4715
|
-
|
|
4716
|
-
|
|
4717
|
-
|
|
4718
|
-
|
|
4719
|
-
|
|
4720
|
-
|
|
4721
|
-
(c) => c.type !== "comment" && c.type !== "//" && c.type !== "/*" && c.type !== "{" && c.type !== "}" && c.text.trim() !== ""
|
|
4722
|
-
);
|
|
4723
|
-
return nonTrivial.length === 0;
|
|
4724
|
-
}
|
|
4725
|
-
function getAsExpressionType(node) {
|
|
4726
|
-
if (node.type !== "as_expression") return null;
|
|
4727
|
-
const typeChild = node.children.find((c) => c.fieldName === "type");
|
|
4728
|
-
return typeChild?.text ?? null;
|
|
4712
|
+
});
|
|
4713
|
+
|
|
4714
|
+
// src/plugins/registry.ts
|
|
4715
|
+
var registry_exports = {};
|
|
4716
|
+
__export(registry_exports, {
|
|
4717
|
+
PLUGIN_DIR: () => PLUGIN_DIR,
|
|
4718
|
+
discoverAndLoadPlugins: () => discoverAndLoadPlugins,
|
|
4719
|
+
getPluginDir: () => getPluginDir,
|
|
4720
|
+
pluginRegistry: () => pluginRegistry
|
|
4721
|
+
});
|
|
4722
|
+
import { join as join2 } from "node:path";
|
|
4723
|
+
import { readdir } from "node:fs/promises";
|
|
4724
|
+
import { existsSync as existsSync2 } from "node:fs";
|
|
4725
|
+
function getPluginDir(rootDir) {
|
|
4726
|
+
return join2(rootDir, PLUGIN_DIR);
|
|
4729
4727
|
}
|
|
4730
|
-
function
|
|
4731
|
-
if (
|
|
4732
|
-
|
|
4733
|
-
node,
|
|
4734
|
-
(n) => ["function_declaration", "arrow_function", "method_definition"].includes(n.type)
|
|
4735
|
-
);
|
|
4736
|
-
if (funcAncestor) {
|
|
4737
|
-
const text = funcAncestor.text.toLowerCase();
|
|
4738
|
-
if (/prisma|drizzle|sequelize|mongoose|typeorm|knex|supabase/.test(text))
|
|
4739
|
-
return "orm";
|
|
4740
|
-
if (/json\.parse|parse\(/.test(text)) return "json";
|
|
4728
|
+
async function discoverAndLoadPlugins(rootDir) {
|
|
4729
|
+
if (pluginRegistry.isLoaded) {
|
|
4730
|
+
return pluginRegistry.getEngines();
|
|
4741
4731
|
}
|
|
4742
|
-
|
|
4743
|
-
|
|
4744
|
-
|
|
4745
|
-
|
|
4746
|
-
|
|
4747
|
-
|
|
4748
|
-
|
|
4749
|
-
|
|
4750
|
-
|
|
4751
|
-
|
|
4752
|
-
|
|
4753
|
-
|
|
4754
|
-
|
|
4755
|
-
|
|
4756
|
-
|
|
4757
|
-
|
|
4758
|
-
|
|
4759
|
-
|
|
4760
|
-
|
|
4732
|
+
const pluginDir = getPluginDir(rootDir);
|
|
4733
|
+
if (!existsSync2(pluginDir)) {
|
|
4734
|
+
pluginRegistry.setLoaded(true);
|
|
4735
|
+
return [];
|
|
4736
|
+
}
|
|
4737
|
+
try {
|
|
4738
|
+
const files = await readdir(pluginDir);
|
|
4739
|
+
const pluginPaths = files.filter((f) => f.endsWith(".js") || f.endsWith(".mjs")).map((f) => join2(pluginDir, f));
|
|
4740
|
+
const engines = await loadPlugins(pluginPaths);
|
|
4741
|
+
for (let i = 0; i < engines.length; i++) {
|
|
4742
|
+
const engine = engines[i];
|
|
4743
|
+
pluginRegistry.register({
|
|
4744
|
+
id: engine.name,
|
|
4745
|
+
path: pluginPaths[i],
|
|
4746
|
+
engine,
|
|
4747
|
+
loaded: true
|
|
4748
|
+
});
|
|
4749
|
+
}
|
|
4750
|
+
for (let i = 0; i < pluginPaths.length; i++) {
|
|
4751
|
+
const path2 = pluginPaths[i];
|
|
4752
|
+
const engine = engines.find((e) => {
|
|
4753
|
+
const entry = pluginRegistry.getAll().find((ent) => ent.path === path2);
|
|
4754
|
+
return entry?.engine;
|
|
4755
|
+
});
|
|
4756
|
+
if (!engine && !pluginRegistry.has(path2)) {
|
|
4757
|
+
pluginRegistry.register({
|
|
4758
|
+
id: `plugin-${i}`,
|
|
4759
|
+
path: path2,
|
|
4760
|
+
engine: null,
|
|
4761
|
+
loaded: false,
|
|
4762
|
+
error: "Failed to load plugin module"
|
|
4763
|
+
});
|
|
4761
4764
|
}
|
|
4762
4765
|
}
|
|
4766
|
+
pluginRegistry.setLoaded(true);
|
|
4767
|
+
return engines;
|
|
4768
|
+
} catch {
|
|
4769
|
+
pluginRegistry.setLoaded(true);
|
|
4770
|
+
return [];
|
|
4763
4771
|
}
|
|
4764
|
-
return { source, symbols, line: node.startRow + 1, isTypeOnly };
|
|
4765
4772
|
}
|
|
4766
|
-
|
|
4767
|
-
|
|
4768
|
-
|
|
4769
|
-
"
|
|
4770
|
-
|
|
4771
|
-
|
|
4772
|
-
|
|
4773
|
-
|
|
4774
|
-
|
|
4775
|
-
|
|
4776
|
-
|
|
4777
|
-
|
|
4778
|
-
|
|
4773
|
+
var PluginRegistry, pluginRegistry, PLUGIN_DIR;
|
|
4774
|
+
var init_registry = __esm({
|
|
4775
|
+
"src/plugins/registry.ts"() {
|
|
4776
|
+
"use strict";
|
|
4777
|
+
init_loader();
|
|
4778
|
+
PluginRegistry = class {
|
|
4779
|
+
entries = /* @__PURE__ */ new Map();
|
|
4780
|
+
loaded = false;
|
|
4781
|
+
/** Get all registered plugins */
|
|
4782
|
+
getAll() {
|
|
4783
|
+
return [...this.entries.values()];
|
|
4784
|
+
}
|
|
4785
|
+
/** Get all successfully loaded engines */
|
|
4786
|
+
getEngines() {
|
|
4787
|
+
return [...this.entries.values()].filter((e) => e.loaded).map((e) => e.engine);
|
|
4788
|
+
}
|
|
4789
|
+
/** Get a specific plugin by id */
|
|
4790
|
+
get(id) {
|
|
4791
|
+
return this.entries.get(id);
|
|
4792
|
+
}
|
|
4793
|
+
/** Get a loaded engine by name */
|
|
4794
|
+
getEngine(name) {
|
|
4795
|
+
const entry = this.entries.get(name);
|
|
4796
|
+
return entry?.loaded ? entry.engine : void 0;
|
|
4797
|
+
}
|
|
4798
|
+
/** Register a plugin entry */
|
|
4799
|
+
register(entry) {
|
|
4800
|
+
this.entries.set(entry.id, entry);
|
|
4801
|
+
}
|
|
4802
|
+
/** Remove a plugin by id */
|
|
4803
|
+
remove(id) {
|
|
4804
|
+
return this.entries.delete(id);
|
|
4805
|
+
}
|
|
4806
|
+
/** Check if a plugin is registered */
|
|
4807
|
+
has(id) {
|
|
4808
|
+
return this.entries.has(id);
|
|
4809
|
+
}
|
|
4810
|
+
/** Number of registered plugins */
|
|
4811
|
+
get size() {
|
|
4812
|
+
return this.entries.size;
|
|
4813
|
+
}
|
|
4814
|
+
/** Whether the registry has been loaded from disk */
|
|
4815
|
+
get isLoaded() {
|
|
4816
|
+
return this.loaded;
|
|
4817
|
+
}
|
|
4818
|
+
/** Mark the registry as loaded */
|
|
4819
|
+
setLoaded(loaded) {
|
|
4820
|
+
this.loaded = loaded;
|
|
4779
4821
|
}
|
|
4780
|
-
|
|
4781
|
-
|
|
4782
|
-
|
|
4783
|
-
|
|
4784
|
-
return results;
|
|
4785
|
-
}
|
|
4786
|
-
function findPythonClasses(root) {
|
|
4787
|
-
const classNodes = findNodesOfTypes(root, [
|
|
4788
|
-
"class_definition",
|
|
4789
|
-
"decorated_definition"
|
|
4790
|
-
]);
|
|
4791
|
-
const results = [];
|
|
4792
|
-
for (const node of classNodes) {
|
|
4793
|
-
if (node.type === "decorated_definition") {
|
|
4794
|
-
const inner = node.children.find(
|
|
4795
|
-
(c) => c.type === "class_definition"
|
|
4796
|
-
);
|
|
4797
|
-
if (inner) {
|
|
4798
|
-
results.push(extractPythonClassInfo(inner, node));
|
|
4822
|
+
/** Clear all entries */
|
|
4823
|
+
clear() {
|
|
4824
|
+
this.entries.clear();
|
|
4825
|
+
this.loaded = false;
|
|
4799
4826
|
}
|
|
4800
|
-
}
|
|
4801
|
-
|
|
4802
|
-
|
|
4803
|
-
}
|
|
4804
|
-
return results;
|
|
4805
|
-
}
|
|
4806
|
-
function findPythonImports(root) {
|
|
4807
|
-
const importNodes = findNodesOfTypes(root, [
|
|
4808
|
-
"import_statement",
|
|
4809
|
-
"import_from_statement"
|
|
4810
|
-
]);
|
|
4811
|
-
return importNodes.map(extractPythonImportInfo);
|
|
4812
|
-
}
|
|
4813
|
-
function isPythonFunctionStub(funcInfo) {
|
|
4814
|
-
const text = funcInfo.text;
|
|
4815
|
-
const bodyLines = text.split("\n").slice(1).join("\n").trim();
|
|
4816
|
-
if (/^(\s*(pass|\.\.\.)\s*)$/.test(bodyLines)) return true;
|
|
4817
|
-
const docstringOnly = bodyLines.replace(/"""[\s\S]*?"""/g, "").replace(/'''[\s\S]*?'''/g, "").trim();
|
|
4818
|
-
if (docstringOnly === "" || docstringOnly === "pass" || docstringOnly === "...") {
|
|
4819
|
-
return true;
|
|
4827
|
+
};
|
|
4828
|
+
pluginRegistry = new PluginRegistry();
|
|
4829
|
+
PLUGIN_DIR = ".deep-slop/plugins";
|
|
4820
4830
|
}
|
|
4821
|
-
|
|
4822
|
-
|
|
4823
|
-
|
|
4824
|
-
|
|
4825
|
-
|
|
4826
|
-
|
|
4827
|
-
|
|
4828
|
-
|
|
4829
|
-
|
|
4830
|
-
|
|
4831
|
-
|
|
4831
|
+
});
|
|
4832
|
+
|
|
4833
|
+
// src/utils/suppress.ts
|
|
4834
|
+
import { join as join3 } from "node:path";
|
|
4835
|
+
import { readFileSync as readFileSync2 } from "node:fs";
|
|
4836
|
+
function parseSuppressDirectives(content) {
|
|
4837
|
+
const entries = [];
|
|
4838
|
+
const lines = content.split("\n");
|
|
4839
|
+
for (let i = 0; i < lines.length; i++) {
|
|
4840
|
+
const line = lines[i].trim();
|
|
4841
|
+
const lineNum = i + 1;
|
|
4842
|
+
const ignoreNextMatch = line.match(
|
|
4843
|
+
/\/\/\s*deep-slop-ignore-next(?:\s+(.+))?$/
|
|
4844
|
+
);
|
|
4845
|
+
if (ignoreNextMatch) {
|
|
4846
|
+
entries.push({
|
|
4847
|
+
directiveLine: lineNum,
|
|
4848
|
+
targetLine: lineNum + 1,
|
|
4849
|
+
rules: parseRuleList(ignoreNextMatch[1]),
|
|
4850
|
+
type: "next-line"
|
|
4832
4851
|
});
|
|
4852
|
+
continue;
|
|
4833
4853
|
}
|
|
4834
|
-
|
|
4835
|
-
|
|
4836
|
-
for (const tryNode of tryNodes) {
|
|
4837
|
-
const exceptNodes = tryNode.children.filter(
|
|
4838
|
-
(c) => c.type === "except_clause"
|
|
4854
|
+
const ignoreLineMatch = line.match(
|
|
4855
|
+
/\/\/\s*deep-slop-ignore-line(?:\s+(.+))?$/
|
|
4839
4856
|
);
|
|
4840
|
-
|
|
4841
|
-
|
|
4842
|
-
|
|
4843
|
-
|
|
4844
|
-
|
|
4845
|
-
|
|
4846
|
-
|
|
4847
|
-
|
|
4848
|
-
|
|
4849
|
-
|
|
4850
|
-
|
|
4851
|
-
|
|
4857
|
+
if (ignoreLineMatch) {
|
|
4858
|
+
entries.push({
|
|
4859
|
+
directiveLine: lineNum,
|
|
4860
|
+
targetLine: lineNum,
|
|
4861
|
+
rules: parseRuleList(ignoreLineMatch[1]),
|
|
4862
|
+
type: "line"
|
|
4863
|
+
});
|
|
4864
|
+
continue;
|
|
4865
|
+
}
|
|
4866
|
+
const ignoreRuleMatch = line.match(
|
|
4867
|
+
/\/\/\s*deep-slop-ignore(?:\s+(.+))?$/
|
|
4868
|
+
);
|
|
4869
|
+
if (ignoreRuleMatch) {
|
|
4870
|
+
const rulePart = ignoreRuleMatch[1];
|
|
4871
|
+
if (rulePart !== "start" && rulePart !== "end") {
|
|
4872
|
+
entries.push({
|
|
4873
|
+
directiveLine: lineNum,
|
|
4874
|
+
targetLine: lineNum + 1,
|
|
4875
|
+
rules: parseRuleList(rulePart),
|
|
4876
|
+
type: "next-line"
|
|
4852
4877
|
});
|
|
4878
|
+
continue;
|
|
4853
4879
|
}
|
|
4854
4880
|
}
|
|
4855
|
-
|
|
4856
|
-
|
|
4857
|
-
|
|
4858
|
-
|
|
4859
|
-
|
|
4860
|
-
|
|
4861
|
-
|
|
4862
|
-
|
|
4863
|
-
|
|
4881
|
+
const ignoreStartMatch = line.match(
|
|
4882
|
+
/\/\/\s*deep-slop-ignore-start(?:\s+(.+))?$/
|
|
4883
|
+
);
|
|
4884
|
+
if (ignoreStartMatch) {
|
|
4885
|
+
entries.push({
|
|
4886
|
+
directiveLine: lineNum,
|
|
4887
|
+
targetLine: lineNum,
|
|
4888
|
+
rules: parseRuleList(ignoreStartMatch[1]),
|
|
4889
|
+
type: "block-start"
|
|
4864
4890
|
});
|
|
4891
|
+
continue;
|
|
4865
4892
|
}
|
|
4866
|
-
|
|
4867
|
-
|
|
4868
|
-
|
|
4869
|
-
|
|
4870
|
-
|
|
4871
|
-
|
|
4872
|
-
|
|
4873
|
-
|
|
4874
|
-
|
|
4893
|
+
const ignoreEndMatch = line.match(
|
|
4894
|
+
/\/\/\s*deep-slop-ignore-end/
|
|
4895
|
+
);
|
|
4896
|
+
if (ignoreEndMatch) {
|
|
4897
|
+
entries.push({
|
|
4898
|
+
directiveLine: lineNum,
|
|
4899
|
+
targetLine: lineNum,
|
|
4900
|
+
rules: /* @__PURE__ */ new Set(),
|
|
4901
|
+
type: "block-end"
|
|
4875
4902
|
});
|
|
4903
|
+
continue;
|
|
4876
4904
|
}
|
|
4877
|
-
|
|
4878
|
-
|
|
4879
|
-
|
|
4880
|
-
|
|
4881
|
-
|
|
4882
|
-
|
|
4883
|
-
|
|
4884
|
-
|
|
4885
|
-
|
|
4886
|
-
|
|
4887
|
-
|
|
4888
|
-
|
|
4889
|
-
|
|
4890
|
-
|
|
4891
|
-
|
|
4892
|
-
|
|
4893
|
-
|
|
4894
|
-
|
|
4895
|
-
|
|
4905
|
+
const nextLineMatch = line.match(
|
|
4906
|
+
/\/\/\s*deep-slop-disable-next-line(?:\s+(.+))?$/
|
|
4907
|
+
);
|
|
4908
|
+
if (nextLineMatch) {
|
|
4909
|
+
entries.push({
|
|
4910
|
+
directiveLine: lineNum,
|
|
4911
|
+
targetLine: lineNum + 1,
|
|
4912
|
+
rules: parseRuleList(nextLineMatch[1]),
|
|
4913
|
+
type: "next-line"
|
|
4914
|
+
});
|
|
4915
|
+
continue;
|
|
4916
|
+
}
|
|
4917
|
+
const lineMatch = line.match(
|
|
4918
|
+
/\/\/\s*deep-slop-disable-line(?:\s+(.+))?$/
|
|
4919
|
+
);
|
|
4920
|
+
if (lineMatch) {
|
|
4921
|
+
entries.push({
|
|
4922
|
+
directiveLine: lineNum,
|
|
4923
|
+
targetLine: lineNum,
|
|
4924
|
+
rules: parseRuleList(lineMatch[1]),
|
|
4925
|
+
type: "line"
|
|
4926
|
+
});
|
|
4927
|
+
continue;
|
|
4928
|
+
}
|
|
4929
|
+
const blockStart = line.match(
|
|
4930
|
+
/\/\*\s*deep-slop-disable(?:\s+(.+))?\s*\//
|
|
4931
|
+
);
|
|
4932
|
+
if (blockStart) {
|
|
4933
|
+
entries.push({
|
|
4934
|
+
directiveLine: lineNum,
|
|
4935
|
+
targetLine: lineNum,
|
|
4936
|
+
rules: parseRuleList(blockStart[1]),
|
|
4937
|
+
type: "block-start"
|
|
4938
|
+
});
|
|
4939
|
+
continue;
|
|
4940
|
+
}
|
|
4941
|
+
const blockEnd = line.match(/\/\*\s*deep-slop-enable\s*\//);
|
|
4942
|
+
if (blockEnd) {
|
|
4943
|
+
entries.push({
|
|
4944
|
+
directiveLine: lineNum,
|
|
4945
|
+
targetLine: lineNum,
|
|
4946
|
+
rules: /* @__PURE__ */ new Set(),
|
|
4947
|
+
type: "block-end"
|
|
4948
|
+
});
|
|
4896
4949
|
}
|
|
4897
4950
|
}
|
|
4898
|
-
return
|
|
4899
|
-
name,
|
|
4900
|
-
decorators,
|
|
4901
|
-
parameters,
|
|
4902
|
-
isAsync,
|
|
4903
|
-
line: funcNode.startRow + 1,
|
|
4904
|
-
endLine: funcNode.endRow + 1,
|
|
4905
|
-
text: funcNode.text
|
|
4906
|
-
};
|
|
4951
|
+
return entries;
|
|
4907
4952
|
}
|
|
4908
|
-
function
|
|
4909
|
-
|
|
4910
|
-
const
|
|
4911
|
-
|
|
4912
|
-
|
|
4913
|
-
|
|
4914
|
-
const
|
|
4915
|
-
|
|
4916
|
-
|
|
4917
|
-
|
|
4918
|
-
|
|
4919
|
-
|
|
4920
|
-
|
|
4953
|
+
function parseRuleList(rulesStr) {
|
|
4954
|
+
if (!rulesStr) return /* @__PURE__ */ new Set();
|
|
4955
|
+
const rules = rulesStr.split(/[,\\s]+/).map((r) => r.trim()).filter(Boolean);
|
|
4956
|
+
return new Set(rules);
|
|
4957
|
+
}
|
|
4958
|
+
function buildSuppressChecker(entries) {
|
|
4959
|
+
const blockRanges = [];
|
|
4960
|
+
let currentStart = null;
|
|
4961
|
+
for (const entry of entries) {
|
|
4962
|
+
if (entry.type === "block-start") {
|
|
4963
|
+
currentStart = { line: entry.directiveLine, rules: entry.rules };
|
|
4964
|
+
} else if (entry.type === "block-end" && currentStart) {
|
|
4965
|
+
blockRanges.push({
|
|
4966
|
+
startLine: currentStart.line,
|
|
4967
|
+
endLine: entry.directiveLine,
|
|
4968
|
+
rules: currentStart.rules
|
|
4969
|
+
});
|
|
4970
|
+
currentStart = null;
|
|
4921
4971
|
}
|
|
4922
4972
|
}
|
|
4923
|
-
|
|
4924
|
-
(
|
|
4925
|
-
|
|
4926
|
-
|
|
4927
|
-
|
|
4928
|
-
|
|
4929
|
-
|
|
4930
|
-
|
|
4931
|
-
|
|
4932
|
-
|
|
4933
|
-
|
|
4934
|
-
|
|
4935
|
-
|
|
4936
|
-
|
|
4973
|
+
if (currentStart) {
|
|
4974
|
+
blockRanges.push({
|
|
4975
|
+
startLine: currentStart.line,
|
|
4976
|
+
endLine: 999999,
|
|
4977
|
+
rules: currentStart.rules
|
|
4978
|
+
});
|
|
4979
|
+
}
|
|
4980
|
+
return (line, rule) => {
|
|
4981
|
+
for (const entry of entries) {
|
|
4982
|
+
if (entry.type === "next-line" || entry.type === "line") {
|
|
4983
|
+
if (entry.targetLine === line) {
|
|
4984
|
+
if (entry.rules.size === 0 || entry.rules.has(rule)) {
|
|
4985
|
+
return true;
|
|
4986
|
+
}
|
|
4937
4987
|
}
|
|
4938
4988
|
}
|
|
4939
4989
|
}
|
|
4940
|
-
|
|
4941
|
-
|
|
4942
|
-
|
|
4943
|
-
|
|
4944
|
-
|
|
4945
|
-
|
|
4946
|
-
|
|
4947
|
-
|
|
4948
|
-
text: classNode.text
|
|
4990
|
+
for (const range2 of blockRanges) {
|
|
4991
|
+
if (line >= range2.startLine && line <= range2.endLine) {
|
|
4992
|
+
if (range2.rules.size === 0 || range2.rules.has(rule)) {
|
|
4993
|
+
return true;
|
|
4994
|
+
}
|
|
4995
|
+
}
|
|
4996
|
+
}
|
|
4997
|
+
return false;
|
|
4949
4998
|
};
|
|
4950
4999
|
}
|
|
4951
|
-
function
|
|
4952
|
-
const
|
|
4953
|
-
|
|
4954
|
-
|
|
4955
|
-
|
|
4956
|
-
|
|
4957
|
-
|
|
4958
|
-
|
|
4959
|
-
|
|
4960
|
-
|
|
4961
|
-
|
|
4962
|
-
|
|
4963
|
-
|
|
4964
|
-
|
|
4965
|
-
|
|
4966
|
-
|
|
4967
|
-
|
|
5000
|
+
function buildSuppressMap(content) {
|
|
5001
|
+
const entries = parseSuppressDirectives(content);
|
|
5002
|
+
const isSuppressed = buildSuppressChecker(entries);
|
|
5003
|
+
return { entries, isSuppressed };
|
|
5004
|
+
}
|
|
5005
|
+
function loadIgnoreFile(rootDir) {
|
|
5006
|
+
const ignorePath = join3(rootDir, ".deep-slop", ".deep-slop-ignore");
|
|
5007
|
+
try {
|
|
5008
|
+
const content = readFileSync2(ignorePath, "utf-8");
|
|
5009
|
+
return content.split("\n").map((line) => line.split("#")[0].trim()).filter((line) => line && !line.startsWith("file:"));
|
|
5010
|
+
} catch {
|
|
5011
|
+
return [];
|
|
5012
|
+
}
|
|
5013
|
+
}
|
|
5014
|
+
function applySuppressDirectives(diagnostics, fileContents, globallySuppressed = /* @__PURE__ */ new Set()) {
|
|
5015
|
+
const suppressMaps = /* @__PURE__ */ new Map();
|
|
5016
|
+
for (const [filePath, content] of fileContents) {
|
|
5017
|
+
suppressMaps.set(filePath, buildSuppressMap(content));
|
|
5018
|
+
}
|
|
5019
|
+
const filtered = [];
|
|
5020
|
+
let suppressedCount = 0;
|
|
5021
|
+
for (const diag8 of diagnostics) {
|
|
5022
|
+
if (globallySuppressed.has(diag8.rule)) {
|
|
5023
|
+
suppressedCount++;
|
|
5024
|
+
continue;
|
|
4968
5025
|
}
|
|
4969
|
-
|
|
4970
|
-
|
|
4971
|
-
|
|
4972
|
-
|
|
5026
|
+
const map = suppressMaps.get(diag8.filePath);
|
|
5027
|
+
if (map && map.isSuppressed(diag8.line, diag8.rule)) {
|
|
5028
|
+
suppressedCount++;
|
|
5029
|
+
} else {
|
|
5030
|
+
filtered.push(diag8);
|
|
4973
5031
|
}
|
|
4974
|
-
}
|
|
4975
|
-
|
|
4976
|
-
|
|
4977
|
-
|
|
4978
|
-
|
|
4979
|
-
|
|
4980
|
-
|
|
4981
|
-
|
|
4982
|
-
|
|
5032
|
+
}
|
|
5033
|
+
return { filtered, suppressedCount };
|
|
5034
|
+
}
|
|
5035
|
+
var init_suppress = __esm({
|
|
5036
|
+
"src/utils/suppress.ts"() {
|
|
5037
|
+
"use strict";
|
|
5038
|
+
}
|
|
5039
|
+
});
|
|
5040
|
+
|
|
5041
|
+
// src/utils/file-utils.ts
|
|
5042
|
+
import { readFile as readFile2 } from "node:fs/promises";
|
|
5043
|
+
async function readFileContent(filePath) {
|
|
5044
|
+
const buffer = await readFile2(filePath);
|
|
5045
|
+
let content = buffer.toString("utf-8");
|
|
5046
|
+
if (content.charCodeAt(0) === 65279) {
|
|
5047
|
+
content = content.slice(1);
|
|
5048
|
+
}
|
|
5049
|
+
return content;
|
|
5050
|
+
}
|
|
5051
|
+
function detectEncodingAnomalies(content) {
|
|
5052
|
+
const hasBom = content.charCodeAt(0) === 65279;
|
|
5053
|
+
const hasCrlf = content.includes("\r\n");
|
|
5054
|
+
const hasZwnbsp = content.includes("\uFEFF");
|
|
5055
|
+
const lfOnly = (content.match(/(?<!\r)\n/g) ?? []).length;
|
|
5056
|
+
const crlfCount = (content.match(/\r\n/g) ?? []).length;
|
|
5057
|
+
const lineEnding = crlfCount > 0 && lfOnly > crlfCount ? "mixed" : crlfCount > 0 ? "crlf" : "lf";
|
|
5058
|
+
return { hasBom, hasCrlf, hasZwnbsp, lineEnding };
|
|
5059
|
+
}
|
|
5060
|
+
function toLines(content) {
|
|
5061
|
+
return content.split("\n").map((text, i) => ({ num: i + 1, text }));
|
|
5062
|
+
}
|
|
5063
|
+
function extractImports(content, language) {
|
|
5064
|
+
const imports = [];
|
|
5065
|
+
const lines = toLines(content);
|
|
5066
|
+
for (const { num, text } of lines) {
|
|
5067
|
+
const trimmed = text.trim();
|
|
5068
|
+
if (language === "typescript" || language === "javascript") {
|
|
5069
|
+
const jsMatch = trimmed.match(
|
|
5070
|
+
/^import\s+(?:type\s+)?(?:\{[^}]*\}|\*\s+as\s+\w+|\w+)\s+from\s+['"]([^'"]+)['"]/
|
|
5071
|
+
);
|
|
5072
|
+
if (jsMatch) {
|
|
5073
|
+
imports.push({
|
|
5074
|
+
line: num,
|
|
5075
|
+
source: jsMatch[1],
|
|
5076
|
+
raw: trimmed,
|
|
5077
|
+
isTypeOnly: trimmed.includes("import type"),
|
|
5078
|
+
isDefault: !trimmed.includes("{")
|
|
5079
|
+
});
|
|
5080
|
+
}
|
|
5081
|
+
const dynMatch = trimmed.match(/import\s*\(\s*['"]([^'"]+)['"]\s*\)/);
|
|
5082
|
+
if (dynMatch) {
|
|
5083
|
+
imports.push({
|
|
5084
|
+
line: num,
|
|
5085
|
+
source: dynMatch[1],
|
|
5086
|
+
raw: trimmed,
|
|
5087
|
+
isTypeOnly: false,
|
|
5088
|
+
isDynamic: true
|
|
5089
|
+
});
|
|
5090
|
+
}
|
|
5091
|
+
const reqMatch = trimmed.match(/(?:const|let|var)\s+[^=]*=\s*require\s*\(\s*['"]([^'"]+)['"]\s*\)/);
|
|
5092
|
+
if (reqMatch) {
|
|
5093
|
+
imports.push({
|
|
5094
|
+
line: num,
|
|
5095
|
+
source: reqMatch[1],
|
|
5096
|
+
raw: trimmed,
|
|
5097
|
+
isTypeOnly: false,
|
|
5098
|
+
isRequire: true
|
|
5099
|
+
});
|
|
5100
|
+
}
|
|
4983
5101
|
}
|
|
4984
|
-
|
|
4985
|
-
|
|
4986
|
-
|
|
5102
|
+
if (language === "python") {
|
|
5103
|
+
const pyMatch = trimmed.match(/^from\s+([^\s]+)\s+import/);
|
|
5104
|
+
if (pyMatch) {
|
|
5105
|
+
imports.push({ line: num, source: pyMatch[1], raw: trimmed, isTypeOnly: false });
|
|
5106
|
+
}
|
|
5107
|
+
const pyImport = trimmed.match(/^import\s+([^\s]+)/);
|
|
5108
|
+
if (pyImport) {
|
|
5109
|
+
imports.push({ line: num, source: pyImport[1], raw: trimmed, isTypeOnly: false });
|
|
4987
5110
|
}
|
|
4988
5111
|
}
|
|
4989
|
-
|
|
4990
|
-
|
|
4991
|
-
|
|
4992
|
-
|
|
4993
|
-
|
|
4994
|
-
isFromImport,
|
|
4995
|
-
line: importNode.startRow + 1,
|
|
4996
|
-
text: importNode.text
|
|
4997
|
-
};
|
|
4998
|
-
}
|
|
4999
|
-
function convertNode(node, parent) {
|
|
5000
|
-
const children = [];
|
|
5001
|
-
const astNode = {
|
|
5002
|
-
type: node.type,
|
|
5003
|
-
text: node.text,
|
|
5004
|
-
startRow: node.startPosition.row,
|
|
5005
|
-
startCol: node.startPosition.column,
|
|
5006
|
-
endRow: node.endPosition.row,
|
|
5007
|
-
endCol: node.endPosition.column,
|
|
5008
|
-
children,
|
|
5009
|
-
parent,
|
|
5010
|
-
fieldName: null
|
|
5011
|
-
};
|
|
5012
|
-
for (let i = 0; i < node.childCount; i++) {
|
|
5013
|
-
const child = node.child(i);
|
|
5014
|
-
if (child) {
|
|
5015
|
-
const converted = convertNode(child, astNode);
|
|
5016
|
-
converted.fieldName = node.fieldNameForChild(i) ?? null;
|
|
5017
|
-
children.push(converted);
|
|
5112
|
+
if (language === "go") {
|
|
5113
|
+
const goMatch = trimmed.match(/"([^"]+)"/);
|
|
5114
|
+
if (trimmed.startsWith("import") && goMatch) {
|
|
5115
|
+
imports.push({ line: num, source: goMatch[1], raw: trimmed, isTypeOnly: false });
|
|
5116
|
+
}
|
|
5018
5117
|
}
|
|
5019
5118
|
}
|
|
5020
|
-
return
|
|
5119
|
+
return imports;
|
|
5021
5120
|
}
|
|
5022
|
-
var
|
|
5023
|
-
|
|
5024
|
-
"src/utils/tree-sitter.ts"() {
|
|
5121
|
+
var init_file_utils = __esm({
|
|
5122
|
+
"src/utils/file-utils.ts"() {
|
|
5025
5123
|
"use strict";
|
|
5026
|
-
parserInstance = null;
|
|
5027
|
-
tsLang = null;
|
|
5028
|
-
tsxLang = null;
|
|
5029
|
-
initPromise = null;
|
|
5030
|
-
initDone = false;
|
|
5031
|
-
initOk = false;
|
|
5032
|
-
pyLang = null;
|
|
5033
|
-
pyInitDone = false;
|
|
5034
|
-
pyInitOk = false;
|
|
5035
|
-
goLang = null;
|
|
5036
|
-
goInitDone = false;
|
|
5037
|
-
goInitOk = false;
|
|
5038
|
-
rustLang = null;
|
|
5039
|
-
rustInitDone = false;
|
|
5040
|
-
rustInitOk = false;
|
|
5041
|
-
phpLang = null;
|
|
5042
|
-
phpInitDone = false;
|
|
5043
|
-
phpInitOk = false;
|
|
5044
|
-
csharpLang = null;
|
|
5045
|
-
csharpInitDone = false;
|
|
5046
|
-
csharpInitOk = false;
|
|
5047
|
-
swiftLang = null;
|
|
5048
|
-
swiftInitDone = false;
|
|
5049
|
-
swiftInitOk = false;
|
|
5050
5124
|
}
|
|
5051
5125
|
});
|
|
5052
5126
|
|
|
@@ -25862,6 +25936,7 @@ import { performance as performance3 } from "node:perf_hooks";
|
|
|
25862
25936
|
async function runScan(context, callbacks) {
|
|
25863
25937
|
const startTotal = performance3.now();
|
|
25864
25938
|
clearFileCache();
|
|
25939
|
+
clearParseCache();
|
|
25865
25940
|
if (context.files?.length) {
|
|
25866
25941
|
await preloadFiles(context.files);
|
|
25867
25942
|
}
|
|
@@ -26039,6 +26114,7 @@ var init_orchestrator = __esm({
|
|
|
26039
26114
|
init_rule_overrides();
|
|
26040
26115
|
init_store();
|
|
26041
26116
|
init_file_cache();
|
|
26117
|
+
init_tree_sitter();
|
|
26042
26118
|
init_registry();
|
|
26043
26119
|
init_suppress();
|
|
26044
26120
|
EXT_TO_LANG = {
|
|
@@ -29831,7 +29907,7 @@ function computeExitCode(options) {
|
|
|
29831
29907
|
init_formatter();
|
|
29832
29908
|
|
|
29833
29909
|
// src/version.ts
|
|
29834
|
-
var APP_VERSION = "1.
|
|
29910
|
+
var APP_VERSION = "1.6.0";
|
|
29835
29911
|
|
|
29836
29912
|
// src/output/sarif.ts
|
|
29837
29913
|
function mapSeverity4(sev) {
|