Skip to content
Merged
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
36 changes: 19 additions & 17 deletions Plugins/BridgeJS/Sources/BridgeJSCore/SwiftToSkeleton.swift
Original file line number Diff line number Diff line change
Expand Up @@ -394,22 +394,28 @@ private enum ExportSwiftConstants {
static let supportedRawTypes = SwiftEnumRawType.allCases.map { $0.rawValue }
}

extension AttributeSyntax {
/// The attribute name as text when it is a simple identifier (e.g. "JS", "JSFunction").
/// Prefer this over `attributeName.trimmedDescription` for name checks to avoid unnecessary string work.
fileprivate var attributeNameText: String? {
attributeName.as(IdentifierTypeSyntax.self)?.name.text
}
}

extension AttributeListSyntax {
func hasJSAttribute() -> Bool {
firstJSAttribute != nil
}

var firstJSAttribute: AttributeSyntax? {
first(where: {
$0.as(AttributeSyntax.self)?.attributeName.trimmedDescription == "JS"
})?.as(AttributeSyntax.self)
first(where: { $0.as(AttributeSyntax.self)?.attributeNameText == "JS" })?.as(AttributeSyntax.self)
}

/// Returns true if any attribute has the given name (e.g. "JSClass").
func hasAttribute(name: String) -> Bool {
contains { attribute in
guard let syntax = attribute.as(AttributeSyntax.self) else { return false }
return syntax.attributeName.trimmedDescription == name
return syntax.attributeNameText == name
}
}
}
Expand Down Expand Up @@ -1916,46 +1922,42 @@ private final class ImportSwiftMacrosAPICollector: SyntaxAnyVisitor {
}

static func firstJSFunctionAttribute(_ attributes: AttributeListSyntax?) -> AttributeSyntax? {
attributes?.first { attribute in
attribute.as(AttributeSyntax.self)?.attributeName.trimmedDescription == "JSFunction"
}?.as(AttributeSyntax.self)
firstAttribute(attributes, named: "JSFunction")
}

static func hasJSGetterAttribute(_ attributes: AttributeListSyntax?) -> Bool {
hasAttribute(attributes, name: "JSGetter")
}

static func firstJSGetterAttribute(_ attributes: AttributeListSyntax?) -> AttributeSyntax? {
attributes?.first { attribute in
attribute.as(AttributeSyntax.self)?.attributeName.trimmedDescription == "JSGetter"
}?.as(AttributeSyntax.self)
firstAttribute(attributes, named: "JSGetter")
}

static func hasJSSetterAttribute(_ attributes: AttributeListSyntax?) -> Bool {
hasAttribute(attributes, name: "JSSetter")
}

static func firstJSSetterAttribute(_ attributes: AttributeListSyntax?) -> AttributeSyntax? {
attributes?.first { attribute in
attribute.as(AttributeSyntax.self)?.attributeName.trimmedDescription == "JSSetter"
}?.as(AttributeSyntax.self)
firstAttribute(attributes, named: "JSSetter")
}

static func hasJSClassAttribute(_ attributes: AttributeListSyntax?) -> Bool {
hasAttribute(attributes, name: "JSClass")
}

static func firstJSClassAttribute(_ attributes: AttributeListSyntax?) -> AttributeSyntax? {
attributes?.first { attribute in
attribute.as(AttributeSyntax.self)?.attributeName.trimmedDescription == "JSClass"
}?.as(AttributeSyntax.self)
firstAttribute(attributes, named: "JSClass")
}

static func firstAttribute(_ attributes: AttributeListSyntax?, named name: String) -> AttributeSyntax? {
attributes?.first { $0.as(AttributeSyntax.self)?.attributeNameText == name }?.as(AttributeSyntax.self)
}

static func hasAttribute(_ attributes: AttributeListSyntax?, name: String) -> Bool {
guard let attributes else { return false }
return attributes.contains { attribute in
guard let syntax = attribute.as(AttributeSyntax.self) else { return false }
return syntax.attributeName.trimmedDescription == name
return syntax.attributeNameText == name
}
}

Expand Down