@@ -57,6 +57,9 @@ export class TypeProcessor {
5757 /** @type {Set<string> } */
5858 this . emittedStringLiteralUnionNames = new Set ( ) ;
5959
60+ /** @type {Set<ts.Node> } */
61+ this . warnedExportNodes = new Set ( ) ;
62+
6063 /** @type {Set<string> } */
6164 this . visitedDeclarationKeys = new Set ( ) ;
6265
@@ -192,6 +195,8 @@ export class TypeProcessor {
192195 this . visitEnumDeclaration ( node ) ;
193196 } else if ( ts . isExportDeclaration ( node ) ) {
194197 this . visitExportDeclaration ( node ) ;
198+ } else if ( ts . isExportAssignment ( node ) ) {
199+ this . visitExportAssignment ( node ) ;
195200 }
196201 }
197202
@@ -239,6 +244,7 @@ export class TypeProcessor {
239244 }
240245 } else {
241246 // export * as ns from "..." is not currently supported by BridgeJS imports.
247+ this . warnExportSkip ( node , "Skipping namespace re-export (export * as ns) which is not supported" ) ;
242248 return ;
243249 }
244250
@@ -254,6 +260,19 @@ export class TypeProcessor {
254260 this . visitNode ( declaration ) ;
255261 }
256262 }
263+
264+ if ( targetSymbols . length === 0 ) {
265+ this . warnExportSkip ( node , "Export declaration resolved to no symbols; nothing was generated" ) ;
266+ }
267+ }
268+
269+ /**
270+ * Handle `export default foo;` style assignments.
271+ * @param {ts.ExportAssignment } node
272+ */
273+ visitExportAssignment ( node ) {
274+ // BridgeJS does not currently model default export assignments (they may point to expressions).
275+ this . warnExportSkip ( node , "Skipping export assignment (export default ...) which is not supported" ) ;
257276 }
258277
259278 /**
@@ -271,7 +290,10 @@ export class TypeProcessor {
271290 const isConst = ( node . declarationList . flags & ts . NodeFlags . Const ) !== 0 ;
272291
273292 for ( const decl of node . declarationList . declarations ) {
274- if ( ! ts . isIdentifier ( decl . name ) ) continue ;
293+ if ( ! ts . isIdentifier ( decl . name ) ) {
294+ this . warnExportSkip ( decl , "Skipping exported variable with a non-identifier name" ) ;
295+ continue ;
296+ }
275297
276298 const jsName = decl . name . text ;
277299 const swiftName = this . swiftTypeName ( jsName ) ;
@@ -399,7 +421,12 @@ export class TypeProcessor {
399421 */
400422 visitEnumDeclaration ( node ) {
401423 const name = node . name ?. text ;
402- if ( ! name ) return ;
424+ if ( ! name ) {
425+ if ( this . isExported ( node ) ) {
426+ this . warnExportSkip ( node , "Skipping exported enum without a name" ) ;
427+ }
428+ return ;
429+ }
403430 this . emitEnumFromDeclaration ( name , node , node ) ;
404431 }
405432
@@ -532,7 +559,12 @@ export class TypeProcessor {
532559 * @private
533560 */
534561 visitFunctionDeclaration ( node ) {
535- if ( ! node . name ) return ;
562+ if ( ! node . name ) {
563+ if ( this . isExported ( node ) ) {
564+ this . warnExportSkip ( node , "Skipping exported function without a name" ) ;
565+ }
566+ return ;
567+ }
536568 const jsName = node . name . text ;
537569 const swiftName = this . swiftTypeName ( jsName ) ;
538570 const fromArg = this . renderDefaultJSImportFromArgument ( ) ;
@@ -774,7 +806,12 @@ export class TypeProcessor {
774806 * @private
775807 */
776808 visitClassDecl ( node ) {
777- if ( ! node . name ) return ;
809+ if ( ! node . name ) {
810+ if ( this . isExported ( node ) ) {
811+ this . warnExportSkip ( node , "Skipping exported class without a name" ) ;
812+ }
813+ return ;
814+ }
778815
779816 const jsName = node . name . text ;
780817 if ( this . emittedStructuredTypeNames . has ( jsName ) ) return ;
@@ -1244,6 +1281,28 @@ export class TypeProcessor {
12441281 return parts . join ( " " ) ;
12451282 }
12461283
1284+ /**
1285+ * @param {ts.Node } node
1286+ * @returns {boolean }
1287+ */
1288+ isExported ( node ) {
1289+ const hasExportModifier = /** @type {ts.ModifierLike[] | undefined } */ ( node . modifiers ) ?. some (
1290+ ( m ) => m . kind === ts . SyntaxKind . ExportKeyword
1291+ ) ?? false ;
1292+ return hasExportModifier || ts . isExportAssignment ( node ) ;
1293+ }
1294+
1295+ /**
1296+ * Emit a single warning per node when an exported declaration cannot be generated.
1297+ * @param {ts.Node } node
1298+ * @param {string } reason
1299+ */
1300+ warnExportSkip ( node , reason ) {
1301+ if ( this . warnedExportNodes . has ( node ) ) return ;
1302+ this . warnedExportNodes . add ( node ) ;
1303+ this . diagnosticEngine . print ( "warning" , `${ reason } . Swift binding not generated` , node ) ;
1304+ }
1305+
12471306 /**
12481307 * Render identifier with backticks if needed
12491308 * @param {string } name
0 commit comments