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

159 lines
4.5 KiB
Go

package languages
import (
"github.com/zzet/gortex/internal/graph"
"github.com/zzet/gortex/internal/parser"
sitter "github.com/zzet/gortex/internal/parser/tsitter"
)
// captureAppleUIRoles classifies Apple-UI types from their inheritance clause:
// a SwiftUI `View` conformer is a component, an `@main` `App` is the app entry
// point, and a `UIViewController` / `UIView` / `UITableViewCell` subclass is a
// UIKit view-controller / view / cell. The role is stamped on the type node's
// Meta["swiftui_role"] or Meta["uikit_role"]; an app entry additionally carries
// Meta["entry_point"]=true so the dead-code and process analyzers treat it as a
// root. Runs at the tail of Extract so the type nodes already exist.
func captureAppleUIRoles(result *parser.ExtractionResult, root *sitter.Node, filePath string, src []byte) {
if root == nil || result == nil {
return
}
swiftUIWalk(root, func(n *sitter.Node) {
if n.Type() != "class_declaration" {
return
}
name := swiftUITypeName(n, src)
if name == "" {
return
}
conf := swiftUIConformances(n, src)
swiftRole := ""
switch {
case swiftUIHasMainAttr(n, src) && conf["App"]:
swiftRole = "app_entry"
case conf["View"]:
swiftRole = "component"
}
uikitRole := uikitRoleFor(conf)
fluentModel := conf["Model"]
if swiftRole == "" && uikitRole == "" && !fluentModel {
return
}
nd := findSwiftUITypeNode(result.Nodes, name, int(n.StartPoint().Row)+1)
if nd == nil {
return
}
if nd.Meta == nil {
nd.Meta = map[string]any{}
}
if swiftRole != "" {
nd.Meta["swiftui_role"] = swiftRole
if swiftRole == "app_entry" {
nd.Meta["entry_point"] = true
}
if swiftRole == "component" {
nd.Meta["ui_component"] = "swiftui"
}
}
if uikitRole != "" {
nd.Meta["uikit_role"] = uikitRole
}
if fluentModel {
nd.Meta["fluent_model"] = true
}
})
}
// uikitRoleFor classifies a UIKit subclass by the framework base type in its
// inheritance clause. Cell base types are checked before UIView since they are
// themselves UIView subclasses by name shape only.
func uikitRoleFor(conf map[string]bool) string {
switch {
case conf["UIViewController"], conf["UITableViewController"], conf["UICollectionViewController"], conf["UINavigationController"], conf["UITabBarController"]:
return "view_controller"
case conf["UITableViewCell"], conf["UICollectionViewCell"]:
return "cell"
case conf["UIView"]:
return "view"
}
return ""
}
// swiftUITypeName returns the declared name of a class_declaration — its first
// direct type_identifier child (the modifiers / inheritance type_identifiers
// are nested deeper, not direct children).
func swiftUITypeName(decl *sitter.Node, src []byte) string {
for i, _nc := 0, int(decl.NamedChildCount()); i < _nc; i++ {
if c := decl.NamedChild(i); c != nil && c.Type() == "type_identifier" {
return c.Content(src)
}
}
return ""
}
// swiftUIConformances returns the set of protocol / base-type names in a
// declaration's inheritance clause.
func swiftUIConformances(decl *sitter.Node, src []byte) map[string]bool {
out := map[string]bool{}
for i, _nc := 0, int(decl.NamedChildCount()); i < _nc; i++ {
c := decl.NamedChild(i)
if c == nil || c.Type() != "inheritance_specifier" {
continue
}
swiftUIWalk(c, func(t *sitter.Node) {
if t.Type() == "type_identifier" {
out[t.Content(src)] = true
}
})
}
return out
}
// swiftUIHasMainAttr reports whether a declaration carries the `@main` attribute.
func swiftUIHasMainAttr(decl *sitter.Node, src []byte) bool {
for i, _nc := 0, int(decl.NamedChildCount()); i < _nc; i++ {
c := decl.NamedChild(i)
if c == nil || c.Type() != "modifiers" {
continue
}
found := false
swiftUIWalk(c, func(t *sitter.Node) {
if t.Type() == "type_identifier" && t.Content(src) == "main" {
found = true
}
})
if found {
return true
}
}
return false
}
// findSwiftUITypeNode returns the type node for name, preferring the one whose
// start line matches the declaration.
func findSwiftUITypeNode(nodes []*graph.Node, name string, line int) *graph.Node {
var byName *graph.Node
for _, n := range nodes {
if n == nil || n.Kind != graph.KindType || n.Name != name {
continue
}
if n.StartLine == line {
return n
}
if byName == nil {
byName = n
}
}
return byName
}
// swiftUIWalk visits n and all its named descendants.
func swiftUIWalk(n *sitter.Node, fn func(*sitter.Node)) {
if n == nil {
return
}
fn(n)
for i, _nc := 0, int(n.NamedChildCount()); i < _nc; i++ {
swiftUIWalk(n.NamedChild(i), fn)
}
}