Skip to content

Commit 806f6ea

Browse files
committed
introduce the RtxtParser and RtxtWriter
1 parent 2614a88 commit 806f6ea

File tree

7 files changed

+179
-98
lines changed

7 files changed

+179
-98
lines changed

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

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,21 @@ protected void ClearDesignerClass (TypeDefinition designer)
7878
designer.Events.Clear ();
7979
}
8080

81+
protected Dictionary<string, int> BuildResourceDesignerFieldLookup (TypeDefinition type)
82+
{
83+
var output = new Dictionary<string, int> ();
84+
foreach (TypeDefinition definition in type.NestedTypes)
85+
{
86+
foreach (FieldDefinition field in definition.Fields)
87+
{
88+
string key = $"{definition.Name}::{field.Name}";
89+
if (!output.ContainsKey (key))
90+
output.Add(key, int.Parse (field.Constant?.ToString () ?? "0"));
91+
}
92+
}
93+
return output;
94+
}
95+
8196
protected void FixType (TypeDefinition type, TypeDefinition localDesigner)
8297
{
8398
foreach (MethodDefinition method in type.Methods)

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

Lines changed: 0 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -60,21 +60,6 @@ protected override void EndProcess ()
6060
}
6161
}
6262

63-
Dictionary<string, int> BuildResourceDesignerFieldLookup (TypeDefinition type)
64-
{
65-
var output = new Dictionary<string, int> ();
66-
foreach (TypeDefinition definition in type.NestedTypes)
67-
{
68-
foreach (FieldDefinition field in definition.Fields)
69-
{
70-
string key = $"{definition.Name}::{field.Name}";
71-
if (!output.ContainsKey (key))
72-
output.Add(key, int.Parse (field.Constant?.ToString () ?? "0"));
73-
}
74-
}
75-
return output;
76-
}
77-
7863
protected override void FixBody (MethodBody body, TypeDefinition designer)
7964
{
8065
Dictionary<Instruction, int> instructions = new Dictionary<Instruction, int>();

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

Lines changed: 15 additions & 71 deletions
Original file line numberDiff line numberDiff line change
@@ -124,8 +124,21 @@ bool Run(DirectoryAssemblyResolver res) {
124124
CreateCtor (resourceDesigner, module);
125125
module.Types.Add(resourceDesigner);
126126

127-
if (File.Exists (RTxtFile.ItemSpec))
128-
ProcessRtxtFile (RTxtFile.ItemSpec, resourceDesigner, module);
127+
if (File.Exists (RTxtFile.ItemSpec)) {
128+
var parser = new RtxtParser ();
129+
var resources = parser.Parse (RTxtFile.ItemSpec, Log, resource_fixup);
130+
foreach (var resource in resources) {
131+
var r = resource.Value;
132+
switch (r.Type) {
133+
case RType.Integer:
134+
CreateIntProperty (resource.Key, r.Identifier, r.Id, resourceDesigner, module);
135+
break;
136+
case RType.Array:
137+
CreateIntArrayProperty (resource.Key, r.Identifier, r.Ids, resourceDesigner, module);
138+
break;
139+
}
140+
}
141+
}
129142

130143
assembly.Write (OutputFile.ItemSpec);
131144
return !Log.HasLoggedErrors;
@@ -138,59 +151,6 @@ MethodReference ImportCustomAttributeConstructor (string type, ModuleDefinition
138151
return module.ImportReference (tv.Methods.First(x => x.IsConstructor));
139152
}
140153

141-
void ProcessRtxtFile (string file, TypeDefinition resourceDesigner, ModuleDefinition module)
142-
{
143-
var lines = System.IO.File.ReadLines (file);
144-
foreach (var line in lines) {
145-
var items = line.Split (new char [] { ' ' }, 4);
146-
int value = items [1] != "styleable" ? Convert.ToInt32 (items [3], 16) : -1;
147-
string itemName = GetResourceName(items [1], items [2], resource_fixup);
148-
switch (items [1]) {
149-
case "anim":
150-
case "animator":
151-
case "attr":
152-
case "array":
153-
case "bool":
154-
case "color":
155-
case "dimen":
156-
case "drawable":
157-
case "font":
158-
case "id":
159-
case "integer":
160-
case "interpolator":
161-
case "layout":
162-
case "menu":
163-
case "mipmap":
164-
case "plurals":
165-
case "raw":
166-
case "string":
167-
case "style":
168-
case "transition":
169-
case "xml":
170-
CreateIntProperty (items [1], itemName, value, resourceDesigner, module);
171-
break;
172-
case "styleable":
173-
switch (items [0]) {
174-
case "int":
175-
CreateIntProperty (items[1], itemName, Convert.ToInt32 (items [3], 10), resourceDesigner, module);
176-
break;
177-
case "int[]":
178-
var arrayValues = items [3].Trim (new char [] { '{', '}' })
179-
.Replace (" ", "")
180-
.Split (new char [] { ',' });
181-
CreateIntArrayProperty (items[1], itemName,
182-
arrayValues.Select (x => string.IsNullOrEmpty (x) ? -1 : Convert.ToInt32 (x, 16)).ToArray (), resourceDesigner, module);
183-
break;
184-
}
185-
break;
186-
// for custom views
187-
default:
188-
CreateIntProperty (items [1], itemName, value, resourceDesigner, module);
189-
break;
190-
}
191-
}
192-
}
193-
194154
void CreateIntProperty (string resourceClass, string propertyName, int value, TypeDefinition resourceDesigner, ModuleDefinition module)
195155
{
196156
TypeDefinition nestedType = CreateResourceClass (resourceDesigner, resourceClass, module);
@@ -265,21 +225,5 @@ PropertyDefinition CreateArrayProperty (string propertyName, IEnumerable<int> va
265225
il.Emit (OpCodes.Ret);
266226
return p;
267227
}
268-
269-
// TODO: Borrowed code!
270-
internal string GetResourceName (string type, string name, Dictionary<string, string> map)
271-
{
272-
string mappedValue;
273-
string key = string.Format ("{0}{1}{2}", type, Path.DirectorySeparatorChar, name).ToLowerInvariant ();
274-
275-
if (map.TryGetValue (key, out mappedValue)) {
276-
Log.LogDebugMessage (" - Remapping resource: {0}.{1} -> {2}", type, name, mappedValue);
277-
return ResourceIdentifier.CreateValidIdentifier (mappedValue.Substring (mappedValue.LastIndexOf (Path.DirectorySeparatorChar) + 1));
278-
}
279-
280-
Log.LogDebugMessage (" - Not remapping resource: {0}.{1}", type, name);
281-
282-
return ResourceIdentifier.CreateValidIdentifier (name);
283-
}
284228
}
285229
}

src/Xamarin.Android.Build.Tasks/Utilities/ResourceIdentifier.cs

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
using System.Linq;
77
using System.Reflection;
88
using System.Text.RegularExpressions;
9+
using Microsoft.Android.Build.Tasks;
910
using Microsoft.Build.Utilities;
1011

1112
namespace Xamarin.Android.Tasks
@@ -42,5 +43,20 @@ public static string CreateValidIdentifier (string identifier)
4243

4344
return result;
4445
}
46+
47+
internal static string GetResourceName (string type, string name, Dictionary<string, string> map, TaskLoggingHelper log)
48+
{
49+
string mappedValue;
50+
string key = string.Format ("{0}{1}{2}", type, Path.DirectorySeparatorChar, name).ToLowerInvariant ();
51+
52+
if (map.TryGetValue (key, out mappedValue)) {
53+
log.LogDebugMessage (" - Remapping resource: {0}.{1} -> {2}", type, name, mappedValue);
54+
return ResourceIdentifier.CreateValidIdentifier (mappedValue.Substring (mappedValue.LastIndexOf (Path.DirectorySeparatorChar) + 1));
55+
}
56+
57+
log.LogDebugMessage (" - Not remapping resource: {0}.{1}", type, name);
58+
59+
return ResourceIdentifier.CreateValidIdentifier (name);
60+
}
4561
}
46-
}
62+
}

