Skip to content

Commit a5855a5

Browse files
committed
get the FileResourceParser kinda working
1 parent ac021a7 commit a5855a5

File tree

6 files changed

+113
-23
lines changed

6 files changed

+113
-23
lines changed

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,11 +19,11 @@ public class GenerateRtxt : AndroidTask
1919

2020
[Required]
2121
public string ResourceDirectory { get; set; }
22-
2322
public string[] AdditionalResourceDirectories { get; set; }
2423

2524
public string JavaPlatformJarPath { get; set; }
2625

26+
public string ResourceFlagFile { get; set; }
2727
public string CaseMapFile { get; set; }
2828

2929
public override bool RunTask ()

src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/Tasks/ManagedResourceParserTests.cs

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -479,19 +479,27 @@ public void RtxtGeneratorOutput ()
479479
int platform = AndroidSdkResolver.GetMaxInstalledPlatform ();
480480
string resPath = Path.Combine (Root, path, "res");
481481
string rTxt = Path.Combine (Root, path, "R.txt");
482+
string expectedrTxt = Path.Combine (Root, path, "expectedR.txt");
483+
File.WriteAllText (expectedrTxt, Rtxt);
482484
CreateResourceDirectory (path);
483485
List<BuildErrorEventArgs> errors = new List<BuildErrorEventArgs> ();
484486
List<BuildMessageEventArgs> messages = new List<BuildMessageEventArgs> ();
485487
IBuildEngine engine = new MockBuildEngine (TestContext.Out, errors: errors, messages: messages);
486488
var generateRtxt = new GenerateRtxt () {
487489
BuildEngine = engine,
488-
RtxtFile = rTxt,
490+
RTxtFile = rTxt,
489491
ResourceDirectory = resPath,
490492
JavaPlatformJarPath = Path.Combine (AndroidSdkDirectory, "platforms", $"android-{platform}", "android.jar"),
493+
ResourceFlagFile = Path.Combine (Root, path, "res.flag"),
494+
AdditionalResourceDirectories = new string[] {
495+
Path.Combine (Root, path, "lp", "res"),
496+
},
491497
};
492498
Assert.IsTrue (generateRtxt.Execute (), "Task should have succeeded.");
493499
FileAssert.Exists (rTxt, $"{rTxt} should have been created.");
494500

501+
CompareFilesIgnoreRuntimeInfoString (rTxt, expectedrTxt);
502+
495503
Directory.Delete (Path.Combine (Root, path), recursive: true);
496504
}
497505

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

