diff --git a/SourceryFramework/Sources/Parsing/Utils/AnnotationsParser.swift b/SourceryFramework/Sources/Parsing/Utils/AnnotationsParser.swift index 24f65063e..5dbd55fca 100644 --- a/SourceryFramework/Sources/Parsing/Utils/AnnotationsParser.swift +++ b/SourceryFramework/Sources/Parsing/Utils/AnnotationsParser.swift @@ -212,8 +212,8 @@ public struct AnnotationsParser { } // `case` is not included in the key of enum case definition, so we strip it manually - let isInsideCaseDefinition = prefix.trimmingCharacters(in: .whitespacesAndNewlines).hasPrefix("case") - prefix = prefix.trimmingPrefix("case").trimmingCharacters(in: .whitespaces) + let isInsideCaseDefinition = prefix.trimmingCharacters(in: .whitespacesAndNewlines).hasPrefix("case ") + prefix = prefix.trimmingPrefix("case ").trimmingCharacters(in: .whitespaces) var inlineCommentFound = false while !prefix.isEmpty { @@ -242,7 +242,17 @@ public struct AnnotationsParser { let previousLine = lines[position.line - 2] let content = previousLine.content.trimmingCharacters(in: .whitespaces) - guard previousLine.type == .comment || previousLine.type == .documentationComment || previousLine.type == .propertyWrapper || previousLine.type == .macros, content.hasPrefix("//") || content.hasSuffix("*/") || content.hasPrefix("@") || content.hasPrefix("#") else { + guard + previousLine.type == .comment + || previousLine.type == .documentationComment + || previousLine.type == .propertyWrapper + || previousLine.type == .macros, + + content.hasPrefix("//") + || content.hasSuffix("*/") + || content.hasPrefix("@") + || content.hasPrefix("#") + else { stop = true return (annotations, shouldUsePositionBeforeTrailing) } diff --git a/SourceryTests/SourcerySpec.swift b/SourceryTests/SourcerySpec.swift index 2fab68f9b..30643f1a8 100644 --- a/SourceryTests/SourcerySpec.swift +++ b/SourceryTests/SourcerySpec.swift @@ -479,6 +479,57 @@ class SourcerySpecTests: QuickSpec { expect(result).to(equal(expectedResult)) } + it("extracts annotations when prefix contains case noun") { + update(code: """ + struct MyStruct { + // sourcery:inline:MyStruct.Inlined + // This will be replaced + // sourcery:end + // sourcery: stub = "A" + let basic: String; + // sourcery: stub = "B" + let caseProperty: String; + // sourcery: stub = "C" + let casesProperty: String; + // sourcery: stub = "D" + let CaseProperty: String; + } + """, in: sourcePath) + update(code: """ + // sourcery:inline:MyStruct.Inlined + {% for type in types.all %} + {% for variable in type.storedVariables %} + let {{ variable.name }}XXX = "{{ variable.annotations["stub"] }}"; + {% endfor %} + {% endfor %} + // sourcery:end + """, in: templatePath) + + expect { try Sourcery(watcherEnabled: false, cacheDisabled: true).processFiles(.sources(Paths(include: [sourcePath])), usingTemplates: Paths(include: [templatePath]), output: output, baseIndentation: 0) }.toNot(throwError()) + + let expectedResult = """ + struct MyStruct { + // sourcery:inline:MyStruct.Inlined + let basicXXX = "A"; + let casePropertyXXX = "B"; + let casesPropertyXXX = "C"; + let CasePropertyXXX = "D"; + // sourcery:end + // sourcery: stub = "A" + let basic: String; + // sourcery: stub = "B" + let caseProperty: String; + // sourcery: stub = "C" + let casesProperty: String; + // sourcery: stub = "D" + let CaseProperty: String; + } + """ + + let result = try? sourcePath.read(.utf8) + expect(result).to(equal(expectedResult)) + } + it("handles previously generated code with UTF16 characters") { update(code: """ class A {