1 parent
23844ae301
commit
d25b5dbe6d
268 files changed
+3684
-8861
No files matched your search
+11
-36
@@ -39,19 +39,13 @@ async function loadLanguage(language: string) {
|
||||
if (!AST_SUPPORTED_LANGUAGES.includes(language)) return null
|
||||
// locateFile 指到内嵌的 tree-sitter.wasm:emscripten 默认按脚本所在目录找,
|
||||
// 单二进制里那个目录是 /$bunfs/root,它自己找不着
|
||||
if (!initPromise)
|
||||
initPromise = Parser.init({ locateFile: () => treeSitterWasmPath })
|
||||
if (!initPromise) initPromise = Parser.init({ locateFile: () => treeSitterWasmPath })
|
||||
await initPromise
|
||||
|
||||
const cached = languages.get(language)
|
||||
if (cached) return cached
|
||||
|
||||
const wasmPath =
|
||||
language === "C"
|
||||
? cWasmPath
|
||||
: language === "C++"
|
||||
? cppWasmPath
|
||||
: pythonWasmPath
|
||||
const wasmPath = language === "C" ? cWasmPath : language === "C++" ? cppWasmPath : pythonWasmPath
|
||||
const loaded = await Language.load(wasmPath)
|
||||
languages.set(language, loaded)
|
||||
return loaded
|
||||
@@ -75,8 +69,7 @@ function targetName(rule: AstRule, language?: string) {
|
||||
|
||||
function countPhrase(verb: string, rule: AstRule) {
|
||||
if (rule.exact !== undefined) return `${verb} ${rule.exact} 次`
|
||||
if (rule.min !== undefined && rule.max !== undefined)
|
||||
return `${verb} ${rule.min}~${rule.max} 次`
|
||||
if (rule.min !== undefined && rule.max !== undefined) return `${verb} ${rule.min}~${rule.max} 次`
|
||||
if (rule.min !== undefined) return `至少${verb} ${rule.min} 次`
|
||||
if (rule.max !== undefined) return `至多${verb} ${rule.max} 次`
|
||||
return ""
|
||||
@@ -115,9 +108,7 @@ export function describeAstRule(rule: AstRule, language?: string): string {
|
||||
// 「必须使用 for_loop 嵌套」,旧栈 ast_checker/engines/nesting.py 是翻的
|
||||
const outer = astNodeLabel(rule.outer ?? "", language)
|
||||
const inner = astNodeLabel(rule.inner ?? "", language)
|
||||
return outer === inner
|
||||
? `必须使用 ${outer} 嵌套`
|
||||
: `必须在 ${outer} 中嵌套使用 ${inner}`
|
||||
return outer === inner ? `必须使用 ${outer} 嵌套` : `必须在 ${outer} 中嵌套使用 ${inner}`
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -185,15 +176,12 @@ export function astRulesError(astRules: AstRules | null): string | null {
|
||||
const at = `代码规则 ${language} 第 ${index + 1} 条`
|
||||
const target = rule.target ?? ""
|
||||
if (rule.engine.endsWith("_node")) {
|
||||
if (!(target in nodes))
|
||||
return `${at}:${language} 没有「${target}」这种语法`
|
||||
if (!(target in nodes)) return `${at}:${language} 没有「${target}」这种语法`
|
||||
} else if (rule.engine === "must_use_operator") {
|
||||
if (!(target in operators))
|
||||
return `${at}:${language} 没有「${target}」运算符`
|
||||
if (!(target in operators)) return `${at}:${language} 没有「${target}」运算符`
|
||||
} else if (rule.engine === "must_have_nesting") {
|
||||
for (const value of [rule.outer ?? "", rule.inner ?? ""]) {
|
||||
if (!(value in nodes))
|
||||
return `${at}:${language} 没有「${value}」这种语法`
|
||||
if (!(value in nodes)) return `${at}:${language} 没有「${value}」这种语法`
|
||||
}
|
||||
} else if (!target.trim()) {
|
||||
return `${at}:要检查的函数名/方法名不能为空`
|
||||
@@ -212,10 +200,7 @@ export function astRulesError(astRules: AstRules | null): string | null {
|
||||
* 早年配过 C++ 规则,如今 tab 里看不到那组规则,保存却被「暂不支持 C++」拦下,
|
||||
* 老师在界面上无从修改。
|
||||
*/
|
||||
export function pickAstRules(
|
||||
astRules: AstRules | null,
|
||||
languages: string[],
|
||||
): AstRules | null {
|
||||
export function pickAstRules(astRules: AstRules | null, languages: string[]): AstRules | null {
|
||||
if (!astRules) return null
|
||||
const out: AstRules = {}
|
||||
for (const [language, rules] of Object.entries(astRules)) {
|
||||
@@ -261,27 +246,17 @@ function methodCalls(root: Node, target: string, language: string) {
|
||||
if (language === "C++") {
|
||||
return collectNodes(root, "call_expression").filter((call) => {
|
||||
const fn = call.childForFieldName("function")
|
||||
return (
|
||||
fn?.type === "field_expression" &&
|
||||
fn.childForFieldName("field")?.text === target
|
||||
)
|
||||
return fn?.type === "field_expression" && fn.childForFieldName("field")?.text === target
|
||||
})
|
||||
}
|
||||
if (language !== "Python") return []
|
||||
return collectNodes(root, "call").filter((call) => {
|
||||
const fn = call.childForFieldName("function")
|
||||
return (
|
||||
fn?.type === "attribute" &&
|
||||
fn.childForFieldName("attribute")?.text === target
|
||||
)
|
||||
return fn?.type === "attribute" && fn.childForFieldName("attribute")?.text === target
|
||||
})
|
||||
}
|
||||
|
||||
function evaluateRule(
|
||||
root: Node,
|
||||
rule: AstRule,
|
||||
language: string,
|
||||
): AstResult | null {
|
||||
function evaluateRule(root: Node, rule: AstRule, language: string): AstResult | null {
|
||||
const target = rule.target ?? ""
|
||||
const nodeType = astTargetNodeType(target, language)
|
||||
|
||||
|
||||
Reference in new issue
Block a user