From 83c0fedcd514dffa55b55f578888a9787ee233b9 Mon Sep 17 00:00:00 2001 From: Rolf Bjarne Kvinge Date: Fri, 6 Sep 2024 12:44:14 +0200 Subject: [PATCH 1/9] [bgen] Add support for more backing field types. (#21172) --- docs/website/binding_types_reference_guide.md | 2 ++ src/bgen/Enums.cs | 9 ++++- tests/generator/BGenTests.cs | 4 +++ tests/generator/tests/backingfieldtype.cs | 36 +++++++++++++++++++ 4 files changed, 50 insertions(+), 1 deletion(-) diff --git a/docs/website/binding_types_reference_guide.md b/docs/website/binding_types_reference_guide.md index cdead73d06..78b90f26cb 100644 --- a/docs/website/binding_types_reference_guide.md +++ b/docs/website/binding_types_reference_guide.md @@ -2250,6 +2250,8 @@ Currently, these types are supported: * `nint` * `nuint` +* `int`, `uint` +* `long`, `ulong` * `NSNumber` * `NSString` (this is the default if none is specified) diff --git a/src/bgen/Enums.cs b/src/bgen/Enums.cs index 48e9652e06..7a262a0b32 100644 --- a/src/bgen/Enums.cs +++ b/src/bgen/Enums.cs @@ -94,7 +94,14 @@ public partial class Generator { var isBackingFieldValueType = backingFieldType.IsValueType; var visibility = is_internal ? "internal" : "public"; - if (backingFieldType != TypeCache.System_nint && backingFieldType != TypeCache.System_nuint && backingFieldType != TypeCache.NSString && backingFieldType != TypeCache.NSNumber) { + if (backingFieldType != TypeCache.System_nint && + backingFieldType != TypeCache.System_nuint && + backingFieldType != TypeCache.System_Int32 && + backingFieldType != TypeCache.System_Int64 && + backingFieldType != TypeCache.System_UInt32 && + backingFieldType != TypeCache.System_UInt64 && + backingFieldType != TypeCache.NSString && + backingFieldType != TypeCache.NSNumber) { exceptions.Add (ErrorHelper.CreateError (1088 /* The backing field type '{0}' is invalid. Valid backing field types are: "NSString", "NSNumber", "nint" and "nuint". */, backingFieldType.FullName)); backingFieldType = TypeCache.NSString; } diff --git a/tests/generator/BGenTests.cs b/tests/generator/BGenTests.cs index 26e67f552a..76ef27f18c 100644 --- a/tests/generator/BGenTests.cs +++ b/tests/generator/BGenTests.cs @@ -1669,6 +1669,10 @@ namespace GeneratorTests { new { BackingFieldType = "NSNumber", NullableType = "Foundation.NSNumber", RenderedBackingFieldType = "Foundation.NSNumber", SimplifiedNullableType = "Foundation.NSNumber" }, new { BackingFieldType = "NSInteger", NullableType = $"System.Nullable`1<{nintName}>", RenderedBackingFieldType = nintName, SimplifiedNullableType = "System.Nullable`1" }, new { BackingFieldType = "NSUInteger", NullableType = $"System.Nullable`1<{nuintName}>", RenderedBackingFieldType = nuintName, SimplifiedNullableType = "System.Nullable`1" }, + new { BackingFieldType = "Int32", NullableType = $"System.Nullable`1", RenderedBackingFieldType = "System.Int32", SimplifiedNullableType = "System.Nullable`1" }, + new { BackingFieldType = "Int64", NullableType = $"System.Nullable`1", RenderedBackingFieldType = "System.Int64", SimplifiedNullableType = "System.Nullable`1" }, + new { BackingFieldType = "UInt32", NullableType = $"System.Nullable`1", RenderedBackingFieldType = "System.UInt32", SimplifiedNullableType = "System.Nullable`1" }, + new { BackingFieldType = "UInt64", NullableType = $"System.Nullable`1", RenderedBackingFieldType = "System.UInt64", SimplifiedNullableType = "System.Nullable`1" }, }; foreach (var tc in testCases) { diff --git a/tests/generator/tests/backingfieldtype.cs b/tests/generator/tests/backingfieldtype.cs index 9eef6b6ddb..fd360715fc 100644 --- a/tests/generator/tests/backingfieldtype.cs +++ b/tests/generator/tests/backingfieldtype.cs @@ -20,6 +20,30 @@ namespace BackingField { C, } + [BackingFieldType (typeof (Int32))] + enum Int32FieldType { + [Field ("DField", "__Internal")] + D, + } + + [BackingFieldType (typeof (Int64))] + enum Int64FieldType { + [Field ("EField", "__Internal")] + E, + } + + [BackingFieldType (typeof (UInt32))] + enum UInt32FieldType { + [Field ("FField", "__Internal")] + F, + } + + [BackingFieldType (typeof (UInt64))] + enum UInt64FieldType { + [Field ("GField", "__Internal")] + G, + } + [BaseType (typeof (NSObject))] interface SomeObj { [Export ("nsIntegerField")] @@ -30,5 +54,17 @@ namespace BackingField { [Export ("nsNumberField")] NSNumberFieldType NSNumberField { get; set; } + + [Export ("int32Field")] + Int32FieldType Int32Field { get; set; } + + [Export ("int64Field")] + Int64FieldType Int64Field { get; set; } + + [Export ("uint32Field")] + UInt32FieldType UInt32Field { get; set; } + + [Export ("uint64Field")] + UInt64FieldType UInt64Field { get; set; } } } From 52ee4555af2c11737399cde55748cdcf620ef945 Mon Sep 17 00:00:00 2001 From: Manuel de la Pena Date: Fri, 6 Sep 2024 07:15:50 -0400 Subject: [PATCH 2/9] [CI] Start moving to parse the configuration of the build in the tests pipelines (#21009) At the moment we are recaculating the configuration that was used in the build to decide which tests to run, that is not needed since the configuration was uploaded to the artifacts. This change will allow to do the following: - Load the default variables on the build pipeline this will allow us to set the name of the tests to match those of the build for easy parsing. - Load the default variables to set the property comment in the PR. - Do not recalculate the built platforms on the tests matrix. - Do not calculate the API scan matrix, it is not needed for the tests. --------- Co-authored-by: Rolf Bjarne Kvinge --- tools/devops/automation/scripts/VSTS.psm1 | 35 ++++++ .../templates/common/load_configuration.yml | 106 ++++++++++++++++++ .../automation/templates/tests-stage.yml | 2 +- 3 files changed, 142 insertions(+), 1 deletion(-) create mode 100644 tools/devops/automation/templates/common/load_configuration.yml diff --git a/tools/devops/automation/scripts/VSTS.psm1 b/tools/devops/automation/scripts/VSTS.psm1 index f7c43f276c..655df55a66 100644 --- a/tools/devops/automation/scripts/VSTS.psm1 +++ b/tools/devops/automation/scripts/VSTS.psm1 @@ -448,6 +448,11 @@ class BuildConfiguration { $this.StoreParentBuildVariables($configuration) + # store if dotnet has been enabled + $variableName = "ENABLE_DOTNET" + $variableValue = [Environment]::GetEnvironmentVariable($variableName) + $configuration | Add-Member -NotePropertyName $variableName -NotePropertyValue $variableValue + # For each .NET platform we support, add a INCLUDE_DOTNET_ variable specifying whether that platform is enabled or not. $dotnetPlatforms = $configuration.DOTNET_PLATFORMS.Split(' ', [StringSplitOptions]::RemoveEmptyEntries) foreach ($platform in $dotnetPlatforms) { @@ -479,6 +484,36 @@ class BuildConfiguration { } } + # store all the variables needed when classic xamarin has been enabled + $configuration | Add-Member -NotePropertyName "INCLUDE_XAMARIN_LEGACY" -NotePropertyValue $Env:INCLUDE_XAMARIN_LEGACY + + # if xamarin legacy has been included, check if we need to include the xamarin sdk for each of the platforms, otherewise it will be + # false for all + $xamarinPlatforms = @("ios", "macos", "tvos", "watchos", "maccatalyst") + if ($configuration.INCLUDE_XAMARIN_LEGACY -eq "true") { + foreach ($platform in $xamarinPlatforms) { + $variableName = "INCLUDE_LEGACY_$($platform.ToUpper())" + $variableValue = [Environment]::GetEnvironmentVariable("$variableName") + $configuration | Add-Member -NotePropertyName $variableName -NotePropertyValue $variableValue + } + } else { + foreach ($platform in $xamarinPlatforms) { + $variableName = "INCLUDE_LEGACY_$($platform.ToUpper())" + $configuration | Add-Member -NotePropertyName $variableName -NotePropertyValue "false" + } + } + + # add all the include platforms as well as the nuget os version + foreach ($platform in $xamarinPlatforms) { + $variableName = "INCLUDE_$($platform.ToUpper())" + $variableValue = [Environment]::GetEnvironmentVariable("$variableName") + $configuration | Add-Member -NotePropertyName $variableName -NotePropertyValue $variableValue + + $variableName = "$($platform.ToUpper())__NUGET_OS_VERSION" + $variableValue = [Environment]::GetEnvironmentVariable("$variableName") + $configuration | Add-Member -NotePropertyName $variableName -NotePropertyValue $variableValue + } + # calculate the commit to later share it with the cascade pipelines if ($Env:BUILD_REASON -eq "PullRequest") { $changeId = $configuration.PARENT_BUILD_BUILD_SOURCEBRANCH.Replace("refs/pull/", "").Replace("/merge", "") diff --git a/tools/devops/automation/templates/common/load_configuration.yml b/tools/devops/automation/templates/common/load_configuration.yml new file mode 100644 index 0000000000..5ecac652b1 --- /dev/null +++ b/tools/devops/automation/templates/common/load_configuration.yml @@ -0,0 +1,106 @@ +# yamllint disable rule:line-length +# This job will parse all the labels present in a PR, will set +# the tags for the build AND will set a number of configuration +# variables to be used by the rest of the projects +parameters: + + - name: uploadArtifacts + type: boolean + default: false + + - name: use1ES + type: boolean + default: false + + - name: repositoryAlias + type: string + default: self + + - name: commit + type: string + default: HEAD + + - name: uploadPrefix + type: string + default: '$(MaciosUploadPrefix)' + + - name: testConfigurations + type: object + default: [] + + - name: supportedPlatforms + type: object + default: [] + + - name: testsLabels + type: string + default: '' + + - name: statusContext + type: string + default: '' + +steps: + - template: checkout.yml + parameters: + isPR: true + repositoryAlias: ${{ parameters.repositoryAlias }} + commit: ${{ parameters.commit }} + + - download: macios + displayName: Download Build Config + artifact: build-configuration + + - pwsh: | + Get-ChildItem -Path "$(Pipeline.Workspace)/macios" -Recurse -Force + displayName: 'Display downloads' + timeoutInMinutes: 5 + + - bash: ./xamarin-macios/tools/devops/automation/scripts/bash/configure-platforms.sh + name: configure_platforms + displayName: 'Configure platforms' + + - pwsh: | + Import-Module $Env:SYSTEM_DEFAULTWORKINGDIRECTORY/xamarin-macios/tools/devops/automation/scripts/MaciosCI.psd1 + $jsonPath = Join-Path -Path "$(Build.ArtifactStagingDirectory)" -ChildPath "configuration.json" + Write-Host "##vso[task.setvariable variable=CONFIG_PATH]$jsonPath" + New-BuildConfiguration -ConfigFile $jsonPath + env: + GITHUB_TOKEN: $(GitHub.Token) + ACCESSTOKEN: $(AzDoBuildAccess.Token) + name: labels + displayName: 'Configure build' + + - bash: ./xamarin-macios/tools/devops/automation/scripts/bash/configure-decisions.sh + name: decisions + displayName: 'Make decisions' + + - pwsh: $(System.DefaultWorkingDirectory)/xamarin-macios/tools/devops/automation/scripts/show_env.ps1 + displayName: 'Show Environment' + + - pwsh: | + Import-Module $Env:SYSTEM_DEFAULTWORKINGDIRECTORY/xamarin-macios/tools/devops/automation/scripts/MaciosCI.psd1 + # load the configuration files and set the required variables to be used in the later stages + $configPath = Get-ChildItem -Path "$(Pipeline.Workspace)/macios/build-configuration/configuration.json" -Recurse -Force + $config = Import-BuildConfiguration -ConfigFile $configPath + $testMatrix = $config.TEST_MATRIX + Write-Host "##vso[task.setvariable variable=TEST_MATRIX;isOutput=true]$testMatrix" + name: test_matrix + displayName: 'Create tests strategy matrix' + + # upload config to be consumed later + - ${{ if eq(parameters.uploadArtifacts, true) }}: + - ${{ if eq(parameters.use1ES, true) }}: + - task: 1ES.PublishPipelineArtifact@1 + displayName: 'Publish Artifact: configuration.json' + inputs: + path: '$(Build.ArtifactStagingDirectory)/configuration.json' + artifact: '${{ parameters.uploadPrefix }}build-configuration' + continueOnError: true + - ${{ else }}: + - task: PublishPipelineArtifact@1 + displayName: 'Publish Artifact: configuration.json' + inputs: + targetPath: '$(Build.ArtifactStagingDirectory)/configuration.json' + artifactName: '${{ parameters.uploadPrefix }}build-configuration' + continueOnError: true diff --git a/tools/devops/automation/templates/tests-stage.yml b/tools/devops/automation/templates/tests-stage.yml index b70b751121..10a451545f 100644 --- a/tools/devops/automation/templates/tests-stage.yml +++ b/tools/devops/automation/templates/tests-stage.yml @@ -296,7 +296,7 @@ stages: BRANCH_NAME: $[ replace(variables['Build.SourceBranch'], 'refs/heads/', '') ] steps: - - template: common/configure.yml + - template: common/load_configuration.yml parameters: repositoryAlias: ${{ parameters.repositoryAlias }} commit: ${{ parameters.commit }} From 7325ce8ca8edb6400bda9c4b1fd843772b5fe02e Mon Sep 17 00:00:00 2001 From: Rolf Bjarne Kvinge Date: Mon, 9 Sep 2024 12:25:03 +0200 Subject: [PATCH 3/9] [bgen] Fix compiler warnings. (#21184) And make warnings report as errors, so this doesn't happen again. --- tests/bgen/bgen-tests.csproj | 2 +- tests/generator/BGenTests.cs | 10 +--------- 2 files changed, 2 insertions(+), 10 deletions(-) diff --git a/tests/bgen/bgen-tests.csproj b/tests/bgen/bgen-tests.csproj index e4a9f30070..6ee37f30a0 100644 --- a/tests/bgen/bgen-tests.csproj +++ b/tests/bgen/bgen-tests.csproj @@ -5,7 +5,7 @@ bgen_tests false - Nullable + true diff --git a/tests/generator/BGenTests.cs b/tests/generator/BGenTests.cs index 76ef27f18c..629381f707 100644 --- a/tests/generator/BGenTests.cs +++ b/tests/generator/BGenTests.cs @@ -1701,15 +1701,7 @@ namespace GeneratorTests { public void UnderlyingFieldType (Profile profile) { Configuration.IgnoreIfIgnoredPlatform (profile.AsPlatform ()); - var bgen = BuildFile (profile, true, true, "tests/underlyingfieldtype.cs"); - -#if NET - const string nintName = "System.IntPtr"; - const string nuintName = "System.UIntPtr"; -#else - const string nintName = "System.nint"; - const string nuintName = "System.nuint"; -#endif + BuildFile (profile, true, true, "tests/underlyingfieldtype.cs"); } [Test] From 941ead0ff4c13bc43d85d6f1c137d7e13f099770 Mon Sep 17 00:00:00 2001 From: Rolf Bjarne Kvinge Date: Mon, 9 Sep 2024 14:28:15 +0200 Subject: [PATCH 4/9] [bgen] Fix using types that are in multiple namespaces. (#21182) There's both a Network.NWEndpoint and a NetworkExtension.NWEndpoint, and the generator generates ambiguous code in certain cases. Fix the generator to use the full type reference for such types. --- src/bgen/Caches/NamespaceCache.cs | 5 +++++ src/bgen/Generator.cs | 3 +++ src/bgen/TypeManager.cs | 18 +++++++++++++++++- tests/generator/BGenTests.cs | 7 +++++++ .../tests/types-in-multiple-namespaces.cs | 15 +++++++++++++++ 5 files changed, 47 insertions(+), 1 deletion(-) create mode 100644 tests/generator/tests/types-in-multiple-namespaces.cs diff --git a/src/bgen/Caches/NamespaceCache.cs b/src/bgen/Caches/NamespaceCache.cs index 90463540d3..9ce97d9dc2 100644 --- a/src/bgen/Caches/NamespaceCache.cs +++ b/src/bgen/Caches/NamespaceCache.cs @@ -17,6 +17,7 @@ public class NamespaceCache { public ICollection UINamespaces { get; private set; } public ICollection ImplicitNamespaces { get; private set; } public ICollection NamespacesThatConflictWithTypes { get; private set; } + public ICollection TypesInMultipleNamespaces { get; private set; } public NamespaceCache (PlatformName currentPlatform, string customObjCRuntimeNS, bool skipSystemDrawing) { @@ -154,6 +155,10 @@ public class NamespaceCache { "AudioUnit", }; + TypesInMultipleNamespaces = new HashSet { + "NWEndpoint", // Both in Network and NetworkExtension + }; + if (!skipSystemDrawing) ImplicitNamespaces.Add ("System.Drawing"); } diff --git a/src/bgen/Generator.cs b/src/bgen/Generator.cs index 8c97f6c1fc..05ce9781c4 100644 --- a/src/bgen/Generator.cs +++ b/src/bgen/Generator.cs @@ -894,6 +894,9 @@ public partial class Generator : IMemberGatherer { return safe_name + ".Handle"; } + if (TypeCache.INativeObject.IsAssignableFrom (pi.ParameterType)) + return $"{safe_name}.GetHandle ()"; + // This means you need to add a new MarshalType in the method "Go" throw new BindingException (1002, true, pi.ParameterType.FullName, mi.DeclaringType.FullName, mi.Name.GetSafeParamName ()); } diff --git a/src/bgen/TypeManager.cs b/src/bgen/TypeManager.cs index 2cdc7a1238..a608bf7534 100644 --- a/src/bgen/TypeManager.cs +++ b/src/bgen/TypeManager.cs @@ -300,12 +300,17 @@ public class TypeManager { if (t.Namespace is not null) { string ns = t.Namespace; - if (NamespaceCache.ImplicitNamespaces.Contains (ns) || t.IsGenericType) { + var isImplicitNamespace = NamespaceCache.ImplicitNamespaces.Contains (ns); + var isInMultipleNamespaces = IsInMultipleNamespaces (t); + var nonGlobalCandidate = isImplicitNamespace && !isInMultipleNamespaces; + if (nonGlobalCandidate || t.IsGenericType) { var targs = t.GetGenericArguments (); if (targs.Length == 0) return t.Name + nullable; return $"global::{t.Namespace}." + t.Name.RemoveArity () + "<" + string.Join (", ", targs.Select (l => FormatTypeUsedIn (null, l)).ToArray ()) + ">" + nullable; } + if (isInMultipleNamespaces) + return "global::" + t.FullName + nullable; if (NamespaceCache.NamespacesThatConflictWithTypes.Contains (ns)) return "global::" + t.FullName + nullable; if (t.Name == t.Namespace) @@ -317,6 +322,17 @@ public class TypeManager { return t.FullName + nullable; } + bool IsInMultipleNamespaces (Type? type) + { + if (type is null) + return false; + + if (NamespaceCache.TypesInMultipleNamespaces.Contains (type.Name)) + return true; + + return IsInMultipleNamespaces (type.GetElementType ()); + } + // TODO: If we ever have an API with nested properties of the same name more than // 2 deep, we'll need to have this return a list of PropertyInfo and comb through them all. public PropertyInfo? GetParentTypeWithSameNamedProperty (BaseTypeAttribute bta, string propertyName) diff --git a/tests/generator/BGenTests.cs b/tests/generator/BGenTests.cs index 629381f707..3295ffd1e6 100644 --- a/tests/generator/BGenTests.cs +++ b/tests/generator/BGenTests.cs @@ -526,6 +526,13 @@ namespace GeneratorTests { BuildFile (Profile.iOS, "sof20696157.cs"); } + [Test] + [TestCase (Profile.iOS)] + public void TypesInMultipleNamespaces (Profile profile) + { + BuildFile (profile, "tests/types-in-multiple-namespaces.cs"); + } + [Test] public void HyphenInName () { diff --git a/tests/generator/tests/types-in-multiple-namespaces.cs b/tests/generator/tests/types-in-multiple-namespaces.cs new file mode 100644 index 0000000000..37fae9e134 --- /dev/null +++ b/tests/generator/tests/types-in-multiple-namespaces.cs @@ -0,0 +1,15 @@ +using System; + +using CoreFoundation; +using Foundation; +using ObjCRuntime; + +namespace NS { + delegate void D1 ([NullAllowed] Network.NWEndpoint remoteEndpoints); + + [BaseType (typeof (NSObject))] + interface TypesInMultipleNamespaces { + [Export ("someProperty")] + D1 SomeProperty { get; set; } + } +} From d909174f47bc976d6baa48f8def3df30fe1ea3c4 Mon Sep 17 00:00:00 2001 From: Rolf Bjarne Kvinge Date: Mon, 9 Sep 2024 15:03:14 +0200 Subject: [PATCH 5/9] [tests] Make the simulator the default runtime identifier when running test suites from the command line. (#21194) Because simulator is where we most commonly run tests. And hardcode arm64 - if x64 is ever needed, and I'm bugged enough to add auto-detection, I'll do it then. --- tests/common/shared-dotnet.mk | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/common/shared-dotnet.mk b/tests/common/shared-dotnet.mk index 9950843027..91caa4161a 100644 --- a/tests/common/shared-dotnet.mk +++ b/tests/common/shared-dotnet.mk @@ -78,9 +78,9 @@ endif ifeq ($(RID),) ifeq ($(PLATFORM),iOS) -RID=ios-arm64 +RID=iossimulator-arm64 else ifeq ($(PLATFORM),tvOS) -RID=tvos-arm64 +RID=tvossimulator-arm64 else ifeq ($(PLATFORM),MacCatalyst) ifeq ($(CONFIG),Release) RID=maccatalyst-x64;maccatalyst-arm64 From ef077323f3a156f7c0eff54357a0710ef4677884 Mon Sep 17 00:00:00 2001 From: Rolf Bjarne Kvinge Date: Mon, 9 Sep 2024 15:25:38 +0200 Subject: [PATCH 6/9] [bgen] Fix using arrays of INativeObjects in delegate signatures. (#21183) --- src/bgen/Generator.cs | 5 +++++ tests/generator/BGenTests.cs | 8 ++++++++ .../tests/inativeobject-arrays-in-blocks.cs | 16 ++++++++++++++++ 3 files changed, 29 insertions(+) create mode 100644 tests/generator/tests/inativeobject-arrays-in-blocks.cs diff --git a/src/bgen/Generator.cs b/src/bgen/Generator.cs index 05ce9781c4..bf32f444af 100644 --- a/src/bgen/Generator.cs +++ b/src/bgen/Generator.cs @@ -716,6 +716,11 @@ public partial class Generator : IMemberGatherer { invoke.AppendFormat ("CFArray.ArrayFromHandle<{0}> ({1})!", TypeManager.FormatType (null, et), safe_name); continue; } + if (TypeCache.INativeObject.IsAssignableFrom (et)) { + pars.Add (new TrampolineParameterInfo (NativeHandleType, safe_name)); + invoke.AppendFormat ("NSArray.ArrayFromHandle<{0}> ({1})!", TypeManager.FormatType (t, et), safe_name); + continue; + } } if (pi.ParameterType.IsPointer && pi.ParameterType.GetElementType ().IsValueType) { diff --git a/tests/generator/BGenTests.cs b/tests/generator/BGenTests.cs index 3295ffd1e6..556946c22d 100644 --- a/tests/generator/BGenTests.cs +++ b/tests/generator/BGenTests.cs @@ -605,6 +605,14 @@ namespace GeneratorTests { BuildFile (Profile.iOS, "multiple-api-definitions2-a.cs", "multiple-api-definitions2-b.cs"); } + + [Test] + [TestCase (Profile.iOS)] + public void INativeObjectArraysInBlocks (Profile profile) + { + BuildFile (profile, "tests/inativeobject-arrays-in-blocks.cs"); + } + [Test] [TestCase (Profile.iOS)] public void ClassNameCollision (Profile profile) diff --git a/tests/generator/tests/inativeobject-arrays-in-blocks.cs b/tests/generator/tests/inativeobject-arrays-in-blocks.cs new file mode 100644 index 0000000000..076485892f --- /dev/null +++ b/tests/generator/tests/inativeobject-arrays-in-blocks.cs @@ -0,0 +1,16 @@ +using System; + +using CoreFoundation; +using CoreVideo; +using Foundation; +using ObjCRuntime; + +namespace NS { + delegate void NEDatagramAndFlowEndpointsRead ([NullAllowed] CVPixelBuffer [] remoteEndpoints); + + [BaseType (typeof (NSObject))] + interface INativeObjectInBlocks { + [Export ("someOtherProperty")] + NEDatagramAndFlowEndpointsRead SomeOtherProperty { get; set; } + } +} From 71d7d64dd91d3df152245c720fabfb76f973c48d Mon Sep 17 00:00:00 2001 From: Rolf Bjarne Kvinge Date: Mon, 9 Sep 2024 16:42:16 +0200 Subject: [PATCH 7/9] [actions] There's no reason to keep testing legacy for single platform release branch testing. (#21201) --- .github/workflows/update-single-platform-branches.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/update-single-platform-branches.yml b/.github/workflows/update-single-platform-branches.yml index fec038ae61..0a0deab61f 100644 --- a/.github/workflows/update-single-platform-branches.yml +++ b/.github/workflows/update-single-platform-branches.yml @@ -28,7 +28,7 @@ jobs: set -ex git config user.email "github-actions-single-platform-branch-updater@xamarin.com" git config user.name "GitHub Actions Single Platform Branch Updater" - for platform in dotnet-iOS dotnet-tvOS dotnet-MacCatalyst dotnet-macOS dotnet legacy legacy-iOS legacy-macOS; do + for platform in dotnet-iOS dotnet-tvOS dotnet-MacCatalyst dotnet-macOS dotnet; do git checkout -b release-test/only-$platform origin/release-test/only-$platform git merge origin/main git push From ec7538047d5a2eda6432a1fdd911ccfc05511349 Mon Sep 17 00:00:00 2001 From: Rolf Bjarne Kvinge Date: Tue, 10 Sep 2024 11:49:44 +0200 Subject: [PATCH 8/9] [system-dependencies.sh] We don't need the watchOS simulator anymore. (#21203) --- system-dependencies.sh | 2 -- 1 file changed, 2 deletions(-) diff --git a/system-dependencies.sh b/system-dependencies.sh index 4ee34b8661..730279a1bc 100755 --- a/system-dependencies.sh +++ b/system-dependencies.sh @@ -316,8 +316,6 @@ function xcodebuild_download_selected_platforms () "$XCODE_DEVELOPER_ROOT/usr/bin/xcodebuild" -downloadPlatform iOS log "Executing '$XCODE_DEVELOPER_ROOT/usr/bin/xcodebuild -downloadPlatform tvOS' $1" "$XCODE_DEVELOPER_ROOT/usr/bin/xcodebuild" -downloadPlatform tvOS - log "Executing '$XCODE_DEVELOPER_ROOT/usr/bin/xcodebuild -downloadPlatform watchOS' $1" - "$XCODE_DEVELOPER_ROOT/usr/bin/xcodebuild" -downloadPlatform watchOS } function download_xcode_platforms () From 39459a2352db1de03a147e2c906d19d454ebeb59 Mon Sep 17 00:00:00 2001 From: Rolf Bjarne Kvinge Date: Tue, 10 Sep 2024 18:59:05 +0200 Subject: [PATCH 9/9] [bgen] Fix detecting NSObject types and generating block code with types that aren't NSObjects. (#21181) --- src/bgen/Generator.cs | 21 +++++++++++++++++-- tests/generator/BGenTests.cs | 14 +++++++++++++ tests/generator/BGenTool.cs | 14 +++++++++++++ .../tests/inativeobjects-in-blocks-sources.cs | 9 ++++++++ .../tests/inativeobjects-in-blocks.cs | 21 +++++++++++++++++++ 5 files changed, 77 insertions(+), 2 deletions(-) create mode 100644 tests/generator/tests/inativeobjects-in-blocks-sources.cs create mode 100644 tests/generator/tests/inativeobjects-in-blocks.cs diff --git a/src/bgen/Generator.cs b/src/bgen/Generator.cs index bf32f444af..30e546003d 100644 --- a/src/bgen/Generator.cs +++ b/src/bgen/Generator.cs @@ -167,7 +167,22 @@ public partial class Generator : IMemberGatherer { return false; } - return type.IsInterface; + // If any of the interfaces this type implements is an NSObject, + // then this type is also an NSObject + var ifaces = type.GetInterfaces (); + foreach (var iface in ifaces) + if (IsNSObject (iface)) + return true; + + if (type.IsInterface) { + var bta = ReflectionExtensions.GetBaseTypeAttribute (type, this); + if (bta?.BaseType is not null) + return IsNSObject (bta.BaseType); + + return false; + } + + return false; } public string PrimitiveType (Type t, bool formatted = false) @@ -604,8 +619,10 @@ public partial class Generator : IMemberGatherer { invoke.AppendFormat (" Runtime.GetINativeObject<{1}> ({0}, false)!", safe_name, pi.ParameterType); } else if (isForced) { invoke.AppendFormat (" Runtime.GetINativeObject<{1}> ({0}, true, {2})!", safe_name, TypeManager.RenderType (pi.ParameterType), isForcedOwns); - } else { + } else if (IsNSObject (pi.ParameterType)) { invoke.AppendFormat (" Runtime.GetNSObject<{1}> ({0})!", safe_name, TypeManager.RenderType (pi.ParameterType)); + } else { + invoke.AppendFormat (" Runtime.GetINativeObject<{1}> ({0}, false)!", safe_name, TypeManager.RenderType (pi.ParameterType)); } continue; } diff --git a/tests/generator/BGenTests.cs b/tests/generator/BGenTests.cs index 556946c22d..ffd40b0ed3 100644 --- a/tests/generator/BGenTests.cs +++ b/tests/generator/BGenTests.cs @@ -404,6 +404,20 @@ namespace GeneratorTests { Assert.AreEqual (expectedAttributes, renderedAttributes, "Introduced attributes"); } + [Test] + [TestCase (Profile.iOS)] + public void INativeObjectsInBlocks (Profile profile) + { + var bgen = new BGenTool (); + bgen.Profile = profile; + bgen.Defines = BGenTool.GetDefaultDefines (bgen.Profile); + bgen.AddTestApiDefinition ("tests/inativeobjects-in-blocks.cs"); + bgen.AddExtraSourcesRelativeToGeneratorDirectory ("tests/inativeobjects-in-blocks-sources.cs"); + bgen.CreateTemporaryBinding (); + bgen.AssertExecute ("build"); + bgen.AssertNoWarnings (); + } + [Test] public void Bug36457 () { diff --git a/tests/generator/BGenTool.cs b/tests/generator/BGenTool.cs index 681ba2003b..1bbf9ea397 100644 --- a/tests/generator/BGenTool.cs +++ b/tests/generator/BGenTool.cs @@ -26,6 +26,7 @@ namespace Xamarin.Tests { public List ApiDefinitions = new List (); public List Sources = new List (); + public List ExtraSources = new List (); public List References = new List (); #if NET public List? CompileCommand = null; @@ -71,6 +72,16 @@ namespace Xamarin.Tests { ApiDefinitions.Add (Path.Combine (Configuration.SourceRoot, "tests", "generator", filename)); } + public void AddExtraSourcesRelativeToGeneratorDirectory (string pathRelativeToGeneratorDirectory) + { + ExtraSources.Add (GetFullPathRelativeToGeneratorDirectory (pathRelativeToGeneratorDirectory)); + } + + public string GetFullPathRelativeToGeneratorDirectory (string pathRelativeToGeneratorDirectory) + { + return Path.Combine (Configuration.SourceRoot, "tests", "generator", pathRelativeToGeneratorDirectory); + } + public AssemblyDefinition ApiAssembly { get { return LoadAssembly (); @@ -169,6 +180,9 @@ namespace Xamarin.Tests { foreach (var s in Sources) sb.Add ($"-s={s}"); + foreach (var x in ExtraSources) + sb.Add ($"-x={x}"); + if (ReferenceBclByDefault) { if (tf is null) { // do nothing diff --git a/tests/generator/tests/inativeobjects-in-blocks-sources.cs b/tests/generator/tests/inativeobjects-in-blocks-sources.cs new file mode 100644 index 0000000000..c2ce8653b9 --- /dev/null +++ b/tests/generator/tests/inativeobjects-in-blocks-sources.cs @@ -0,0 +1,9 @@ +using System; + +using CoreFoundation; +using Foundation; +using ObjCRuntime; + +namespace NS { + public partial class DispatchData2 : NativeObject { } +} diff --git a/tests/generator/tests/inativeobjects-in-blocks.cs b/tests/generator/tests/inativeobjects-in-blocks.cs new file mode 100644 index 0000000000..3a340ef899 --- /dev/null +++ b/tests/generator/tests/inativeobjects-in-blocks.cs @@ -0,0 +1,21 @@ +using System; + +using CoreFoundation; +using Foundation; +using ObjCRuntime; + +namespace NS { + + [Partial] + interface DispatchData2 { + } + + delegate void DispatchB (DispatchData2 data); + delegate void DispatchA (DispatchData2 data, [BlockCallback] DispatchB dispatch); + + [BaseType (typeof (NSObject))] + interface INativeObjectInBlocks { + [Export ("someProperty")] + DispatchA SomeProperty { get; set; } + } +}