Skip to content

Commit 0a43b3d

Browse files
committed
Rewrite yaml merging block removal.
Fixes OpenRA#2922, OpenRA#6818.
1 parent b4fa704 commit 0a43b3d

File tree

2 files changed

+33
-26
lines changed

2 files changed

+33
-26
lines changed

OpenRA.Game/GameRules/ActorInfo.cs

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -37,8 +37,7 @@ public ActorInfo(string name, MiniYaml node, Dictionary<string, MiniYaml> allUni
3737

3838
Name = name;
3939
foreach (var t in mergedNode)
40-
if (t.Key != "Inherits" && !t.Key.StartsWith("-"))
41-
Traits.Add(LoadTraitInfo(t.Key.Split('@')[0], t.Value));
40+
Traits.Add(LoadTraitInfo(t.Key.Split('@')[0], t.Value));
4241
}
4342
catch (YamlException e)
4443
{
@@ -69,8 +68,7 @@ static MiniYaml MergeWithParent(MiniYaml node, Dictionary<string, MiniYaml> allU
6968
{
7069
var result = MiniYaml.MergeStrict(node, MergeWithParent(parent, allUnits));
7170

72-
// strip the '-'
73-
result.Nodes.RemoveAll(a => a.Key.StartsWith("-"));
71+
result.Nodes.RemoveAll(a => a.Key == "Inherits");
7472
return result;
7573
}
7674

OpenRA.Game/MiniYaml.cs

100755100644
Lines changed: 31 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -254,17 +254,17 @@ public static List<MiniYamlNode> FromString(string text, string fileName = "<no
254254
return FromLines(text.Split(new[] { "\r\n", "\n" }, StringSplitOptions.RemoveEmptyEntries), fileName);
255255
}
256256

257-
public static List<MiniYamlNode> MergeLiberal(List<MiniYamlNode> a, List<MiniYamlNode> b)
257+
public static List<MiniYamlNode> MergeStrict(List<MiniYamlNode> a, List<MiniYamlNode> b)
258258
{
259259
return Merge(a, b, false);
260260
}
261261

262-
public static List<MiniYamlNode> MergeStrict(List<MiniYamlNode> a, List<MiniYamlNode> b)
262+
public static List<MiniYamlNode> MergeLiberal(List<MiniYamlNode> a, List<MiniYamlNode> b)
263263
{
264264
return Merge(a, b, true);
265265
}
266266

267-
static List<MiniYamlNode> Merge(List<MiniYamlNode> a, List<MiniYamlNode> b, bool throwErrors)
267+
static List<MiniYamlNode> Merge(List<MiniYamlNode> a, List<MiniYamlNode> b, bool allowUnresolvedRemoves = false)
268268
{
269269
if (a.Count == 0)
270270
return b;
@@ -275,58 +275,67 @@ static List<MiniYamlNode> Merge(List<MiniYamlNode> a, List<MiniYamlNode> b, bool
275275

276276
var dictA = a.ToDictionaryWithConflictLog(x => x.Key, "MiniYaml.Merge", null, x => "{0} (at {1})".F(x.Key, x.Location));
277277
var dictB = b.ToDictionaryWithConflictLog(x => x.Key, "MiniYaml.Merge", null, x => "{0} (at {1})".F(x.Key, x.Location));
278-
var keys = dictA.Keys.Union(dictB.Keys).ToList();
278+
var allKeys = dictA.Keys.Union(dictB.Keys);
279279

280-
var noInherit = keys.Where(x => x.Length > 0 && x[0] == '-')
281-
.ToDictionary(x => x.Substring(1), x => false);
280+
var keys = allKeys.Where(x => x.Length == 0 || x[0] != '-').ToList();
281+
var removeKeys = allKeys.Where(x => x.Length > 0 && x[0] == '-')
282+
.Select(k => k.Substring(1)).ToHashSet();
282283

283284
foreach (var key in keys)
284285
{
285286
MiniYamlNode aa, bb;
286287
dictA.TryGetValue(key, out aa);
287288
dictB.TryGetValue(key, out bb);
288289

289-
if (noInherit.ContainsKey(key))
290-
{
291-
if (!throwErrors)
292-
if (aa != null)
293-
ret.Add(aa);
294-
295-
noInherit[key] = true;
296-
}
290+
if (removeKeys.Contains(key))
291+
removeKeys.Remove(key);
297292
else
298293
{
299294
var loc = aa == null ? default(MiniYamlNode.SourceLocation) : aa.Location;
300-
var merged = (aa == null || bb == null) ? aa ?? bb : new MiniYamlNode(key, Merge(aa.Value, bb.Value, throwErrors), loc);
295+
var merged = (aa == null || bb == null) ? aa ?? bb : new MiniYamlNode(key, Merge(aa.Value, bb.Value, allowUnresolvedRemoves), loc);
301296
ret.Add(merged);
302297
}
303298
}
304299

305-
if (throwErrors && noInherit.ContainsValue(false))
306-
throw new YamlException("Bogus yaml removals: {0}".F(
307-
noInherit.Where(x => !x.Value).JoinWith(", ")));
300+
if (removeKeys.Any())
301+
{
302+
if (allowUnresolvedRemoves)
303+
{
304+
// Add the removal nodes back for the next pass to deal with
305+
foreach (var k in removeKeys)
306+
{
307+
var key = "-" + k;
308+
MiniYamlNode rem;
309+
if (!dictA.TryGetValue(key, out rem))
310+
rem = dictB[key];
311+
ret.Add(rem);
312+
}
313+
}
314+
else
315+
throw new YamlException("Bogus yaml removals: {0}".F(removeKeys.JoinWith(", ")));
316+
}
308317

309318
return ret;
310319
}
311320

312321
public static MiniYaml MergeLiberal(MiniYaml a, MiniYaml b)
313322
{
314-
return Merge(a, b, false);
323+
return Merge(a, b, true);
315324
}
316325

317326
public static MiniYaml MergeStrict(MiniYaml a, MiniYaml b)
318327
{
319-
return Merge(a, b, true);
328+
return Merge(a, b, false);
320329
}
321330

322-
static MiniYaml Merge(MiniYaml a, MiniYaml b, bool throwErrors)
331+
static MiniYaml Merge(MiniYaml a, MiniYaml b, bool allowUnresolvedRemoves)
323332
{
324333
if (a == null)
325334
return b;
326335
if (b == null)
327336
return a;
328337

329-
return new MiniYaml(a.Value ?? b.Value, Merge(a.Nodes, b.Nodes, throwErrors));
338+
return new MiniYaml(a.Value ?? b.Value, Merge(a.Nodes, b.Nodes, allowUnresolvedRemoves));
330339
}
331340

332341
public IEnumerable<string> ToLines(string name)

0 commit comments

Comments
 (0)