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

59 lines
2.0 KiB
Go

package languages
import (
"regexp"
"strings"
"github.com/zzet/gortex/internal/graph"
"github.com/zzet/gortex/internal/parser"
)
// goWSUpgradeRe matches the server-side WebSocket upgrade calls of the
// common Go libraries: gorilla/websocket `upgrader.Upgrade(...)`,
// gobwas/ws `ws.UpgradeHTTP(...)`, and coder/nhooyr `websocket.Accept(...)`.
var goWSUpgradeRe = regexp.MustCompile(`\.Upgrade\s*\(|\.UpgradeHTTP\s*\(|websocket\.Accept\s*\(`)
// emitGoWebSocketEdges marks each function that performs a WebSocket
// upgrade as a real-time endpoint: it emits an EdgeListensOn from the
// handler to a per-handler websocket KindEvent node, so `analyze
// kind=pubsub` / architecture queries surface the WebSocket surface that
// the call graph cannot see. Gated on the file importing a websocket
// package to avoid matching unrelated `.Upgrade(` methods.
func emitGoWebSocketEdges(src []byte, filePath string, result *parser.ExtractionResult) {
s := string(src)
if !strings.Contains(s, "websocket") && !strings.Contains(s, "gobwas/ws") {
return
}
locs := goWSUpgradeRe.FindAllStringIndex(s, -1)
if len(locs) == 0 {
return
}
funcRanges := buildFuncRanges(result)
seenNode := map[string]bool{}
for _, m := range locs {
line := lineAt(src, m[0])
callerID := findEnclosingFunc(funcRanges, line)
if callerID == "" {
continue
}
topic := callerID
if i := strings.LastIndexAny(topic, ":./"); i >= 0 {
topic = topic[i+1:]
}
nodeID := "event::pubsub::" + transportWebSocket + "::" + topic
if !seenNode[nodeID] {
seenNode[nodeID] = true
result.Nodes = append(result.Nodes, &graph.Node{
ID: nodeID, Kind: graph.KindEvent, Name: topic,
FilePath: filePath, Language: "go",
Meta: map[string]any{"event_kind": "pubsub", "transport": transportWebSocket, "name": topic},
})
}
result.Edges = append(result.Edges, &graph.Edge{
From: callerID, To: nodeID, Kind: graph.EdgeListensOn,
FilePath: filePath, Line: line, Origin: graph.OriginASTInferred,
Meta: map[string]any{"method": "upgrade", "transport": transportWebSocket},
})
}
}