Skip to content
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
8 changes: 8 additions & 0 deletions Plugins/BridgeJS/Sources/BridgeJSMacros/JSClassMacro.swift
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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: ", ")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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 =
Expand Down
45 changes: 21 additions & 24 deletions Plugins/BridgeJS/Tests/BridgeJSMacrosTests/JSClassMacroTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -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
)
Expand All @@ -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
)
Expand All @@ -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
)
Expand Down