From 7f3395ea1127893d4b1e944711abe30077d87ba1 Mon Sep 17 00:00:00 2001 From: Kyle Date: Tue, 19 Aug 2025 23:28:29 +0800 Subject: [PATCH 1/4] Add Attribute+Debug support --- Sources/OpenGraphShims/Attribute+Debug.swift | 54 ++++++++++++++++++++ 1 file changed, 54 insertions(+) create mode 100644 Sources/OpenGraphShims/Attribute+Debug.swift diff --git a/Sources/OpenGraphShims/Attribute+Debug.swift b/Sources/OpenGraphShims/Attribute+Debug.swift new file mode 100644 index 00000000..f53139f1 --- /dev/null +++ b/Sources/OpenGraphShims/Attribute+Debug.swift @@ -0,0 +1,54 @@ +// +// Attribute+Debug.swift +// OpenGraphShims + +extension Attribute: Swift.CustomDebugStringConvertible { + public var debugDescription: String { + #""" + Attribute<\#(Value.self)> { + \#(identifier.debugDescription) + } + """# + } +} + +extension AnyAttribute: Swift.CustomDebugStringConvertible { + public var debugDescription: String { + guard self != .nil else { + return "AnyAttribute.nil" + } + var description = #""" + rawValue: \#(rawValue) + graph: \#(graph) + """# + if rawValue % 2 == 0 { // direct + description.append("\n(direct attribute)") + + let valueType = valueType + description.append("\nvalueType: \(valueType)") + + var value: Any! + func project1(type: T.Type) { + value = unsafeCast(to: type).value + } + _openExistential(valueType, do: project1) + description.append("\nvalue: \(value!)") + + let bodyType = _bodyType + description.append("\nbodyType: \(bodyType)") + + var bodyValue: Any! + func project2(type: T.Type) { + bodyValue = _bodyPointer.assumingMemoryBound(to: type).pointee + } + _openExistential(bodyType, do: project2) + description.append("\nbodyValue: \(bodyValue!)") + + } else { // indrect + description.append("\n(indirect attribute)") + description.append("\n\nsource attribute:") + description.append("\n\(source.debugDescription)") + } + return description + } +} From bd16ff7bb6e2e30c5c993c1db25c64f14a354d99 Mon Sep 17 00:00:00 2001 From: Kyle Date: Tue, 19 Aug 2025 23:45:13 +0800 Subject: [PATCH 2/4] Add indent support --- Sources/OpenGraphShims/Attribute+Debug.swift | 65 +++++++++++++++----- 1 file changed, 48 insertions(+), 17 deletions(-) diff --git a/Sources/OpenGraphShims/Attribute+Debug.swift b/Sources/OpenGraphShims/Attribute+Debug.swift index f53139f1..bf490dc5 100644 --- a/Sources/OpenGraphShims/Attribute+Debug.swift +++ b/Sources/OpenGraphShims/Attribute+Debug.swift @@ -4,51 +4,82 @@ extension Attribute: Swift.CustomDebugStringConvertible { public var debugDescription: String { - #""" - Attribute<\#(Value.self)> { - \#(identifier.debugDescription) - } + _debugDescription(indent: 0) + } + + func _debugDescription(indent: Int) -> String { + let tabs = String(repeating: "\t", count: indent) + return #""" + \#(tabs)Attribute<\#(Value.self)> { + \#(identifier._debugDescription(indent: indent + 1)) + \#(tabs)} """# } } extension AnyAttribute: Swift.CustomDebugStringConvertible { public var debugDescription: String { + _debugDescription(indent: 0) + } + + func _debugDescription(indent: Int) -> String { + let tabs = String(repeating: "\t", count: indent) + guard self != .nil else { - return "AnyAttribute.nil" + return "\(tabs)AnyAttribute.nil" } + var description = #""" - rawValue: \#(rawValue) - graph: \#(graph) + \#(tabs)rawValue: \#(rawValue) + \#(tabs)graph: \#(graph) """# + if rawValue % 2 == 0 { // direct - description.append("\n(direct attribute)") + description.append("\n\(tabs)(direct attribute)") let valueType = valueType - description.append("\nvalueType: \(valueType)") + description.append("\n\(tabs)valueType: \(valueType)") var value: Any! func project1(type: T.Type) { value = unsafeCast(to: type).value } _openExistential(valueType, do: project1) - description.append("\nvalue: \(value!)") + description.append("\n\(tabs)value: \(value!)") let bodyType = _bodyType - description.append("\nbodyType: \(bodyType)") + description.append("\n\(tabs)bodyType: \(bodyType)") var bodyValue: Any! func project2(type: T.Type) { bodyValue = _bodyPointer.assumingMemoryBound(to: type).pointee } _openExistential(bodyType, do: project2) - description.append("\nbodyValue: \(bodyValue!)") + + let bodyValueDescription = _formatBodyValue(bodyValue!, indent: indent) + description.append("\n\(tabs)bodyValue:\n\(bodyValueDescription)") - } else { // indrect - description.append("\n(indirect attribute)") - description.append("\n\nsource attribute:") - description.append("\n\(source.debugDescription)") + } else { // indirect + description.append("\n\(tabs)(indirect attribute)") + description.append("\n\(tabs)source attribute:") + description.append("\n\(source._debugDescription(indent: indent + 1))") } return description } -} + + private func _formatBodyValue(_ bodyValue: Any, indent: Int) -> String { + let bodyValueString = String(describing: bodyValue) + let nextTabs = String(repeating: "\t", count: indent + 1) + + // Check if the body value contains attributes + if bodyValueString.contains("Attribute<") { + // Split lines and add proper indentation + let lines = bodyValueString.components(separatedBy: .newlines) + return lines.enumerated().map { index, line in + return "\(nextTabs)\(line)" + }.joined(separator: "\n") + } + + return "\(nextTabs)\(bodyValueString)" + } +} \ No newline at end of file From a82d95b1ef038068e9772040d846bd8184957015 Mon Sep 17 00:00:00 2001 From: Kyle Date: Wed, 20 Aug 2025 01:47:07 +0800 Subject: [PATCH 3/4] Add test case --- Sources/OpenGraphShims/Attribute+Debug.swift | 13 +++-- .../Attribute+DebugTests.swift | 50 +++++++++++++++++++ 2 files changed, 58 insertions(+), 5 deletions(-) create mode 100644 Tests/OpenGraphShimsTests/Attribute+DebugTests.swift diff --git a/Sources/OpenGraphShims/Attribute+Debug.swift b/Sources/OpenGraphShims/Attribute+Debug.swift index bf490dc5..0df73856 100644 --- a/Sources/OpenGraphShims/Attribute+Debug.swift +++ b/Sources/OpenGraphShims/Attribute+Debug.swift @@ -2,13 +2,16 @@ // Attribute+Debug.swift // OpenGraphShims +// Use 4 spaces instead of \t for bettern test case expect +private let tab = " " + extension Attribute: Swift.CustomDebugStringConvertible { public var debugDescription: String { _debugDescription(indent: 0) } func _debugDescription(indent: Int) -> String { - let tabs = String(repeating: "\t", count: indent) + let tabs = String(repeating: tab, count: indent) return #""" \#(tabs)Attribute<\#(Value.self)> { \#(identifier._debugDescription(indent: indent + 1)) @@ -23,8 +26,8 @@ extension AnyAttribute: Swift.CustomDebugStringConvertible { } func _debugDescription(indent: Int) -> String { - let tabs = String(repeating: "\t", count: indent) - + let tabs = String(repeating: tab, count: indent) + guard self != .nil else { return "\(tabs)AnyAttribute.nil" } @@ -69,8 +72,8 @@ extension AnyAttribute: Swift.CustomDebugStringConvertible { private func _formatBodyValue(_ bodyValue: Any, indent: Int) -> String { let bodyValueString = String(describing: bodyValue) - let nextTabs = String(repeating: "\t", count: indent + 1) - + let nextTabs = String(repeating: tab, count: indent + 1) + // Check if the body value contains attributes if bodyValueString.contains("Attribute<") { // Split lines and add proper indentation diff --git a/Tests/OpenGraphShimsTests/Attribute+DebugTests.swift b/Tests/OpenGraphShimsTests/Attribute+DebugTests.swift new file mode 100644 index 00000000..414454e2 --- /dev/null +++ b/Tests/OpenGraphShimsTests/Attribute+DebugTests.swift @@ -0,0 +1,50 @@ +// +// Attribute+DebugTests.swift +// OpenGraphShimsTests + +import Testing +import OpenGraphShims + +@MainActor +@Suite(.disabled(if: !attributeGraphEnabled, "Subgraph is not implemented on OG"), .graphScope) +struct Attribute_DebugTests { + @Test + func directAttribute() { + let attribute = Attribute(value: 3) + + #expect(attribute.debugDescription == #""" + Attribute { + rawValue: \#(attribute.identifier.rawValue) + graph: \#(attribute.graph) + (direct attribute) + valueType: Int + value: 3 + bodyType: External + bodyValue: + Int + } + """#) + } + + @Test + func indirectAttribute() { + let tuple = Attribute(value: Tuple(first: 1, second: "2")) + let second = tuple[keyPath: \.second] + #expect(second.debugDescription == #""" + Attribute { + rawValue: \#(second.identifier.rawValue) + graph: \#(second.graph) + (indirect attribute) + source attribute: + rawValue: \#(tuple.identifier.rawValue) + graph: \#(tuple.graph) + (direct attribute) + valueType: Tuple + value: Tuple(first: 1, second: "2") + bodyType: External> + bodyValue: + Tuple + } + """#) + } +} From cbb24a6f096237924e2ce4216a5d50f68991d643 Mon Sep 17 00:00:00 2001 From: Kyle Date: Wed, 20 Aug 2025 03:01:59 +0800 Subject: [PATCH 4/4] Fix compiler crash --- Sources/OpenGraphShims/Attribute+Debug.swift | 5 ++++- Tests/OpenGraphShimsTests/Attribute+DebugTests.swift | 3 +++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/Sources/OpenGraphShims/Attribute+Debug.swift b/Sources/OpenGraphShims/Attribute+Debug.swift index 0df73856..15c6e03c 100644 --- a/Sources/OpenGraphShims/Attribute+Debug.swift +++ b/Sources/OpenGraphShims/Attribute+Debug.swift @@ -2,6 +2,8 @@ // Attribute+Debug.swift // OpenGraphShims +#if canImport(Darwin) && DEBUG // Compiler crash for Darwin + release and non-Darwin build + // Use 4 spaces instead of \t for bettern test case expect private let tab = " " @@ -85,4 +87,5 @@ extension AnyAttribute: Swift.CustomDebugStringConvertible { return "\(nextTabs)\(bodyValueString)" } -} \ No newline at end of file +} +#endif diff --git a/Tests/OpenGraphShimsTests/Attribute+DebugTests.swift b/Tests/OpenGraphShimsTests/Attribute+DebugTests.swift index 414454e2..4aa0636b 100644 --- a/Tests/OpenGraphShimsTests/Attribute+DebugTests.swift +++ b/Tests/OpenGraphShimsTests/Attribute+DebugTests.swift @@ -2,6 +2,8 @@ // Attribute+DebugTests.swift // OpenGraphShimsTests +#if canImport(Darwin) && DEBUG + import Testing import OpenGraphShims @@ -48,3 +50,4 @@ struct Attribute_DebugTests { """#) } } +#endif