声明名称未被Swift宏覆盖。

huangapple go评论68阅读模式
英文:

Declaration name is not covered by Swift macro

问题

I'm fiddling around with the new Swift 5.9 Macros.

I have the following macro:

给定以下枚举

@associatedValues
enum Fruit {
    case banana(Banana)
    case grape(Grape)
}

我想要

@associatedValues
enum Fruit {
    case banana(Banana)
    case grape(Grape)

    var bananaValue: Banana? { if ... return ... } }
    var grapeValue: Grape? { if ... return ... } }
}

My implementation is like so:

我的实现如下:

public static func expansion<Declaration, Context>(
        of node: SwiftSyntax.AttributeSyntax,
        providingMembersOf declaration: Declaration,
        in context: Context
    ) throws -> [SwiftSyntax.DeclSyntax]
    where Declaration: SwiftSyntax.DeclGroupSyntax,
          Context: SwiftSyntaxMacros.MacroExpansionContext
    {
        
        guard let enumDeclaration = declaration.as(EnumDeclSyntax.self) else {
            throw AssociatedValuesMacroError.onlyApplicableToEnum
        }
        
        return enumDeclaration.memberBlock.members
            .compactMap { $0.decl.as(EnumCaseDeclSyntax.self) }
            .map { (_case: EnumCaseDeclSyntax) in

                let _element: EnumCaseElementListSyntax.Element = _case.elements.first!
                let caseName = _element.identifier
                let typeName = _element.associatedValue!.parameterList.first!.description

                return
                    """
                    var \(raw: caseName)Value: \(raw: typeName)? {
                        if case let .\(raw: caseName)(value) = self {
                            return value
                        } else {
                            return nil
                        }
                    }
                    """
            }
    }

Now, the autocompletion detects the new properties, but the compiler tells me:

现在,自动完成检测到了新属性,但编译器告诉我:

Declaration name 'bananaValue' is not covered by macro 'associatedValues'

Declaration name 'grapeValue' is not covered by macro 'associatedValues'

The tests run and validate the output but not when compiling.

测试运行并验证了输出,但在编译时不通过。

What am I missing?
Thank you

我漏掉了什么?
谢谢

英文:

I'm fiddling around with the new Swift 5.9 Macros.

I have the following macro:

Given the following enum

@associatedValues
enum Fruit {
    case banana(Banana)
    case grape(Grape)
}

I want

@associatedValues
enum Fruit {
    case banana(Banana)
    case grape(Grape)

    var bananaValue: Banana? { if ... return ... } }
    var grapeValue: Grape? { if ... return ... } }
}

My implementation is like so:

public static func expansion<Declaration, Context>(
        of node: SwiftSyntax.AttributeSyntax,
        providingMembersOf declaration: Declaration,
        in context: Context
    ) throws -> [SwiftSyntax.DeclSyntax]
    where Declaration: SwiftSyntax.DeclGroupSyntax,
          Context: SwiftSyntaxMacros.MacroExpansionContext
    {
        
        guard let enumDeclaration = declaration.as(EnumDeclSyntax.self) else {
            throw AssociatedValuesMacroError.onlyApplicableToEnum
        }
        
        return enumDeclaration.memberBlock.members
            .compactMap { $0.decl.as(EnumCaseDeclSyntax.self) }
            .map { (_case: EnumCaseDeclSyntax) in

                let _element: EnumCaseElementListSyntax.Element = _case.elements.first!
                let caseName = _element.identifier
                let typeName = _element.associatedValue!.parameterList.first!.description

                return
                    """
                    var \(raw: caseName)Value: \(raw: typeName)? {
                        if case let .\(raw: caseName)(value) = self {
                            return value
                        } else {
                            return nil
                        }
                    }
                    """
            }
    }

Now, the autocompletion detects the new properties, but the compiler tells me:

Declaration name 'bananaValue' is not covered by macro 'associatedValues'

Declaration name 'grapeValue' is not covered by macro 'associatedValues'

The tests run and validate the output but not when compiling.

声明名称未被Swift宏覆盖。

声明名称未被Swift宏覆盖。

What am I missing?
Thank you

答案1

得分: 10

We need to add names: arbitrary to the macro role.

注意:在我的情况下,我需要使用 "arbitrary",因为名称是动态的。但如果您知道要添加的属性,应改用 names: myCustomName

此外,尽管不是对特定问题的回答,但确保将您的宏类型添加到 CompilerPlugin 提供的宏列表中。

#if canImport(SwiftCompilerPlugin)
import SwiftCompilerPlugin
import SwiftSyntaxMacros

@main
struct MacrosPlugin: CompilerPlugin {
  let providingMacros: [Macro.Type] = [
      AssociatedValueMacro.self
  ]
}
英文:

We need to add names: arbitrary to the macro role.

@attached(member, names: arbitrary)
public macro AssociatedValues() = #externalMacro(module: "MyMacrosModule", type: "AssociatedValuesMacro")

Note: In my case I needed arbitrary because the names are dynamic. But if you do know what attributes you're adding, you should use names: myCustomName instead.


Also, though not an answer to the specific question, but make sure you add your macro type to the list of providing Macros in CompilerPlugin.

#if canImport(SwiftCompilerPlugin)
import SwiftCompilerPlugin
import SwiftSyntaxMacros

@main
struct MacrosPlugin: CompilerPlugin {
  let providingMacros: [Macro.Type] = [
      AssociatedValueMacro.self
  ]
}

huangapple
  • 本文由 发表于 2023年6月9日 14:40:42
  • 转载请务必保留本文链接:https://go.coder-hub.com/76437819.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定