From be7e2efad0b11892214201996578920f6b41e123 Mon Sep 17 00:00:00 2001 From: Yuta Saito Date: Mon, 26 Jan 2026 18:05:22 +0900 Subject: [PATCH] =?UTF-8?q?-=20Updated=20`@JSClass`=20macro=20to=20emit=20?= =?UTF-8?q?an=20error=20unless=20it=E2=80=99s=20attached=20to=20a=20`struc?= =?UTF-8?q?t`=20(`Plugins/BridgeJS/Sources/BridgeJSMacros/JSClassMacro.swi?= =?UTF-8?q?ft:13`).=20-=20Added=20new=20diagnostic=20message=20`@JSClass?= =?UTF-8?q?=20can=20only=20be=20applied=20to=20structs.`=20(`Plugins/Bridg?= =?UTF-8?q?eJS/Sources/BridgeJSMacros/JSMacroSupport.swift:8`).=20-=20Upda?= =?UTF-8?q?ted=20macro=20expansion=20tests=20so=20`class`/`enum`/`actor`?= =?UTF-8?q?=20usages=20now=20produce=20diagnostics=20and=20no=20generated?= =?UTF-8?q?=20members/extensions=20(`Plugins/BridgeJS/Tests/BridgeJSMacros?= =?UTF-8?q?Tests/JSClassMacroTests.swift:147`).=20-=20Verified=20with=20`s?= =?UTF-8?q?wift=20test=20--package-path=20./Plugins/BridgeJS=20--filter=20?= =?UTF-8?q?BridgeJSMacrosTests`.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Sources/BridgeJSMacros/JSClassMacro.swift | 8 ++++ .../BridgeJSMacros/JSMacroSupport.swift | 1 + .../JSClassMacroTests.swift | 45 +++++++++---------- 3 files changed, 30 insertions(+), 24 deletions(-) diff --git a/Plugins/BridgeJS/Sources/BridgeJSMacros/JSClassMacro.swift b/Plugins/BridgeJS/Sources/BridgeJSMacros/JSClassMacro.swift index 060d2269b..8a3f83f05 100644 --- a/Plugins/BridgeJS/Sources/BridgeJSMacros/JSClassMacro.swift +++ b/Plugins/BridgeJS/Sources/BridgeJSMacros/JSClassMacro.swift @@ -12,6 +12,13 @@ extension JSClassMacro: MemberMacro { conformingTo protocols: [TypeSyntax], in context: some MacroExpansionContext ) throws -> [DeclSyntax] { + guard declaration.is(StructDeclSyntax.self) else { + context.diagnose( + Diagnostic(node: Syntax(declaration), message: JSMacroMessage.unsupportedJSClassDeclaration) + ) + return [] + } + var members: [DeclSyntax] = [] let existingMembers = declaration.memberBlock.members @@ -59,6 +66,7 @@ extension JSClassMacro: ExtensionMacro { conformingTo protocols: [TypeSyntax], in context: some MacroExpansionContext ) throws -> [ExtensionDeclSyntax] { + guard declaration.is(StructDeclSyntax.self) else { return [] } guard !protocols.isEmpty else { return [] } let conformanceList = protocols.map { $0.trimmed.description }.joined(separator: ", ") diff --git a/Plugins/BridgeJS/Sources/BridgeJSMacros/JSMacroSupport.swift b/Plugins/BridgeJS/Sources/BridgeJSMacros/JSMacroSupport.swift index b10871f6a..59fa1c4c2 100644 --- a/Plugins/BridgeJS/Sources/BridgeJSMacros/JSMacroSupport.swift +++ b/Plugins/BridgeJS/Sources/BridgeJSMacros/JSMacroSupport.swift @@ -5,6 +5,7 @@ import SwiftDiagnostics enum JSMacroMessage: String, DiagnosticMessage { case unsupportedDeclaration = "@JSFunction can only be applied to functions or initializers." + case unsupportedJSClassDeclaration = "@JSClass can only be applied to structs." case unsupportedVariable = "@JSGetter can only be applied to single-variable declarations." case unsupportedSetterDeclaration = "@JSSetter can only be applied to functions." case invalidSetterName = diff --git a/Plugins/BridgeJS/Tests/BridgeJSMacrosTests/JSClassMacroTests.swift b/Plugins/BridgeJS/Tests/BridgeJSMacrosTests/JSClassMacroTests.swift index 95e3893ed..b27b93941 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSMacrosTests/JSClassMacroTests.swift +++ b/Plugins/BridgeJS/Tests/BridgeJSMacrosTests/JSClassMacroTests.swift @@ -153,16 +153,15 @@ import BridgeJSMacros """, expandedSource: """ class MyClass { - let jsObject: JSObject - - init(unsafelyWrapping jsObject: JSObject) { - self.jsObject = jsObject - } - } - - extension MyClass: _JSBridgedClass { } """, + diagnostics: [ + DiagnosticSpec( + message: "@JSClass can only be applied to structs.", + line: 1, + column: 1 + ) + ], macroSpecs: macroSpecs, indentationWidth: indentationWidth ) @@ -177,16 +176,15 @@ import BridgeJSMacros """, expandedSource: """ enum MyEnum { - let jsObject: JSObject - - init(unsafelyWrapping jsObject: JSObject) { - self.jsObject = jsObject - } - } - - extension MyEnum: _JSBridgedClass { } """, + diagnostics: [ + DiagnosticSpec( + message: "@JSClass can only be applied to structs.", + line: 1, + column: 1 + ) + ], macroSpecs: macroSpecs, indentationWidth: indentationWidth ) @@ -201,16 +199,15 @@ import BridgeJSMacros """, expandedSource: """ actor MyActor { - let jsObject: JSObject - - init(unsafelyWrapping jsObject: JSObject) { - self.jsObject = jsObject - } - } - - extension MyActor: _JSBridgedClass { } """, + diagnostics: [ + DiagnosticSpec( + message: "@JSClass can only be applied to structs.", + line: 1, + column: 1 + ) + ], macroSpecs: macroSpecs, indentationWidth: indentationWidth )