From a55babfc31eac402395644e08bb87c40bff1c741 Mon Sep 17 00:00:00 2001 From: Michael O'Brien <98201889+mobrien-ghost@users.noreply.github.com> Date: Mon, 11 Mar 2024 01:27:57 +1000 Subject: [PATCH] Fixing incorrect optional description bug for effected semantic types (#36) * Fixing incorrect optional description bug for effected semantic types --- .../Semantics/Components/ArrayDecl.swift | 3 +- .../Public/Semantics/Components/Closure.swift | 7 +++ .../Semantics/Components/DictionaryDecl.swift | 3 +- .../Public/Semantics/Components/Result.swift | 3 +- .../Public/Semantics/Components/SetDecl.swift | 3 +- .../Public/Semantics/Components/Tuple.swift | 3 +- .../Declarations/FunctionTests.swift | 43 ++++++++++++++++--- .../Declarations/VariableTests.swift | 6 ++- 8 files changed, 58 insertions(+), 13 deletions(-) diff --git a/Sources/SyntaxSparrow/Public/Semantics/Components/ArrayDecl.swift b/Sources/SyntaxSparrow/Public/Semantics/Components/ArrayDecl.swift index 18844eb7..1799af47 100644 --- a/Sources/SyntaxSparrow/Public/Semantics/Components/ArrayDecl.swift +++ b/Sources/SyntaxSparrow/Public/Semantics/Components/ArrayDecl.swift @@ -85,6 +85,7 @@ public struct ArrayDecl: Hashable, Equatable, CustomStringConvertible { // MARK: - CustomStringConvertible public var description: String { - resolver.node.description.trimmed + let base = resolver.node.description.trimmed + return base + (isOptional ? "?" : "") } } diff --git a/Sources/SyntaxSparrow/Public/Semantics/Components/Closure.swift b/Sources/SyntaxSparrow/Public/Semantics/Components/Closure.swift index acd8eef4..c208f799 100644 --- a/Sources/SyntaxSparrow/Public/Semantics/Components/Closure.swift +++ b/Sources/SyntaxSparrow/Public/Semantics/Components/Closure.swift @@ -85,4 +85,11 @@ public struct Closure: DeclarationComponent { public init(node: FunctionTypeSyntax) { resolver = ClosureSemanticsResolver(node: node) } + + // MARK: - CustomStringConvertible + + public var description: String { + let base = node.description.trimmed + return isOptional ? "(\(base))?" : base + } } diff --git a/Sources/SyntaxSparrow/Public/Semantics/Components/DictionaryDecl.swift b/Sources/SyntaxSparrow/Public/Semantics/Components/DictionaryDecl.swift index 09e99a00..80db83c1 100644 --- a/Sources/SyntaxSparrow/Public/Semantics/Components/DictionaryDecl.swift +++ b/Sources/SyntaxSparrow/Public/Semantics/Components/DictionaryDecl.swift @@ -92,6 +92,7 @@ public struct DictionaryDecl: Hashable, Equatable, CustomStringConvertible { // MARK: - CustomStringConvertible public var description: String { - resolver.node.description.trimmed + let base = resolver.node.description.trimmed + return base + (isOptional ? "?" : "") } } diff --git a/Sources/SyntaxSparrow/Public/Semantics/Components/Result.swift b/Sources/SyntaxSparrow/Public/Semantics/Components/Result.swift index f1ec8401..8a0fcd95 100644 --- a/Sources/SyntaxSparrow/Public/Semantics/Components/Result.swift +++ b/Sources/SyntaxSparrow/Public/Semantics/Components/Result.swift @@ -66,6 +66,7 @@ public struct Result: Hashable, Equatable, CustomStringConvertible { // MARK: - CustomStringConvertible public var description: String { - resolver.node.description.trimmed + let base = resolver.node.description.trimmed + return base + (isOptional ? "?" : "") } } diff --git a/Sources/SyntaxSparrow/Public/Semantics/Components/SetDecl.swift b/Sources/SyntaxSparrow/Public/Semantics/Components/SetDecl.swift index a1977993..5c595b22 100644 --- a/Sources/SyntaxSparrow/Public/Semantics/Components/SetDecl.swift +++ b/Sources/SyntaxSparrow/Public/Semantics/Components/SetDecl.swift @@ -63,6 +63,7 @@ public struct SetDecl: Hashable, Equatable, CustomStringConvertible { // MARK: - CustomStringConvertible public var description: String { - resolver.node.description.trimmed + let base = resolver.node.description.trimmed + return base + (isOptional ? "?" : "") } } diff --git a/Sources/SyntaxSparrow/Public/Semantics/Components/Tuple.swift b/Sources/SyntaxSparrow/Public/Semantics/Components/Tuple.swift index 8d72161e..ab939596 100644 --- a/Sources/SyntaxSparrow/Public/Semantics/Components/Tuple.swift +++ b/Sources/SyntaxSparrow/Public/Semantics/Components/Tuple.swift @@ -56,6 +56,7 @@ public struct Tuple: Hashable, Equatable, CustomStringConvertible { // MARK: - CustomStringConvertible public var description: String { - resolver.node.description.trimmed + let base = elements.signatureInputString() + return isOptional ? "\(base)?" : base } } diff --git a/Tests/SyntaxSparrowTests/Declarations/FunctionTests.swift b/Tests/SyntaxSparrowTests/Declarations/FunctionTests.swift index 62266d58..5fe4b408 100644 --- a/Tests/SyntaxSparrowTests/Declarations/FunctionTests.swift +++ b/Tests/SyntaxSparrowTests/Declarations/FunctionTests.swift @@ -321,7 +321,8 @@ final class FunctionTests: XCTestCase { func asyncAwaitMethodThrowing() throws async {} func asyncAwaitMethodThrowingReturning() throws async -> String {} func arrayShorthand(persons: [(name: String, age: Int?)]?) {} - func arrayIdentifier(names: Array) {} + func arrayIdentifier(names: Array) {} + func arrayIdentifier(names: Array?) {} func setIdentifier(names: Set) {} func dictionaryShorthand(persons: [String: (name: String, age: Int?)]?) {} func dictionaryIdentifier(names: Dictionary?) {} @@ -330,7 +331,7 @@ final class FunctionTests: XCTestCase { XCTAssertTrue(instanceUnderTest.isStale) instanceUnderTest.collectChildren() XCTAssertFalse(instanceUnderTest.isStale) - XCTAssertEqual(instanceUnderTest.functions.count, 26) + XCTAssertEqual(instanceUnderTest.functions.count, 27) // No Parameters // func noParameters() throws {} @@ -577,6 +578,7 @@ final class FunctionTests: XCTestCase { XCTAssertEqual(tuple.elements[1].name, "age") XCTAssertNil(tuple.elements[1].secondName) XCTAssertTrue(tuple.elements[1].isOptional) + XCTAssertEqual(tuple.description, "(name: String, age: Int?)?") } else { XCTFail("function.signature.input[0] type should be tuple") } @@ -609,6 +611,7 @@ final class FunctionTests: XCTestCase { XCTAssertFalse(closure.isOptional) XCTAssertTrue(closure.isEscaping) XCTAssertFalse(closure.isAutoEscaping) + XCTAssertEqual(closure.description, "(Int) -> Void") } else { XCTFail("function.signature.input[0] type should be closure") } @@ -640,6 +643,7 @@ final class FunctionTests: XCTestCase { XCTAssertTrue(closure.isOptional) XCTAssertTrue(closure.isEscaping) XCTAssertTrue(closure.isAutoEscaping) + XCTAssertEqual(closure.description, "((Int) -> Void)?") } else { XCTFail("function.signature.input[0] type should be closure") } @@ -669,6 +673,7 @@ final class FunctionTests: XCTestCase { XCTAssertTrue(closure.isOptional) XCTAssertTrue(closure.isEscaping) XCTAssertTrue(closure.isAutoEscaping) + XCTAssertEqual(closure.description, "((name: String, age: Int) -> String?)?") if case let EntityType.tuple(tuple) = closure.input { XCTAssertEqual(tuple.elements.count, 2) XCTAssertEqual(tuple.elements[0].name, "name") @@ -676,6 +681,7 @@ final class FunctionTests: XCTestCase { XCTAssertEqual(tuple.elements[1].name, "age") XCTAssertEqual(tuple.elements[1].type, .simple("Int")) XCTAssertFalse(tuple.isOptional) + XCTAssertEqual(tuple.description, "(name: String, age: Int)") } else { XCTFail("closure input type should be tuple") } @@ -706,6 +712,7 @@ final class FunctionTests: XCTestCase { XCTAssertEqual(result.successType, .simple("String")) XCTAssertEqual(result.failureType, .simple("Error")) XCTAssertFalse(result.isOptional) + XCTAssertEqual(result.description, "Result") } else { XCTFail("function.signature.input[0] type should be Result") } @@ -733,6 +740,7 @@ final class FunctionTests: XCTestCase { XCTAssertEqual(result.successType, .simple("String")) XCTAssertEqual(result.failureType, .simple("Error")) XCTAssertTrue(result.isOptional) + XCTAssertEqual(result.description, "Result?") } else { XCTFail("function.signature.input[0] type should be Result") } @@ -831,12 +839,13 @@ final class FunctionTests: XCTestCase { XCTAssertEqual(tuple.elements[1].name, "age") XCTAssertEqual(tuple.elements[1].type, .simple("Int?")) XCTAssertFalse(tuple.isOptional) + XCTAssertEqual(array.description, "[(name: String, age: Int?)]?") } } else { XCTFail("function.signature.input[0] type should be Array") } - // func arrayIdentifier(names: Array) {} + // func arrayIdentifier(names: Array) {} function = instanceUnderTest.functions[22] XCTAssertEqual(function.keyword, "func") XCTAssertEqual(function.identifier, "arrayIdentifier") @@ -847,14 +856,34 @@ final class FunctionTests: XCTestCase { if case let EntityType.array(array) = function.signature.input[0].type { XCTAssertEqual(array.declType, .generic) XCTAssertFalse(array.isOptional) - XCTAssertEqual(array.elementType, .simple("String")) + XCTAssertEqual(array.elementType, .simple("String?")) + XCTAssertEqual(array.elementType.description, "String?") + XCTAssertEqual(array.description, "Array") } else { XCTFail("function.signature.input[0] type should be Array") } - // func setIdentifier(names: Set) {} + // func arrayIdentifier(names: Array?) {} function = instanceUnderTest.functions[23] XCTAssertEqual(function.keyword, "func") + XCTAssertEqual(function.identifier, "arrayIdentifier") + XCTAssertNil(function.signature.effectSpecifiers?.throwsSpecifier) + XCTAssertNil(function.signature.effectSpecifiers?.asyncSpecifier) + XCTAssertEqual(function.signature.input.count, 1) + + if case let EntityType.array(array) = function.signature.input[0].type { + XCTAssertEqual(array.declType, .generic) + XCTAssertTrue(array.isOptional) + XCTAssertEqual(array.elementType, .simple("String?")) + XCTAssertEqual(array.elementType.description, "String?") + XCTAssertEqual(array.description, "Array?") + } else { + XCTFail("function.signature.input[0] type should be Array") + } + + // func setIdentifier(names: Set) {} + function = instanceUnderTest.functions[24] + XCTAssertEqual(function.keyword, "func") XCTAssertEqual(function.identifier, "setIdentifier") XCTAssertNil(function.signature.effectSpecifiers?.throwsSpecifier) XCTAssertNil(function.signature.effectSpecifiers?.asyncSpecifier) @@ -868,7 +897,7 @@ final class FunctionTests: XCTestCase { } // func dictionaryShorthand(persons: [String: (name: String, age: Int?)]?) {} - function = instanceUnderTest.functions[24] + function = instanceUnderTest.functions[25] XCTAssertEqual(function.keyword, "func") XCTAssertEqual(function.identifier, "dictionaryShorthand") XCTAssertNil(function.signature.effectSpecifiers?.throwsSpecifier) @@ -892,7 +921,7 @@ final class FunctionTests: XCTestCase { } // func dictionaryIdentifier(names: Dictionary?) {} - function = instanceUnderTest.functions[25] + function = instanceUnderTest.functions[26] XCTAssertEqual(function.keyword, "func") XCTAssertEqual(function.identifier, "dictionaryIdentifier") XCTAssertNil(function.signature.effectSpecifiers?.throwsSpecifier) diff --git a/Tests/SyntaxSparrowTests/Declarations/VariableTests.swift b/Tests/SyntaxSparrowTests/Declarations/VariableTests.swift index b9e00f77..1a2613c6 100644 --- a/Tests/SyntaxSparrowTests/Declarations/VariableTests.swift +++ b/Tests/SyntaxSparrowTests/Declarations/VariableTests.swift @@ -296,7 +296,7 @@ final class VariableTests: XCTestCase { XCTAssertEqual(variable.description, "var handler: Void? = {}") } - func test_variable_typealiasType_optionalVariants_willResolveExpectedValues() { + func test_variable_tupleType_optionalVariants_willResolveExpectedValues() { let source = #""" var person: (name: String, age: Int?) = ("name", 20) var person: (name: String, age: Int?)? = ("name", 20) @@ -321,6 +321,7 @@ final class VariableTests: XCTestCase { XCTAssertEqual(tuple.elements[1].name, "age") XCTAssertEqual(tuple.elements[1].type, .simple("Int?")) XCTAssertFalse(tuple.isOptional) + XCTAssertEqual(tuple.description, "(name: String, age: Int?)") } else { XCTFail("variable type should be tuple") } @@ -339,6 +340,7 @@ final class VariableTests: XCTestCase { XCTAssertEqual(tuple.elements[1].name, "age") XCTAssertEqual(tuple.elements[1].type, .simple("Int?")) XCTAssertTrue(tuple.isOptional) + XCTAssertEqual(tuple.description, "(name: String, age: Int?)?") } else { XCTFail("variable type should be tuple") } @@ -366,6 +368,7 @@ final class VariableTests: XCTestCase { XCTAssertEqual(closure.input, .simple("String")) XCTAssertEqual(closure.output, .simple("Int?")) XCTAssertFalse(closure.isOptional) + XCTAssertEqual(closure.description, "(String) -> Int?") } else { XCTFail("variable type should be closure") } @@ -381,6 +384,7 @@ final class VariableTests: XCTestCase { XCTAssertEqual(closure.input, .simple("String")) XCTAssertEqual(closure.output, .simple("Int?")) XCTAssertTrue(closure.isOptional) + XCTAssertEqual(closure.description, "((String) -> Int?)?") } else { XCTFail("variable type should be closure") }