Lines changed: 92 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -16,12 +16,20 @@ namespace Xamarin.Android.Tasks
1616
{
1717
class FileResourceParser : ResourceParser
1818
{
19+
public string JavaPlatformDirectory { get; set; }
20+
21+
public string ResourceFlagFile { get; set; }
22+
1923
Dictionary<R, R []> arrayMapping = new Dictionary<R, R []> ();
20-
public Dictionary<string, R> Parse (string resourceDirectory, IEnumerable<string> additionalResourceDirectories, Dictionary<string, string> resourceMap)
24+
public IDictionary<string, R> Parse (string resourceDirectory, IEnumerable<string> additionalResourceDirectories, Dictionary<string, string> resourceMap)
2125
{
22-
Log.LogDebugMessage ($"Processing Directory {resourceDirectory}");
23-
var result = new Dictionary<string, R> ();
26+
Log.LogDebugMessage ($"Parsing Directory {resourceDirectory}");
27+
var result = new SortedDictionary<string, R> ();
2428
Dictionary<string, SortedSet<R>> resources = new Dictionary<string, SortedSet<R>> ();
29+
foreach (var kvp in RtxtParser.knownTypes) {
30+
Log.LogDebugMessage ($"Adding {kvp.Key}");
31+
resources.Add (kvp.Key, new SortedSet<R> ());
32+
}
2533
foreach (var dir in Directory.EnumerateDirectories (resourceDirectory, "*", SearchOption.TopDirectoryOnly)) {
2634
foreach (var file in Directory.EnumerateFiles (dir, "*.*", SearchOption.AllDirectories)) {
2735
ProcessResourceFile (file, resources);
@@ -39,11 +47,25 @@ public Dictionary<string, R> Parse (string resourceDirectory, IEnumerable<string
3947
}
4048
}
4149
}
50+
foreach (var kvp in resources) {
51+
foreach (R r in kvp.Value) {
52+
if (!result.ContainsKey (r.ToSortedString()))
53+
result.Add (r.ToSortedString(), r);
54+
}
55+
}
4256
return result;
4357
}
4458

59+
HashSet<string> resourceNamesToUseDirectly = new HashSet<string> () {
60+
"integer-array",
61+
"string-array",
62+
"declare-styleable",
63+
"add-resource",
64+
};
65+
4566
void ProcessResourceFile (string file, Dictionary<string, SortedSet<R>> resources)
4667
{
68+
Log.LogDebugMessage ($"{nameof(ProcessResourceFile)} {file}");
4769
var fileName = Path.GetFileNameWithoutExtension (file);
4870
if (string.IsNullOrEmpty (fileName))
4971
return;
@@ -65,22 +87,55 @@ void ProcessResourceFile (string file, Dictionary<string, SortedSet<R>> resource
6587
default:
6688
break;
6789
}
68-
if (!resources.ContainsKey (path))
69-
resources[path] = new SortedSet<R>();
90+
// if (!resources.ContainsKey (path)) {
91+
// Log.LogDebugMessage ($"Registering {path}");
92+
// resources[path] = new SortedSet<R>();
93+
// }
94+
CreateResourceField (path, fileName, resources);
95+
}
96+
97+
void CreateResourceField (string root, string id, Dictionary<string, SortedSet<R>> resources) {
98+
var i = root.IndexOf ('-');
99+
var item = i < 0 ? root : root.Substring (0, i);
100+
item = resourceNamesToUseDirectly.Contains (root) ? root : item;
101+
switch (item.ToLower()) {
102+
case "array":
103+
case "string-array":
104+
case "integer-array":
105+
item = "array";
106+
break;
107+
case "enum":
108+
case "flag":
109+
item = "id";
110+
break;
111+
}
70112
var r = new R () {
71-
ResourceTypeName = path,
72-
Identifier = fileName,
113+
ResourceTypeName = item,
114+
Identifier = id,
73115
Id = -1,
74116
};
75-
resources[path].Add (r);
117+
if (!resources.ContainsKey (item)) {
118+
Log.LogDebugMessage ($"Ignoring path:{item} r:{r}");
119+
return;
120+
}
121+
Log.LogDebugMessage ($"Adding 5 path:{item} r:{r}");
122+
resources[item].Add (r);
76123
}
77124

78125
void ProcessStyleable (XmlReader reader, Dictionary<string, SortedSet<R>> resources)
79126
{
127+
Log.LogDebugMessage ($"{nameof(ProcessStyleable)}");
80128
string topName = null;
81129
int fieldCount = 0;
82130
List<R> fields = new List<R> ();
83131
List<string> attribs = new List<string> ();
132+
if (reader.HasAttributes) {
133+
while (reader.MoveToNextAttribute ()) {
134+
if (reader.Name.Replace ("android:", "") == "name")
135+
topName = reader.Value;
136+
Log.LogDebugMessage ($"found top:{topName}");
137+
}
138+
}
84139
while (reader.Read ()) {
85140
if (reader.NodeType == XmlNodeType.Whitespace || reader.NodeType == XmlNodeType.Comment)
86141
continue;
@@ -90,10 +145,11 @@ void ProcessStyleable (XmlReader reader, Dictionary<string, SortedSet<R>> resour
90145
while (reader.MoveToNextAttribute ()) {
91146
if (reader.Name.Replace ("android:", "") == "name")
92147
topName = reader.Value;
148+
Log.LogDebugMessage ($"found {topName}");
93149
}
94150
}
95151
}
96-
if (!reader.IsStartElement () || reader.LocalName == "declare-styleable")
152+
if (!reader.IsStartElement ())
97153
continue;
98154
if (reader.HasAttributes) {
99155
while (reader.MoveToNextAttribute ()) {
@@ -111,6 +167,7 @@ void ProcessStyleable (XmlReader reader, Dictionary<string, SortedSet<R>> resour
111167
Identifier = name,
112168
Id = -1,
113169
};
170+
Log.LogDebugMessage ($"Adding {r}");
114171
resources [r.ResourceTypeName].Add (r);
115172
}
116173
}
@@ -124,20 +181,22 @@ void ProcessStyleable (XmlReader reader, Dictionary<string, SortedSet<R>> resour
124181
attribs.Sort (StringComparer.OrdinalIgnoreCase);
125182
for (int i = 0; i < attribs.Count; i++) {
126183
string name = attribs [i];
184+
Log.LogDebugMessage ($"Checking {name}");
127185
if (!name.StartsWith ("android:", StringComparison.OrdinalIgnoreCase)) {
128186
var r = new R () {
129-
ResourceTypeName = "attrib",
130-
Identifier = name,
187+
ResourceTypeName = "attr",
188+
Identifier = $"{name}",
131189
Id = -1,
132190
};
191+
Log.LogDebugMessage ($"Adding {r}");
133192
resources [r.ResourceTypeName].Add (r);
134193
fields.Add (r);
135194
} else {
136195
// this is an android:xxx resource, we should not calculate the id
137196
// we should get it from "somewhere" maybe the pubic.xml
138197
var r = new R () {
139-
ResourceTypeName = "attrib",
140-
Identifier = name,
198+
ResourceTypeName = "attr",
199+
Identifier = $"{name}",
141200
Id = 0,
142201
};
143202
fields.Add (r);
@@ -146,17 +205,31 @@ void ProcessStyleable (XmlReader reader, Dictionary<string, SortedSet<R>> resour
146205
if (field.Type != RType.Array)
147206
return;
148207
arrayMapping.Add (field, fields.ToArray ());
208+
field.Ids = new int [fields.Count];
209+
resources [field.ResourceTypeName].Add (field);
210+
foreach (R r in fields) {
211+
resources [field.ResourceTypeName].Add (new R () {
212+
ResourceTypeName = field.ResourceTypeName,
213+
Identifier = $"{field.Identifier}_{r.Identifier.Replace (":", "_")}",
214+
Id = 0,
215+
});
216+
}
149217
}
150218
}
151219

152220
void ProcessXmlFile (string file, Dictionary<string, SortedSet<R>> resources)
153221
{
222+
Log.LogDebugMessage ($"{nameof(ProcessXmlFile)}");
154223
using (var reader = XmlReader.Create (file)) {
155224
while (reader.Read ()) {
156225
if (reader.NodeType == XmlNodeType.Whitespace || reader.NodeType == XmlNodeType.Comment)
157226
continue;
158227
if (reader.IsStartElement ()) {
159228
var elementName = reader.Name;
229+
if (elementName == "declare-styleable" || elementName == "configVarying" || elementName == "add-resource") {
230+
ProcessStyleable (reader, resources);
231+
continue;
232+
}
160233
if (reader.HasAttributes) {
161234
string name = null;
162235
string type = null;
@@ -186,17 +259,20 @@ void ProcessXmlFile (string file, Dictionary<string, SortedSet<R>> resources)
186259
Identifier = inflateId,
187260
Id = -1,
188261
};
262+
Log.LogDebugMessage ($"Adding 1 {r}");
189263
resources[r.ResourceTypeName].Add (r);
190264
}
191265
}
266+
Log.LogDebugMessage ($"DEBUG! name:{name} id:{id} type:{type} elementName:{elementName}");
192267
if (name?.Contains ("android:") ?? false)
193268
continue;
194269
if (id?.Contains ("android:") ?? false)
195270
continue;
196271
// Move the reader back to the element node.
197272
reader.MoveToElement ();
198-
//if (!string.IsNullOrEmpty (name))
199-
//CreateResourceField (type ?? elementName, name, reader.ReadSubtree ());
273+
if (!string.IsNullOrEmpty (name)) {
274+
CreateResourceField (type ?? elementName, name, resources);
275+
}
200276
//if (!string.IsNullOrEmpty (custom_id) && !custom_types.TryGetValue (custom_id, out customClass)) {
201277
//customClass = CreateClass (custom_id);
202278
//custom_types.Add (custom_id, customClass);
@@ -208,6 +284,7 @@ void ProcessXmlFile (string file, Dictionary<string, SortedSet<R>> resources)
208284
Identifier = id,
209285
Id = -1,
210286
};
287+
Log.LogDebugMessage ($"Adding 2 {r}");
211288
resources[r.ResourceTypeName].Add (r);
212289
}
213290
}

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

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -37,10 +37,6 @@ public int Compare((int Key, CodeMemberField Value) x, (int Key, CodeMemberField
3737

3838
XDocument publicXml;
3939

40-
public string JavaPlatformDirectory { get; set; }
41-
42-
public string ResourceFlagFile { get; set; }
43-
4440
void SortMembers (CodeTypeDeclaration decl, StringComparison stringComparison = StringComparison.OrdinalIgnoreCase)
4541
{
4642
CodeTypeMember [] members = new CodeTypeMember [decl.Members.Count];

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

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ public enum ResourceType {
1515
System,
1616
Custom,
1717
}
18-
public struct R {
18+
public struct R : IComparable<R> {
1919
public RType Type;
2020
public int Id;
2121
public int [] Ids;
@@ -30,6 +30,14 @@ public override string ToString () {
3030
return $"int {ResourceTypeName} {Identifier} 0x{Id.ToString ("x")}";
3131
return $"int[] {ResourceTypeName} {Identifier} {{{String.Join (",", Ids.Select (x => $"0x{x.ToString ("x")}"))}}}";
3232
}
33+
34+
public string ToSortedString () {
35+
return $"{ResourceTypeName}_{Identifier}";
36+
}
37+
38+
public int CompareTo(R other) {
39+
return String.Compare (ToSortedString (), other.ToSortedString (), StringComparison.Ordinal);
40+
}
3341
}
3442

3543
public class RtxtParser {
@@ -46,6 +54,7 @@ public class RtxtParser {
4654
{ "color", StringComparison.OrdinalIgnoreCase },
4755
{ "dimen", StringComparison.OrdinalIgnoreCase },
4856
{ "drawable", StringComparison.OrdinalIgnoreCase },
57+
{ "font", StringComparison.OrdinalIgnoreCase },
4958
{ "id", StringComparison.OrdinalIgnoreCase },
5059
{ "integer", StringComparison.OrdinalIgnoreCase },
5160
{ "interpolator", StringComparison.OrdinalIgnoreCase },

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ namespace Xamarin.Android.Tasks
1111
/// Write a list of Item to a file
1212
///
1313
public class RtxtWriter {
14-
public void Write (string file, Dictionary<string, R> items) {
14+
public void Write (string file, IDictionary<string, R> items) {
1515
File.WriteAllLines (file, items.Values.Select (x => x.ToString ()), Encoding.UTF8);
1616
}
1717
}

0 commit comments

Comments
 (0)