diff --git a/Configuration.props b/Configuration.props
index 34cd72852..42a55c6d3 100644
--- a/Configuration.props
+++ b/Configuration.props
@@ -69,6 +69,7 @@
$(BuildOutputDirectory)lib\packs\Microsoft.Android.Runtime.$(AndroidApiLevel).android-x64\$(AndroidPackVersion)\runtimes\android-x64\
$(BuildOutputDirectory)lib\packs\$(MicrosoftAndroidSdkPackName)\$(AndroidPackVersion)\
$(MicrosoftAndroidSdkPackDir)\tools\
+ $(BuildOutputDirectory)lib\packs\Microsoft.Android.Ref.$(AndroidApiLevel)\$(AndroidPackVersion)\analyzers\dotnet\cs\
-j$(HostCpuCount)
mono
--debug=casts
diff --git a/Xamarin.Android.Build.Tasks.sln b/Xamarin.Android.Build.Tasks.sln
index 29fa734d9..4dbf9a5aa 100644
--- a/Xamarin.Android.Build.Tasks.sln
+++ b/Xamarin.Android.Build.Tasks.sln
@@ -25,6 +25,10 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.Android.Build.Bas
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Xamarin.Android.Tools.AndroidSdk", "external\xamarin-android-tools\src\Xamarin.Android.Tools.AndroidSdk\Xamarin.Android.Tools.AndroidSdk.csproj", "{E34BCFA0-CAA4-412C-AA1C-75DB8D67D157}"
EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{4A5EE838-A906-4711-972E-E680B0AA68BD}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Microsoft.Android.Sdk.Analysis", "src\Microsoft.Android.Sdk.Analysis\Microsoft.Android.Sdk.Analysis.csproj", "{0D00DD34-3E94-4166-9DEE-12355E4C98A0}"
+EndProject
Global
GlobalSection(SharedMSBuildProjectFiles) = preSolution
src\Xamarin.Android.NamingCustomAttributes\Xamarin.Android.NamingCustomAttributes.projitems*{3f1f2f50-af1a-4a5a-bedb-193372f068d7}*SharedItemsImports = 5
@@ -74,6 +78,10 @@ Global
{E34BCFA0-CAA4-412C-AA1C-75DB8D67D157}.Debug|Any CPU.Build.0 = Debug|Any CPU
{E34BCFA0-CAA4-412C-AA1C-75DB8D67D157}.Release|Any CPU.ActiveCfg = Release|Any CPU
{E34BCFA0-CAA4-412C-AA1C-75DB8D67D157}.Release|Any CPU.Build.0 = Release|Any CPU
+ {0D00DD34-3E94-4166-9DEE-12355E4C98A0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {0D00DD34-3E94-4166-9DEE-12355E4C98A0}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {0D00DD34-3E94-4166-9DEE-12355E4C98A0}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {0D00DD34-3E94-4166-9DEE-12355E4C98A0}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@@ -84,6 +92,7 @@ Global
{DE40756E-57F6-4AF2-B155-55E3A88CCED8} = {385E71CC-BAE5-488B-805E-ACAE55F01DF5}
{3DE17662-DCD6-4F49-AF06-D39AACC8649A} = {385E71CC-BAE5-488B-805E-ACAE55F01DF5}
{E34BCFA0-CAA4-412C-AA1C-75DB8D67D157} = {385E71CC-BAE5-488B-805E-ACAE55F01DF5}
+ {0D00DD34-3E94-4166-9DEE-12355E4C98A0} = {4A5EE838-A906-4711-972E-E680B0AA68BD}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {F32556C5-6FD4-4F1D-884A-DEDF2EE865F6}
diff --git a/Xamarin.Android.sln b/Xamarin.Android.sln
index eaf3ea4fb..831275998 100644
--- a/Xamarin.Android.sln
+++ b/Xamarin.Android.sln
@@ -121,6 +121,10 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "create-android-api", "build
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Xamarin.Android.Tools.Aidl-Tests", "tests\Xamarin.Android.Tools.Aidl-Tests\Xamarin.Android.Tools.Aidl-Tests.csproj", "{A39B6D7C-6616-40D6-8AE4-C6CEE93D2708}"
EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{FFCF518F-2A4A-40A2-9174-2EE13B76C723}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Microsoft.Android.Sdk.Analysis", "src\Microsoft.Android.Sdk.Analysis\Microsoft.Android.Sdk.Analysis.csproj", "{5E806C9F-1B67-4B6B-A6AB-258834250DBB}"
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|AnyCPU = Debug|AnyCPU
@@ -335,6 +339,10 @@ Global
{A39B6D7C-6616-40D6-8AE4-C6CEE93D2708}.Debug|AnyCPU.Build.0 = Debug|Any CPU
{A39B6D7C-6616-40D6-8AE4-C6CEE93D2708}.Release|AnyCPU.ActiveCfg = Release|Any CPU
{A39B6D7C-6616-40D6-8AE4-C6CEE93D2708}.Release|AnyCPU.Build.0 = Release|Any CPU
+ {5E806C9F-1B67-4B6B-A6AB-258834250DBB}.Debug|AnyCPU.ActiveCfg = Debug|Any CPU
+ {5E806C9F-1B67-4B6B-A6AB-258834250DBB}.Debug|AnyCPU.Build.0 = Debug|Any CPU
+ {5E806C9F-1B67-4B6B-A6AB-258834250DBB}.Release|AnyCPU.ActiveCfg = Release|Any CPU
+ {5E806C9F-1B67-4B6B-A6AB-258834250DBB}.Release|AnyCPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@@ -393,6 +401,7 @@ Global
{C0E44558-FEE3-4DD3-986A-3F46DD1BF41B} = {04E3E11E-B47D-4599-8AFC-50515A95E715}
{BA4D889D-066B-4C2C-A973-09E319CBC396} = {E351F97D-EA4F-4E7F-AAA0-8EBB1F2A4A62}
{A39B6D7C-6616-40D6-8AE4-C6CEE93D2708} = {CAB438D8-B0F5-4AF0-BEBD-9E2ADBD7B483}
+ {5E806C9F-1B67-4B6B-A6AB-258834250DBB} = {FFCF518F-2A4A-40A2-9174-2EE13B76C723}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {53A1F287-EFB2-4D97-A4BB-4A5E145613F6}
diff --git a/build-tools/create-packs/ConfigureLocalWorkload.targets b/build-tools/create-packs/ConfigureLocalWorkload.targets
index 379848d03..6a4a6b824 100644
--- a/build-tools/create-packs/ConfigureLocalWorkload.targets
+++ b/build-tools/create-packs/ConfigureLocalWorkload.targets
@@ -2,6 +2,7 @@
<_FrameworkListInputs Include="$(MicrosoftAndroidRefPackDir)**" />
+ <_FrameworkListInputs Include="$(MicrosoftAndroidSdkAnalysisOutDir)Microsoft.Android.Sdk.Analysis.dll" />
<_FrameworkListOutputs Include="$(BuildOutputDirectory)lib\packs\Microsoft.Android.Ref.$(AndroidDefaultTargetDotnetApiLevel)\$(AndroidPackVersion)\data\FrameworkList.xml" />
<_FrameworkListOutputs Include="$(BuildOutputDirectory)lib\packs\Microsoft.Android.Ref.$(AndroidLatestStableApiLevel)\$(AndroidPackVersion)\data\FrameworkList.xml" />
<_FrameworkListOutputs Include="$(BuildOutputDirectory)lib\packs\Microsoft.Android.Ref.$(AndroidLatestUnstableApiLevel)\$(AndroidPackVersion)\data\FrameworkList.xml" />
diff --git a/build-tools/create-packs/Directory.Build.targets b/build-tools/create-packs/Directory.Build.targets
index 7a0b67e7f..c06a6b600 100644
--- a/build-tools/create-packs/Directory.Build.targets
+++ b/build-tools/create-packs/Directory.Build.targets
@@ -28,7 +28,7 @@
Files="@(_PackageFiles)"
FileClassifications="@(FrameworkListFileClass)"
TargetFile="$(FrameworkListFile)"
- TargetFilePrefixes="ref;runtimes"
+ TargetFilePrefixes="ref;runtimes;analyzers"
RootAttributes="@(FrameworkListRootAttributes)"
/>
diff --git a/build-tools/create-packs/Microsoft.Android.Ref.proj b/build-tools/create-packs/Microsoft.Android.Ref.proj
index 9a1bdd0da..d55e8dafe 100644
--- a/build-tools/create-packs/Microsoft.Android.Ref.proj
+++ b/build-tools/create-packs/Microsoft.Android.Ref.proj
@@ -13,6 +13,7 @@ by projects that use the Microsoft.Android framework in .NET 6+.
Microsoft.Android.Ref.$(AndroidApiLevel)
Microsoft.Android reference assemblies for API $(AndroidApiLevel). Please do not reference directly.
<_AndroidRefPackAssemblyPath>ref\$(DotNetTargetFramework)
+ <_AndroidRefPackAnalyzersPath>analyzers\dotnet\cs
@@ -36,11 +37,14 @@ by projects that use the Microsoft.Android framework in .NET 6+.
<_AndroidRefPackAssemblies Include="$(_MonoAndroidNETDefaultOutDir)ref\Mono.Android.Runtime.dll" />
<_AndroidRefPackAssemblies Include="$(_MonoAndroidNETOutputRoot)$(AndroidLatestStableApiLevel)\ref\Mono.Android.Export.dll" />
+ <_AndroidRefPackAnalyzers Include="$(MicrosoftAndroidSdkAnalysisOutDir)Microsoft.Android.Sdk.Analysis.dll" />
+
<_PackageFiles Include="@(_AndroidRefPackAssemblies)" PackagePath="$(_AndroidRefPackAssemblyPath)" TargetPath="$(_AndroidRefPackAssemblyPath)" />
+ <_PackageFiles Include="@(_AndroidRefPackAnalyzers)" PackagePath="$(_AndroidRefPackAnalyzersPath)" TargetPath="$(_AndroidRefPackAnalyzersPath)" />
<_PackageFiles Include="$(_MonoAndroidNETDefaultOutDir)Java.Interop.xml" PackagePath="$(_AndroidRefPackAssemblyPath)" />
<_PackageFiles Include="$(_MonoAndroidNETDefaultOutDir)Mono.Android.xml" PackagePath="$(_AndroidRefPackAssemblyPath)" />
<_PackageFiles Include="$(_MonoAndroidNETDefaultOutDir)mono.android.jar" PackagePath="$(_AndroidRefPackAssemblyPath)" />
diff --git a/eng/Versions.props b/eng/Versions.props
index 24fdf4150..65dcac20e 100644
--- a/eng/Versions.props
+++ b/eng/Versions.props
@@ -6,7 +6,7 @@
9.0.0-rtm.24473.2
9.0.0-rtm.24473.2
7.0.0-beta.22103.1
- 9.0.0-beta.24408.2
+ 10.0.0-beta.24476.2
9.0.0-rtm.24469.1
$(MicrosoftNETWorkloadEmscriptenCurrentManifest90100TransportVersion)
7.0.100-rc.1.22410.7
diff --git a/src/Microsoft.Android.Sdk.Analysis/Microsoft.Android.Sdk.Analysis.csproj b/src/Microsoft.Android.Sdk.Analysis/Microsoft.Android.Sdk.Analysis.csproj
new file mode 100644
index 000000000..6f7a62412
--- /dev/null
+++ b/src/Microsoft.Android.Sdk.Analysis/Microsoft.Android.Sdk.Analysis.csproj
@@ -0,0 +1,19 @@
+
+
+
+ netstandard2.0
+ false
+ $(MicrosoftAndroidSdkAnalysisOutDir)
+ true
+ latest
+ true
+ ..\..\product.snk
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/Microsoft.Android.Sdk.Analysis/ResourceDesignerDiagnosticSuppressor.cs b/src/Microsoft.Android.Sdk.Analysis/ResourceDesignerDiagnosticSuppressor.cs
new file mode 100644
index 000000000..0b22e1c23
--- /dev/null
+++ b/src/Microsoft.Android.Sdk.Analysis/ResourceDesignerDiagnosticSuppressor.cs
@@ -0,0 +1,71 @@
+using System.Linq;
+using System.Collections.Immutable;
+using System.Threading;
+using Microsoft.CodeAnalysis;
+using Microsoft.CodeAnalysis.CSharp.Syntax;
+using Microsoft.CodeAnalysis.Diagnostics;
+using Microsoft.CodeAnalysis.Text;
+
+[DiagnosticAnalyzer(LanguageNames.CSharp)]
+public class ResourceDesignerDiagnosticSuppressor : DiagnosticSuppressor
+{
+ private const string DesignerNamespace = "_Microsoft.Android.Resource.Designer";
+ private static readonly SuppressionDescriptor Rule = new(
+ "XAD0001",
+ "IDE0002",
+ "The Resource Designer class should not be simplified."
+ );
+
+ public override ImmutableArray SupportedSuppressions
+ => ImmutableArray.Create(Rule);
+
+ public override void ReportSuppressions(SuppressionAnalysisContext context)
+ {
+ foreach (var diagnostic in context.ReportedDiagnostics)
+ {
+ if (diagnostic.Id != Rule.SuppressedDiagnosticId)
+ continue;
+ Location location = diagnostic.Location;
+ SyntaxTree syntaxTree = location.SourceTree;
+ if (syntaxTree is null)
+ continue;
+
+ SyntaxNode root = syntaxTree.GetRoot(context.CancellationToken);
+ SyntaxNode syntaxNode = root.FindNode(location.SourceSpan)
+ .DescendantNodesAndSelf()
+ .FirstOrDefault ();
+
+ if (syntaxNode is null)
+ continue;
+
+ SemanticModel model = context.GetSemanticModel(syntaxTree);
+ ISymbol typeSymbol = model.GetSymbolInfo (syntaxNode).Symbol;
+ if (typeSymbol is not INamedTypeSymbol namedTypeSymbol)
+ continue;
+
+ if (IsResourceDesignerDerivedType(namedTypeSymbol))
+ {
+ Suppression suppression = Suppression.Create(Rule, diagnostic);
+ context.ReportSuppression(suppression);
+ }
+ }
+ }
+
+ private static bool IsResourceDesignerDerivedType(INamedTypeSymbol typeSymbol)
+ {
+ return IsDerivedFrom(typeSymbol, DesignerNamespace);
+ }
+
+ private static bool IsDerivedFrom(INamedTypeSymbol typeSymbol, string baseClassName)
+ {
+ while (typeSymbol != null)
+ {
+ if (typeSymbol.ToDisplayString().StartsWith(baseClassName))
+ {
+ return true;
+ }
+ typeSymbol = typeSymbol.BaseType;
+ }
+ return false;
+ }
+}
\ No newline at end of file
diff --git a/src/Xamarin.Android.Build.Tasks/Tasks/GenerateResourceDesignerAssembly.cs b/src/Xamarin.Android.Build.Tasks/Tasks/GenerateResourceDesignerAssembly.cs
index d1f165c4d..4f61d5d6d 100644
--- a/src/Xamarin.Android.Build.Tasks/Tasks/GenerateResourceDesignerAssembly.cs
+++ b/src/Xamarin.Android.Build.Tasks/Tasks/GenerateResourceDesignerAssembly.cs
@@ -123,6 +123,12 @@ namespace Xamarin.Android.Tasks
TypeReference e = ImportType ("System.ComponentModel.EditorBrowsableState", module, netstandardDef.MainModule);
var editorBrowserAttr = new CustomAttribute (editorBrowserConstructor);
editorBrowserAttr.ConstructorArguments.Add (new CustomAttributeArgument (e, System.ComponentModel.EditorBrowsableState.Never));
+
+ MethodReference generatedCodeConstructor = ImportCustomAttributeConstructor (cache, "System.CodeDom.Compiler.GeneratedCodeAttribute", module, netstandardDef.MainModule, argCount: 2);
+ var generatedCodeAttr = new CustomAttribute (generatedCodeConstructor);
+ generatedCodeAttr.ConstructorArguments.Add (new CustomAttributeArgument (module.TypeSystem.String, nameof(GenerateResourceDesignerAssembly)));
+ var version = typeof(GenerateResourceDesignerAssembly).Assembly.GetName().Version;
+ generatedCodeAttr.ConstructorArguments.Add (new CustomAttributeArgument (module.TypeSystem.String, version.ToString ()));
var att = TypeAttributes.AutoClass | TypeAttributes.AnsiClass | TypeAttributes.Public | TypeAttributes.BeforeFieldInit;
@@ -139,6 +145,7 @@ namespace Xamarin.Android.Tasks
);
CreateCtor (cache, resourceDesigner, module);
resourceDesigner.CustomAttributes.Add (editorBrowserAttr);
+ resourceDesigner.CustomAttributes.Add (generatedCodeAttr);
module.Types.Add (resourceDesigner);
TypeDefinition constDesigner = null;
if (IsApplication) {
@@ -152,6 +159,7 @@ namespace Xamarin.Android.Tasks
);
CreateCtor (cache, constDesigner, module);
constDesigner.CustomAttributes.Add (editorBrowserAttr);
+ constDesigner.CustomAttributes.Add (generatedCodeAttr);
module.Types.Add (constDesigner);
}
diff --git a/src/Xamarin.Android.Build.Tasks/Tasks/GenerateResourceDesignerIntermediateClass.cs b/src/Xamarin.Android.Build.Tasks/Tasks/GenerateResourceDesignerIntermediateClass.cs
index 22f9d4cf3..7308996b8 100644
--- a/src/Xamarin.Android.Build.Tasks/Tasks/GenerateResourceDesignerIntermediateClass.cs
+++ b/src/Xamarin.Android.Build.Tasks/Tasks/GenerateResourceDesignerIntermediateClass.cs
@@ -21,6 +21,7 @@ namespace Xamarin.Android.Tasks
//
//------------------------------------------------------------------------------
using System;
+using System.CodeDom.Compiler;
namespace %NAMESPACE% {
#pragma warning disable IDE0002
@@ -28,6 +29,7 @@ namespace %NAMESPACE% {
/// Android Resource Designer class.
/// Exposes the Android Resource designer assembly into the project Namespace.
///
+ [GeneratedCode(""%TOOL%"", ""%VERSION%"")]
public partial class Resource : %BASECLASS% {
}
#pragma warning restore IDE0002
@@ -40,6 +42,7 @@ namespace %NAMESPACE% {
//------------------------------------------------------------------------------
namespace %NAMESPACE%
+[]
type Resource = %BASECLASS%
";
@@ -54,11 +57,19 @@ type Resource = %BASECLASS%
//bool isVB = string.Equals (extension, ".vb", StringComparison.OrdinalIgnoreCase);
bool isFSharp = string.Equals (language, "F#", StringComparison.OrdinalIgnoreCase);
bool isCSharp = string.Equals (language, "C#", StringComparison.OrdinalIgnoreCase);
+ var version = typeof(GenerateResourceDesignerIntermediateClass).Assembly.GetName().Version;
string template = "";
- if (isCSharp)
- template = CSharpTemplate.Replace ("%NAMESPACE%", Namespace).Replace ("%BASECLASS%", ns);
- else if (isFSharp)
- template = FSharpTemplate.Replace ("%NAMESPACE%", Namespace).Replace ("%BASECLASS%", ns);
+ if (isCSharp) {
+ template = CSharpTemplate.Replace ("%NAMESPACE%", Namespace)
+ .Replace ("%BASECLASS%", ns)
+ .Replace ("%VERSION%", version.ToString ())
+ .Replace ("%TOOL%", nameof (GenerateResourceDesignerIntermediateClass));
+ } else if (isFSharp) {
+ template = FSharpTemplate.Replace ("%NAMESPACE%", Namespace)
+ .Replace ("%BASECLASS%", ns)
+ .Replace ("%VERSION%", version.ToString ())
+ .Replace ("%TOOL%", nameof (GenerateResourceDesignerIntermediateClass));
+ }
Files.CopyIfStringChanged (template, OutputFile.ItemSpec);
return !Log.HasLoggedErrors;