Notice
Recent Posts
Recent Comments
Link
관리 메뉴

김종권의 iOS 앱 개발 알아가기

[iOS - swift] Swift Macro에서 사용되는 SwiftSyntax 개념 본문

Swift Macro

[iOS - swift] Swift Macro에서 사용되는 SwiftSyntax 개념

jake-kim 2023. 9. 9. 01:08

swift-syntax 오픈소스

  • SwiftSyntax는 Swift 소스 코드를 parsing, inspecting, generating, transforming하기 위한 Swift 라이브러리 (git repo)
  • 애플에서는 Swift Document와 별개로 SwiftSyntax 문서도 관리하여 공개 (SwiftSyntax 관련 문서)
 

SwiftSyntax Documentation – Swift Package Index

swiftpackageindex.com

  • SwiftSyntax는 단어 그대로 Swift를 Syntax (구문) 별로 tree 자료구조 형태로 표현한 것을 의미
    • tree 자료구조 형태로 표현하여, parse, inspect, generate, transform를 사용하여 Swift Souce Code로 만들 수 있는 기능

SwiftSyntax가 있는 이유?

  • Swift Macro의 기능 중 하나는 컴파일 단계에서도 특정 조건이 맞지 않으면 오류를 내서 실수를 막거나 기능의 의도를 명확히 할 수 있는데, 이 때 컴파일 단계에서도 에러가 발생시키게 하려면 컴파일러 내부의 코드를 확장해야 가능
  • 직접 컴파일러의 내부를 이해하고 해당 구조를 해석하는것이 어렵기 때문에 swift-syntax라는 것을 만들어서 컴파일러 내부를 몰라도 swift-syntax형태로 구현하면 쉽게 사용할 수 있도록 만든 것

SwiftSyntax 특징 - AST 구조

  • SwiftSyntax를 사용하면 Swift 코드를 분석하고 이해하기 쉬운 AST(Abstract Syntax Tree) 형태로 변환 가능
  • AST형태 특성 상 코드 분석, 검색, 변환 및 자동화 작업을 수행하기가 훨씬 쉬워지는 장점이 존재

SwiftSynax 활성화

  • swift-syntax Git repo에서 최초 Release를 보면 2022년 1월 25일로, 오랫동안 개발된 것은 아님을 확인

https://github.com/apple/swift-syntax/releases

  • Tags를 보면 포스팅 기준 날짜로 다양하게 tag가 달리며 애플에서 많은 기능을 수정하고 추가하고 있다는 것을 파악 가능

SwiftSyntax 사용해보기

  • 설명에 사용될 예제 내용
    • input: 문자열로 된 swift 코드
    • output: 문자열로 된 swift 코드 중 함수 이름을 출력

(input)

let sourceCode = """
    func sayHello() {
        print("Hello, World!")
    }
    """

(기대하는 ouput)
-> sayHello를 출력

SwiftSyntax, SwiftVisitor를 이용하여 함수 이름 출력 방법

  • 방법
    • 1) SwiftSyntax로 트리 구조로 파싱
    • 2) 트리를 순회하면서 함수의 이름을 print하는 것을 구현 - SwiftVisitor를 이용하면 매우 간편
  • 1) SwiftSyntax로 트리 구조로 파싱
let sourceCode = """
    func sayHello() {
        print("Hello, World!")
    }
    """

// SwiftSyntax를 사용하여 코드를 파싱
let syntax = try! SyntaxParser.parse(source: sourceCode)
  • 2) SyntaxVisitor의 visit을 override하여 함수 이름을 출력
// SyntaxVisitor 클래스를 정의
class FunctionDeclarationVisitor: SyntaxVisitor {
    override func visit(_ node: FunctionDeclSyntax) -> SyntaxVisitorContinueKind {
        print("Function Name: \(node.identifier.text)")
        return .skipChildren
    }
}

// SyntaxVisitor를 사용하여 함수 선언을 찾아 출력
let visitor = FunctionDeclarationVisitor()
visitor.walk(syntax)

정리

  • 문자열로된 swift 코드를 SwiftSyntax를 사용하면 AST(Abstract Syntax Tree)로 변환이 가능
  • AST형태라는 것은 쉽게 parsing, inspecting, generating, transforming 가능
  • 결국 문자열들을 분석하여 swift macro와 같은곳에 사용할 때 AST로 만드는것이 핵심이고, 만드는 것은 SwiftSyntax를 사용

* 전체 코드: https://github.com/JK0369/ExSwiftSyntax.git
* 참고
https://github.com/apple/swift-syntax/releases
https://swiftpackageindex.com/apple/swift-syntax/508.0.1/documentation/swiftsyntax
https://github.com/apple/swift-syntax

Comments