diff --git a/Sources/StructuredQueriesMacros/SQLMacro.swift b/Sources/StructuredQueriesMacros/SQLMacro.swift index c9ecef37..a8195c6c 100644 --- a/Sources/StructuredQueriesMacros/SQLMacro.swift +++ b/Sources/StructuredQueriesMacros/SQLMacro.swift @@ -24,6 +24,7 @@ public enum SQLMacro: ExpressionMacro { var unexpectedBind: (segment: StringSegmentSyntax, offset: Int)? var unexpectedClose: (delimiter: UInt8, segment: StringSegmentSyntax, offset: Int)? var invalidBind = false + var isInComment = false if let string = argument.as(StringLiteralExprSyntax.self) { for segment in string.segments { guard let segment = segment.as(StringSegmentSyntax.self) @@ -75,6 +76,12 @@ public enum SQLMacro: ExpressionMacro { while offset < segment.content.syntaxTextBytes.endIndex { defer { offset += 1 } let byte = segment.content.syntaxTextBytes[offset] + if isInComment { + if byte == UInt8(ascii: "\n") { + isInComment = false + } + continue + } if let delimiter = currentDelimiter ?? parenStack.last { if byte == delimiters[delimiter.delimiter] { if currentDelimiter == nil { @@ -104,6 +111,12 @@ public enum SQLMacro: ExpressionMacro { unexpectedClose = (byte, segment, offset) } else if binds.contains(byte) { unexpectedBind = (segment, offset) + } else if byte == UInt8(ascii: "-"), + segment.content.syntaxTextBytes.indices.contains(offset + 1), + segment.content.syntaxTextBytes[offset + 1] == byte + { + offset += 1 + isInComment = true } } } diff --git a/Sources/StructuredQueriesSQLiteCore/Documentation.docc/Articles/Views.md b/Sources/StructuredQueriesSQLiteCore/Documentation.docc/Articles/Views.md index 460f25ad..f1a2b3d0 100644 --- a/Sources/StructuredQueriesSQLiteCore/Documentation.docc/Articles/Views.md +++ b/Sources/StructuredQueriesSQLiteCore/Documentation.docc/Articles/Views.md @@ -28,9 +28,9 @@ one does with common table expressions, and it allows one to represent a type th purposes seems like a regular SQLite table, but it's not actually persisted in the database. With that type defined we can use the -``StructuredQueriesCore/Table/createTemporaryView(ifNotExists:as:)`` to create a SQL query that -creates a temporary view. You provide a select statement that selects all the data needed for the -view: +``StructuredQueriesCore/Table/createTemporaryView(ifNotExists:as:)`` function to create a SQL query +that creates a temporary view. You provide a select statement that selects all the data needed for +the view: ```swift ReminderWithList.createTemporaryView( diff --git a/Tests/StructuredQueriesMacrosTests/SQLMacroTests.swift b/Tests/StructuredQueriesMacrosTests/SQLMacroTests.swift index 1d18809c..a722befe 100644 --- a/Tests/StructuredQueriesMacrosTests/SQLMacroTests.swift +++ b/Tests/StructuredQueriesMacrosTests/SQLMacroTests.swift @@ -374,5 +374,64 @@ extension SnapshotTests { """ } } + + @Test func sqlComments() { + assertMacro { + """ + #sql("SELECT 1 -- TODO: Implement logic") + """ + } expansion: { + """ + StructuredQueriesCore.SQLQueryExpression("SELECT 1 -- TODO: Implement logic") + """ + } + assertMacro { + """ + #sql("SELECT '1 -- TODO: Implement logic'") + """ + } expansion: { + """ + StructuredQueriesCore.SQLQueryExpression("SELECT '1 -- TODO: Implement logic'") + """ + } + assertMacro { + #""" + #sql( + """ + SELECT * FROM reminders -- TODO: We should write columns out by hand + WHERE isCompleted -- TODO: Double-check this logic + """ + ) + """# + } expansion: { + #""" + StructuredQueriesCore.SQLQueryExpression( + """ + SELECT * FROM reminders -- TODO: We should write columns out by hand + WHERE isCompleted -- TODO: Double-check this logic + """) + """# + } + assertMacro { + #""" + #sql( + """ + SELECT ( -- TODO: ;-) + 1 = 1 + ) + """ + ) + """# + } expansion: { + #""" + StructuredQueriesCore.SQLQueryExpression( + """ + SELECT ( -- TODO: ;-) + 1 = 1 + ) + """) + """# + } + } } }