Skip to content

Commit eba48ba

Browse files
committed
WIP: Generate bindings from Sentry-Swift.h
1 parent e58a8f1 commit eba48ba

File tree

7 files changed

+1033
-399
lines changed

7 files changed

+1033
-399
lines changed

scripts/generate-cocoa-bindings.ps1

Lines changed: 178 additions & 106 deletions
Original file line numberDiff line numberDiff line change
@@ -102,8 +102,8 @@ if (!(Test-Path '/Library/Frameworks/Xamarin.iOS.framework/Versions/Current/lib/
102102
}
103103
}
104104

105-
# Get iPhone SDK version
106-
$iPhoneSdkVersion = sharpie xcode -sdks | grep -o -m 1 'iphoneos\S*'
105+
# Get iPhone SDK version (TODO: fix iphoneos26.0 compat)
106+
$iPhoneSdkVersion = sharpie xcode -sdks | grep -o -v 'iphoneos26.0' | grep -o -m 1 'iphoneos\S*'
107107
Write-Output "iPhoneSdkVersion: $iPhoneSdkVersion"
108108

109109
## Imports in the various header files are provided in the "new" style of:
@@ -141,16 +141,43 @@ else
141141
{
142142
Write-Host "File not found: $privateHeaderFile"
143143
}
144+
$swiftHeaderFile = "$HeadersPath/Sentry-Swift.h"
145+
if (Test-Path $swiftHeaderFile)
146+
{
147+
$content = Get-Content -Path $swiftHeaderFile -Raw
148+
# Replace module @imports with traditional #includes
149+
$content = $content -replace '(?m)^#if\s+(__has_feature\(objc_modules\))', '#if 1 // $1'
150+
$content = $content -replace '(?m)^@import\s+ObjectiveC;\s*\n', ''
151+
$content = $content -replace '(?m)^@import\s+(\w+);', '#include <$1/$1.h>'
152+
$content = $content -replace '(?m)^#import\s+"Sentry.h"\s*\n', ''
153+
154+
Set-Content -Path $swiftHeaderFile -Value $content
155+
Write-Host "Patched includes: $swiftHeaderFile"
156+
}
157+
else
158+
{
159+
Write-Host "File not found: $swiftHeaderFile"
160+
}
144161

