Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,9 @@ jobs:
fileName: 'Portable.Xaml.snk'
encodedString: ${{ secrets.STRONG_NAME_KEY }}

- name: Clear package cache as a temporary workaround for actions/setup-dotnet#155
run: dotnet clean && dotnet nuget locals all --clear

- name: Build
run: dotnet build ${{ env.PlatformBuildParameters }} ${{ env.BuildParameters }} "/p:AssemblyOriginatorKeyFile=${{ steps.get_strong_name.outputs.filePath }}"

Expand Down
37 changes: 33 additions & 4 deletions src/Portable.Xaml/Portable.Xaml/PrefixLookup.cs
Original file line number Diff line number Diff line change
Expand Up @@ -70,16 +70,45 @@ public string AddNamespace (string ns)
string prefix, s;
if (ns == XamlLanguage.Xaml2006Namespace)
prefix = "x";
else if (!l.Any (i => i.Prefix == String.Empty))
else if (!AnyHavePrefix(l, String.Empty))
prefix = String.Empty;
else if ((s = GetAcronym (ns)) != null && !l.Any (i => i.Prefix == s))
prefix = s;
else
prefix = sctx.GetPreferredPrefix (ns);
{
s = GetAcronym(ns) ?? sctx.GetPreferredPrefix(ns);
prefix = AnyHavePrefix(l, s) ? MakePrefixAddNumber(l, s) : s;
}
l.Add (new NamespaceDeclaration (ns, prefix));
return prefix;
}

string MakePrefixAddNumber(List<NamespaceDeclaration> namespaces, string prefix)
{
var prefixLen = prefix.Length;

int max = 0;
for (int i = 0; i < namespaces.Count; i++)
{
var p = namespaces[i].Prefix;
var suffix = !p.StartsWith(prefix) ? 0 :
int.TryParse(p.Substring(prefixLen), out var idx) ? idx :
0;
max = Math.Max(suffix, max);
}

return prefix + (max+1);
}

bool AnyHavePrefix(List<NamespaceDeclaration> namespaces, string prefix)
{
for (int i = 0; i < namespaces.Count; i++)
{
var ns = namespaces[i];
if (ns.Prefix == prefix)
return true;
}
return false;
}

const string pre = "clr-namespace:";

string GetAcronym (string ns)
Expand Down
107 changes: 106 additions & 1 deletion src/Test/System.Xaml/XamlXmlWriterTest.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
//
//
// Copyright (C) 2010 Novell Inc. http://novell.com
//
// Permission is hereby granted, free of charge, to any person obtaining
Expand Down Expand Up @@ -27,6 +27,7 @@
using System.Linq;
using System.Reflection;
using NUnit.Framework;
using System.Xml.Serialization;
#if PORTABLE_XAML
using Portable.Xaml.Markup;
using Portable.Xaml.ComponentModel;
Expand Down Expand Up @@ -1281,10 +1282,114 @@ public void Write_ShoudSerializeObjectInCollection()
Assert.AreEqual(xaml, actual);
}
}

[Test]
public void Write_AcronymNonDuplicate()
{
var list = new List<object>();
list.Add(new Acronym.Class1());

var genXaml = XamlServices.Save(list);

// match object
var readList = XamlServices.Parse(genXaml);
Assert.AreEqual(list, readList, "#1");

// check namespace
Assert.IsTrue(genXaml.Contains(@"xmlns:tpxa=""clr-namespace:Tests.Portable.Xaml.Acronym;assembly="), "#2");
}
[Test]
public void Write_AcronymDuplicate1()
{
var list = new List<object>();
list.Add(new Acronym.Class1());
list.Add(new Acronym1.Class1());

var genXaml = XamlServices.Save(list);

// match object
var readList = XamlServices.Parse(genXaml);
Assert.AreEqual(list, readList, "#1");

// check namespace
Assert.IsTrue(genXaml.Contains(@"xmlns:tpxa=""clr-namespace:Tests.Portable.Xaml.Acronym;assembly="), "#2");
Assert.IsTrue(genXaml.Contains(@"xmlns:tpxa1=""clr-namespace:Tests.Portable.Xaml.Acronym1;assembly="), "#3");
}

[Test]
public void Write_AcronymDuplicate2()
{
var list = new List<object>();
list.Add(new Acronym.Class1());
list.Add(new Acronym1.Class1());
list.Add(new Acronym2.Class1());

var genXaml = XamlServices.Save(list);

// match object
var readList = XamlServices.Parse(genXaml);
Assert.AreEqual(list, readList, "#1");

// check namespace
Assert.IsTrue(genXaml.Contains(@"xmlns:tpxa=""clr-namespace:Tests.Portable.Xaml.Acronym;assembly="), "#2");
Assert.IsTrue(genXaml.Contains(@"xmlns:tpxa1=""clr-namespace:Tests.Portable.Xaml.Acronym1;assembly="), "#3");
Assert.IsTrue(genXaml.Contains(@"xmlns:tpxa2=""clr-namespace:Tests.Portable.Xaml.Acronym2;assembly="), "#4");
}

[Test]
public void Write_AcronymDuplicate3()
{
var list = new List<object>();
list.Add(new Acronym.Class1());
list.Add(new Acronym1.Class1());
list.Add(new Acronym2.Class1());
list.Add(new Acronym3.Class1());

var genXaml = XamlServices.Save(list);

// match object
var readList = XamlServices.Parse(genXaml);
Assert.AreEqual(list, readList, "#1");

// check namespace
Assert.IsTrue(genXaml.Contains(@"xmlns:tpxa=""clr-namespace:Tests.Portable.Xaml.Acronym;assembly="), "#2");
Assert.IsTrue(genXaml.Contains(@"xmlns:tpxa1=""clr-namespace:Tests.Portable.Xaml.Acronym1;assembly="), "#3");
Assert.IsTrue(genXaml.Contains(@"xmlns:tpxa2=""clr-namespace:Tests.Portable.Xaml.Acronym2;assembly="), "#4");
Assert.IsTrue(genXaml.Contains(@"xmlns:tpxa3=""clr-namespace:Tests.Portable.Xaml.Acronym3;assembly="), "#5");
}
}

public class TestXmlWriterClass1
{
public int Foo { get; set; }
}

namespace Acronym
{
public class Class1 {
public override bool Equals(object obj)
{
if (obj == null)
{
return false;
}

return GetType() == obj.GetType();
}

public override int GetHashCode() =>this.GetType().GetHashCode();
}
}
namespace Acronym1
{
public class Class1: Acronym.Class1 { }
}
namespace Acronym2
{
public class Class1: Acronym.Class1 { }
}
namespace Acronym3
{
public class Class1: Acronym.Class1 { }
}
}