Skip to content

Commit cfb9fce

Browse files
committed
Updates for .net 6 (almost working). Added F# Support!!!
1 parent 37848fa commit cfb9fce

File tree

6 files changed

+164
-68
lines changed

6 files changed

+164
-68
lines changed

src/Xamarin.Android.Build.Tasks/Linker/MonoDroid.Tuner/FixLegacyResourceDesignerStep.cs

Lines changed: 66 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -13,75 +13,86 @@
1313
using Mono.Tuner;
1414
#if ILLINK
1515
using Microsoft.Android.Sdk.ILLink;
16-
#endif
16+
#endif // ILLINK
1717

1818
namespace MonoDroid.Tuner
1919
{
20-
public class FixLegacyResourceDesignerStep :
21-
#if ILLINK
22-
BaseMarkHandler
23-
#else // !ILLINK
24-
BaseStep
25-
#endif // !ILLINK
20+
public class FixLegacyResourceDesignerStep : BaseStep
2621
{
22+
#if ILLINK
23+
protected override void Process ()
24+
{
25+
cache = Context;
26+
}
27+
#else
28+
public FixLegacyResourceDesignerStep (IMetadataResolver cache)
29+
{
30+
this.cache = cache;
31+
}
32+
33+
readonly
34+
#endif
35+
IMetadataResolver cache;
2736
AssemblyDefinition designerAssembly = null;
37+
Dictionary<string, MethodDefinition> lookup;
2838

29-
#if ILLINK
30-
public override void Initialize (LinkContext context, MarkContext markContext)
39+
protected override void ProcessAssembly (AssemblyDefinition assembly)
3140
{
32-
base.Initialize (context, markContext);
33-
markContext.RegisterMarkAssemblyAction (asm => ProcessAssembly (asm));
34-
var designerNameAssembly = AssemblyNameReference.Parse ("Xamarin.Android.Resource.Designer, Version=1.0.0.0");
35-
try {
36-
designerAssembly = Context.Resolve (designerNameAssembly);
37-
} catch (Mono.Cecil.AssemblyResolutionException) {
38-
}
39-
if (designerAssembly == null) {
40-
context.LogMessage ($" Did not find Xamarin.Android.Resource.Designer");
41+
LoadDesigner ();
42+
43+
var action = Annotations.HasAction (assembly) ? Annotations.GetAction (assembly) : AssemblyAction.Skip;
44+
if (action == AssemblyAction.Delete)
4145
return;
46+
47+
if (ProcessAssemblyDesigner (assembly)) {
48+
if (action == AssemblyAction.Skip || action == AssemblyAction.Copy)
49+
Annotations.SetAction (assembly, AssemblyAction.Save);
4250
}
4351
}
4452

45-
protected void ProcessAssembly (AssemblyDefinition assembly)
53+
public virtual void LogMessage (string message)
4654
{
47-
ProcessAssemblyDesigner (assembly);
55+
Context.LogMessage (message);
4856
}
49-
#else
50-
protected override void Process ()
57+
58+
public virtual AssemblyDefinition Resolve (AssemblyNameReference name)
5159
{
60+
return Context.Resolve (name);
61+
}
62+
63+
protected bool LoadDesigner ()
64+
{
65+
if (designerAssembly != null)
66+
return true;
5267
var designerNameAssembly = AssemblyNameReference.Parse ("Xamarin.Android.Resource.Designer, Version=1.0.0.0");
5368
try {
54-
designerAssembly = Context.Resolver.Resolve (designerNameAssembly);
69+
designerAssembly = Resolve (designerNameAssembly);
5570
} catch (Mono.Cecil.AssemblyResolutionException) {
5671
}
5772
if (designerAssembly == null) {
58-
Context.LogMessage ($" Did not find Xamarin.Android.Resource.Designer");
59-
return;
73+
LogMessage ($" Did not find Xamarin.Android.Resource.Designer");
74+
return false;
6075
}
76+
return true;
6177
}
62-
63-
64-
protected override void ProcessAssembly (AssemblyDefinition assembly)
65-
{
66-
ProcessAssemblyDesigner (assembly);
67-
}
68-
#endif
69-
Dictionary<string, MethodDefinition> lookup;
70-
void ProcessAssemblyDesigner (AssemblyDefinition assembly)
78+
internal bool ProcessAssemblyDesigner (AssemblyDefinition assembly)
7179
{
7280
if (designerAssembly == null) {
73-
Context.LogMessage ($" Not using Xamarin.Android.Resource.Designer");
74-
return;
81+
LogMessage ($" Not using Xamarin.Android.Resource.Designer");
82+
return false;
7583
}
84+
7685
if (!FindResourceDesigner (assembly, mainApplication: false, out TypeDefinition designer, out CustomAttribute designerAttribute)) {
77-
Context.LogMessage ($" {assembly.Name.Name} has not designer. ");
78-
return;
86+
LogMessage ($" {assembly.Name.Name} has not designer. ");
87+
return false;
7988
}
80-
Context.LogMessage ($" {assembly.Name.Name} has a designer. ");
89+
90+
LogMessage ($" {assembly.Name.Name} has a designer. ");
8191
if (designer.BaseType.FullName == "Xamarin.Android.Resource.Designer.Resource") {
82-
Context.LogMessage ($" {assembly.Name.Name} has already been processed. ");
83-
return;
92+
LogMessage ($" {assembly.Name.Name} has already been processed. ");
93+
return false;
8494
}
95+
8596
assembly.MainModule.AssemblyReferences.Add (designerAssembly.Name);
8697
var designerAssemblyDef = assembly.MainModule.AssemblyResolver.Resolve(designerAssembly.Name);
8798
var t = designerAssemblyDef.MainModule.GetTypes ().First (x => x.FullName == "Xamarin.Android.Resource.Designer.Resource");
@@ -91,9 +102,11 @@ void ProcessAssemblyDesigner (AssemblyDefinition assembly)
91102

92103
// now replace all ldsfld with a call to the property get_ method.
93104
FixupAssemblyTypes (assembly, designer);
105+
94106
// then clean out the designer.
95107
ClearDesignerClass (designer);
96108
designer.BaseType = designerType;
109+
return true;
97110
}
98111

99112
Dictionary<string, MethodDefinition> BuildResourceDesignerPropertyLookup (TypeDefinition type)
@@ -154,7 +167,7 @@ bool FindResourceDesigner (AssemblyDefinition assembly, bool mainApplication, ou
154167

155168
void ClearDesignerClass (TypeDefinition designer)
156169
{
157-
Context.LogMessage ($" TryRemoving {designer.FullName}");
170+
LogMessage ($" TryRemoving {designer.FullName}");
158171
designer.NestedTypes.Clear ();
159172
designer.Methods.Clear ();
160173
designer.Fields.Clear ();
@@ -166,11 +179,13 @@ void ClearDesignerClass (TypeDefinition designer)
166179

167180
void FixupAssemblyTypes (AssemblyDefinition assembly, TypeDefinition designer)
168181
{
169-
Context.LogMessage ($" Fixup Types for {assembly.FullName} using {designer.FullName}");
182+
LogMessage ($" Fixup Types for {assembly.FullName} using {designer.FullName}");
170183
foreach (ModuleDefinition module in assembly.Modules)
171184
{
172185
foreach (TypeDefinition type in module.Types)
173186
{
187+
if (type.FullName == designer.FullName)
188+
continue;
174189
FixType (type, designer);
175190
}
176191
}
@@ -179,9 +194,8 @@ void FixupAssemblyTypes (AssemblyDefinition assembly, TypeDefinition designer)
179194
void FixBody (MethodBody body, TypeDefinition designer)
180195
{
181196
// look for ldsfld lines which call a designer field
182-
if (!body.Method.FullName.StartsWith ("System.Void Xamarin.Forms.Platform.Android.FormsAppCompatActivity::OnCreate", StringComparison.Ordinal))
183-
return;
184-
Context.LogMessage ($" Fixing up {body.Method.FullName} for {designer.FullName}");
197+
//if (!body.Method.FullName.StartsWith ("System.Void Xamarin.Forms.Platform.Android.FormsAppCompatActivity::OnCreate", StringComparison.Ordinal))
198+
// return;
185199

186200
// IL_0068: ldsfld int32 Xamarin.Forms.Platform.Android.Resource/Layout::Toolbar
187201
// replace with
@@ -194,22 +208,23 @@ void FixBody (MethodBody body, TypeDefinition designer)
194208
string line = i.ToString ();
195209
int idx = line.IndexOf (designerFullName, StringComparison.OrdinalIgnoreCase);
196210
if (idx >= 0) {
197-
Context.LogMessage ($" {i.OpCode} => {line}");
211+
LogMessage ($" Fixing up {body.Method.FullName} for {designer.FullName}");
212+
LogMessage ($" {i.OpCode} => {line}");
198213
string key = line.Substring (idx + designerFullName.Length);
199-
Context.LogMessage ($" Looking for {key}");
214+
LogMessage ($" Looking for {key}");
200215
if (lookup.TryGetValue (key, out MethodDefinition method)) {
201-
Context.LogMessage ($" Found {key}");
216+
LogMessage ($" Found {key}");
202217
var importedMethod = designer.Module.ImportReference (method);
203218
var newIn = Instruction.Create (OpCodes.Call, importedMethod);
204219
instructions.Add (i, newIn);
205220
}
206221
}
207222
}
208223
if (instructions.Count > 0)
209-
Context.LogMessage ($" Fixing up {body.Method.FullName}");
224+
LogMessage ($" Fixing up {body.Method.FullName}");
210225
foreach (var i in instructions)
211226
{
212-
Context.LogMessage ($" Fixing up {i.Key} => {i.Value}");
227+
LogMessage ($" Fixing up {i.Key} => {i.Value}");
213228
processor.Replace(i.Key, i.Value);
214229
}
215230
}

src/Xamarin.Android.Build.Tasks/Linker/MonoDroid.Tuner/Linker.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -111,7 +111,7 @@ static Pipeline CreatePipeline (LinkerOptions options)
111111
pipeline.AppendStep (new RemoveResources (options.I18nAssemblies)); // remove collation tables
112112
// end monodroid specific
113113

114-
pipeline.AppendStep (new FixLegacyResourceDesignerStep ());
114+
pipeline.AppendStep (new FixLegacyResourceDesignerStep (cache));
115115
pipeline.AppendStep (new FixAbstractMethodsStep (cache));
116116
pipeline.AppendStep (new MonoDroidMarkStep (cache));
117117
pipeline.AppendStep (new SweepStep ());

src/Xamarin.Android.Build.Tasks/MSBuild/Xamarin/Android/Xamarin.Android.Resource.Designer.targets

Lines changed: 37 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,11 @@ Copyright (C) 2016 Xamarin. All rights reserved.
2222
<PropertyGroup>
2323
<AndroidUseDesignerAssembly Condition=" '$(AndroidUseIntermediateDesignerFile)' == 'False' And '$(AndroidUseDesignerAssembly)' == '' ">True</AndroidUseDesignerAssembly>
2424
<AndroidUseDesignerAssembly Condition=" '$(AndroidUseDesignerAssembly)' == '' ">False</AndroidUseDesignerAssembly>
25-
<_GenerateResourceDesignerAssemblyOutput>$(IntermediateOutputPath)Xamarin.Android.Resource.Designer.dll</_GenerateResourceDesignerAssemblyOutput>
26-
<_GenerateResourceDesignerClassFile>$(IntermediateOutputPath)_Xamarin.Android.Resource.Designer.cs</_GenerateResourceDesignerClassFile>
25+
<_DesignerIntermediateOutputPath Condition="'$(_OuterIntermediateOutputPath)' != '' ">$(_OuterIntermediateOutputPath)</_DesignerIntermediateOutputPath>
26+
<_DesignerIntermediateOutputPath Condition="'$(_DesignerIntermediateOutputPath)' == '' ">$(IntermediateOutputPath)</_DesignerIntermediateOutputPath>
27+
<_GenerateResourceDesignerAssemblyOutput>$(_DesignerIntermediateOutputPath)Xamarin.Android.Resource.Designer.dll</_GenerateResourceDesignerAssemblyOutput>
28+
<_GenerateResourceDesignerClassFile Condition=" '$(Language)' == 'F#' ">$(_DesignerIntermediateOutputPath)_Xamarin.Android.Resource.Designer.fs</_GenerateResourceDesignerClassFile>
29+
<_GenerateResourceDesignerClassFile Condition=" '$(_GenerateResourceDesignerClassFile)' == '' ">$(_DesignerIntermediateOutputPath)_Xamarin.Android.Resource.Designer.cs</_GenerateResourceDesignerClassFile>
2730
</PropertyGroup>
2831

2932
<Target Name="_GenerateResourceDesignerIntermediateClass"
@@ -41,17 +44,21 @@ Copyright (C) 2016 Xamarin. All rights reserved.
4144
</GenerateResourceDesignerIntermediateClass>
4245
<ItemGroup>
4346
<FileWrites Include="$(_GenerateResourceDesignerClassFile)" />
44-
<Compile Include="$(_GenerateResourceDesignerClassFile)" />
47+
<Compile Include="$(_GenerateResourceDesignerClassFile)" Condition=" '$(Language)' != 'F#' "/>
48+
<!-- For F# we need to use the CompileBefore ItemGroup so that our type is processed
49+
before all the other types in the build. Otherwise we get weird compiler errors.
50+
-->
51+
<CompileBefore Include="$(_GenerateResourceDesignerClassFile)" Condition=" '$(Language)' == 'F#' "/>
4552
</ItemGroup>
4653
</Target>
4754

4855
<Target Name="_GenerateResourceDesignerAssembly"
49-
Inputs="$(IntermediateOutputPath)R.txt"
56+
Inputs="$(_DesignerIntermediateOutputPath)R.txt"
5057
Outputs="$(_GenerateResourceDesignerAssemblyOutput)"
51-
Condition=" '$(AndroidUseDesignerAssembly)' == 'True' And Exists ('$(IntermediateOutputPath)R.txt') ">
58+
Condition=" '$(AndroidUseDesignerAssembly)' == 'True' And Exists ('$(_DesignerIntermediateOutputPath)R.txt')">
5259
<GenerateResourceDesignerAssembly
5360
ContinueOnError="$(DesignTimeBuild)"
54-
RTxtFile="$(IntermediateOutputPath)R.txt"
61+
RTxtFile="$(_DesignerIntermediateOutputPath)R.txt"
5562
IsApplication="$(AndroidApplication)"
5663
DesignTimeBuild="$(DesignTimeBuild)"
5764
OutputFile="$(_GenerateResourceDesignerAssemblyOutput)"
@@ -67,13 +74,35 @@ Copyright (C) 2016 Xamarin. All rights reserved.
6774
<ItemGroup>
6875
<FileWrites Include="$(_GenerateResourceDesignerAssemblyOutput)" />
6976
<ReferencePath Include="$(_GenerateResourceDesignerAssemblyOutput)">
70-
<CopyLocal>true</CopyLocal>
77+
<PostprocessAssembly>True</PostprocessAssembly>
78+
<CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory>
79+
<IsTrimmable>true</IsTrimmable>
80+
<RuntimeIdentifier>android</RuntimeIdentifier>
7181
</ReferencePath>
72-
<ResolvedFileToPublish Include="$(_GenerateResourceDesignerAssemblyOutput)" />
82+
<ResolvedFileToPublish Include="$(_GenerateResourceDesignerAssemblyOutput)">
83+
<PostprocessAssembly>True</PostprocessAssembly>
84+
<CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory>
85+
<IsTrimmable>true</IsTrimmable>
86+
<TrimMode>link</TrimMode>
87+
<RuntimeIdentifier>android</RuntimeIdentifier>
88+
</ResolvedFileToPublish>
7389
<Compile Remove="$(_AndroidResourceDesignerFile)" />
7490
</ItemGroup>
7591
</Target>
7692

93+
94+
<Target Name="_InjectDesigner" AfterTargets="PrepareForILLink" BeforeTargets="_RunILLink">
95+
<ItemGroup>
96+
<ManagedAssemblyToLink Include="$(_GenerateResourceDesignerAssemblyOutput)">
97+
<PostprocessAssembly>True</PostprocessAssembly>
98+
<CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory>
99+
<IsTrimmable>true</IsTrimmable>
100+
<TrimMode>link</TrimMode>
101+
<RuntimeIdentifier>android</RuntimeIdentifier>
102+
</ManagedAssemblyToLink>
103+
</ItemGroup>
104+
</Target>
105+
77106
<PropertyGroup>
78107
<BuildResourceDesignerDependsOn>
79108
$(_GenerateResourceDesignerIntermediateClass);

src/Xamarin.Android.Build.Tasks/Microsoft.Android.Sdk/targets/Microsoft.Android.Sdk.ILLink.targets

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,12 @@ This file contains the .NET 5-specific targets to customize ILLink
9292
AfterStep="CleanStep"
9393
Type="MonoDroid.Tuner.GetAssembliesStep"
9494
/>
95-
95+
<_TrimmerCustomSteps
96+
Condition=" '$(AndroidUseDesignerAssembly)' == 'true' "
97+
Include="$(_AndroidLinkerCustomStepAssembly)"
98+
AfterStep="CleanStep"
99+
Type="MonoDroid.Tuner.FixLegacyResourceDesignerStep"
100+
/>
96101
<_PreserveLists Include="$(MSBuildThisFileDirectory)..\PreserveLists\*.xml" />
97102
<TrimmerRootDescriptor
98103
Condition=" '@(ResolvedFileToPublish->Count())' != '0' and '%(Filename)' != '' "

src/Xamarin.Android.Build.Tasks/Tasks/GenerateResourceDesignerIntermediateClass.cs

Lines changed: 28 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
1+
using System;
12
using System.IO;
3+
using System.CodeDom.Compiler;
24
using Microsoft.Build.Framework;
35
using Microsoft.Build.Utilities;
46
using Microsoft.Android.Build.Tasks;
@@ -9,18 +11,37 @@ public class GenerateResourceDesignerIntermediateClass : AndroidTask
911
{
1012
public override string TaskPrefix => "GRDIC";
1113

14+
private const string CSharpTemplate = @"// This is an Auto Generated file DO NOT EDIT
15+
using System;
16+
17+
namespace %NAMESPACE% {
18+
public class Resource : Xamarin.Android.Resource.Designer.Resource {
19+
}
20+
}
21+
";
22+
private const string FSharpTemplate = @"// This is an Auto Generated file DO NOT EDIT
23+
namespace %NAMESPACE%
24+
25+
type Resource = Xamarin.Android.Resource.Designer.Resource
26+
";
27+
1228
public string Namespace { get; set; }
1329
public ITaskItem OutputFile { get; set; }
1430
public override bool RunTask ()
1531
{
16-
File.WriteAllText (OutputFile.ItemSpec, $@"// This is an Auto Generated file DO NOT EDIT
17-
using System;
32+
var extension = Path.GetExtension (OutputFile.ItemSpec);
33+
var language = string.Compare (extension, ".fs", StringComparison.OrdinalIgnoreCase) == 0 ? "F#" : CodeDomProvider.GetLanguageFromExtension (extension);
34+
//bool isVB = string.Equals (extension, ".vb", StringComparison.OrdinalIgnoreCase);
35+
bool isFSharp = string.Equals (language, "F#", StringComparison.OrdinalIgnoreCase);
36+
bool isCSharp = string.Equals (language, "C#", StringComparison.OrdinalIgnoreCase);
37+
string template = "";
38+
if (isCSharp)
39+
template = CSharpTemplate.Replace ("%NAMESPACE%", Namespace);
40+
else if (isFSharp)
41+
template = FSharpTemplate.Replace ("%NAMESPACE%", Namespace);
42+
1843

19-
namespace {Namespace} {{
20-
public class Resource : Xamarin.Android.Resource.Designer.Resource {{
21-
}}
22-
}}
23-
", System.Text.Encoding.UTF8);
44+
File.WriteAllText (OutputFile.ItemSpec, template, System.Text.Encoding.UTF8);
2445
return !Log.HasLoggedErrors;
2546
}
2647
}

0 commit comments

Comments
 (0)