Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit8cad280

Browse files
committed
BridgeJS: Add support for static / class functions
1 parent68466e1 commit8cad280

File tree

30 files changed

+2166
-69
lines changed

30 files changed

+2166
-69
lines changed

‎Plugins/BridgeJS/Sources/BridgeJSCore/ExportSwift.swift‎

Lines changed: 148 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,7 @@ public class ExportSwift {
9393
varname:String?
9494
varcases:[EnumCase]=[]
9595
varrawType:String?
96+
varstaticMethods:[ExportedFunction]=[]
9697
}
9798
varcurrentEnum=CurrentEnum()
9899

@@ -152,28 +153,54 @@ public class ExportSwift {
152153
}
153154

154155
overridefunc visit(_ node:FunctionDeclSyntax)->SyntaxVisitorContinueKind{
156+
guard node.attributes.hasJSAttribute()else{
157+
return.skipChildren
158+
}
159+
160+
letisStatic= node.modifiers.contains{ modifierin
161+
modifier.name.tokenKind==.keyword(.static) ||
162+
modifier.name.tokenKind==.keyword(.class)
163+
}
164+
155165
switch state{
156166
case.topLevel:
157-
iflet exportedFunction=visitFunction(
158-
node: node
159-
){
167+
if isStatic{
168+
diagnose(node: node, message:"Top-level functions cannot be static")
169+
return.skipChildren
170+
}
171+
iflet exportedFunction=visitFunction(node: node, isStatic:false){
160172
exportedFunctions.append(exportedFunction)
161173
}
162174
return.skipChildren
163-
case.classBody(_,let classKey):
175+
case.classBody(let className,let classKey):
164176
iflet exportedFunction=visitFunction(
165-
node: node
177+
node: node,
178+
isStatic: isStatic,
179+
className: className,
180+
classKey: classKey
166181
){
167182
exportedClassByName[classKey]?.methods.append(exportedFunction)
168183
}
169184
return.skipChildren
170-
case.enumBody:
171-
diagnose(node: node, message:"Functions are not supported inside enums")
185+
case.enumBody(let enumName):
186+
if !isStatic{
187+
diagnose(node: node, message:"Only static functions are supported in enums")
188+
return.skipChildren
189+
}
190+
iflet exportedFunction=visitFunction(node: node, isStatic: isStatic, enumName: enumName){
191+
currentEnum.staticMethods.append(exportedFunction)
192+
}
172193
return.skipChildren
173194
}
174195
}
175196

176-
privatefunc visitFunction(node:FunctionDeclSyntax)->ExportedFunction?{
197+
privatefunc visitFunction(
198+
node:FunctionDeclSyntax,
199+
isStatic:Bool,
200+
className:String?=nil,
201+
classKey:String?=nil,
202+
enumName:String?=nil
203+
)->ExportedFunction?{
177204
guardlet jsAttribute= node.attributes.firstJSAttributeelse{
178205
returnnil
179206
}
@@ -189,6 +216,14 @@ public class ExportSwift {
189216
)
190217
}
191218

219+
if namespace!=nil, case.enumBody= state{
220+
diagnose(
221+
node: jsAttribute,
222+
message:"Namespace is not supported for enum static functions",
223+
hint:"Remove the namespace from @JS attribute - enum functions inherit namespace from enum"
224+
)
225+
}
226+
192227
varparameters:[Parameter]=[]
193228
forparamin node.signature.parameterClause.parameters{
194229
letresolvedType=self.parent.lookupType(for: param.type)
@@ -226,20 +261,52 @@ public class ExportSwift {
226261
}
227262

228263
letabiName:String
264+
letstaticContext:StaticContext?
265+
229266
switch state{
230267
case.topLevel:
231268
abiName="bjs_\(name)"
269+
staticContext=nil
232270
case.classBody(let className, _):
233-
abiName="bjs_\(className)_\(name)"
234-
case.enumBody:
235-
abiName=""
236-
diagnose(
237-
node: node,
238-
message:"Functions are not supported inside enums"
239-
)
271+
if isStatic{
272+
abiName="bjs_\(className)_static_\(name)"
273+
staticContext=.className(className)
274+
}else{
275+
abiName="bjs_\(className)_\(name)"
276+
staticContext=nil
277+
}
278+
case.enumBody(let enumName):
279+
if !isStatic{
280+
diagnose(node: node, message:"Only static functions are supported in enums")
281+
returnnil
282+
}
283+
284+
letisNamespaceEnum= currentEnum.cases.isEmpty
285+
286+
if isNamespaceEnum{
287+
// For namespace enums, compute the full Swift call path manually
288+
varswiftPath:[String]=[]
289+
varcurrentNode:Syntax?= node.parent
290+
whilelet parent= currentNode{
291+
iflet enumDecl= parent.as(EnumDeclSyntax.self),
292+
enumDecl.attributes.hasJSAttribute()
293+
{
294+
swiftPath.insert(enumDecl.name.text, at:0)
295+
}
296+
currentNode= parent.parent
297+
}
298+
letfullEnumCallName= swiftPath.joined(separator:".")
299+
300+
// ABI name should include full namespace path to avoid conflicts
301+
abiName="bjs_\(swiftPath.joined(separator:"_"))_\(name)"
302+
staticContext=.namespaceEnum(fullEnumCallName)
303+
}else{
304+
abiName="bjs_\(enumName)_static_\(name)"
305+
staticContext=.enumName(enumName)
306+
}
240307
}
241308

242-
guardlet effects=collectEffects(signature: node.signature)else{
309+
guardlet effects=collectEffects(signature: node.signature, isStatic: isStatic)else{
243310
returnnil
244311
}
245312

@@ -249,11 +316,12 @@ public class ExportSwift {
249316
parameters: parameters,
250317
returnType: returnType,
251318
effects: effects,
252-
namespace: namespace
319+
namespace: namespace,
320+
staticContext: staticContext
253321
)
254322
}
255323

256-
privatefunc collectEffects(signature:FunctionSignatureSyntax)->Effects?{
324+
privatefunc collectEffects(signature:FunctionSignatureSyntax, isStatic:Bool=false)->Effects?{
257325
letisAsync= signature.effectSpecifiers?.asyncSpecifier!=nil
258326
varisThrows=false
259327
iflet throwsClause:ThrowsClauseSyntax= signature.effectSpecifiers?.throwsClause{
@@ -274,7 +342,7 @@ public class ExportSwift {
274342
}
275343
isThrows=true
276344
}
277-
returnEffects(isAsync: isAsync, isThrows: isThrows)
345+
returnEffects(isAsync: isAsync, isThrows: isThrows, isStatic: isStatic)
278346
}
279347

280348
privatefunc extractNamespace(
@@ -537,15 +605,25 @@ public class ExportSwift {
537605
}
538606

539607
letemitStyle=extractEnumStyle(from: jsAttribute)??.const
540-
if case.tsEnum= emitStyle,
541-
let raw= currentEnum.rawType,
542-
let rawEnum=SwiftEnumRawType.from(raw), rawEnum==.bool
543-
{
544-
diagnose(
545-
node: jsAttribute,
546-
message:"TypeScript enum style is not supported for Bool raw-value enums",
547-
hint:"Use enumStyle: .const or change the raw type to String or a numeric type"
548-
)
608+
609+
if case.tsEnum= emitStyle{
610+
iflet raw= currentEnum.rawType,
611+
let rawEnum=SwiftEnumRawType.from(raw), rawEnum==.bool
612+
{
613+
diagnose(
614+
node: jsAttribute,
615+
message:"TypeScript enum style is not supported for Bool raw-value enums",
616+
hint:"Use enumStyle: .const or change the raw type to String or a numeric type"
617+
)
618+
}
619+
620+
if !currentEnum.staticMethods.isEmpty{
621+
diagnose(
622+
node: jsAttribute,
623+
message:"TypeScript enum style does not support static functions",
624+
hint:"Use enumStyle: .const to generate a const object that supports static functions"
625+
)
626+
}
549627
}
550628

551629
if currentEnum.cases.contains(where:{ !$0.associatedValues.isEmpty}){
@@ -597,7 +675,8 @@ public class ExportSwift {
597675
cases: currentEnum.cases,
598676
rawType: currentEnum.rawType,
599677
namespace: effectiveNamespace,
600-
emitStyle: emitStyle
678+
emitStyle: emitStyle,
679+
staticMethods: currentEnum.staticMethods
601680
)
602681
exportedEnumByName[enumName]= exportedEnum
603682
exportedEnumNames.append(enumName)
@@ -862,6 +941,10 @@ public class ExportSwift {
862941
case.namespace:
863942
()
864943
}
944+
945+
forstaticMethodin enumDef.staticMethods{
946+
decls.append(tryrenderSingleExportedFunction(function: staticMethod))
947+
}
865948
}
866949

867950
forfunctionin exportedFunctions{
@@ -1269,7 +1352,24 @@ public class ExportSwift {
12691352
forparamin function.parameters{
12701353
try builder.liftParameter(param: param)
12711354
}
1272-
builder.call(name: function.name, returnType: function.returnType)
1355+
1356+
if function.effects.isStatic,let staticContext= function.staticContext{
1357+
letcallName:String
1358+
switch staticContext{
1359+
case.className(let className):
1360+
callName="\(className).\(function.name)"
1361+
case.enumName(let enumName):
1362+
callName="\(enumName).\(function.name)"
1363+
case.namespaceEnum(let enumName):
1364+
callName="\(enumName).\(function.name)"
1365+
case.explicitNamespace(let namespace):
1366+
callName="\(namespace.joined(separator:".")).\(function.name)"
1367+
}
1368+
builder.call(name: callName, returnType: function.returnType)
1369+
}else{
1370+
builder.call(name: function.name, returnType: function.returnType)
1371+
}
1372+
12731373
try builder.lowerReturnValue(returnType: function.returnType)
12741374
return builder.render(abiName: function.abiName)
12751375
}
@@ -1335,17 +1435,25 @@ public class ExportSwift {
13351435
}
13361436
formethodin klass.methods{
13371437
letbuilder=ExportedThunkBuilder(effects: method.effects)
1338-
try builder.liftParameter(
1339-
param:Parameter(label:nil, name:"_self", type:BridgeType.swiftHeapObject(klass.swiftCallName))
1340-
)
1341-
forparamin method.parameters{
1342-
try builder.liftParameter(param: param)
1438+
1439+
if method.effects.isStatic{
1440+
forparamin method.parameters{
1441+
try builder.liftParameter(param: param)
1442+
}
1443+
builder.call(name:"\(klass.swiftCallName).\(method.name)", returnType: method.returnType)
1444+
}else{
1445+
try builder.liftParameter(
1446+
param:Parameter(label:nil, name:"_self", type:BridgeType.swiftHeapObject(klass.swiftCallName))
1447+
)
1448+
forparamin method.parameters{
1449+
try builder.liftParameter(param: param)
1450+
}
1451+
builder.callMethod(
1452+
klassName: klass.swiftCallName,
1453+
methodName: method.name,
1454+
returnType: method.returnType
1455+
)
13431456
}
1344-
builder.callMethod(
1345-
klassName: klass.swiftCallName,
1346-
methodName: method.name,
1347-
returnType: method.returnType
1348-
)
13491457
try builder.lowerReturnValue(returnType: method.returnType)
13501458
decls.append(builder.render(abiName: method.abiName))
13511459
}

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp