Files
wehub-resource-sync a06f331eb8
CI / benchmark (push) Has been skipped
install-script / posix-syntax (push) Successful in 6m1s
CI / build-onnx (push) Failing after 6m43s
init-smoke / dry-run (push) Failing after 15m57s
security / govulncheck (push) Has been cancelled
security / trivy-fs (push) Has been cancelled
CI / test (1.26, ubuntu-latest) (push) Has been cancelled
Scorecard supply-chain security / Scorecard analysis (push) Has been cancelled
CI / test (1.26, macos-latest) (push) Has been cancelled
CI / build-windows (push) Has been cancelled
CI / lint (push) Has been cancelled
install-script / powershell-syntax (push) Has been cancelled
install-script / install (macos-14) (push) Has been cancelled
install-script / install (ubuntu-latest) (push) Has been cancelled
chore: import upstream snapshot with attribution
2026-07-13 12:33:42 +08:00

54 lines
1.7 KiB
Go

package languages
import (
"regexp"
"github.com/zzet/gortex/internal/graph"
"github.com/zzet/gortex/internal/parser"
)
// objcSelectorRe matches an Objective-C @selector(...) literal, capturing the
// full selector including its colons (`doThing:`, `setX:y:`).
var objcSelectorRe = regexp.MustCompile(`@selector\s*\(\s*([A-Za-z_][A-Za-z0-9_:]*)\s*\)`)
// captureObjCSelectors records each @selector(sel) literal whose selector names
// a method declared in the same file as a function-as-value reference, so the
// targeted method is reachable through the selector even though no direct call
// edge exists. Objective-C is regex-extracted, so this is a focused scan rather
// than the tree-walking captureFnValueCandidates pass; it mirrors the Swift
// #selector handling (recv hint <self>, resolved against same-file methods).
func captureObjCSelectors(src []byte, methodRanges []objcSpan, filePath string, result *parser.ExtractionResult) {
funcs := map[string]bool{}
for _, n := range result.Nodes {
if n == nil || n.FilePath != filePath {
continue
}
if n.Kind == graph.KindMethod || n.Kind == graph.KindFunction {
funcs[n.Name] = true
}
}
var cands []FnValueCandidate
seen := map[string]bool{}
for _, m := range objcSelectorRe.FindAllSubmatchIndex(src, -1) {
sel := string(src[m[2]:m[3]])
if sel == "" || !funcs[sel] {
continue
}
line := lineAt(src, m[0])
fromID := objcEnclosing(methodRanges, line)
if fromID == "" {
continue
}
key := fromID + "\x00" + sel
if seen[key] {
continue
}
seen[key] = true
cands = append(cands, FnValueCandidate{
FromID: fromID, Name: sel, FilePath: filePath, Line: line,
Form: "selector", RecvHint: "<self>", Lang: "objc",
})
}
EmitFnValueCandidates(result, cands)
}