@@ -151,6 +151,7 @@ struct ImportTS {
151151 } else {
152152 body. append ( " let ret = \( raw: call) " )
153153 }
154+ body. append ( " if let error = _swift_js_take_exception() { throw error } " )
154155 }
155156
156157 func liftReturnValue( returnType: BridgeType ) throws {
@@ -253,6 +254,7 @@ struct ImportTS {
253254 )
254255 }
255256 } ) ,
257+ effectSpecifiers: ImportTS . buildFunctionEffect ( throws: true , async : false ) ,
256258 returnClause: ReturnClauseSyntax (
257259 arrow: . arrowToken( ) ,
258260 type: IdentifierTypeSyntax ( name: . identifier( returnType. swiftType) )
@@ -280,7 +282,8 @@ struct ImportTS {
280282 )
281283 }
282284 }
283- )
285+ ) ,
286+ effectSpecifiers: ImportTS . buildFunctionEffect ( throws: true , async : false )
284287 ) ,
285288 bodyBuilder: {
286289 self . renderImportDecl ( )
@@ -364,38 +367,33 @@ struct ImportTS {
364367 try builder. liftReturnValue ( returnType: property. type)
365368 return AccessorDeclSyntax (
366369 accessorSpecifier: . keyword( . get) ,
370+ effectSpecifiers: Self . buildAccessorEffect ( throws: true , async : false ) ,
367371 body: CodeBlockSyntax {
368372 builder. renderImportDecl ( )
369373 builder. body
370374 }
371375 )
372376 }
373377
374- func renderSetterDecl( property: ImportedPropertySkeleton ) throws -> AccessorDeclSyntax {
378+ func renderSetterDecl( property: ImportedPropertySkeleton ) throws -> DeclSyntax {
375379 let builder = ImportedThunkBuilder (
376380 moduleName: moduleName,
377381 abiName: property. setterAbiName ( context: type)
378382 )
383+ let newValue = Parameter ( label: nil , name: " newValue " , type: property. type)
379384 try builder. lowerParameter ( param: Parameter ( label: nil , name: " self " , type: . jsObject( name) ) )
380- try builder. lowerParameter ( param: Parameter ( label : nil , name : " newValue " , type : property . type ) )
385+ try builder. lowerParameter ( param: newValue)
381386 builder. call ( returnType: . void)
382- return AccessorDeclSyntax (
383- modifier: DeclModifierSyntax ( name: . keyword( . nonmutating) ) ,
384- accessorSpecifier: . keyword( . set) ,
385- body: CodeBlockSyntax {
386- builder. renderImportDecl ( )
387- builder. body
388- }
387+ return builder. renderThunkDecl (
388+ name: " set \( property. name. capitalizedFirstLetter ( ) ) " ,
389+ parameters: [ newValue] ,
390+ returnType: . void
389391 )
390392 }
391393
392394 func renderPropertyDecl( property: ImportedPropertySkeleton ) throws -> [ DeclSyntax ] {
393- var accessorDecls : [ AccessorDeclSyntax ] = [ ]
394- accessorDecls. append ( try renderGetterDecl ( property: property) )
395- if !property. isReadonly {
396- accessorDecls. append ( try renderSetterDecl ( property: property) )
397- }
398- return [
395+ let accessorDecls : [ AccessorDeclSyntax ] = [ try renderGetterDecl ( property: property) ]
396+ var decls : [ DeclSyntax ] = [
399397 DeclSyntax (
400398 VariableDeclSyntax (
401399 leadingTrivia: Self . renderDocumentation ( documentation: property. documentation) ,
@@ -418,6 +416,10 @@ struct ImportTS {
418416 )
419417 )
420418 ]
419+ if !property. isReadonly {
420+ decls. append ( try renderSetterDecl ( property: property) )
421+ }
422+ return decls
421423 }
422424 let classDecl = try StructDeclSyntax (
423425 leadingTrivia: Self . renderDocumentation ( documentation: type. documentation) ,
@@ -469,4 +471,36 @@ struct ImportTS {
469471 let lines = documentation. split { $0. isNewline }
470472 return Trivia ( pieces: lines. flatMap { [ TriviaPiece . docLineComment ( " /// \( $0) " ) , . newlines( 1 ) ] } )
471473 }
474+
475+ static func buildFunctionEffect( throws: Bool , async : Bool ) -> FunctionEffectSpecifiersSyntax {
476+ return FunctionEffectSpecifiersSyntax (
477+ asyncSpecifier: `async` ? . keyword( . async) : nil ,
478+ throwsClause: `throws`
479+ ? ThrowsClauseSyntax (
480+ throwsSpecifier: . keyword( . throws) ,
481+ leftParen: . leftParenToken( ) ,
482+ type: IdentifierTypeSyntax ( name: . identifier( " JSException " ) ) ,
483+ rightParen: . rightParenToken( )
484+ ) : nil
485+ )
486+ }
487+ static func buildAccessorEffect( throws: Bool , async : Bool ) -> AccessorEffectSpecifiersSyntax {
488+ return AccessorEffectSpecifiersSyntax (
489+ asyncSpecifier: `async` ? . keyword( . async) : nil ,
490+ throwsClause: `throws`
491+ ? ThrowsClauseSyntax (
492+ throwsSpecifier: . keyword( . throws) ,
493+ leftParen: . leftParenToken( ) ,
494+ type: IdentifierTypeSyntax ( name: . identifier( " JSException " ) ) ,
495+ rightParen: . rightParenToken( )
496+ ) : nil
497+ )
498+ }
499+ }
500+
501+ extension String {
502+ func capitalizedFirstLetter( ) -> String {
503+ guard !isEmpty else { return self }
504+ return prefix ( 1 ) . uppercased ( ) + dropFirst( )
505+ }
472506}
0 commit comments