src/Xamarin.Android.Build.Tasks/Utilities/ResourceParser.cs

Lines changed: 1 addition & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -40,17 +40,7 @@ internal static string GetNestedTypeName (string name)
4040

4141
internal string GetResourceName (string type, string name, Dictionary<string, string> map)
4242
{
43-
string mappedValue;
44-
string key = string.Format ("{0}{1}{2}", type, Path.DirectorySeparatorChar, name).ToLowerInvariant ();
45-
46-
if (map.TryGetValue (key, out mappedValue)) {
47-
Log.LogDebugMessage (" - Remapping resource: {0}.{1} -> {2}", type, name, mappedValue);
48-
return ResourceIdentifier.CreateValidIdentifier (mappedValue.Substring (mappedValue.LastIndexOf (Path.DirectorySeparatorChar) + 1));
49-
}
50-
51-
Log.LogDebugMessage (" - Not remapping resource: {0}.{1}", type, name);
52-
53-
return ResourceIdentifier.CreateValidIdentifier (name);
43+
return ResourceIdentifier.GetResourceName (type, name, map, Log);
5444
}
5545

5646
}
Lines changed: 113 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,113 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.IO;
4+
using System.Linq;
5+
using Microsoft.Android.Build.Tasks;
6+
using Microsoft.Build.Utilities;
7+
8+
namespace Xamarin.Android.Tasks
9+
{
10+
public enum RType {
11+
Integer,
12+
Array,
13+
}
14+
public struct R {
15+
public RType Type = RType.Integer;
16+
public int Id;
17+
public int [] Ids;
18+
public string Identifier;
19+
public string ResourceType;
20+
21+
public override string ToString () {
22+
if (Type == RType.Integer)
23+
return $"int {ResourceType} {Identifier} 0x{Id.ToString ("x")}";
24+
return $"int[] {ResourceType} {Identifier} {{{String.Join (",", Ids.Select (x => $"0x{x.ToString ("x")}"))}}}";
25+
}
26+
}
27+
28+
public class RtxtParser {
29+
30+
TaskLoggingHelper log;
31+
Dictionary<string, string> map;
32+
33+
Dictionary<string, string> resource_fixup = new Dictionary<string, string> (StringComparer.OrdinalIgnoreCase);
34+
public Dictionary<string, R> Parse (string file, TaskLoggingHelper logger, Dictionary<string, string> mapping){
35+
log = logger;
36+
map = mapping;
37+
var result = new Dictionary<string, R> ();
38+
if (File.Exists (file))
39+
ProcessRtxtFile (file, result);
40+
return result;
41+
}
42+
43+
void ProcessRtxtFile (string file, Dictionary<string, R> result)
44+
{
45+
var lines = File.ReadLines (file);
46+
foreach (var line in lines) {
47+
var items = line.Split (new char [] { ' ' }, 4);
48+
int value = items [1] != "styleable" ? Convert.ToInt32 (items [3], 16) : -1;
49+
string itemName = ResourceIdentifier.GetResourceName(items [1], items [2], resource_fixup, log);
50+
switch (items [1]) {
51+
case "anim":
52+
case "animator":
53+
case "attr":
54+
case "array":
55+
case "bool":
56+
case "color":
57+
case "dimen":
58+
case "drawable":
59+
case "font":
60+
case "id":
61+
case "integer":
62+
case "interpolator":
63+
case "layout":
64+
case "menu":
65+
case "mipmap":
66+
case "plurals":
67+
case "raw":
68+
case "string":
69+
case "style":
70+
case "transition":
71+
case "xml":
72+
result[ items [1]] = new R () {
73+
ResourceType = items[1],
74+
Identifier = itemName,
75+
Id = value,
76+
};
77+
break;
78+
case "styleable":
79+
switch (items [0]) {
80+
case "int":
81+
result[ items [1]] = new R () {
82+
ResourceType = items[1],
83+
Identifier = itemName,
84+
Id = Convert.ToInt32 (items [3], 10),
85+
};
86+
break;
87+
case "int[]":
88+
var arrayValues = items [3].Trim (new char [] { '{', '}' })
89+
.Replace (" ", "")
90+
.Split (new char [] { ',' });
91+
92+
result[ items [1]] = new R () {
93+
ResourceType = items[1],
94+
Type = RType.Array,
95+
Identifier = itemName,
96+
Ids = arrayValues.Select (x => string.IsNullOrEmpty (x) ? -1 : Convert.ToInt32 (x, 16)).ToArray (),
97+
};
98+
break;
99+
}
100+
break;
101+
// for custom views
102+
default:
103+
result[ items [1]] = new R () {
104+
ResourceType = items[1],
105+
Identifier = itemName,
106+
Id = value,
107+
};
108+
break;
109+
}
110+
}
111+
}
112+
}
113+
}
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.IO;
4+
using System.Text;
5+
using System.Linq;
6+
using Microsoft.Android.Build.Tasks;
7+
using Microsoft.Build.Utilities;
8+
9+
namespace Xamarin.Android.Tasks
10+
{
11+
/// Write a list of Item to a file
12+
///
13+
public class RtxtWriter {
14+
public void Write (string file, Dictionary<string, R> items) {
15+
File.WriteAllLines (file, items.Values.Select (x => x.ToString ()), Encoding.UTF8);
16+
}
17+
}
18+
}

0 commit comments

Comments
 (0)