145-
# Generate bindings
146-
Write-Output 'Generating bindings with Objective Sharpie.'
162+
# Generate Obj-C bindings
163+
Write-Output 'Generating Obj-C bindings with Objective Sharpie.'
147164
sharpie bind -sdk $iPhoneSdkVersion `
148165
-scope "$CocoaSdkPath" `
149166
"$HeadersPath/Sentry.h" `
150167
"$PrivateHeadersPath/PrivateSentrySDKOnly.h" `
151168
-o $BindingsPath `
152169
-c -Wno-objc-property-no-attribute
153170

171+
# Generate Swift bindings
172+
Write-Output 'Generating Swift bindings with Objective Sharpie.'
173+
sharpie bind -sdk $iPhoneSdkVersion `
174+
-scope "$CocoaSdkPath" `
175+
"$HeadersPath/Sentry.h" `
176+
"$HeadersPath/Sentry-Swift.h" `
177+
-o $BindingsPath `
178+
-p Swift `
179+
-c -Wno-objc-property-no-attribute
180+
154181
# Ensure backup path exists
155182
if (!(Test-Path $BackupPath))
156183
{
@@ -170,144 +197,189 @@ $Header = @"
170197
################################################################################
171198
# Patch StructsAndEnums.cs
172199
################################################################################
173-
$File = 'StructsAndEnums.cs'
174-
Write-Output "Patching $BindingsPath/$File"
175-
Copy-Item "$BindingsPath/$File" -Destination "$BackupPath/$File"
176-
$Text = Get-Content "$BindingsPath/$File" -Raw
200+
function Patch-StructsAndEnums([string] $File)
201+
{
202+
Write-Output "Patching $BindingsPath/$File"
203+
Copy-Item "$BindingsPath/$File" -Destination "$BackupPath/$File"
204+
$Text = Get-Content "$BindingsPath/$File" -Raw
177205

178-
# Tabs to spaces
179-
$Text = $Text -replace '\t', ' '
206+
# Tabs to spaces
207+
$Text = $Text -replace '\t', ' '
180208

181-
# Trim extra newline at EOF
182-
$Text = $Text -replace '\n$', ''
209+
# Trim extra newline at EOF
210+
$Text = $Text -replace '\n$', ''
183211

184-
# Insert namespace
185-
$Text = $Text -replace 'using .+;\n\n', "$&namespace Sentry.CocoaSdk;`n`n"
212+
# Insert namespace
213+
$Text = $Text -replace 'using .+;\n\n', "$&namespace Sentry.CocoaSdk;`n`n"
186214

187-
# Public to internal
188-
$Text = $Text -replace '\bpublic\b', 'internal'
215+
# Public to internal
216+
$Text = $Text -replace '\bpublic\b', 'internal'
189217

190-
# Remove static CFunctions class
191-
$Text = $Text -replace '(?ms)\nstatic class CFunctions.*?}\n', ''
218+
# Remove static CFunctions class
219+
$Text = $Text -replace '(?ms)\nstatic class CFunctions.*?}\n', ''
220+
221+
# Add header and output file
222+
$Text = "$Header`n`n$Text"
223+
$Text | Out-File "$BindingsPath/$File"
224+
}
192225

193-
# Add header and output file
194-
$Text = "$Header`n`n$Text"
195-
$Text | Out-File "$BindingsPath/$File"
226+
Patch-StructsAndEnums 'StructsAndEnums.cs'
227+
Patch-StructsAndEnums 'SwiftStructsAndEnums.cs'
196228

197229
################################################################################
198230
# Patch ApiDefinitions.cs
199231
################################################################################
200-
$File = 'ApiDefinitions.cs'
201-
Write-Output "Patching $BindingsPath/$File"
202-
Copy-Item "$BindingsPath/$File" -Destination "$BackupPath/$File"
203-
$Text = Get-Content "$BindingsPath/$File" -Raw
232+
function Patch-ApiDefinitions([string] $File, [switch] $RemoveDelegates = $false)
233+
{
234+
Write-Output "Patching $BindingsPath/$File"
235+
Copy-Item "$BindingsPath/$File" -Destination "$BackupPath/$File"
236+
$Text = Get-Content "$BindingsPath/$File" -Raw
204237

205-
# Tabs to spaces
206-
$Text = $Text -replace '\t', ' '
238+
# Tabs to spaces
239+
$Text = $Text -replace '\t', ' '
207240

208-
# Trim extra newline at EOF
209-
$Text = $Text -replace '\n$', ''
241+
# Trim extra newline at EOF
242+
$Text = $Text -replace '\n$', ''
210243

211-
# Insert namespace
212-
$Text = $Text -replace 'using .+;\n\n', "$&namespace Sentry.CocoaSdk;`n`n"
244+
# Insert namespace
245+
$Text = $Text -replace 'using .+;\n\n', "$&namespace Sentry.CocoaSdk;`n`n"
213246

214-
# Set Internal attributes on interfaces and delegates
215-
$Text = $Text -replace '(?m)^(partial interface|interface|delegate)\b', "[Internal]`n$&"
247+
# Fix broken multi-line comments
248+
$Text = $Text -replace '(DEPRECATED_MSG_ATTRIBUTE\()\n\s*', '$1'
249+
$Text = $Text -replace '(DEPRECATED_MSG_ATTRIBUTE\([^)]*?)"\s*\r?\n\s*"', '$1 '
216250

217-
# Fix ISentrySerializable usage
218-
$Text = $Text -replace '\bISentrySerializable\b', 'SentrySerializable'
251+
if ($RemoveDelegates)
252+
{
253+
# Remove delegate definitions
254+
$Text = $Text -replace '(?ms)// typedef[^\n]*\n(?:\[Internal\]\n)?delegate[^\{;]+;\n\n', ''
255+
}
219256

220-
# Remove INSCopying due to https://github.com/xamarin/xamarin-macios/issues/17130
221-
$Text = $Text -replace ': INSCopying,', ':' -replace '\s?[:,] INSCopying', ''
257+
# Set Internal attributes on interfaces and delegates
258+
$Text = $Text -replace '(?m)^(partial interface|interface|delegate)\b', "[Internal]`n$&"
222259

223-
# Remove iOS attributes like [iOS (13, 0)]
224-
$Text = $Text -replace '\[iOS \(13,\s?0\)\]\n?\s*', ''
260+
# Fix ISentrySerializable usage
261+
$Text = $Text -replace '\bISentrySerializable\b', 'SentrySerializable'
225262

226-
# Remove Unavailable attributes like [Unavailable (PlatformName.iOSAppExtension)]
227-
$Text = $Text -replace '\[Unavailable \(PlatformName\.\w+\)\]\n?\s*', ''
263+
# Remove INSCopying due to https://github.com/xamarin/xamarin-macios/issues/17130
264+
$Text = $Text -replace ': INSCopying,', ':' -replace '\s?[:,] INSCopying', ''
228265

