Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix undetectable mock annotations with attributes above. #281

Merged
merged 4 commits into from
Dec 7, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 16 additions & 5 deletions Sources/MockoloFramework/Parsers/SwiftSyntaxExtensions.swift
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
// limitations under the License.
//

import Algorithms
import Foundation
import SwiftSyntax
import SwiftParser
Expand Down Expand Up @@ -259,7 +260,7 @@ extension IfConfigDeclSyntax {
in: subModels,
exclude: [:],
fullnames: []
).map({ $0 })
).sorted(path: \.value.offset, fallback: \.key)
fummicc1 marked this conversation as resolved.
Show resolved Hide resolved

let macroModel = IfMacroModel(name: name, offset: self.offset, entities: uniqueSubModels)
return (macroModel, attrDesc, hasInit)
Expand Down Expand Up @@ -300,7 +301,12 @@ extension ProtocolDeclSyntax: EntityNode {
}

func annotationMetadata(with annotation: String) -> AnnotationMetadata? {
return leadingTrivia.annotationMetadata(with: annotation)
let trivias = [
leadingTrivia,
protocolKeyword.leadingTrivia,
modifiers.leadingTrivia,
] + attributes.map(\.leadingTrivia)
return trivias.firstNonNil { $0.annotationMetadata(with: annotation) }
}

var hasBlankInit: Bool {
Expand Down Expand Up @@ -358,7 +364,12 @@ extension ClassDeclSyntax: EntityNode {
}

func annotationMetadata(with annotation: String) -> AnnotationMetadata? {
return leadingTrivia.annotationMetadata(with: annotation)
let trivias = [
leadingTrivia,
classKeyword.leadingTrivia,
modifiers.leadingTrivia,
] + attributes.map(\.leadingTrivia)
return trivias.firstNonNil { $0.annotationMetadata(with: annotation) }
}

func subContainer(metadata: AnnotationMetadata?, declKind: NominalTypeDeclKind, path: String?, isProcessed: Bool) -> EntityNodeSubContainer {
Expand Down Expand Up @@ -863,9 +874,9 @@ extension Trivia {
// See metadata(with:, in:) for more info on the annotation arguments.
func annotationMetadata(with annotation: String) -> AnnotationMetadata? {
guard !annotation.isEmpty else { return nil }

var ret: AnnotationMetadata?
for i in 0..<count {
let trivia = self[i]
for trivia in self {
switch trivia {
case .docLineComment(let val):
ret = metadata(with: annotation, in: val)
Expand Down
6 changes: 6 additions & 0 deletions Tests/TestActor/ActorTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -13,4 +13,10 @@ final class ActorTests: MockoloTestCase {
verify(srcContent: globalActorProtocol,
dstContent: globalActorProtocolMock)
}

func testAttributeAboveAnnotationComment() {
verify(srcContent: attributeAboveAnnotationComment,
dstContent: attributeAboveAnnotationCommentMock,
declType: .all)
}
}
32 changes: 32 additions & 0 deletions Tests/TestActor/FixtureGlobalActor.swift
Original file line number Diff line number Diff line change
Expand Up @@ -43,3 +43,35 @@ class RootBuildableMock: RootBuildable {
}
}
"""


let attributeAboveAnnotationComment = """
@MainActor
/// \(String.mockAnnotation)
protocol P0 {
}

@MainActor
/// \(String.mockAnnotation)
@available(iOS 18.0, *) protocol P1 {
}

@MainActor
/// \(String.mockAnnotation)
public class C0 {
}
"""

let attributeAboveAnnotationCommentMock = """
class P0Mock: P0 {
init() { }
}

class P1Mock: P1 {
init() { }
}

public class C0Mock: C0 {
public init() { }
}
"""
Loading