@@ -243,50 +243,20 @@ public class ExportSwift {
243
243
return . null
244
244
}
245
245
246
- if let stringLiteral = expr. as ( StringLiteralExprSyntax . self) ,
247
- let segment = stringLiteral. segments. first? . as ( StringSegmentSyntax . self) ,
248
- type. matches ( against: . string)
249
- {
250
- return . string( segment. content. text)
251
- }
252
-
253
- if let boolLiteral = expr. as ( BooleanLiteralExprSyntax . self) ,
254
- type. matches ( against: . bool)
255
- {
256
- return . bool( boolLiteral. literal. text == " true " )
257
- }
258
-
259
- if let intLiteral = expr. as ( IntegerLiteralExprSyntax . self) ,
260
- let intValue = Int ( intLiteral. literal. text) ,
261
- type. matches ( against: . int)
262
- {
263
- return . int( intValue)
264
- }
265
-
266
- if let floatLiteral = expr. as ( FloatLiteralExprSyntax . self) {
267
- if type. matches ( against: . float) ,
268
- let floatValue = Float ( floatLiteral. literal. text)
269
- {
270
- return . float( floatValue)
271
- }
272
- if type. matches ( against: . double) ,
273
- let doubleValue = Double ( floatLiteral. literal. text)
274
- {
275
- return . double( doubleValue)
276
- }
277
- }
278
-
279
246
if let memberExpr = expr. as ( MemberAccessExprSyntax . self) ,
280
247
let enumValue = extractEnumCaseValue ( from: memberExpr, type: type)
281
248
{
282
249
return enumValue
283
250
}
284
251
285
- // Constructor calls (e.g., Greeter(name: "John"))
286
252
if let funcCall = expr. as ( FunctionCallExprSyntax . self) {
287
253
return extractConstructorDefaultValue ( from: funcCall, type: type)
288
254
}
289
255
256
+ if let literalValue = extractLiteralValue ( from: expr, type: type) {
257
+ return literalValue
258
+ }
259
+
290
260
diagnose (
291
261
node: expr,
292
262
message: " Unsupported default parameter value expression " ,
@@ -300,7 +270,6 @@ public class ExportSwift {
300
270
from funcCall: FunctionCallExprSyntax ,
301
271
type: BridgeType
302
272
) -> DefaultValue ? {
303
- // Extract class name
304
273
guard let calledExpr = funcCall. calledExpression. as ( DeclReferenceExprSyntax . self) else {
305
274
diagnose (
306
275
node: funcCall,
@@ -311,8 +280,6 @@ public class ExportSwift {
311
280
}
312
281
313
282
let className = calledExpr. baseName. text
314
-
315
- // Verify type matches
316
283
let expectedClassName : String ?
317
284
switch type {
318
285
case . swiftHeapObject( let name) :
@@ -337,17 +304,13 @@ public class ExportSwift {
337
304
return nil
338
305
}
339
306
340
- // Handle parameterless constructor
341
307
if funcCall. arguments. isEmpty {
342
308
return . object( className)
343
309
}
344
310
345
- // Extract arguments for constructor with parameters
346
311
var constructorArgs : [ DefaultValue ] = [ ]
347
312
for argument in funcCall. arguments {
348
- // Recursively extract the argument's default value
349
- // For now, only support literals in constructor arguments
350
- guard let argValue = extractConstructorArgumentValue ( from: argument. expression) else {
313
+ guard let argValue = extractLiteralValue ( from: argument. expression) else {
351
314
diagnose (
352
315
node: argument. expression,
353
316
message: " Constructor argument must be a literal value " ,
@@ -362,42 +325,64 @@ public class ExportSwift {
362
325
return . objectWithArguments( className, constructorArgs)
363
326
}
364
327
365
- /// Extracts a literal value from an expression for use in constructor arguments
366
- private func extractConstructorArgumentValue( from expr: ExprSyntax ) -> DefaultValue ? {
367
- // String literals
328
+ /// Extracts a literal value from an expression with optional type checking
329
+ private func extractLiteralValue( from expr: ExprSyntax , type: BridgeType ? = nil ) -> DefaultValue ? {
330
+ if expr. is ( NilLiteralExprSyntax . self) {
331
+ return . null
332
+ }
333
+
368
334
if let stringLiteral = expr. as ( StringLiteralExprSyntax . self) ,
369
335
let segment = stringLiteral. segments. first? . as ( StringSegmentSyntax . self)
370
336
{
371
- return . string( segment. content. text)
337
+ let value = DefaultValue . string ( segment. content. text)
338
+ if let type = type, !type. isCompatibleWith ( . string) {
339
+ return nil
340
+ }
341
+ return value
372
342
}
373
343
374
- // Boolean literals
375
344
if let boolLiteral = expr. as ( BooleanLiteralExprSyntax . self) {
376
- return . bool( boolLiteral. literal. text == " true " )
345
+ let value = DefaultValue . bool ( boolLiteral. literal. text == " true " )
346
+ if let type = type, !type. isCompatibleWith ( . bool) {
347
+ return nil
348
+ }
349
+ return value
350
+ }
351
+
352
+ var numericExpr = expr
353
+ var isNegative = false
354
+ if let prefixExpr = expr. as ( PrefixOperatorExprSyntax . self) ,
355
+ prefixExpr. operator. text == " - "
356
+ {
357
+ numericExpr = prefixExpr. expression
358
+ isNegative = true
377
359
}
378
360
379
- // Integer literals
380
- if let intLiteral = expr. as ( IntegerLiteralExprSyntax . self) ,
361
+ if let intLiteral = numericExpr. as ( IntegerLiteralExprSyntax . self) ,
381
362
let intValue = Int ( intLiteral. literal. text)
382
363
{
383
- return . int( intValue)
364
+ let value = DefaultValue . int ( isNegative ? - intValue : intValue)
365
+ if let type = type, !type. isCompatibleWith ( . int) {
366
+ return nil
367
+ }
368
+ return value
384
369
}
385
370
386
- // Float literals
387
- if let floatLiteral = expr. as ( FloatLiteralExprSyntax . self) {
371
+ if let floatLiteral = numericExpr. as ( FloatLiteralExprSyntax . self) {
388
372
if let floatValue = Float ( floatLiteral. literal. text) {
389
- return . float( floatValue)
373
+ let value = DefaultValue . float ( isNegative ? - floatValue : floatValue)
374
+ if type == nil || type? . isCompatibleWith ( . float) == true {
375
+ return value
376
+ }
390
377
}
391
378
if let doubleValue = Double ( floatLiteral. literal. text) {
392
- return . double( doubleValue)
379
+ let value = DefaultValue . double ( isNegative ? - doubleValue : doubleValue)
380
+ if type == nil || type? . isCompatibleWith ( . double) == true {
381
+ return value
382
+ }
393
383
}
394
384
}
395
385
396
- // nil literal
397
- if expr. is ( NilLiteralExprSyntax . self) {
398
- return . null
399
- }
400
-
401
386
return nil
402
387
}
403
388
@@ -885,7 +870,7 @@ public class ExportSwift {
885
870
swiftCallName: swiftCallName,
886
871
explicitAccessControl: explicitAccessControl,
887
872
cases: [ ] , // Will be populated in visit(EnumCaseDeclSyntax)
888
- rawType: rawType,
873
+ rawType: SwiftEnumRawType ( rawType) ,
889
874
namespace: effectiveNamespace,
890
875
emitStyle: emitStyle,
891
876
staticMethods: [ ] ,
@@ -923,9 +908,7 @@ public class ExportSwift {
923
908
924
909
if case . tsEnum = emitStyle {
925
910
// Check for Bool raw type limitation
926
- if let raw = exportedEnum. rawType,
927
- let rawEnum = SwiftEnumRawType . from ( raw) , rawEnum == . bool
928
- {
911
+ if exportedEnum. rawType == . bool {
929
912
diagnose (
930
913
node: jsAttribute,
931
914
message: " TypeScript enum style is not supported for Bool raw-value enums " ,
@@ -1180,7 +1163,7 @@ public class ExportSwift {
1180
1163
return Constants . supportedRawTypes. contains ( typeName)
1181
1164
} ? . type. trimmedDescription
1182
1165
1183
- if let rawTypeString , let rawType = SwiftEnumRawType . from ( rawTypeString) {
1166
+ if let rawType = SwiftEnumRawType ( rawTypeString) {
1184
1167
return . rawValueEnum( swiftCallName, rawType)
1185
1168
} else {
1186
1169
let hasAnyCases = enumDecl. memberBlock. members. contains { member in
@@ -2160,12 +2143,13 @@ extension WithModifiersSyntax {
2160
2143
}
2161
2144
2162
2145
fileprivate extension BridgeType {
2163
- func matches( against expected: BridgeType ) -> Bool {
2164
- switch ( self , expected) {
2146
+ /// Returns true if a value of `expectedType` can be assigned to this type.
2147
+ func isCompatibleWith( _ expectedType: BridgeType ) -> Bool {
2148
+ switch ( self , expectedType) {
2165
2149
case let ( lhs, rhs) where lhs == rhs:
2166
2150
return true
2167
- case ( . optional( let wrapped) , expected ) :
2168
- return wrapped == expected
2151
+ case ( . optional( let wrapped) , expectedType ) :
2152
+ return wrapped == expectedType
2169
2153
default :
2170
2154
return false
2171
2155
}
0 commit comments