chore: import upstream snapshot with attribution
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
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
This commit is contained in:
@@ -0,0 +1,103 @@
|
||||
package languages
|
||||
|
||||
import (
|
||||
"regexp"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/zzet/gortex/internal/parser"
|
||||
)
|
||||
|
||||
var (
|
||||
markupScriptRe = regexp.MustCompile(`(?is)<script\b([^>]*)>(.*?)</script>`)
|
||||
markupLangAttrRe = regexp.MustCompile(`(?i)\blang\s*=\s*["']([a-z]+)["']`)
|
||||
)
|
||||
|
||||
// scriptTagIsTypeScript reports whether a <script> tag's attribute string
|
||||
// declares a TypeScript dialect.
|
||||
func scriptTagIsTypeScript(attrs []byte) bool {
|
||||
m := markupLangAttrRe.FindSubmatch(attrs)
|
||||
if m == nil {
|
||||
return false
|
||||
}
|
||||
switch strings.ToLower(string(m[1])) {
|
||||
case "ts", "tsx", "typescript":
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// carveAndDelegateScripts runs every <script>/<script setup> block in src through
|
||||
// the TypeScript or JavaScript extractor (per its lang attribute) and merges the
|
||||
// result rebased into host-file coordinates. It is the shared carving loop behind
|
||||
// the Svelte and Astro extractors.
|
||||
func carveAndDelegateScripts(src []byte, filePath, fileID, language string, ts, js parser.Extractor, result *parser.ExtractionResult) {
|
||||
for _, m := range markupScriptRe.FindAllSubmatchIndex(src, -1) {
|
||||
contentStart, contentEnd := m[4], m[5]
|
||||
if contentStart < 0 {
|
||||
continue
|
||||
}
|
||||
delegate := js
|
||||
if scriptTagIsTypeScript(src[m[2]:m[3]]) {
|
||||
delegate = ts
|
||||
}
|
||||
lineOffset := strings.Count(string(src[:contentStart]), "\n")
|
||||
delegateInlineScriptSlice(delegate, src[contentStart:contentEnd], lineOffset, filePath, fileID, language, result)
|
||||
}
|
||||
}
|
||||
|
||||
// delegateInlineScriptSlice runs delegate over a carved inline-script slice and
|
||||
// merges its symbols/edges into result, rebased into the host file's coordinate
|
||||
// space. content is the raw script body; lineOffset is the 0-based line in the
|
||||
// host file where the slice begins. Every delegated node/edge line is shifted by
|
||||
// lineOffset, the synthetic file node is dropped, file-defines edges are
|
||||
// repointed at fileID, nodes are relabeled to the host filePath (and language,
|
||||
// when non-empty), and Meta["inline_script"]=true is stamped so downstream
|
||||
// passes can tell a carved symbol from a natively-parsed one.
|
||||
//
|
||||
// It is the shared spine behind every markup extractor that embeds another
|
||||
// language (HTML/Vue/Svelte/Astro <script>, Razor @code), so the error-prone
|
||||
// offset-rebase math lives — and is tested — in exactly one place.
|
||||
func delegateInlineScriptSlice(delegate parser.Extractor, content []byte, lineOffset int, filePath, fileID, language string, result *parser.ExtractionResult) {
|
||||
if delegate == nil || result == nil || strings.TrimSpace(string(content)) == "" {
|
||||
return
|
||||
}
|
||||
virtual := filePath + "#script:" + strconv.Itoa(lineOffset+1)
|
||||
sub, err := delegate.Extract(virtual, content)
|
||||
if err != nil || sub == nil {
|
||||
return
|
||||
}
|
||||
for _, n := range sub.Nodes {
|
||||
if n == nil || n.ID == virtual { // drop the synthetic file node
|
||||
continue
|
||||
}
|
||||
n.FilePath = filePath
|
||||
if language != "" {
|
||||
n.Language = language
|
||||
}
|
||||
if n.StartLine > 0 {
|
||||
n.StartLine += lineOffset
|
||||
}
|
||||
if n.EndLine > 0 {
|
||||
n.EndLine += lineOffset
|
||||
}
|
||||
if n.Meta == nil {
|
||||
n.Meta = map[string]any{}
|
||||
}
|
||||
n.Meta["inline_script"] = true
|
||||
result.Nodes = append(result.Nodes, n)
|
||||
}
|
||||
for _, ed := range sub.Edges {
|
||||
if ed == nil {
|
||||
continue
|
||||
}
|
||||
if ed.From == virtual { // "file defines symbol" → the host file owns it
|
||||
ed.From = fileID
|
||||
}
|
||||
ed.FilePath = filePath
|
||||
if ed.Line > 0 {
|
||||
ed.Line += lineOffset
|
||||
}
|
||||
result.Edges = append(result.Edges, ed)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user