229-
# Fix delegate argument names
230-
$Text = $Text -replace '(NSError) arg\d', '$1 error'
231-
$Text = $Text -replace '(NSHttpUrlResponse) arg\d', '$1 response'
232-
$Text = $Text -replace '(SentryEvent) arg\d', '$1 @event'
233-
$Text = $Text -replace '(SentrySamplingContext) arg\d', '$1 samplingContext'
234-
$Text = $Text -replace '(SentryBreadcrumb) arg\d', '$1 breadcrumb'
235-
$Text = $Text -replace '(SentrySpan) arg\d', '$1 span'
236-
$Text = $Text -replace '(SentryAppStartMeasurement) arg\d', '$1 appStartMeasurement'
237-
$Text = $Text -replace '(SentryLog) arg\d', '$1 log'
266+
# Remove iOS attributes like [iOS (13, 0)]
267+
$Text = $Text -replace '\[iOS \(13,\s?0\)\]\n?\s*', ''
238268

239-
# Adjust nullable return delegates (though broken until this is fixed: https://github.com/xamarin/xamarin-macios/issues/17109)
240-
$Text = $Text -replace 'delegate \w+ Sentry(BeforeBreadcrumb|BeforeSendEvent|TracesSampler)Callback', "[return: NullAllowed]`n$&"
269+
# Remove Unavailable attributes like [Unavailable (PlatformName.iOSAppExtension)]
270+
$Text = $Text -replace '\[Unavailable \(PlatformName\.\w+\)\]\n?\s*', ''
241271

242-
# Adjust protocols (some are models)
243-
$Text = $Text -replace '(?ms)(@protocol.+?)/\*.+?\*/', '$1'
244-
$Text = $Text -replace '(?ms)@protocol (SentrySerializable|SentrySpan).+?\[Protocol\]', "`$&`n[Model]"
272+
# Fix delegate argument names
273+
$Text = $Text -replace '(NSError) arg\d', '$1 error'
274+
$Text = $Text -replace '(NSHttpUrlResponse) arg\d', '$1 response'
275+
$Text = $Text -replace '(SentryEvent) arg\d', '$1 @event'
276+
$Text = $Text -replace '(SentrySamplingContext) arg\d', '$1 samplingContext'
277+
$Text = $Text -replace '(SentryBreadcrumb) arg\d', '$1 breadcrumb'
278+
$Text = $Text -replace '(SentrySpan) arg\d', '$1 span'
279+
$Text = $Text -replace '(SentryAppStartMeasurement) arg\d', '$1 appStartMeasurement'
280+
$Text = $Text -replace '(SentryLog) arg\d', '$1 log'
245281

246-
# Adjust SentrySpan base type
247-
$Text = $Text -replace 'interface SentrySpan\b', "[BaseType (typeof(NSObject))]`n`$&"
282+
# Adjust nullable return delegates (though broken until this is fixed: https://github.com/xamarin/xamarin-macios/issues/17109)
283+
$Text = $Text -replace 'delegate \w+ Sentry(BeforeBreadcrumb|BeforeSendEvent|TracesSampler)Callback', "[return: NullAllowed]`n$&"
248284

249-
# Fix string constants
250-
$Text = $Text -replace '(?m)(.*\n){2}^\s{4}NSString k.+?\n\n?', ''
251-
$Text = $Text -replace '(?m)(.*\n){4}^partial interface Constants\n{\n}\n', ''
252-
$Text = $Text -replace '\[Verify \(ConstantsInterfaceAssociation\)\]\n', ''
285+
# Remove empty SentryRRWebEvent protocol
286+
$Text = $Text -replace '(?ms)\[Protocol\]\s*\[Internal\]\s*interface\s+SentryRRWebEvent\s*:\s*SentrySerializable[^\{]*\{[^\}]*\}', ''
253287

254-
# Remove SentryVersionNumber
255-
$Text = $Text -replace '.*SentryVersionNumber.*\n?', ''
288+
# Adjust protocols (some are models)
289+
$Text = $Text -replace '(?ms)(@protocol.+?)/\*.+?\*/', '$1'
290+
$Text = $Text -replace '(?ms)@protocol (SentrySerializable|SentrySpan).+?\[Protocol\]', "`$&`n[Model]"
291+
$Text = $Text -replace '(?ms)@protocol (SentryRedactOptions|SentryCurrentDateProvider).+?\[Protocol \(Name = \"\w+\"\)\]', "`$&`n[Model]"
256292

