@@ -2056,6 +2056,7 @@ private final class ImportSwiftMacrosAPICollector: SyntaxAnyVisitor {
20562056 let name : String
20572057 let jsName : String ?
20582058 let from : JSImportFrom ?
2059+ let accessLevel : BridgeJSAccessLevel
20592060 var constructor : ImportedConstructorSkeleton ?
20602061 var methods : [ ImportedFunctionSkeleton ]
20612062 var staticMethods : [ ImportedFunctionSkeleton ]
@@ -2271,6 +2272,7 @@ private final class ImportSwiftMacrosAPICollector: SyntaxAnyVisitor {
22712272 name: typeName,
22722273 jsName: nil ,
22732274 from: nil ,
2275+ accessLevel: . internal,
22742276 constructor: nil ,
22752277 methods: [ ] ,
22762278 staticMethods: [ ] ,
@@ -2279,12 +2281,18 @@ private final class ImportSwiftMacrosAPICollector: SyntaxAnyVisitor {
22792281 )
22802282 }
22812283
2282- private func enterJSClass( _ typeName: String , jsName: String ? , from: JSImportFrom ? ) {
2284+ private func enterJSClass(
2285+ _ typeName: String ,
2286+ jsName: String ? ,
2287+ from: JSImportFrom ? ,
2288+ accessLevel: BridgeJSAccessLevel
2289+ ) {
22832290 stateStack. append ( . jsClassBody( name: typeName) )
22842291 currentType = CurrentType (
22852292 name: typeName,
22862293 jsName: jsName,
22872294 from: from,
2295+ accessLevel: accessLevel,
22882296 constructor: nil ,
22892297 methods: [ ] ,
22902298 staticMethods: [ ] ,
@@ -2305,7 +2313,8 @@ private final class ImportSwiftMacrosAPICollector: SyntaxAnyVisitor {
23052313 staticMethods: type. staticMethods,
23062314 getters: type. getters,
23072315 setters: type. setters,
2308- documentation: nil
2316+ documentation: nil ,
2317+ accessLevel: type. accessLevel
23092318 )
23102319 )
23112320 currentType = nil
@@ -2318,7 +2327,8 @@ private final class ImportSwiftMacrosAPICollector: SyntaxAnyVisitor {
23182327 let attribute = AttributeChecker . firstJSClassAttribute ( node. attributes)
23192328 let jsName = attribute. flatMap ( AttributeChecker . extractJSName)
23202329 let from = attribute. flatMap ( AttributeChecker . extractJSImportFrom)
2321- enterJSClass ( node. name. text, jsName: jsName, from: from)
2330+ let accessLevel = Self . bridgeAccessLevel ( from: node. modifiers)
2331+ enterJSClass ( node. name. text, jsName: jsName, from: from, accessLevel: accessLevel)
23222332 }
23232333 return . visitChildren
23242334 }
@@ -2334,7 +2344,8 @@ private final class ImportSwiftMacrosAPICollector: SyntaxAnyVisitor {
23342344 let attribute = AttributeChecker . firstJSClassAttribute ( node. attributes)
23352345 let jsName = attribute. flatMap ( AttributeChecker . extractJSName)
23362346 let from = attribute. flatMap ( AttributeChecker . extractJSImportFrom)
2337- enterJSClass ( node. name. text, jsName: jsName, from: from)
2347+ let accessLevel = Self . bridgeAccessLevel ( from: node. modifiers)
2348+ enterJSClass ( node. name. text, jsName: jsName, from: from, accessLevel: accessLevel)
23382349 }
23392350 return . visitChildren
23402351 }
@@ -2499,8 +2510,14 @@ private final class ImportSwiftMacrosAPICollector: SyntaxAnyVisitor {
24992510 else {
25002511 return nil
25012512 }
2513+ // Initializers without an explicit modifier inherit access from the
2514+ // enclosing `@JSClass` (the user's example pattern: `public init(...)`
2515+ // inside `public struct JSDocument`).
2516+ let parentLevel = currentType? . accessLevel ?? . internal
2517+ let accessLevel = Self . bridgeAccessLevel ( from: initializer. modifiers, default: parentLevel)
25022518 return ImportedConstructorSkeleton (
2503- parameters: parseParameters ( from: initializer. signature. parameterClause)
2519+ parameters: parseParameters ( from: initializer. signature. parameterClause) ,
2520+ accessLevel: accessLevel
25042521 )
25052522 }
25062523
@@ -2533,14 +2550,16 @@ private final class ImportSwiftMacrosAPICollector: SyntaxAnyVisitor {
25332550 } else {
25342551 returnType = . void
25352552 }
2553+ let accessLevel = Self . bridgeAccessLevel ( from: node. modifiers)
25362554 return ImportedFunctionSkeleton (
25372555 name: name,
25382556 jsName: jsName,
25392557 from: from,
25402558 parameters: parameters,
25412559 returnType: returnType,
25422560 effects: effects,
2543- documentation: nil
2561+ documentation: nil ,
2562+ accessLevel: accessLevel
25442563 )
25452564 }
25462565
@@ -2572,13 +2591,15 @@ private final class ImportSwiftMacrosAPICollector: SyntaxAnyVisitor {
25722591 let propertyName = SwiftToSkeleton . normalizeIdentifier ( identifier. identifier. text)
25732592 let jsName = AttributeChecker . extractJSName ( from: jsGetter)
25742593 let from = AttributeChecker . extractJSImportFrom ( from: jsGetter)
2594+ let accessLevel = Self . bridgeAccessLevel ( from: node. modifiers)
25752595 return ImportedGetterSkeleton (
25762596 name: propertyName,
25772597 jsName: jsName,
25782598 from: from,
25792599 type: propertyType,
25802600 documentation: nil ,
2581- functionName: nil
2601+ functionName: nil ,
2602+ accessLevel: accessLevel
25822603 )
25832604 }
25842605
@@ -2601,12 +2622,14 @@ private final class ImportSwiftMacrosAPICollector: SyntaxAnyVisitor {
26012622 return nil
26022623 }
26032624
2625+ let accessLevel = Self . bridgeAccessLevel ( from: node. modifiers)
26042626 return ImportedSetterSkeleton (
26052627 name: propertyName,
26062628 jsName: validation. jsName,
26072629 type: validation. valueType,
26082630 documentation: nil ,
2609- functionName: " \( functionBaseName) _set "
2631+ functionName: " \( functionBaseName) _set " ,
2632+ accessLevel: accessLevel
26102633 )
26112634 }
26122635
@@ -2652,6 +2675,31 @@ private final class ImportSwiftMacrosAPICollector: SyntaxAnyVisitor {
26522675 modifier. name. tokenKind == . keyword( . static) || modifier. name. tokenKind == . keyword( . class)
26532676 }
26542677 }
2678+
2679+ /// Maps Swift's declaration modifiers to a `BridgeJSAccessLevel` for
2680+ /// recording on imported skeleton entries. Falls back to `default` when no
2681+ /// access modifier is present (typically `.internal`, but the caller may
2682+ /// override — e.g. an `init` inheriting from its enclosing `@JSClass`).
2683+ /// `private`/`fileprivate` are mapped to the fallback because the macros
2684+ /// already reject those access levels for `@JS*` declarations.
2685+ fileprivate static func bridgeAccessLevel(
2686+ from modifiers: DeclModifierListSyntax ,
2687+ default fallback: BridgeJSAccessLevel = . internal
2688+ ) -> BridgeJSAccessLevel {
2689+ for modifier in modifiers {
2690+ switch modifier. name. tokenKind {
2691+ case . keyword( . public) , . keyword( . open) :
2692+ return . public
2693+ case . keyword( . package ) :
2694+ return . package
2695+ case . keyword( . internal) :
2696+ return . internal
2697+ default :
2698+ continue
2699+ }
2700+ }
2701+ return fallback
2702+ }
26552703}
26562704
26572705extension GenericArgumentListSyntax {
0 commit comments