From e9e4072f945002c7e4e2eb0b8f5a34f0477e777e Mon Sep 17 00:00:00 2001
From: "dotnet-maestro[bot]"
<42748379+dotnet-maestro[bot]@users.noreply.github.com>
Date: Tue, 15 Oct 2024 09:16:32 +0200
Subject: [PATCH 01/18] [main] Update dependencies from dotnet/xharness
(#21431)
This pull request updates the following dependencies
## From https://github.com/dotnet/xharness
- **Subscription**: 601bc5e1-1cae-44b5-cf5f-08db9342aa2f
- **Build**: 20241011.1
- **Date Produced**: October 11, 2024 7:48:41 AM UTC
- **Commit**: 8c6d5afd99c713777165f4378462085a5679c223
- **Branch**: refs/heads/main
- **Updates**:
- **Microsoft.DotNet.XHarness.iOS.Shared**: [from 10.0.0-prerelease.24509.1 to 10.0.0-prerelease.24511.1][1]
[1]: https://github.com/dotnet/xharness/compare/973ef6c89b...8c6d5afd99
---
eng/Version.Details.xml | 4 ++--
eng/Versions.props | 2 +-
2 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml
index 9c0d8f07d2c4..a345502ac12f 100644
--- a/eng/Version.Details.xml
+++ b/eng/Version.Details.xml
@@ -78,9 +78,9 @@
https://github.com/dotnet/templating
-
+
https://github.com/dotnet/xharness
- 973ef6c89b67f2f746f62c413e3aeeb01a9034a3
+ 8c6d5afd99c713777165f4378462085a5679c223
diff --git a/eng/Versions.props b/eng/Versions.props
index e186c008dee2..e56d65115684 100644
--- a/eng/Versions.props
+++ b/eng/Versions.props
@@ -12,7 +12,7 @@
9.0.0-rc.2.24462.10
7.0.100-alpha.1.21601.1
0.11.5-alpha.24467.1
- 10.0.0-prerelease.24509.1
+ 10.0.0-prerelease.24511.1
$(MicrosoftNETWorkloadEmscriptenCurrentManifest80100Version)
$(MicrosoftNETWorkloadEmscriptenCurrentManifest80100Version)
From 395aca6e74b75c295417bdc36e6839d89aa6aef7 Mon Sep 17 00:00:00 2001
From: Rolf Bjarne Kvinge
Date: Tue, 15 Oct 2024 09:24:29 +0200
Subject: [PATCH 02/18] [compare-commits] Simplify comment about unclean
working directory. (#21433)
---
tools/compare-commits.sh | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/tools/compare-commits.sh b/tools/compare-commits.sh
index ab9b7c6c337d..71b34510ba0c 100755
--- a/tools/compare-commits.sh
+++ b/tools/compare-commits.sh
@@ -221,10 +221,10 @@ mkdir -p "$(dirname "$GH_COMMENTS_FILE")"
if test -z "$SKIP_DIRTY_CHECK"; then
if [ -n "$(git status --porcelain --ignore-submodule)" ]; then
- report_error_line "${RED}** Error: Working directory isn't clean:${CLEAR}"
+ report_error_line "${RED}** Error: Working directory isn't clean - check build log for more information.${CLEAR}"
# The funny GIT_COLOR_P syntax is explained here: https://stackoverflow.com/a/61551944/183422
- git ${GIT_COLOR_P[@]+"${GIT_COLOR_P[@]}"} status --ignore-submodules | sed 's/^/ /' | while read -r line; do report_error_line "$line"; done || true
- git ${GIT_COLOR_P[@]+"${GIT_COLOR_P[@]}"} diff --ignore-submodules | sed 's/^/ /' | while read -r line; do report_error_line "$line"; done || true
+ git ${GIT_COLOR_P[@]+"${GIT_COLOR_P[@]}"} status --ignore-submodules | sed 's/^/ /' || true
+ git ${GIT_COLOR_P[@]+"${GIT_COLOR_P[@]}"} diff --ignore-submodules | sed 's/^/ /' || true
exit 1
fi
fi
From e63de079a67866121ad9464349d91a839573d357 Mon Sep 17 00:00:00 2001
From: Rolf Bjarne Kvinge
Date: Tue, 15 Oct 2024 09:24:47 +0200
Subject: [PATCH 03/18] [tests] Remove dead code. (#21422)
This logic was intented to zip up the .NET unit tests to run them on Windows,
but in the end we went with a different approach that doesn't require zipping.
---
tests/Makefile | 8 -------
tests/package-dotnet-tests.sh | 45 -----------------------------------
2 files changed, 53 deletions(-)
delete mode 100755 tests/package-dotnet-tests.sh
diff --git a/tests/Makefile b/tests/Makefile
index f13e4860ebe9..9f9a6d770f63 100644
--- a/tests/Makefile
+++ b/tests/Makefile
@@ -240,14 +240,6 @@ else
@echo Not enabled
endif
-ifdef INCLUDE_DOTNET
-dotnet-test-package.7z:
- ./package-dotnet-tests.sh
-else
-dotnet-test-package.7z:
- @echo Not enabled
-endif
-
#XI
ifdef INCLUDE_IOS
wrench-mtouch:
diff --git a/tests/package-dotnet-tests.sh b/tests/package-dotnet-tests.sh
deleted file mode 100755
index b22146d9a783..000000000000
--- a/tests/package-dotnet-tests.sh
+++ /dev/null
@@ -1,45 +0,0 @@
-#!/bin/bash -ex
-
-cd "$(dirname "${BASH_SOURCE[0]}")"
-
-# Clone files instead of copying them on APFS file systems. Much faster.
-CP="cp"
-if df -t apfs / >/dev/null 2>&1; then
- CP="cp -c"
-fi
-
-#git clean -xfdq
-
-rm -Rf "$(pwd)/dotnet-test-package"
-DIR=$(pwd)/dotnet-test-package/xamarin-macios
-ZIP=$DIR.7z
-mkdir -p $DIR
-mkdir -p $DIR/tests/dotnet/UnitTests/bin/Debug/net5.0/
-mkdir -p $DIR/.git
-
-make -j8
-make -C dotnet/UnitTests publish
-
-$CP -r dotnet $DIR/tests/
-rm -Rf $DIR/tests/dotnet/packages
-
-# Various files to make 'make' work
-$CP -p ../Make.config $DIR
-$CP -p ../Make.versions $DIR
-$CP -p ../Make.config $DIR
-mkdir -p $DIR/mk
-$CP -p ../Make.config $DIR
-$CP -p ../mk/subdirs.mk $DIR/mk
-$CP -p ../mk/rules.mk $DIR/mk
-$CP -p ../mk/quiet.mk $DIR/mk
-$CP -p ../mk/mono.mk "$DIR/mk"
-
-# Files to make the unit tests run
-$CP -p ../global.json $DIR
-$CP -p ../NuGet.config $DIR
-$CP -p test.config $DIR/tests
-
-# Zip it all up
-rm -f dotnet-test-package.7z
-cd dotnet-test-package
-7z a ../dotnet-test-package.7z *
From a10899ef62a112e3b270078ea1b98dc3a1eb21be Mon Sep 17 00:00:00 2001
From: Rolf Bjarne Kvinge
Date: Tue, 15 Oct 2024 09:25:03 +0200
Subject: [PATCH 04/18] [tests] Improve failure message when a process times
out. (#21429)
---
tests/common/DotNet.cs | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/tests/common/DotNet.cs b/tests/common/DotNet.cs
index 15be67b95b77..0f1f37d81b55 100644
--- a/tests/common/DotNet.cs
+++ b/tests/common/DotNet.cs
@@ -270,7 +270,11 @@ public static ExecutionResult Execute (string verb, string project, Dictionary
Date: Tue, 15 Oct 2024 09:25:21 +0200
Subject: [PATCH 05/18] [tests] Ignore output that looks like errors when
installing .NET on Windows. (#21430)
Just trust the exit code instead.
This way the installation doesn't fail due to random output.
---
tests/dotnet/Windows/InstallDotNet.csproj | 1 +
1 file changed, 1 insertion(+)
diff --git a/tests/dotnet/Windows/InstallDotNet.csproj b/tests/dotnet/Windows/InstallDotNet.csproj
index 2f208f0f270d..3fdd23ec26eb 100644
--- a/tests/dotnet/Windows/InstallDotNet.csproj
+++ b/tests/dotnet/Windows/InstallDotNet.csproj
@@ -171,6 +171,7 @@
Command=""$(DotNetToolPath)" workload install %(_WorkloadIds.Identity) --skip-manifest-update --verbosity diag --temp-dir "$(DotNetTempDirectory)" --configfile "$(MacIosRootDirectory)NuGet.config" --skip-sign-check"
WorkingDirectory="$(MSBuildThisFileDirectory)"
EnvironmentVariables="DOTNET_MULTILEVEL_LOOKUP=0"
+ IgnoreStandardErrorWarningFormat="true"
/>
From 209de6f29755c66a80ac3c01961b8f7390886e69 Mon Sep 17 00:00:00 2001
From: Rolf Bjarne Kvinge
Date: Tue, 15 Oct 2024 09:25:44 +0200
Subject: [PATCH 06/18] [devops] Fix calling the show_bot_info.ps1 script.
(#21428)
---
tools/devops/automation/templates/windows/reserve-mac.yml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/tools/devops/automation/templates/windows/reserve-mac.yml b/tools/devops/automation/templates/windows/reserve-mac.yml
index 8298a73c0da2..83ab5a98fb4a 100644
--- a/tools/devops/automation/templates/windows/reserve-mac.yml
+++ b/tools/devops/automation/templates/windows/reserve-mac.yml
@@ -33,7 +33,7 @@ steps:
- checkout: maccore
persistCredentials: true # hugely important, else there are some scripts that check a single file from maccore that will fail
-- pwsh: '"$Env:SYSTEM_DEFAULTWORKINGDIRECTORY/$($Env:BUILD_REPOSITORY_NAME.Split(''/'')[1])/tools/devops/automation/scripts/show_bot_info.ps1"'
+- pwsh: '& "$Env:SYSTEM_DEFAULTWORKINGDIRECTORY/$($Env:BUILD_REPOSITORY_NAME.Split(''/'')[1])/tools/devops/automation/scripts/show_bot_info.ps1"'
displayName: 'Show Bot Info'
- bash: '$SYSTEM_DEFAULTWORKINGDIRECTORY/${BUILD_REPOSITORY_NAME/#*\//}/tools/devops/automation/scripts/bash/clean-bot.sh'
From 6abfff689043beb50256e02ab832f7f42cb66f6b Mon Sep 17 00:00:00 2001
From: Manuel de la Pena
Date: Tue, 15 Oct 2024 10:00:20 -0400
Subject: [PATCH 07/18] [CI] Remove the APIScan stage since we have a pipeline
to run it. (#21432)
In the process of ensuring that we can run tests a single time, we are
removing all extra stages from the CI. We have move the APIScan to the
following pipelines.
- CI Pipeline:
https://devdiv.visualstudio.com/DevDiv/_build?definitionId=24050
- PR Pipeline:
https://devdiv.visualstudio.com/DevDiv/_build?definitionId=24049
---
tools/devops/automation/templates/main-stage.yml | 8 --------
1 file changed, 8 deletions(-)
diff --git a/tools/devops/automation/templates/main-stage.yml b/tools/devops/automation/templates/main-stage.yml
index f8b10cb71838..9a53e3f0e5de 100644
--- a/tools/devops/automation/templates/main-stage.yml
+++ b/tools/devops/automation/templates/main-stage.yml
@@ -186,14 +186,6 @@ parameters:
stages:
- - ${{ if eq(parameters.runGovernanceTests, true) }}:
- - template: ./governance/stage.yml
- parameters:
- isPR: ${{ parameters.isPR }}
- repositoryAlias: ${{ parameters.repositoryAlias }}
- commit: ${{ parameters.commit }}
- stageDisplayNamePrefix: ${{ parameters.stageDisplayNamePrefix }}
-
- stage: configure_build
displayName: '${{ parameters.stageDisplayNamePrefix }}Configure'
dependsOn: ${{ parameters.dependsOn }}
From 0f35909d56ea0055457a89ba3879649d6d0d632c Mon Sep 17 00:00:00 2001
From: Manuel de la Pena
Date: Tue, 15 Oct 2024 14:56:09 -0400
Subject: [PATCH 08/18] [RGen] First inclusion of a roslyn generator for the
bindings. (#21389)
We are doing the following:
1. Adding the rgen directory with the following solutions:
* Analyzer: Analyzer that will catch errors in the bindings. At the
moment it provides a single error when the BindingTypeAttribute is used
in a nont partial type.
* Analyzer Tests: Allows tests for the analyzer.
* Analyzer Sample: Sample project to test the analyzer.
* Code Generator: A code generator that adds the BindingTypeAttribute to
the compilcation.
* Code Generator Tests: Allows tests for the generator.
* Code Sample: Sample project for the code generator.
2. Make rule to build the roslyn code generator.
3. Makefile changes to add the code generator as part as the second
compilation of the bindings.
This changes add the starting gounds to move to roslyn.
---------
Co-authored-by: GitHub Actions Autoformatter
Co-authored-by: Rolf Bjarne Kvinge
Co-authored-by: Alex Soto
---
docs/preview-apis.md | 7 +
src/Makefile | 6 +-
src/Makefile.rgenerator | 8 +
src/ObjCBindings/BindingTypeAttribute.cs | 25 +++
src/frameworks.sources | 1 +
.../Examples.cs | 12 ++
...oft.Macios.Bindings.Analyzer.Sample.csproj | 19 ++
.../AnalyzerReleases.Shipped.md | 7 +
.../AnalyzerReleases.Unshipped.md | 4 +
.../BindingTypeCodeFixProvider.cs | 59 ++++++
.../BindingTypeSemanticAnalyzer.cs | 72 ++++++++
.../Microsoft.Macios.Bindings.Analyzer.csproj | 46 +++++
.../Properties/launchSettings.json | 9 +
.../Readme.md | 26 +++
.../Resources.Designer.cs | 96 ++++++++++
.../Resources.resx | 37 ++++
.../Microsoft.Macios.Generator.Sample.csproj | 19 ++
.../SampleBinding.cs | 9 +
.../BindingSourceGeneratorGenerator.cs | 24 +++
.../ExtraSources.cs | 5 +
.../Microsoft.Macios.Generator.csproj | 26 +++
.../Properties/launchSettings.json | 9 +
src/rgen/Microsoft.Macios.Generator/Readme.md | 21 +++
src/rgen/rgen.sln | 46 +++++
tests/bgen/bgen-tests.csproj | 3 +
.../Documentation.KnownFailures.txt | 1 +
tests/cecil-tests/cecil-tests.csproj | 3 +
tests/common/Configuration.cs | 151 +--------------
tests/common/ConfigurationNUnit.cs | 172 ++++++++++++++++++
tests/common/ConfigurationXUnit.cs | 57 ++++++
tests/common/ExecutionHelper.cs | 4 -
tests/common/mac/project_building.mk | 1 +
tests/dotnet/UnitTests/DotNetUnitTests.csproj | 3 +
tests/generator/generator-tests.csproj | 3 +
tests/introspection/ApiFrameworkTest.cs | 3 +
tests/mmptest/mmptest.csproj | 3 +
.../dotnet/macOS/monotouch-test.csproj | 3 +
.../Xamarin.MacDev.Tasks.Tests.csproj | 3 +
.../Xamarin.MacDev.Tests.csproj | 3 +
tests/mtouch/mtouchtests.csproj | 3 +
.../BaseGeneratorWithAnalyzerTestClass.cs | 35 ++++
.../BindingTypeSemanticAnalyzerTests.cs | 36 ++++
...soft.Macios.Bindings.Analyzer.Tests.csproj | 27 +++
.../BaseGeneratorTestClass.cs | 70 +++++++
.../BaseTestDataGenerator.cs | 13 ++
.../BindingSourceGeneratorGeneratorTests.cs | 44 +++++
.../Microsoft.Macios.Generator.Tests.csproj | 59 ++++++
tests/xammac_tests/xammac_tests.csproj | 3 +
tests/xharness/Jenkins/Jenkins.cs | 36 ++++
49 files changed, 1176 insertions(+), 156 deletions(-)
create mode 100644 src/Makefile.rgenerator
create mode 100644 src/ObjCBindings/BindingTypeAttribute.cs
create mode 100644 src/rgen/Microsoft.Macios.Bindings.Analyzer.Sample/Examples.cs
create mode 100644 src/rgen/Microsoft.Macios.Bindings.Analyzer.Sample/Microsoft.Macios.Bindings.Analyzer.Sample.csproj
create mode 100644 src/rgen/Microsoft.Macios.Bindings.Analyzer/AnalyzerReleases.Shipped.md
create mode 100644 src/rgen/Microsoft.Macios.Bindings.Analyzer/AnalyzerReleases.Unshipped.md
create mode 100644 src/rgen/Microsoft.Macios.Bindings.Analyzer/BindingTypeCodeFixProvider.cs
create mode 100644 src/rgen/Microsoft.Macios.Bindings.Analyzer/BindingTypeSemanticAnalyzer.cs
create mode 100644 src/rgen/Microsoft.Macios.Bindings.Analyzer/Microsoft.Macios.Bindings.Analyzer.csproj
create mode 100644 src/rgen/Microsoft.Macios.Bindings.Analyzer/Properties/launchSettings.json
create mode 100644 src/rgen/Microsoft.Macios.Bindings.Analyzer/Readme.md
create mode 100644 src/rgen/Microsoft.Macios.Bindings.Analyzer/Resources.Designer.cs
create mode 100644 src/rgen/Microsoft.Macios.Bindings.Analyzer/Resources.resx
create mode 100644 src/rgen/Microsoft.Macios.Generator.Sample/Microsoft.Macios.Generator.Sample.csproj
create mode 100644 src/rgen/Microsoft.Macios.Generator.Sample/SampleBinding.cs
create mode 100644 src/rgen/Microsoft.Macios.Generator/BindingSourceGeneratorGenerator.cs
create mode 100644 src/rgen/Microsoft.Macios.Generator/ExtraSources.cs
create mode 100644 src/rgen/Microsoft.Macios.Generator/Microsoft.Macios.Generator.csproj
create mode 100644 src/rgen/Microsoft.Macios.Generator/Properties/launchSettings.json
create mode 100644 src/rgen/Microsoft.Macios.Generator/Readme.md
create mode 100644 src/rgen/rgen.sln
create mode 100644 tests/common/ConfigurationNUnit.cs
create mode 100644 tests/common/ConfigurationXUnit.cs
create mode 100644 tests/rgen/Microsoft.Macios.Bindings.Analyzer.Tests/BaseGeneratorWithAnalyzerTestClass.cs
create mode 100644 tests/rgen/Microsoft.Macios.Bindings.Analyzer.Tests/BindingTypeSemanticAnalyzerTests.cs
create mode 100644 tests/rgen/Microsoft.Macios.Bindings.Analyzer.Tests/Microsoft.Macios.Bindings.Analyzer.Tests.csproj
create mode 100644 tests/rgen/Microsoft.Macios.Generator.Tests/BaseGeneratorTestClass.cs
create mode 100644 tests/rgen/Microsoft.Macios.Generator.Tests/BaseTestDataGenerator.cs
create mode 100644 tests/rgen/Microsoft.Macios.Generator.Tests/BindingSourceGeneratorGeneratorTests.cs
create mode 100644 tests/rgen/Microsoft.Macios.Generator.Tests/Microsoft.Macios.Generator.Tests.csproj
diff --git a/docs/preview-apis.md b/docs/preview-apis.md
index e056d55a8bac..99f5b1d61049 100644
--- a/docs/preview-apis.md
+++ b/docs/preview-apis.md
@@ -97,3 +97,10 @@ We've tentatively set .NET 11 as the release when we'll stop marking FSKit as pr
The diagnostic id for FSKit is APL0002.
[1]: https://learn.microsoft.com/en-us/dotnet/api/system.diagnostics.codeanalysis.experimentalattribute?view=net-8.0
+
+## Rgen (APL0003)
+
+Rgen is the new Roslyn codegenerator based binding tool. The tool is underdevelopment and its API is open to change until
+a stable release is announced.
+
+The diagnostic id for Rgen is APL0003.
diff --git a/src/Makefile b/src/Makefile
index ea2a4162dcb4..bb088101958c 100644
--- a/src/Makefile
+++ b/src/Makefile
@@ -103,6 +103,7 @@ DOTNET_WARNINGS_TO_FIX = -nowarn:$(CSC_WARNINGS_TO_FIX)
DOTNET_CORE_WARNINGS_TO_FIX = -nowarn:$(CSC_WARNINGS_TO_FIX),$(BGEN_WARNINGS_TO_FIX)
include ./Makefile.generator
+include ./Makefile.rgenerator
include ./generator-diff.mk
SHARED_RESX = $(TOP)/tools/mtouch/Errors.resx
@@ -355,7 +356,7 @@ $($(2)_DOTNET_BUILD_DIR)/core-$(3).dll: $($(2)_DOTNET_CORE_SOURCES) frameworks.s
$($(2)_DOTNET_BUILD_DIR)/$(3)-generated-sources: $(DOTNET_GENERATOR) $($(2)_DOTNET_APIS) $($(2)_DOTNET_BUILD_DIR)/core-$(3).dll $(DOTNET_BINDING_ATTRIBUTES) $($(2)_DOTNET_BUILD_DIR)/$(3).rsp | $($(2)_DOTNET_BUILD_DIR)/generated-sources
$$(Q_DOTNET_GEN) $$< @$($(2)_DOTNET_BUILD_DIR)/$(3).rsp
-$($(2)_DOTNET_BUILD_DIR)/$(3).rsp: Makefile Makefile.generator frameworks.sources $(DOTNET_COMPILER) | $($(2)_DOTNET_BUILD_DIR)
+$($(2)_DOTNET_BUILD_DIR)/$(3).rsp: Makefile Makefile.generator Makefile.rgenerator frameworks.sources $(ROSLYN_GENERATOR) $(DOTNET_COMPILER) | $($(2)_DOTNET_BUILD_DIR)
$(Q) echo \
$($(2)_GENERATOR_FLAGS) \
$(DOTNET_GENERATOR_FLAGS) \
@@ -450,10 +451,11 @@ $(2)_DOTNET_PLATFORM_ASSEMBLY_DIR_DEPENDENCIES = \
$($(2)_DOTNET_BUILD_DIR)/$(4) \
$($(2)_DOTNET_BUILD_DIR)/ref \
-$($(2)_DOTNET_BUILD_DIR)/$(4)/Microsoft.$(1)%dll $($(2)_DOTNET_BUILD_DIR)/$(4)/Microsoft.$(1)%pdb $$($(2)_$(4)_REF_TARGET) $$($(2)_$(4)_DOC_TARGET): $$($(2)_DOTNET_PLATFORM_ASSEMBLY_DEPENDENCIES) | $$($(2)_DOTNET_PLATFORM_ASSEMBLY_DIR_DEPENDENCIES)
+$($(2)_DOTNET_BUILD_DIR)/$(4)/Microsoft.$(1)%dll $($(2)_DOTNET_BUILD_DIR)/$(4)/Microsoft.$(1)%pdb $$($(2)_$(4)_REF_TARGET) $$($(2)_$(4)_DOC_TARGET): $$($(2)_DOTNET_PLATFORM_ASSEMBLY_DEPENDENCIES) $$(ROSLYN_GENERATOR) | $$($(2)_DOTNET_PLATFORM_ASSEMBLY_DIR_DEPENDENCIES)
$$(call Q_PROF_CSC,dotnet/$(4)-bit) \
$(DOTNET_CSC) \
$(DOTNET_FLAGS) \
+ /analyzer:$(ROSLYN_GENERATOR) \
-unsafe \
-optimize \
$$(ARGS_$(1)) \
diff --git a/src/Makefile.rgenerator b/src/Makefile.rgenerator
new file mode 100644
index 000000000000..e3bd9f2b997a
--- /dev/null
+++ b/src/Makefile.rgenerator
@@ -0,0 +1,8 @@
+# Roslyn code generator
+ROSLYN_GENERATOR=$(DOTNET_BUILD_DIR)/common/rgen/Microsoft.Macios.Generator.dll
+ROSLYN_GENERATOR_FILES := $(wildcard rgen/Microsoft.Macios.Generator/*.cs)
+
+$(ROSLYN_GENERATOR): Makefile.rgenerator $(ROSLYN_GENERATOR_FILES)
+ $(Q_DOTNET_BUILD) $(DOTNET) publish rgen/Microsoft.Macios.Generator/Microsoft.Macios.Generator.csproj $(DOTNET_BUILD_VERBOSITY) /p:Configuration=Debug /p:IntermediateOutputPath=$(abspath $(DOTNET_BUILD_DIR)/IDE/obj/common/rgen)/ /p:OutputPath=$(abspath $(DOTNET_BUILD_DIR)/IDE/bin/common/rgen/)/
+ @mkdir -p $(dir $@)
+ $(Q) $(CP) -r $(DOTNET_BUILD_DIR)/IDE/bin/common/rgen/publish/* $(dir $@)
diff --git a/src/ObjCBindings/BindingTypeAttribute.cs b/src/ObjCBindings/BindingTypeAttribute.cs
new file mode 100644
index 000000000000..6f936d77c69a
--- /dev/null
+++ b/src/ObjCBindings/BindingTypeAttribute.cs
@@ -0,0 +1,25 @@
+using System;
+using System.Reflection;
+using System.Diagnostics.CodeAnalysis;
+
+namespace ObjCBindings {
+
+ ///
+ /// Attribute that indicates that a class or enum is a binding type. This attribute is used by the binding generator
+ /// to generate all the necessary code for the binding. The attribute can be used in a class or enum and it is required.
+ ///
+ /// If the attribute is used in a class, the class must be partial otherwise the generator will fail.
+ ///
+ [Experimental ("APL0003")]
+ [AttributeUsage (AttributeTargets.Class | System.AttributeTargets.Enum, AllowMultiple = false)]
+ public class BindingTypeAttribute : Attribute {
+
+ ///
+ /// Indicates the name of the binding type. This is the name that will be used by the registrar to make the
+ /// class available in the ObjC runtime. The default value is string.Empty, in that case the generator
+ /// will use the name of the C# class.
+ ///
+ public string Name { get; set; } = string.Empty;
+ }
+
+}
diff --git a/src/frameworks.sources b/src/frameworks.sources
index e129ca7cd91b..57094027d6fa 100644
--- a/src/frameworks.sources
+++ b/src/frameworks.sources
@@ -2012,6 +2012,7 @@ SHARED_CORE_SOURCES = \
DotNetGlobals.cs \
MinimumVersions.cs \
MonoPInvokeCallbackAttribute.cs \
+ ObjCBindings/BindingTypeAttribute.cs \
ObjCRuntime/ArgumentSemantic.cs \
ObjCRuntime/BindAsAttribute.cs \
ObjCRuntime/Blocks.cs \
diff --git a/src/rgen/Microsoft.Macios.Bindings.Analyzer.Sample/Examples.cs b/src/rgen/Microsoft.Macios.Bindings.Analyzer.Sample/Examples.cs
new file mode 100644
index 000000000000..fe4905a77980
--- /dev/null
+++ b/src/rgen/Microsoft.Macios.Bindings.Analyzer.Sample/Examples.cs
@@ -0,0 +1,12 @@
+namespace Microsoft.Macios.Bindings.Analyzer.Sample;
+
+// If you don't see warnings, build the Analyzers Project.
+
+[BindingType]
+public class Examples {
+}
+
+[BindingType]
+public class Foo {
+
+}
diff --git a/src/rgen/Microsoft.Macios.Bindings.Analyzer.Sample/Microsoft.Macios.Bindings.Analyzer.Sample.csproj b/src/rgen/Microsoft.Macios.Bindings.Analyzer.Sample/Microsoft.Macios.Bindings.Analyzer.Sample.csproj
new file mode 100644
index 000000000000..bc9520bfbacf
--- /dev/null
+++ b/src/rgen/Microsoft.Macios.Bindings.Analyzer.Sample/Microsoft.Macios.Bindings.Analyzer.Sample.csproj
@@ -0,0 +1,19 @@
+
+
+
+ net$(BundledNETCoreAppTargetFrameworkVersion)
+ enable
+
+
+
+
+
+
+
+
+
+ external\Attributes.cs
+
+
+
+
diff --git a/src/rgen/Microsoft.Macios.Bindings.Analyzer/AnalyzerReleases.Shipped.md b/src/rgen/Microsoft.Macios.Bindings.Analyzer/AnalyzerReleases.Shipped.md
new file mode 100644
index 000000000000..5a165075fbca
--- /dev/null
+++ b/src/rgen/Microsoft.Macios.Bindings.Analyzer/AnalyzerReleases.Shipped.md
@@ -0,0 +1,7 @@
+## Release 1.0
+
+### New Rules
+
+| Rule ID | Category | Severity | Notes |
+|---------|----------|----------|------------------------------------------------------|
+| RBI0001 | Usage | Error | Binding types should be declared as partial classes. |
\ No newline at end of file
diff --git a/src/rgen/Microsoft.Macios.Bindings.Analyzer/AnalyzerReleases.Unshipped.md b/src/rgen/Microsoft.Macios.Bindings.Analyzer/AnalyzerReleases.Unshipped.md
new file mode 100644
index 000000000000..44f7c8f4ef7c
--- /dev/null
+++ b/src/rgen/Microsoft.Macios.Bindings.Analyzer/AnalyzerReleases.Unshipped.md
@@ -0,0 +1,4 @@
+### New Rules
+
+| Rule ID | Category | Severity | Notes |
+|---------|----------|----------|-------|
\ No newline at end of file
diff --git a/src/rgen/Microsoft.Macios.Bindings.Analyzer/BindingTypeCodeFixProvider.cs b/src/rgen/Microsoft.Macios.Bindings.Analyzer/BindingTypeCodeFixProvider.cs
new file mode 100644
index 000000000000..17b8a2983607
--- /dev/null
+++ b/src/rgen/Microsoft.Macios.Bindings.Analyzer/BindingTypeCodeFixProvider.cs
@@ -0,0 +1,59 @@
+using System.Collections.Immutable;
+using System.Composition;
+using System.Linq;
+using System.Threading;
+using System.Threading.Tasks;
+using Microsoft.CodeAnalysis;
+using Microsoft.CodeAnalysis.CodeActions;
+using Microsoft.CodeAnalysis.CodeFixes;
+using Microsoft.CodeAnalysis.CSharp.Syntax;
+
+using SyntaxFactory = Microsoft.CodeAnalysis.CSharp.SyntaxFactory;
+using SyntaxKind = Microsoft.CodeAnalysis.CSharp.SyntaxKind;
+
+namespace Microsoft.Macios.Bindings.Analyzer;
+
+///
+/// Code fix provider that adds the 'partial' modifier to the class decorated with BindingTypeAttribute.
+///
+[ExportCodeFixProvider (LanguageNames.CSharp, Name = nameof (BindingTypeCodeFixProvider)), Shared]
+public class BindingTypeCodeFixProvider : CodeFixProvider {
+ // Specify the diagnostic IDs of analyzers that are expected to be linked.
+ public sealed override ImmutableArray FixableDiagnosticIds { get; } =
+ ImmutableArray.Create (BindingTypeSemanticAnalyzer.DiagnosticId);
+
+ // If you don't need the 'fix all' behaviour, return null.
+ public override FixAllProvider? GetFixAllProvider () => null;
+
+ public sealed override async Task RegisterCodeFixesAsync (CodeFixContext context)
+ {
+ var diagnostic = context.Diagnostics.Single ();
+ var diagnosticSpan = diagnostic.Location.SourceSpan;
+ var root = await context.Document.GetSyntaxRootAsync (context.CancellationToken).ConfigureAwait (false);
+ var diagnosticNode = root?.FindNode (diagnosticSpan);
+
+ // To get the required metadata, we should match the Node to the specific type: 'ClassDeclarationSyntax'.
+ if (diagnosticNode is not ClassDeclarationSyntax declaration)
+ return;
+
+ // Register a code action that will invoke the fix.
+ context.RegisterCodeFix (
+ CodeAction.Create (
+ title: Resources.RBI0001CodeFixTitle,
+ createChangedDocument: c => MakePartialClassAsync (context.Document, declaration, c),
+ equivalenceKey: nameof (Resources.RBI0001CodeFixTitle)),
+ diagnostic);
+ }
+
+ async Task MakePartialClassAsync (Document document,
+ ClassDeclarationSyntax classDeclarationSyntax, CancellationToken cancellationToken)
+ {
+ var partialClass = classDeclarationSyntax.AddModifiers (SyntaxFactory.Token (SyntaxKind.PartialKeyword));
+ var oldRoot = await document.GetSyntaxRootAsync (cancellationToken).ConfigureAwait (false);
+ if (oldRoot is null)
+ return document;
+
+ var newRoot = oldRoot.ReplaceNode (classDeclarationSyntax, partialClass);
+ return document.WithSyntaxRoot (newRoot);
+ }
+}
diff --git a/src/rgen/Microsoft.Macios.Bindings.Analyzer/BindingTypeSemanticAnalyzer.cs b/src/rgen/Microsoft.Macios.Bindings.Analyzer/BindingTypeSemanticAnalyzer.cs
new file mode 100644
index 000000000000..fd5df71a0e8b
--- /dev/null
+++ b/src/rgen/Microsoft.Macios.Bindings.Analyzer/BindingTypeSemanticAnalyzer.cs
@@ -0,0 +1,72 @@
+using System.Collections.Immutable;
+using System.Linq;
+using Microsoft.CodeAnalysis;
+using Microsoft.CodeAnalysis.CSharp;
+using Microsoft.CodeAnalysis.CSharp.Syntax;
+using Microsoft.CodeAnalysis.Diagnostics;
+
+namespace Microsoft.Macios.Bindings.Analyzer;
+
+///
+/// Analyzer that ensures that the types that have been declared as binding types are partial and follow the correct
+/// pattern.
+///
+[DiagnosticAnalyzer (LanguageNames.CSharp)]
+public class BindingTypeSemanticAnalyzer : DiagnosticAnalyzer {
+ internal const string DiagnosticId = "RBI0001";
+ static readonly LocalizableString Title = new LocalizableResourceString (nameof (Resources.RBI0001Title),
+ Resources.ResourceManager, typeof (Resources));
+ static readonly LocalizableString MessageFormat =
+ new LocalizableResourceString (nameof (Resources.RBI0001MessageFormat), Resources.ResourceManager,
+ typeof (Resources));
+ static readonly LocalizableString Description =
+ new LocalizableResourceString (nameof (Resources.RBI0001Description), Resources.ResourceManager,
+ typeof (Resources));
+ const string Category = "Usage";
+
+ static readonly DiagnosticDescriptor RBI0001 = new (DiagnosticId, Title, MessageFormat, Category,
+ DiagnosticSeverity.Error, isEnabledByDefault: true, description: Description);
+
+ public override ImmutableArray SupportedDiagnostics { get; } =
+ ImmutableArray.Create (RBI0001);
+
+ public override void Initialize (AnalysisContext context)
+ {
+ context.ConfigureGeneratedCodeAnalysis (GeneratedCodeAnalysisFlags.None);
+ context.EnableConcurrentExecution ();
+ context.RegisterSyntaxNodeAction (AnalysisContext, SyntaxKind.ClassDeclaration);
+ }
+
+ void AnalysisContext (SyntaxNodeAnalysisContext context)
+ {
+ // only care about classes
+ if (context.Node is not ClassDeclarationSyntax classDeclarationNode)
+ return;
+
+ var classSymbol = context.SemanticModel.GetDeclaredSymbol (classDeclarationNode);
+ if (classSymbol is null)
+ return;
+
+ var boundAttributes = classSymbol.GetAttributes ();
+ if (boundAttributes.Length == 0) {
+ return;
+ }
+
+ // the c# syntax is a a list of lists of attributes. That is why we need to iterate through the list of lists
+ foreach (var attributeData in boundAttributes) {
+ // based on the type use the correct parser to retrieve the data
+ var attributeType = attributeData.AttributeClass?.ToDisplayString ();
+ switch (attributeType) {
+ case "ObjCBindings.BindingTypeAttribute":
+ // validate that the class is partial, else we need to report an error
+ if (!classDeclarationNode.Modifiers.Any (x => x.IsKind (SyntaxKind.PartialKeyword))) {
+ var diagnostic = Diagnostic.Create (RBI0001,
+ classDeclarationNode.Identifier.GetLocation (), // point to where the 'class' keyword is used
+ classSymbol.ToDisplayString ());
+ context.ReportDiagnostic (diagnostic);
+ }
+ break;
+ }
+ }
+ }
+}
diff --git a/src/rgen/Microsoft.Macios.Bindings.Analyzer/Microsoft.Macios.Bindings.Analyzer.csproj b/src/rgen/Microsoft.Macios.Bindings.Analyzer/Microsoft.Macios.Bindings.Analyzer.csproj
new file mode 100644
index 000000000000..6f9e0902e438
--- /dev/null
+++ b/src/rgen/Microsoft.Macios.Bindings.Analyzer/Microsoft.Macios.Bindings.Analyzer.csproj
@@ -0,0 +1,46 @@
+
+
+
+ net$(BundledNETCoreAppTargetFrameworkVersion)
+ false
+ enable
+ latest
+
+ true
+ true
+
+ Microsoft.Macios.Bindings.Analyzer
+ Microsoft.Macios.Bindings.Analyzer
+
+
+
+
+ all
+ runtime; build; native; contentfiles; analyzers; buildtransitive
+
+
+
+
+
+
+
+ <_Parameter1>Microsoft.Macios.Bindings.Analyzer.Tests
+
+
+
+
+
+ ResXFileCodeGenerator
+ Resources.Designer.cs
+
+
+
+
+
+ True
+ True
+ Resources.resx
+
+
+
+
diff --git a/src/rgen/Microsoft.Macios.Bindings.Analyzer/Properties/launchSettings.json b/src/rgen/Microsoft.Macios.Bindings.Analyzer/Properties/launchSettings.json
new file mode 100644
index 000000000000..874ffd77b7e5
--- /dev/null
+++ b/src/rgen/Microsoft.Macios.Bindings.Analyzer/Properties/launchSettings.json
@@ -0,0 +1,9 @@
+{
+ "$schema": "https://json.schemastore.org/launchsettings.json",
+ "profiles": {
+ "DebugRoslynAnalyzers": {
+ "commandName": "DebugRoslynComponent",
+ "targetProject": "../Microsoft.Macios.Bindings.Analyzer.Sample/Microsoft.Macios.Bindings.Analyzer.Sample.csproj"
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/rgen/Microsoft.Macios.Bindings.Analyzer/Readme.md b/src/rgen/Microsoft.Macios.Bindings.Analyzer/Readme.md
new file mode 100644
index 000000000000..d3a566c3c1cd
--- /dev/null
+++ b/src/rgen/Microsoft.Macios.Bindings.Analyzer/Readme.md
@@ -0,0 +1,26 @@
+# Roslyn Analyzers Sample
+
+Roslyn analyzer to be installed along side the Roslyn Conde generator that will help developers work on Microsoft.Macios bindings.
+
+## Content
+### Microsoft.Macios.Bindings.Analyzer
+
+A .NET Standard project with implementations of sample analyzers and code fix providers.
+**You must build this project to see the results (warnings) in the IDE.**
+
+### Microsoft.Macios.Bindings.Analyzer.Sample
+A project that references the sample analyzers. Note the parameters of `ProjectReference` in [Microsoft.Macios.Bindings.Analyzer.Sample.csproj](../Microsoft.Macios.Bindings.Analyzer.Sample/Microsoft.Macios.Bindings.Analyzer.Sample.csproj), they make sure that the project is referenced as a set of analyzers.
+
+### Microsoft.Macios.Bindings.Analyzer.Tests
+Unit tests for the sample analyzers and code fix provider. The easiest way to develop language-related features is to start with unit tests.
+
+## How To?
+### How to debug?
+- Use the [launchSettings.json](Properties/launchSettings.json) profile.
+- Debug tests (in VSCode).
+
+### How can I determine which syntax nodes I should expect?
+Consider installing the Roslyn syntax tree viewer plugin [Rossynt](https://plugins.jetbrains.com/plugin/16902-rossynt/).
+
+### Learn more about wiring analyzers
+The complete set of information is available at [roslyn github repo wiki](https://github.com/dotnet/roslyn/blob/main/docs/wiki/README.md).
\ No newline at end of file
diff --git a/src/rgen/Microsoft.Macios.Bindings.Analyzer/Resources.Designer.cs b/src/rgen/Microsoft.Macios.Bindings.Analyzer/Resources.Designer.cs
new file mode 100644
index 000000000000..bfe0d3152b0f
--- /dev/null
+++ b/src/rgen/Microsoft.Macios.Bindings.Analyzer/Resources.Designer.cs
@@ -0,0 +1,96 @@
+//------------------------------------------------------------------------------
+//
+// This code was generated by a tool.
+//
+// Changes to this file may cause incorrect behavior and will be lost if
+// the code is regenerated.
+//
+//------------------------------------------------------------------------------
+
+namespace Microsoft.Macios.Bindings.Analyzer {
+ using System;
+
+
+ [System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")]
+ [System.Diagnostics.DebuggerNonUserCodeAttribute()]
+ [System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
+ internal class Resources {
+
+ private static System.Resources.ResourceManager resourceMan;
+
+ private static System.Globalization.CultureInfo resourceCulture;
+
+ [System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
+ internal Resources() {
+ }
+
+ [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Advanced)]
+ internal static System.Resources.ResourceManager ResourceManager {
+ get {
+ if (object.Equals(null, resourceMan)) {
+ System.Resources.ResourceManager temp = new System.Resources.ResourceManager("Microsoft.Macios.Bindings.Analyzer.Resources", typeof(Resources).Assembly);
+ resourceMan = temp;
+ }
+ return resourceMan;
+ }
+ }
+
+ [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Advanced)]
+ internal static System.Globalization.CultureInfo Culture {
+ get {
+ return resourceCulture;
+ }
+ set {
+ resourceCulture = value;
+ }
+ }
+
+ internal static string AB0001Description {
+ get {
+ return ResourceManager.GetString("AB0001Description", resourceCulture);
+ }
+ }
+
+ internal static string AB0001MessageFormat {
+ get {
+ return ResourceManager.GetString("AB0001MessageFormat", resourceCulture);
+ }
+ }
+
+ internal static string AB0001Title {
+ get {
+ return ResourceManager.GetString("AB0001Title", resourceCulture);
+ }
+ }
+
+ internal static string RBI0001CodeFixTitle {
+ get {
+ return ResourceManager.GetString("RBI0001CodeFixTitle", resourceCulture);
+ }
+ }
+
+ internal static string RBI0001Description {
+ get {
+ return ResourceManager.GetString("RBI0001Description", resourceCulture);
+ }
+ }
+
+ internal static string RBI0001MessageFormat {
+ get {
+ return ResourceManager.GetString("RBI0001MessageFormat", resourceCulture);
+ }
+ }
+
+ internal static string RBI0001Title {
+ get {
+ return ResourceManager.GetString("RBI0001Title", resourceCulture);
+ }
+ }
+
+ internal static string AB0002Description {
+ get {
+ return ResourceManager.GetString("AB0002Description", resourceCulture);
+ }
+ }
+ }
+}
diff --git a/src/rgen/Microsoft.Macios.Bindings.Analyzer/Resources.resx b/src/rgen/Microsoft.Macios.Bindings.Analyzer/Resources.resx
new file mode 100644
index 000000000000..2f228a310c3f
--- /dev/null
+++ b/src/rgen/Microsoft.Macios.Bindings.Analyzer/Resources.resx
@@ -0,0 +1,37 @@
+
+
+
+
+
+
+
+
+
+ text/microsoft-resx
+
+
+ 1.3
+
+
+ System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ Make Binding Type class partial
+ The title of the code fix.
+
+
+ In order for the code to be generated all binding types have to be declared as partial classes.
+ An optional longer localizable description of the diagnostic.
+
+
+ The binding type '{0}' must declared as a partial class
+ The format-able message the diagnostic displays.
+
+
+ Binding type declaration must be partial
+ The title of the diagnostic.
+
+
diff --git a/src/rgen/Microsoft.Macios.Generator.Sample/Microsoft.Macios.Generator.Sample.csproj b/src/rgen/Microsoft.Macios.Generator.Sample/Microsoft.Macios.Generator.Sample.csproj
new file mode 100644
index 000000000000..f21144e77c4c
--- /dev/null
+++ b/src/rgen/Microsoft.Macios.Generator.Sample/Microsoft.Macios.Generator.Sample.csproj
@@ -0,0 +1,19 @@
+
+
+
+ net$(BundledNETCoreAppTargetFrameworkVersion)
+ enable
+ Microsoft.Macios.Generator.Sample
+
+
+
+
+
+
+
+
+ external\Attributes.cs
+
+
+
+
diff --git a/src/rgen/Microsoft.Macios.Generator.Sample/SampleBinding.cs b/src/rgen/Microsoft.Macios.Generator.Sample/SampleBinding.cs
new file mode 100644
index 000000000000..28d28329ae21
--- /dev/null
+++ b/src/rgen/Microsoft.Macios.Generator.Sample/SampleBinding.cs
@@ -0,0 +1,9 @@
+namespace Microsoft.Macios.Generator.Sample;
+
+// This code will not compile until you build the project with the Source Generators
+
+[BindingType]
+public partial class SampleBinding {
+ public int Id { get; } = 42;
+ public string? Name { get; } = "Sample";
+}
diff --git a/src/rgen/Microsoft.Macios.Generator/BindingSourceGeneratorGenerator.cs b/src/rgen/Microsoft.Macios.Generator/BindingSourceGeneratorGenerator.cs
new file mode 100644
index 000000000000..fcc630f160ce
--- /dev/null
+++ b/src/rgen/Microsoft.Macios.Generator/BindingSourceGeneratorGenerator.cs
@@ -0,0 +1,24 @@
+using System.Text;
+using Microsoft.CodeAnalysis;
+using Microsoft.CodeAnalysis.Text;
+
+namespace Microsoft.Macios.Generator;
+
+///
+/// A sample source generator that creates a custom report based on class properties. The target class should be annotated with the 'Generators.ReportAttribute' attribute.
+/// When using the source code as a baseline, an incremental source generator is preferable because it reduces the performance overhead.
+///
+[Generator]
+public class BindingSourceGeneratorGenerator : IIncrementalGenerator {
+
+ public void Initialize (IncrementalGeneratorInitializationContext context)
+ {
+ // Add the binding generator attributes to the compilation. This are only available when the
+ // generator is used, similar to how bgen works.
+ foreach ((string fileName, string content) in ExtraSources.Sources) {
+ context.RegisterPostInitializationOutput (ctx => ctx.AddSource (
+ fileName, SourceText.From (content, Encoding.UTF8)));
+ }
+ }
+
+}
diff --git a/src/rgen/Microsoft.Macios.Generator/ExtraSources.cs b/src/rgen/Microsoft.Macios.Generator/ExtraSources.cs
new file mode 100644
index 000000000000..916949db8768
--- /dev/null
+++ b/src/rgen/Microsoft.Macios.Generator/ExtraSources.cs
@@ -0,0 +1,5 @@
+namespace Microsoft.Macios.Generator;
+
+public static class ExtraSources {
+ public static readonly (string FileName, string Content) [] Sources = new (string, string) [0];
+}
diff --git a/src/rgen/Microsoft.Macios.Generator/Microsoft.Macios.Generator.csproj b/src/rgen/Microsoft.Macios.Generator/Microsoft.Macios.Generator.csproj
new file mode 100644
index 000000000000..f9c73ed0396a
--- /dev/null
+++ b/src/rgen/Microsoft.Macios.Generator/Microsoft.Macios.Generator.csproj
@@ -0,0 +1,26 @@
+
+
+
+ net$(BundledNETCoreAppTargetFrameworkVersion)
+ false
+ enable
+ latest
+
+ true
+ true
+
+ Microsoft.Macios.Generator
+ Microsoft.Macios.Generator
+
+
+
+
+ all
+ runtime; build; native; contentfiles; analyzers; buildtransitive
+
+
+
+
+
+
+
diff --git a/src/rgen/Microsoft.Macios.Generator/Properties/launchSettings.json b/src/rgen/Microsoft.Macios.Generator/Properties/launchSettings.json
new file mode 100644
index 000000000000..5687e6130138
--- /dev/null
+++ b/src/rgen/Microsoft.Macios.Generator/Properties/launchSettings.json
@@ -0,0 +1,9 @@
+{
+ "$schema": "https://json.schemastore.org/launchsettings.json",
+ "profiles": {
+ "DebugRoslynSourceGenerator": {
+ "commandName": "DebugRoslynComponent",
+ "targetProject": "../Microsoft.Macios.Generator.Sample/Microsoft.Macios.Generator.Sample.csproj"
+ }
+ }
+}
diff --git a/src/rgen/Microsoft.Macios.Generator/Readme.md b/src/rgen/Microsoft.Macios.Generator/Readme.md
new file mode 100644
index 000000000000..8151de594361
--- /dev/null
+++ b/src/rgen/Microsoft.Macios.Generator/Readme.md
@@ -0,0 +1,21 @@
+# Roslyn binding code generator
+
+This directory contains the code generator for binding code. The generator is the implementation of [RFC: Migrate bgen to use roslyn instead of the reflection API](https://github.com/xamarin/xamarin-macios/issues/21308)
+
+## Content
+
+### Microsoft.Macios.Generator
+A .NET Standard project with implementations of sample source generators.
+
+**You must build this project to see the result (generated code) in the IDE.**
+
+### Microsoft.Macios.Generator.Sample
+A project that references source generators. Note the parameters of `ProjectReference` in [Microsoft.Macios.Generator.Sample.csproj](../Microsoft.Macios.Generator.Sample/Microsoft.Macios.Generator.Sample.csproj), they make sure that the project is referenced as a set of source generators.
+
+### Microsoft.Macios.Generator.Tests
+Unit tests for source generators. The easiest way to develop language-related features is to start with unit tests.
+
+## How To?
+### How to debug?
+- Use the [launchSettings.json](Properties/launchSettings.json) profile.
+- Debug tests.
\ No newline at end of file
diff --git a/src/rgen/rgen.sln b/src/rgen/rgen.sln
new file mode 100644
index 000000000000..684992039540
--- /dev/null
+++ b/src/rgen/rgen.sln
@@ -0,0 +1,46 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Microsoft.Macios.Generator", "Microsoft.Macios.Generator\Microsoft.Macios.Generator.csproj", "{8E9CF45D-E836-447E-9290-03A9CACE2704}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Microsoft.Macios.Generator.Sample", "Microsoft.Macios.Generator.Sample\Microsoft.Macios.Generator.Sample.csproj", "{AD0A1FDC-350F-47E2-AA9D-A6F32793C130}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Microsoft.Macios.Bindings.Analyzer", "Microsoft.Macios.Bindings.Analyzer\Microsoft.Macios.Bindings.Analyzer.csproj", "{27A7CBB0-A30D-4A08-A475-6D2DFD94C634}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Microsoft.Macios.Bindings.Analyzer.Sample", "Microsoft.Macios.Bindings.Analyzer.Sample\Microsoft.Macios.Bindings.Analyzer.Sample.csproj", "{65649B5A-9C23-4AA8-A687-82319EF4FA7E}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Microsoft.Macios.Generator.Tests", "..\..\tests\rgen\Microsoft.Macios.Generator.Tests\Microsoft.Macios.Generator.Tests.csproj", "{CD222ACD-A54F-49D9-81CA-6D795CC31195}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Microsoft.Macios.Bindings.Analyzer.Tests", "..\..\tests\rgen\Microsoft.Macios.Bindings.Analyzer.Tests\Microsoft.Macios.Bindings.Analyzer.Tests.csproj", "{1AC4A248-CC98-4392-8690-4E2CAF6E194B}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Any CPU = Debug|Any CPU
+ Release|Any CPU = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {8E9CF45D-E836-447E-9290-03A9CACE2704}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {8E9CF45D-E836-447E-9290-03A9CACE2704}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {8E9CF45D-E836-447E-9290-03A9CACE2704}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {8E9CF45D-E836-447E-9290-03A9CACE2704}.Release|Any CPU.Build.0 = Release|Any CPU
+ {AD0A1FDC-350F-47E2-AA9D-A6F32793C130}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {AD0A1FDC-350F-47E2-AA9D-A6F32793C130}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {AD0A1FDC-350F-47E2-AA9D-A6F32793C130}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {AD0A1FDC-350F-47E2-AA9D-A6F32793C130}.Release|Any CPU.Build.0 = Release|Any CPU
+ {27A7CBB0-A30D-4A08-A475-6D2DFD94C634}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {27A7CBB0-A30D-4A08-A475-6D2DFD94C634}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {27A7CBB0-A30D-4A08-A475-6D2DFD94C634}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {27A7CBB0-A30D-4A08-A475-6D2DFD94C634}.Release|Any CPU.Build.0 = Release|Any CPU
+ {65649B5A-9C23-4AA8-A687-82319EF4FA7E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {65649B5A-9C23-4AA8-A687-82319EF4FA7E}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {65649B5A-9C23-4AA8-A687-82319EF4FA7E}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {65649B5A-9C23-4AA8-A687-82319EF4FA7E}.Release|Any CPU.Build.0 = Release|Any CPU
+ {CD222ACD-A54F-49D9-81CA-6D795CC31195}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {CD222ACD-A54F-49D9-81CA-6D795CC31195}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {CD222ACD-A54F-49D9-81CA-6D795CC31195}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {CD222ACD-A54F-49D9-81CA-6D795CC31195}.Release|Any CPU.Build.0 = Release|Any CPU
+ {1AC4A248-CC98-4392-8690-4E2CAF6E194B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {1AC4A248-CC98-4392-8690-4E2CAF6E194B}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {1AC4A248-CC98-4392-8690-4E2CAF6E194B}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {1AC4A248-CC98-4392-8690-4E2CAF6E194B}.Release|Any CPU.Build.0 = Release|Any CPU
+ EndGlobalSection
+EndGlobal
diff --git a/tests/bgen/bgen-tests.csproj b/tests/bgen/bgen-tests.csproj
index 6ee37f30a0a8..cef7c5856f16 100644
--- a/tests/bgen/bgen-tests.csproj
+++ b/tests/bgen/bgen-tests.csproj
@@ -48,6 +48,9 @@
Configuration.cs
+
+ ConfigurationNUnit.cs
+
ExecutionHelper.cs
diff --git a/tests/cecil-tests/Documentation.KnownFailures.txt b/tests/cecil-tests/Documentation.KnownFailures.txt
index 3e025923b416..4389dfbe71ce 100644
--- a/tests/cecil-tests/Documentation.KnownFailures.txt
+++ b/tests/cecil-tests/Documentation.KnownFailures.txt
@@ -44896,6 +44896,7 @@ M:NotificationCenter.NSExtensionContext_NCWidgetAdditions.GetWidgetMaximumSize(F
M:NotificationCenter.NSExtensionContext_NCWidgetAdditions.SetWidgetLargestAvailableDisplayMode(Foundation.NSExtensionContext,NotificationCenter.NCWidgetDisplayMode)
M:NotificationCenter.NSWidgetSearchForTermEventArgs.#ctor(System.String,System.UIntPtr)
M:NotificationCenter.NSWidgetSearchResultSelectedEventArgs.#ctor(Foundation.NSObject)
+M:ObjCBindings.BindingTypeAttribute.#ctor
M:ObjCRuntime.AdoptsAttribute.#ctor(System.String)
M:ObjCRuntime.AssemblyRegistrationEventArgs.#ctor
M:ObjCRuntime.BaseWrapper.#ctor(ObjCRuntime.NativeHandle,System.Boolean)
diff --git a/tests/cecil-tests/cecil-tests.csproj b/tests/cecil-tests/cecil-tests.csproj
index 50d9f62c8f53..eac1c64fe7d1 100644
--- a/tests/cecil-tests/cecil-tests.csproj
+++ b/tests/cecil-tests/cecil-tests.csproj
@@ -19,6 +19,9 @@
Configuration.cs
+
+ ConfigurationNUnit.cs
+
Profile.cs
diff --git a/tests/common/Configuration.cs b/tests/common/Configuration.cs
index 5fdbd955485d..2d2935ef367d 100644
--- a/tests/common/Configuration.cs
+++ b/tests/common/Configuration.cs
@@ -7,8 +7,6 @@
using System.Text;
using System.Threading;
-using NUnit.Framework;
-
using Xamarin.Utils;
#nullable disable // until we get around to fixing this file
@@ -384,12 +382,6 @@ public static bool TryGetRootPath (out string rootPath)
}
}
- static string TestAssemblyDirectory {
- get {
- return TestContext.CurrentContext.WorkDirectory;
- }
- }
-
public static string SourceRoot {
get {
if (mt_src_root is null)
@@ -682,25 +674,6 @@ public static string MlaunchPath {
}
#if !XAMMAC_TESTS
- public static void AssertRuntimeIdentifierAvailable (ApplePlatform platform, string runtimeIdentifier)
- {
- if (string.IsNullOrEmpty (runtimeIdentifier))
- return;
-
- if (GetRuntimeIdentifiers (platform).Contains (runtimeIdentifier))
- return;
-
- Assert.Ignore ($"The runtime identifier {runtimeIdentifier} is not available on {platform}");
- }
-
- public static void AssertRuntimeIdentifiersAvailable (ApplePlatform platform, string runtimeIdentifiers)
- {
- if (string.IsNullOrEmpty (runtimeIdentifiers))
- return;
-
- foreach (var rid in runtimeIdentifiers.Split (new char [] { ';' }, StringSplitOptions.RemoveEmptyEntries))
- AssertRuntimeIdentifierAvailable (platform, rid);
- }
public static string GetBaseLibrary (Profile profile)
{
@@ -913,12 +886,6 @@ public static string GetCompiler (Profile profile, IList args)
return "/Library/Frameworks/Mono.framework/Commands/csc";
}
- public static void AssertiOS32BitAvailable ()
- {
- if (iOSSupports32BitArchitectures)
- return;
- Assert.Ignore ($"32-bit iOS support is not available in the current build.");
- }
#endif // !XAMMAC_TESTS
public static IEnumerable GetIncludedPlatforms (bool dotnet)
@@ -959,27 +926,6 @@ public static string XIBuildPath {
get { return Path.GetFullPath (Path.Combine (RootPath, "tools", "xibuild", "xibuild")); }
}
- public static void AssertDeviceAvailable ()
- {
- if (include_device)
- return;
- Assert.Ignore ("This build does not include device support.");
- }
-
- public static void AssertDotNetAvailable ()
- {
- if (include_dotnet)
- return;
- Assert.Ignore (".NET tests not enabled");
- }
-
- public static void AssertLegacyXamarinAvailable ()
- {
- if (include_legacy_xamarin)
- return;
- Assert.Ignore ("Legacy xamarin build not enabled");
- }
-
public static string CloneTestDirectory (string directory)
{
// Copy the test projects to a temporary directory so that we can run the tests from there without affecting the working directory.
@@ -1072,102 +1018,6 @@ public static void SetBuildVariables (ApplePlatform platform, ref Dictionary notIncluded)
- {
- var allPlatforms = GetAllPlatforms (dotnet);
- var includedPlatforms = GetIncludedPlatforms (dotnet);
- notIncluded = allPlatforms.Where (v => !includedPlatforms.Contains (v)).ToArray ();
- return notIncluded.Any ();
- }
-
- public static void IgnoreIfAnyIgnoredPlatforms (bool dotnet = true)
- {
- if (AnyIgnoredPlatforms (dotnet, out var notIncluded))
- Assert.Ignore ($"This test requires all platforms to be included, but the following platforms aren't included: {string.Join (", ", notIncluded.Select (v => v.AsString ()))}");
- }
-
- public static void IgnoreIfNotOnMacOS ()
- {
- IgnoreIfNotOn (System.Runtime.InteropServices.OSPlatform.OSX);
- }
-
- public static void IgnoreIfNotOnWindows ()
- {
- IgnoreIfNotOn (System.Runtime.InteropServices.OSPlatform.Windows);
- }
-
- public static void IgnoreIfNotOn (System.Runtime.InteropServices.OSPlatform platform)
- {
- if (System.Runtime.InteropServices.RuntimeInformation.IsOSPlatform (platform))
- return;
- Assert.Ignore ($"This test is only applicable on {platform}");
- }
-
- public static void IgnoreIfNotXamarinEnabled ()
- {
- if (EnableXamarin)
- return;
- Assert.Ignore ($"This test is only applicable if Xamarin-specific bits are enabled.");
- }
-
public static string GetTestLibraryDirectory (ApplePlatform platform, bool? simulator = null)
{
string dir;
@@ -1278,3 +1128,4 @@ public static IEnumerable GetUndefinedNativeSymbols (string file, string
}
}
}
+
diff --git a/tests/common/ConfigurationNUnit.cs b/tests/common/ConfigurationNUnit.cs
new file mode 100644
index 000000000000..9e1531be0c84
--- /dev/null
+++ b/tests/common/ConfigurationNUnit.cs
@@ -0,0 +1,172 @@
+using System;
+using System.Collections;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Runtime.InteropServices;
+using System.Text;
+using System.Threading;
+
+using NUnit.Framework;
+
+using Xamarin.Utils;
+
+#nullable disable // until we get around to fixing this file
+
+namespace Xamarin.Tests {
+ static partial class Configuration {
+
+ static string TestAssemblyDirectory {
+ get {
+ return TestContext.CurrentContext.WorkDirectory;
+ }
+ }
+
+#if !XAMMAC_TESTS
+ public static void AssertRuntimeIdentifierAvailable (ApplePlatform platform, string runtimeIdentifier)
+ {
+ if (string.IsNullOrEmpty (runtimeIdentifier))
+ return;
+
+ if (GetRuntimeIdentifiers (platform).Contains (runtimeIdentifier))
+ return;
+
+ Assert.Ignore ($"The runtime identifier {runtimeIdentifier} is not available on {platform}");
+ }
+
+ public static void AssertRuntimeIdentifiersAvailable (ApplePlatform platform, string runtimeIdentifiers)
+ {
+ if (string.IsNullOrEmpty (runtimeIdentifiers))
+ return;
+
+ foreach (var rid in runtimeIdentifiers.Split (new char [] { ';' }, StringSplitOptions.RemoveEmptyEntries))
+ AssertRuntimeIdentifierAvailable (platform, rid);
+ }
+
+ public static void AssertiOS32BitAvailable ()
+ {
+ if (iOSSupports32BitArchitectures)
+ return;
+ Assert.Ignore ($"32-bit iOS support is not available in the current build.");
+ }
+#endif // !XAMMAC_TESTS
+
+ public static void AssertDeviceAvailable ()
+ {
+ if (include_device)
+ return;
+ Assert.Ignore ("This build does not include device support.");
+ }
+
+ public static void AssertDotNetAvailable ()
+ {
+ if (include_dotnet)
+ return;
+ Assert.Ignore (".NET tests not enabled");
+ }
+
+ public static void AssertLegacyXamarinAvailable ()
+ {
+ if (include_legacy_xamarin)
+ return;
+ Assert.Ignore ("Legacy xamarin build not enabled");
+ }
+
+ // Calls Assert.Ignore if the given platform isn't included in the current build.
+ public static void IgnoreIfIgnoredPlatform (ApplePlatform platform)
+ {
+ switch (platform) {
+ case ApplePlatform.iOS:
+ if (!include_ios)
+ Assert.Ignore ("iOS is not included in this build");
+ break;
+ case ApplePlatform.TVOS:
+ if (!include_tvos)
+ Assert.Ignore ("tvOS is not included in this build");
+ break;
+ case ApplePlatform.WatchOS:
+ if (!include_watchos)
+ Assert.Ignore ("watchOS is not included in this build");
+#if NET
+ if (!include_dotnet_watchos)
+ Assert.Ignore ("watchOS is not included in this build");
+#endif
+
+ break;
+ case ApplePlatform.MacOSX:
+ if (!include_mac)
+ Assert.Ignore ("macOS is not included in this build");
+ break;
+ case ApplePlatform.MacCatalyst:
+ if (!include_maccatalyst)
+ Assert.Ignore ("Mac Catalyst is not included in this build");
+ break;
+ default:
+ throw new ArgumentOutOfRangeException ($"Unknown platform: {platform}");
+ }
+ }
+
+ // Calls Assert.Ignore if the given platform isn't included in the current build.
+ public static void IgnoreIfIgnoredPlatform (string platform)
+ {
+ switch (platform.ToLower ()) {
+ case "ios":
+ case "tvos":
+ case "watchos":
+ case "macosx":
+ case "maccatalyst":
+ IgnoreIfIgnoredPlatform ((ApplePlatform) Enum.Parse (typeof (ApplePlatform), platform, true));
+ break;
+ case "macos":
+ IgnoreIfIgnoredPlatform (ApplePlatform.MacOSX);
+ break;
+ default:
+ throw new ArgumentOutOfRangeException ($"Unknown platform: {platform}");
+ }
+ }
+
+ public static bool AnyIgnoredPlatforms (bool dotnet = true)
+ {
+ return AnyIgnoredPlatforms (dotnet, out var _);
+ }
+
+ public static bool AnyIgnoredPlatforms (bool dotnet, out IEnumerable notIncluded)
+ {
+ var allPlatforms = GetAllPlatforms (dotnet);
+ var includedPlatforms = GetIncludedPlatforms (dotnet);
+ notIncluded = allPlatforms.Where (v => !includedPlatforms.Contains (v)).ToArray ();
+ return notIncluded.Any ();
+ }
+
+ public static void IgnoreIfAnyIgnoredPlatforms (bool dotnet = true)
+ {
+ if (AnyIgnoredPlatforms (dotnet, out var notIncluded))
+ Assert.Ignore ($"This test requires all platforms to be included, but the following platforms aren't included: {string.Join (", ", notIncluded.Select (v => v.AsString ()))}");
+ }
+
+ public static void IgnoreIfNotOnMacOS ()
+ {
+ IgnoreIfNotOn (System.Runtime.InteropServices.OSPlatform.OSX);
+ }
+
+ public static void IgnoreIfNotOnWindows ()
+ {
+ IgnoreIfNotOn (System.Runtime.InteropServices.OSPlatform.Windows);
+ }
+
+ public static void IgnoreIfNotOn (System.Runtime.InteropServices.OSPlatform platform)
+ {
+ if (System.Runtime.InteropServices.RuntimeInformation.IsOSPlatform (platform))
+ return;
+ Assert.Ignore ($"This test is only applicable on {platform}");
+ }
+
+ public static void IgnoreIfNotXamarinEnabled ()
+ {
+ if (EnableXamarin)
+ return;
+ Assert.Ignore ($"This test is only applicable if Xamarin-specific bits are enabled.");
+ }
+
+ }
+}
diff --git a/tests/common/ConfigurationXUnit.cs b/tests/common/ConfigurationXUnit.cs
new file mode 100644
index 000000000000..d1555af04e69
--- /dev/null
+++ b/tests/common/ConfigurationXUnit.cs
@@ -0,0 +1,57 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Reflection;
+using Xamarin.Utils;
+using Xunit.Sdk;
+
+namespace Xamarin.Tests {
+
+ [AttributeUsage (AttributeTargets.Method, AllowMultiple = true, Inherited = true)]
+ public sealed class PlatformInlineDataAttribute : DataAttribute {
+ readonly object [] dataValues;
+ public PlatformInlineDataAttribute (ApplePlatform platform, params object [] parameters)
+ {
+ // data values are the join of the platform and all other values passed to the attr
+ dataValues = parameters.Prepend (platform).ToArray ();
+ // based on the passed platform and the configuration, decide if we skip the test
+ switch (platform) {
+ case ApplePlatform.iOS:
+ if (!Configuration.include_ios)
+ Skip = "iOS is not included in this build";
+ break;
+ case ApplePlatform.TVOS:
+ if (!Configuration.include_tvos)
+ Skip = "tvOS is not included in this build";
+ break;
+ case ApplePlatform.MacOSX:
+ if (!Configuration.include_mac)
+ Skip = "macOS is not included in this build";
+ break;
+ case ApplePlatform.MacCatalyst:
+ if (!Configuration.include_maccatalyst)
+ Skip = "Mac Catalyst is not included in this build";
+ break;
+ default:
+ throw new ArgumentOutOfRangeException ($"Unknown platform: {platform}");
+ }
+ }
+
+ public object [] DataValues {
+ get { return dataValues; }
+ }
+
+ public override IEnumerable