257-
# Remove SentryVersionString
258-
$Text = $Text -replace '.*SentryVersionString.*\n?', ''
293+
# Adjust base types
294+
$Text = $Text -replace 'interface (SentrySpan|SentryRedactOptions|SentryCurrentDateProvider)\b', "[BaseType (typeof(NSObject))]`n`$&"
259295

260-
# Remove duplicate attributes
261-
$s = 'partial interface Constants'
262-
$t = $Text -split $s, 2
263-
$t[1] = $t[1] -replace "\[Static\]\n\[Internal\]\n$s", $s
264-
$Text = $t -join $s
296+
# Fix string constants
297+
$Text = $Text -replace '(?m)(.*\n){2}^\s{4}NSString k.+?\n\n?', ''
298+
$Text = $Text -replace '(?m)(.*\n){4}^partial interface Constants\n{\n}\n', ''
299+
$Text = $Text -replace '\[Verify \(ConstantsInterfaceAssociation\)\]\n', ''
265300

266-
# Remove empty Constants block
267-
$Text = $Text -replace '\[Static\]\s*\[Internal\]\s*partial\s+interface\s+Constants\s\{[\s\n]*\}\n\n', ''
301+
# Remove SentryVersionNumber
302+
$Text = $Text -replace '.*SentryVersionNumber.*\n?', ''
268303

269-
# Update MethodToProperty translations
270-
$Text = $Text -replace '(Export \("get\w+"\)\]\n)\s*\[Verify \(MethodToProperty\)\]\n(.+ \{ get; \})', '$1$2'
271-
$Text = $Text -replace '\[Verify \(MethodToProperty\)\]\n\s*(.+ (?:Hash|Value|DefaultIntegrations|AppStartMeasurementWithSpans|BaggageHttpHeader) \{ get; \})', '$1'
272-
$Text = $Text -replace '\[Verify \(MethodToProperty\)\]\n\s*(.+) \{ get; \}', '$1();'
304+
# Remove SentryVersionString
305+
$Text = $Text -replace '.*SentryVersionString.*\n?', ''
273306

274-
# Allow weakly typed NSArray
275-
# We have some that accept either NSString or NSRegularExpression, which have no common type so they use NSObject
276-
$Text = $Text -replace '\s*\[Verify \(StronglyTypedNSArray\)\]\n', ''
307+
# Remove duplicate attributes
308+
$s = 'partial interface Constants'
309+
$t = $Text -split $s, 2
310+
$t[1] = $t[1] -replace "\[Static\]\n\[Internal\]\n$s", $s
311+
$Text = $t -join $s
277312

278-
# Fix broken multi-line comments
279-
$Text = $Text -replace '(DEPRECATED_MSG_ATTRIBUTE\()\n\s*', '$1'
280-
$Text = $Text -replace '(DEPRECATED_MSG_ATTRIBUTE\([^)]*?)"\s*\r?\n\s*"', '$1 '
313+
# Remove empty Constants block
314+
$Text = $Text -replace '\[Static\]\s*\[Internal\]\s*partial\s+interface\s+Constants\s\{[\s\n]*\}\n\n', ''
281315

282-
# Remove default IsEqual implementation (already implemented by NSObject)
283-
$Text = $Text -replace '(?ms)\n?^ *// [^\n]*isEqual:.*?$.*?;\n', ''
316+
# Update MethodToProperty translations
317+
$Text = $Text -replace '(Export \("get\w+"\)\]\n)\s*\[Verify \(MethodToProperty\)\]\n(.+ \{ get; \})', '$1$2'
318+
$Text = $Text -replace '\[Verify \(MethodToProperty\)\]\n\s*(.+ (?:Hash|Value|DefaultIntegrations|AppStartMeasurementWithSpans|BaggageHttpHeader) \{ get; \})', '$1'
319+
$Text = $Text -replace '\[Verify \(MethodToProperty\)\]\n\s*(.+) \{ get; \}', '$1();'
284320

285-
# Replace obsolete platform availability attributes
286-
$Text = $Text -replace '([\[,] )MacCatalyst \(', '$1Introduced (PlatformName.MacCatalyst, '
287-
$Text = $Text -replace '([\[,] )Mac \(', '$1Introduced (PlatformName.MacOSX, '
288-
$Text = $Text -replace '([\[,] )iOS \(', '$1Introduced (PlatformName.iOS, '
321+
# Allow weakly typed NSArray
322+
# We have some that accept either NSString or NSRegularExpression, which have no common type so they use NSObject
323+
$Text = $Text -replace '\s*\[Verify \(StronglyTypedNSArray\)\]\n', ''
289324

