티스토리 뷰

앞에서는 매크로가 뭔지, 매크로 역할(roles)에 대해 작성했었는데, 이제 매크로 구현부는 어떻게 생겼나..소개하는 WWDC 내용을 정리해보겠습니다~

 

구현과 선언 연결하기

일단 앞에서 계속 봤듯이 선언은 이런식으로 macro 키워드와 매크로 이름, 받을 매개변수 등을 적어주고 매크로 위에 역할을 적어주면 됩니다~

 

근데 .. 어떤 내용으로 전개할건지를 포함한 매크로 구현부도 작성해줘야겠죠?!

이 구현부는 함수로 만들고, 선언의 = 옆에 작성해주면 됩니다.

 

대개는 이런 external 매크로를 사용하게 되는데, 이 external macro는 compiler plugin에 구현되어 있습니다.

 

1편에서 봤던 매크로 작동방식중에 이런내용이 있었는데요!!

Swift Compiler에서 #stringify라는 매크로를 인식하면, 이 매크로를 전개하기 위해서 compiler plugin에 요청하고, compiler plugin이 전개된 내용을 다시 swift compiler에게 주는 방식입니다.

 

 

컴파일러에서 매크로가 사용되었음을 인식하면, 별도의 프로세스에서 플러그인을 작동하고 매크로를 전개하도록 요청합니다.

#externalMacro가 이 구현과 선언과의 관계를 정의해주고 이 사이를 링크해줍니다.

위의 예시에서는 Swift가 매크로를 실행할 때, MyLibMacros라는 플러그인 실행하고, 여기서 StringifyMacro라는 타입을 요청하는 것입니다.

 

구현부

WWDC Expand on Swift Macros에서는 3편에서 본 DictionaryStorage 매크로 구현부를 보여줍니다~!

 

DictionaryStorage매크로의 구현부는 요런식으로 구현되어 있습니다.

 

이 매크로를 적용하면 이런식으로 나타나는 것이죠!

 

그럼 매크로 구현부를 다시 보도록 합시다.

 

가장먼저, SwiftSyntax라는 패키지를 불러오는 것부터 시작합니다.

 

SwiftSyntax?

SwiftSyntax는 소스코드 파싱, 점검, manipulate, 코드 생성 등을 돕는 라이브러리입니다.

아래와 같은 코드는 사실 다 string처럼 보이지만(?) 이런 syntax 구조를 가지고 있습니다. SwiftSyntax는 소스코드를 트리구조로 표현합니다.

 

.. 학교다닐때 프로그래밍언어론을 배웠던게 생각나네요 .. 

 

위 트리구조를 하나씩 보면,

먼저 Person이라는 구조체가 StructDeclSyntax 타입의 인스턴스임을 알 수 있습니다. 그리고 구조체의 속성 목록은 내부에 attributes 프로퍼티 내부에 있습니다. 구조체의 이름인 Person은 structKeyword에 있고, 중괄호내부의 본문과 구조체 내부 멤버들은 MemberBlock 프로퍼티 내에 있습니다.

 

프로퍼티의 일부 syntax node는 token이라고 불리는데, token소스파일 속의 특정 텍스트를 나타냅니다. (ex. 이름, 구두점 일부 등)

위에서는 TokenSyntax.keyword("struct") 이 부분과 TokenSyntax.identifier("Person") 이부분이겠죠??

 

attribute 프로퍼티의 AttributeListSyntax노드나 MemberDeclBlockSyntax는 토큰이 아니고, 이 자체 프로퍼티 내부에 또 자식 노드가 있는 형태입니다.

 

MemberDeclBlockSyntax 내부를 보면 또 이런식으로 트리구조로 구성되어있는데, 내부에 brace들은 Token으로, member목록은 또 토큰이 아닌 MemberDeclListSyntax로 구성되어 있습니다. MemberDeclListSyntax도 계속 까보면 (?) 결국 각 프로퍼티에 대한 노드 들이 있겠죠??

 

SwiftSyntax에 관한 내용은 Write Swift Macros 세션을 더 보거나 Swift Syntax문서에 더 자세히 나와있습니다~

 

예시로 직접 Syntax를 확인해봤는데요 ..

@PublicInit
public struct Example {
    public let a: Bool
    let b: String
}

이런 코드의 트리를 확인하면

이런식으로 트리를 확인할 수 있습니다!

 

 

트리 확인하고 직접 작성해보는건 WWDC Write Swift Macros보면 잘 나와있긴 하지만 다음 편에 올려볼게요 ..

 

아무튼 Swift 코드는 그냥 줄글처럼 보이긴 하지만 냅다 글로 작성되어 있는 것이 아니라 Swift Syntax의 요소들과 매칭되어서 트리구조로 작성되어 있다!!!! 라는 것을 알면 될 것 같습니다~!

 

SwiftSyntaxMacros

SwiftSyntaxMacros는 매크로 작성에 필요한 프로토콜과 타입을 제공합니다.

 

SwiftSyntaxBuilder

생성된 코드를 표현하기 위한 syntax tree의 구성에 쓰는 API를 제공합니다. 없어도 되지만 있으면 편리하게 작성할 수 있습니다.

 

각 매크로 role(역할) 에 맞는 프로토콜 준수하기

매크로를 구현하기 위해서는 매크로에 지정된 역할에 맞는 프로토콜을 채택해줘야 합니다!

 

이렇게 매크로 role별로 구현해줘야 하는 프로토콜이 있습니다.

 

예시에서는 attached member macro를 만들어주니까 MemberMacro라는 프로토콜을 구현부에 채택해줍니다. 그럼 각 프로토콜별로 구현해야 하는 expansion함수가 주어집니다.

 

MemberMacro의 경우에, DeclSyntax 배열을 리턴하는데, 이는 MemberMacro가 적용될 타입에 추가할 declaration 목록으로 전개됩니다.



신기했던 점은, 리턴 배열 내의 부분이 그냥 string으로 보이지만 Swift에서는 저걸 코드 조각으로 처리하기 때문에 Swif 파서에 DeclSyntax노드로 바꾸라고 요청한다는 점입니다. 

-> 이게 SwiftSyntaxBuilder의 역할!!

 

일단 여기까지 마무리하고 다음 글에서 오류와 관련된 내용을 가져와보겠습니다~

공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2024/05   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31
글 보관함