diff --git a/CLAUDE.md b/CLAUDE.md index 48693c5..711608a 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -22,7 +22,7 @@ A Swift symbol demangling library. Converts mangled Swift symbols into human-rea mangled string → Demangler or OldDemangler → Node tree → NodePrinter → demangled string ``` -- **Public API** (`String+Demangling.swift`): `String.demangled`, `String.demangling(_:)`, `String.symbolKind` +- **Public API** (`String+Demangling.swift`): `String.demangled`, `String.demangling(_:)`, `String.node`, `String.symbolKind`; `Node` traversal: `kind`, `children`, `text`, `index`, type checks (`isAlias`, `isClass`, `isEnum`, `isProtocol`, `isStruct`), kind queries (`isDeclName`, `isAnyGeneric`, `isEntity`, `isRequirement`, `isContext`, `isFunctionAttr`, `isMacroExpansion`) - **Demangler** (`Demangler.swift`): Handles modern mangling (`$s`, `$S` prefixes). Stack-based iterative parsing - **OldDemangler** (`OldDemangler.swift`): Handles legacy `_T` prefix. Recursive descent parsing - **Demanglerable protocol** (`Demanglerable.swift`): Low-level parsing interface shared by both demanglers (`peekChar`, `nextChar`, `nextIf`, etc.) diff --git a/Sources/SwiftDemangle/Demangler/Demangler.swift b/Sources/SwiftDemangle/Demangler/Demangler.swift index 1ee2fea..bbdbe94 100644 --- a/Sources/SwiftDemangle/Demangler/Demangler.swift +++ b/Sources/SwiftDemangle/Demangler/Demangler.swift @@ -2873,7 +2873,7 @@ class Demangler: Demanglerable, Mangling { } var context = popNode { kind in - kind.isMacroExpandion + kind.isMacroExpansion } if context == nil { diff --git a/Sources/SwiftDemangle/Demangler/String+Demangling.swift b/Sources/SwiftDemangle/Demangler/String+Demangling.swift index 16cb1a4..e19208e 100644 --- a/Sources/SwiftDemangle/Demangler/String+Demangling.swift +++ b/Sources/SwiftDemangle/Demangler/String+Demangling.swift @@ -31,11 +31,12 @@ public extension String { } }) } + + var node: Node? { + demangleSymbolAsNode(printDebugInformation: false) + } var symbolKind: Node.Kind? { - guard let node = demangleSymbolAsNode(printDebugInformation: false) else { - return nil - } - return node.extractSymbolKind() + node?.extractSymbolKind() } } diff --git a/Sources/SwiftDemangle/Node/Node.swift b/Sources/SwiftDemangle/Node/Node.swift index e2d1c9d..d9c8cf7 100644 --- a/Sources/SwiftDemangle/Node/Node.swift +++ b/Sources/SwiftDemangle/Node/Node.swift @@ -13,7 +13,7 @@ public final class Node { private weak var parent: Node? - private(set) var kind: Kind + public private(set) var kind: Kind private(set) var payload: Payload private(set) var _children: [Node] { didSet { @@ -22,6 +22,8 @@ public final class Node { } var copyOfChildren: [Node] { _children } + + public var children: [Node] { copyOfChildren } fileprivate var numberOfParent: Int { var count = 0 @@ -222,7 +224,7 @@ public final class Node { kind == .Identifier && text == desired } - var text: String { + public var text: String { if case let .text(text) = self.payload { return text } else { @@ -234,7 +236,7 @@ public final class Node { self.payload.isText } - var index: UInt64? { + public var index: UInt64? { switch self.payload { case let .index(index): return index @@ -696,7 +698,7 @@ extension Node { var isClassType: Bool { kind == .Class } - var isAlias: Bool { + public var isAlias: Bool { switch self.kind { case .Type: return firstChild.isAlias @@ -707,7 +709,7 @@ extension Node { } } - var isClass: Bool { + public var isClass: Bool { switch self.kind { case .Type: return firstChild.isClass @@ -718,7 +720,7 @@ extension Node { } } - var isEnum: Bool { + public var isEnum: Bool { switch self.kind { case .Type: return firstChild.isEnum @@ -729,7 +731,7 @@ extension Node { } } - var isProtocol: Bool { + public var isProtocol: Bool { switch self.kind { case .Type: return firstChild.isProtocol @@ -740,7 +742,7 @@ extension Node { } } - var isStruct: Bool { + public var isStruct: Bool { switch self.kind { case .Type: return firstChild.isStruct @@ -1593,15 +1595,15 @@ extension Node.Kind { .HasSymbolQuery, ] - var isDeclName: Bool { + public var isDeclName: Bool { Self.declNames.contains(self) } - var isAnyGeneric: Bool { + public var isAnyGeneric: Bool { Self.anyGenerics.contains(self) } - var isEntity: Bool { + public var isEntity: Bool { if self == .Type { return true } else { @@ -1609,20 +1611,19 @@ extension Node.Kind { } } - var isRequirement: Bool { + public var isRequirement: Bool { Self.requirements.contains(self) } - - var isContext: Bool { + public var isContext: Bool { Self.contexts.contains(self) } - var isFunctionAttr: Bool { + public var isFunctionAttr: Bool { Self.functionAttrs.contains(self) } - var isMacroExpandion: Bool { + public var isMacroExpansion: Bool { switch self { case .AccessorAttachedMacroExpansion, .MemberAttributeAttachedMacroExpansion,