290-
# Make interface partial if we need to access private APIs. Other parts will be defined in PrivateApiDefinitions.cs
291-
$Text = $Text -replace '(?m)^interface SentryScope', 'partial $&'
325+
# Remove default IsEqual/CopyWithZone/Description implementations (already implemented by NSObject)
326+
$Text = $Text -replace '(?ms)\n?^ *// [^\n]*isEqual:.*?$.*?;\n', ''
327+
$Text = $Text -replace '(?ms)\n?^ *// [^\n]*copyWithZone:.*?$.*?;\n', ''
292328

293-
$Text = $Text -replace '.*SentryEnvelope .*?[\s\S]*?\n\n', ''
294-
$Text = $Text -replace '.*typedef.*SentryOnAppStartMeasurementAvailable.*?[\s\S]*?\n\n', ''
329+
# Replace obsolete platform availability attributes
330+
$Text = $Text -replace '([\[,] )MacCatalyst \(', '$1Introduced (PlatformName.MacCatalyst, '
331+
$Text = $Text -replace '([\[,] )Mac \(', '$1Introduced (PlatformName.MacOSX, '
332+
$Text = $Text -replace '([\[,] )iOS \(', '$1Introduced (PlatformName.iOS, '
295333

296-
$propertiesToRemove = @(
297-
'SentryAppStartMeasurement',
298-
'SentryOnAppStartMeasurementAvailable',
299-
'SentryMetricsAPI',
300-
'SentryExperimentalOptions',
301-
'description',
302-
'enableMetricKitRawPayload'
303-
)
334+
# Make interface partial if we need to access private APIs. Other parts will be defined in PrivateApiDefinitions.cs
335+
$Text = $Text -replace '(?m)^interface SentryScope', 'partial $&'
304336

305-
foreach ($property in $propertiesToRemove)
306-
{
307-
$Text = $Text -replace "\n.*property.*$property.*?[\s\S]*?\}\n", ''
337+
$Text = $Text -replace '.*typedef.*SentryOnAppStartMeasurementAvailable.*?[\s\S]*?\n\n', ''
338+
$Text = $Text -replace 'NSDictionary<NSString, SentryStructuredLogAttribute>', 'NSDictionary<NSString, NSObject>'
339+
340+
# Comment out interfaces
341+
$Text = $Text -replace 'interface (\w+) : (ISentryRedactOptions|ISentryRRWebEvent)', 'interface $1 //: $2'
342+
343+
$propertiesToRemove = @(
344+
'SentryAppStartMeasurement',
345+
'SentryOnAppStartMeasurementAvailable',
346+
'SentryMetricsAPI',
347+
'SentryExperimentalOptions',
348+
'description',
349+
'enableMetricKitRawPayload'
350+
)
351+
352+
foreach ($property in $propertiesToRemove)
353+
{
354+
$Text = $Text -replace "\n.*property.*$property.*?[\s\S]*?\}\n", ''
355+
}
356+
357+
358+
# Add header and output file
359+
$Text = "$Header`n`n$Text"
360+
$Text | Out-File "$BindingsPath/$File"
308361
}
309362

363+
Patch-ApiDefinitions 'ApiDefinitions.cs'
364+
Patch-ApiDefinitions 'SwiftApiDefinitions.cs' -RemoveDelegates
365+
366+
################################################################################
367+
# Post-process SwiftStructsAndEnums.cs and SwiftApiDefinitions.cs
368+
################################################################################
369+
370+
function PostProcess-SwiftBindings([string] $File)
371+
{
372+
try
373+
{
374+
Write-Output "Post-processing $BindingsPath/$File"
375+
Push-Location $PSScriptRoot
376+
& dotnet run "post-process-swift-bindings.cs" "$BindingsPath/$File" | ForEach-Object { Write-Host $_ }
377+
}
378+
finally
379+
{
380+
Pop-Location
381+
}
382+
}
310383

311-
# Add header and output file
312-
$Text = "$Header`n`n$Text"
313-
$Text | Out-File "$BindingsPath/$File"
384+
PostProcess-SwiftBindings 'SwiftStructsAndEnums.cs'
385+
PostProcess-SwiftBindings 'SwiftApiDefinitions.cs'

scripts/global.json

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
{
2+
"sdk": {
3+
"version": "10.0.100-rc.1"
4+
}
5+
}

0 commit comments

Comments
 (0)