Suffix generated file names with a constant hexadecimal hashcode of the source class full namespace.

This commit is contained in:
Pierre-Luc Ledoux 2018-08-16 15:47:34 -04:00
Родитель bab3aa30e3
Коммит 554c619103
5 изменённых файлов: 145 добавлений и 2 удалений

Просмотреть файл

@ -0,0 +1,25 @@
// ******************************************************************
// Copyright <20> 2015-2018 nventive inc. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
// ******************************************************************
namespace Uno.CodeGen.Tests.ExternalClasses
{
[GeneratedImmutable]
public abstract partial class ConcreteExternalGenericClass<TId>
{
[EqualityHash]
public TId Id { get; }
}
}

Просмотреть файл

@ -0,0 +1,25 @@
// ******************************************************************
// Copyright <20> 2015-2018 nventive inc. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
// ******************************************************************
namespace Uno.CodeGen.Tests.ExternalClasses.SubNamespace
{
[GeneratedImmutable]
public partial class ConcreteExternalClass
{
[EqualityHash]
public string Id { get; }
}
}

Просмотреть файл

@ -0,0 +1,25 @@
// ******************************************************************
// Copyright <20> 2015-2018 nventive inc. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
// ******************************************************************
namespace Uno.CodeGen.Tests.ExternalClasses.SubNamespace
{
[GeneratedImmutable]
public abstract partial class ConcreteExternalGenericClass<TId>
{
[EqualityHash]
public TId Id { get; }
}
}

Просмотреть файл

@ -31,9 +31,13 @@ namespace Uno.Helpers
var substitutions = typeToUseForSubstitutions.GetSubstitutionTypes();
var symbolName = typeSymbol.Name;
// Generate a filename suffix from the namespace to prevent filename clashing when processing classes with the same name.
var filenameSuffix = $"{typeSymbol.GetNamespaceHash():X}";
if (typeSymbol.TypeArguments.Length == 0) // not a generic type
{
return new SymbolNames(typeSymbol, symbolName, "", symbolName, symbolName, symbolName, symbolName, "");
return new SymbolNames(typeSymbol, symbolName, "", symbolName, symbolName, symbolName, $"{symbolName}_{filenameSuffix}", "");
}
var argumentNames = typeSymbol.GetTypeArgumentNames(substitutions);
@ -49,7 +53,7 @@ namespace Uno.Helpers
var symbolNameDefinition = $"{symbolName}<{string.Join(",", typeSymbol.TypeArguments.Select(ta => ""))}>";
// symbolNameWithGenerics: MyType_T1_T2
var symbolFilename = $"{symbolName}_{string.Join("_", argumentNames)}";
var symbolFilename = $"{symbolName}_{string.Join("_", argumentNames)}_{filenameSuffix}";
var genericConstraints = " " + string.Join(" ", typeSymbol
.TypeArguments
@ -98,6 +102,19 @@ namespace Uno.Helpers
return result;
}
public static int GetNamespaceHash(this INamedTypeSymbol typeSymbol)
{
var hashCode = 0;
INamespaceSymbol namespaceSymbol = typeSymbol.ContainingNamespace;
while (!namespaceSymbol?.IsGlobalNamespace ?? false)
{
hashCode ^= namespaceSymbol.Name.GetStableHashCode();
namespaceSymbol = namespaceSymbol.ContainingNamespace;
}
return hashCode;
}
}
public class SymbolNames

Просмотреть файл

@ -0,0 +1,51 @@
// ******************************************************************
// Copyright <20> 2015-2018 nventive inc. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
// ******************************************************************
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using Microsoft.CodeAnalysis;
namespace Uno.Helpers
{
public static class StringExtensions
{
public static int GetStableHashCode(this string str)
{
// A fully managed version of the 64bit GetHashCode() that does not use any randomization and will always return
// the same value for equal strings.
// https://stackoverflow.com/questions/36845430/persistent-hashcode-for-strings
unchecked
{
int hash1 = 5381;
int hash2 = hash1;
for (int i = 0; i < str.Length && str[i] != '\0'; i += 2)
{
hash1 = ((hash1 << 5) + hash1) ^ str[i];
if (i == str.Length - 1 || str[i + 1] == '\0')
break;
hash2 = ((hash2 << 5) + hash2) ^ str[i + 1];
}
return hash1 + (hash2 * 1566083941);
}
}
}
}