Skip to content

Commit

Permalink
perf: Reduce lookups and symbol displayname comparisons
Browse files Browse the repository at this point in the history
  • Loading branch information
jeromelaban committed Oct 12, 2020
1 parent c2fb1ee commit 17e19f3
Show file tree
Hide file tree
Showing 4 changed files with 103 additions and 97 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,8 @@ internal class RoslynMetadataHelper
private readonly Dictionary<string, INamedTypeSymbol> _legacyTypes;
private readonly Func<string, ITypeSymbol[]> _findTypesByName;
private readonly Func<string, ITypeSymbol> _findTypeByFullName;
private readonly Func<INamedTypeSymbol, IEnumerable<INamedTypeSymbol>> _getAllDerivingTypes;
private readonly Func<string, IEnumerable<INamedTypeSymbol>> _getAllTypesAttributedWith;
private readonly Func<INamedTypeSymbol, INamedTypeSymbol[]> _getAllDerivingTypes;
private readonly Func<INamedTypeSymbol, INamedTypeSymbol[]> _getAllTypesAttributedWith;
private readonly Dictionary<string, INamedTypeSymbol> _additionalTypesMap;

public Compilation Compilation { get; }
Expand All @@ -39,8 +39,8 @@ public RoslynMetadataHelper(string configuration, Compilation sourceCompilation,
_findTypeByFullName = Funcs.Create<string, ITypeSymbol>(SourceFindTypeByFullName).AsLockedMemoized();
_additionalTypes = additionalTypes ?? new string[0];
_legacyTypes = BuildLegacyTypes(legacyTypes);
_getAllDerivingTypes = Funcs.Create<INamedTypeSymbol, IEnumerable<INamedTypeSymbol>>(GetAllDerivingTypes).AsLockedMemoized();
_getAllTypesAttributedWith = Funcs.Create<string, IEnumerable<INamedTypeSymbol>>(SourceGetAllTypesAttributedWith).AsLockedMemoized();
_getAllDerivingTypes = Funcs.Create<INamedTypeSymbol, INamedTypeSymbol[]>(GetAllDerivingTypes).AsLockedMemoized();
_getAllTypesAttributedWith = Funcs.Create<INamedTypeSymbol, INamedTypeSymbol[]>(SourceGetAllTypesAttributedWith).AsLockedMemoized();
_project = roslynProject;
_nullableSymbol = Compilation.GetTypeByMetadataName("System.Nullable`1");
}
Expand Down Expand Up @@ -246,65 +246,15 @@ public ITypeSymbol GetTypeByFullName(string fullName)
public IArrayTypeSymbol GetArray(ITypeSymbol type) => Compilation.CreateArrayTypeSymbol(type);

public IEnumerable<INamedTypeSymbol> GetAllTypesDerivingFrom(INamedTypeSymbol baseType)
{
return _getAllDerivingTypes(baseType);
}

private IEnumerable<INamedTypeSymbol> GetAllDerivingTypes(INamedTypeSymbol baseType)
{
return GetTypesDerivingFrom(Compilation.GlobalNamespace);

IEnumerable<INamedTypeSymbol> GetTypesDerivingFrom(INamespaceSymbol ns)
{
foreach (var member in ns.GetMembers())
{
if (member is INamespaceSymbol nsInner)
{
foreach (var t in GetTypesDerivingFrom(nsInner))
{
yield return t;
}
}
else if (member is INamedTypeSymbol type)
{
if (((INamedTypeSymbol)member).Is(baseType))
{
yield return type;
}
}
}
}
}
=> _getAllDerivingTypes(baseType);

public IEnumerable<INamedTypeSymbol> GetAllTypesAttributedWith(string attributeClassFullName)
{
return _getAllTypesAttributedWith(attributeClassFullName);
}
private INamedTypeSymbol[] GetAllDerivingTypes(INamedTypeSymbol baseType)
=> Compilation.GlobalNamespace.GetNamespaceTypes().Where(t => t.Is(baseType)).ToArray();

private IEnumerable<INamedTypeSymbol> SourceGetAllTypesAttributedWith(string attributeClassFullName)
{
return GetTypesAttributedWith(Compilation.GlobalNamespace);
public INamedTypeSymbol[] GetAllTypesAttributedWith(INamedTypeSymbol attributeClass)
=> _getAllTypesAttributedWith(attributeClass);

IEnumerable<INamedTypeSymbol> GetTypesAttributedWith(INamespaceSymbol ns)
{
foreach (var member in ns.GetMembers())
{
if (member is INamespaceSymbol nsInner)
{
foreach (var t in GetTypesAttributedWith(nsInner))
{
yield return t;
}
}
else if (member is INamedTypeSymbol type)
{
if (type.FindAttribute(attributeClassFullName) is AttributeData _)
{
yield return type;
}
}
}
}
}
private INamedTypeSymbol[] SourceGetAllTypesAttributedWith(INamedTypeSymbol attributeClass)
=> Compilation.GlobalNamespace.GetNamespaceTypes().Where(t => t.FindAttribute(attributeClass) is { }).ToArray();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,25 @@ public static IEnumerable<ISymbol> GetAllMembers(this ITypeSymbol symbol)
} while (symbol.SpecialType != SpecialType.System_Object);
}

public static IEnumerable<ISymbol> GetAllMembersWithName(this ITypeSymbol symbol, string name)
{
do
{
foreach (var member in symbol.GetMembers(name))
{
yield return member;
}

symbol = symbol.BaseType;

if (symbol == null)
{
break;
}

} while (symbol.SpecialType != SpecialType.System_Object);
}

public static IEnumerable<IEventSymbol> GetEvents(INamedTypeSymbol symbol) => symbol.GetMembers().OfType<IEventSymbol>();

/// <summary>
Expand Down Expand Up @@ -123,35 +142,55 @@ public static bool IsLocallyPublic(this ISymbol symbol, IModuleSymbol currentSym
);

public static IEnumerable<IMethodSymbol> GetMethods(this INamedTypeSymbol resolvedType)
=> resolvedType.GetMembers().OfType<IMethodSymbol>();

public static IEnumerable<IMethodSymbol> GetMethodsWithName(this INamedTypeSymbol resolvedType, string name)
=> resolvedType.GetMembers(name).OfType<IMethodSymbol>();

public static IEnumerable<IFieldSymbol> GetFields(this INamedTypeSymbol resolvedType)
=> resolvedType.GetMembers().OfType<IFieldSymbol>();

public static IEnumerable<IFieldSymbol> GetFieldsWithName(this INamedTypeSymbol resolvedType, string name)
=> resolvedType.GetMembers(name).OfType<IFieldSymbol>();

/// <summary>
/// Return fields of the current type and all of its ancestors
/// </summary>
/// <param name="symbol"></param>
/// <returns></returns>
public static IEnumerable<IFieldSymbol> GetAllFields(this INamedTypeSymbol symbol)
{
return resolvedType.GetMembers().OfType<IMethodSymbol>();
while (symbol != null)
{
foreach (var property in symbol.GetMembers().OfType<IFieldSymbol>())
{
yield return property;
}

symbol = symbol.BaseType;
}
}

public static IEnumerable<IFieldSymbol> GetFields(this INamedTypeSymbol resolvedType)
/// <summary>
/// Return fields of the current type and all of its ancestors
/// </summary>
/// <param name="symbol"></param>
/// <returns></returns>
public static IEnumerable<IFieldSymbol> GetAllFieldsWithName(this INamedTypeSymbol symbol, string name)
{
return resolvedType.GetMembers().OfType<IFieldSymbol>();
while (symbol != null)
{
foreach (var property in symbol.GetMembers(name).OfType<IFieldSymbol>())
{
yield return property;
}

symbol = symbol.BaseType;
}
}

/// <summary>
/// Return fields of the current type and all of its ancestors
/// </summary>
/// <param name="symbol"></param>
/// <returns></returns>
public static IEnumerable<IFieldSymbol> GetAllFields(this INamedTypeSymbol symbol)
{
while (symbol != null)
{
foreach (var property in symbol.GetMembers().OfType<IFieldSymbol>())
{
yield return property;
}

symbol = symbol.BaseType;
}
}


public static IEnumerable<IFieldSymbol> GetFieldsWithAttribute(this ITypeSymbol resolvedType, string name)

public static IEnumerable<IFieldSymbol> GetFieldsWithAttribute(this ITypeSymbol resolvedType, string name)
{
return resolvedType
.GetMembers()
Expand Down Expand Up @@ -376,6 +415,24 @@ public static IEnumerable<IPropertySymbol> GetAllProperties(this INamedTypeSymbo
}
}

/// <summary>
/// Return properties of the current type and all of its ancestors
/// </summary>
/// <param name="symbol"></param>
/// <returns></returns>
public static IEnumerable<IPropertySymbol> GetAllPropertiesWithName(this INamedTypeSymbol symbol, string name)
{
while (symbol != null)
{
foreach (var property in symbol.GetMembers(name).OfType<IPropertySymbol>())
{
yield return property;
}

symbol = symbol.BaseType;
}
}

/// <summary>
/// Converts declared accessibility on a symbol to a string usable in generated code.
/// </summary>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,7 @@ public bool HasProperty(XamlType xamlType, string propertyName)
{
do
{
if (type.GetAllProperties().Any(property => property.Name == propertyName))
if (type.GetAllPropertiesWithName(propertyName).Any())
{
return true;
}
Expand Down Expand Up @@ -268,8 +268,8 @@ private static bool IsDependencyProperty(INamedTypeSymbol propertyOwner, string
{
if (propertyOwner != null)
{
var propertyDependencyPropertyQuery = propertyOwner.GetAllProperties().Where(p => p.Name == name + "Property");
var fieldDependencyPropertyQuery = propertyOwner.GetAllFields().Where(p => p.Name == name + "Property");
var propertyDependencyPropertyQuery = propertyOwner.GetAllPropertiesWithName(name + "Property");
var fieldDependencyPropertyQuery = propertyOwner.GetAllFieldsWithName(name + "Property");

return propertyDependencyPropertyQuery.Any() || fieldDependencyPropertyQuery.Any();
}
Expand Down Expand Up @@ -381,7 +381,7 @@ private INamedTypeSymbol SourceFindPropertyType(string ownerType, string propert

var resolvedType = type;

var property = resolvedType.GetAllProperties().FirstOrDefault(p => p.Name == propertyName);
var property = resolvedType.GetAllPropertiesWithName(propertyName).FirstOrDefault();
var setMethod = resolvedType.GetMethods().FirstOrDefault(p => p.Name == "Set" + propertyName);

if (property != null)
Expand Down Expand Up @@ -512,7 +512,7 @@ private static bool SourceIsAttachedProperty(INamedTypeSymbol type, string name)
{
do
{
var property = type.GetAllProperties().FirstOrDefault(p => p.Name == name);
var property = type.GetAllPropertiesWithName(name).FirstOrDefault();
var setMethod = type.GetMethods().FirstOrDefault(p => p.Name == "Set" + name);

if (property != null && property.GetMethod.IsStatic)
Expand Down Expand Up @@ -583,7 +583,7 @@ private bool IsInitializableCollection(XamlMember xamlMember)
/// </summary>
private bool IsInitializableCollection(XamlType declaringType, string propertyName)
{
var property = GetPropertyByName(declaringType, propertyName);
var property = GetPropertyWithName(declaringType, propertyName);

if (property != null && IsInitializableProperty(property))
{
Expand Down Expand Up @@ -665,11 +665,10 @@ private bool IsInitializableCollection(XamlObjectDefinition definition)
/// <summary>
/// Gets the
/// </summary>
private IPropertySymbol GetPropertyByName(XamlType declaringType, string propertyName)
private IPropertySymbol GetPropertyWithName(XamlType declaringType, string propertyName)
{
var type = FindType(declaringType);

return type?.GetAllProperties().FirstOrDefault(p => p.Name == propertyName);
return type?.GetAllPropertiesWithName(propertyName).FirstOrDefault();
}

private static bool IsDouble(string typeName)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -228,7 +228,7 @@ bool isUnoAssembly
_colorSymbol = GetType(XamlConstants.Types.Color);

_markupExtensionTypes = _metadataHelper.GetAllTypesDerivingFrom(_markupExtensionSymbol).ToList();
_xamlConversionTypes = _metadataHelper.GetAllTypesAttributedWith(XamlConstants.Types.CreateFromStringAttribute).ToList();
_xamlConversionTypes = _metadataHelper.GetAllTypesAttributedWith(GetType(XamlConstants.Types.CreateFromStringAttribute)).ToList();

_isWasm = isWasm;

Expand Down Expand Up @@ -2130,7 +2130,7 @@ private static IPropertySymbol SourceFindContentProperty(INamedTypeSymbol elemen
{
var name = nameProperty.Value.Value.ToString();

return elementType?.GetAllProperties().FirstOrDefault(p => p.Name == name);
return elementType?.GetAllPropertiesWithName(name).FirstOrDefault();
}
}

Expand Down Expand Up @@ -3484,7 +3484,7 @@ private ITypeSymbol GetXBindPropertyPathType(string propertyPath, INamedTypeSymb

foreach (var part in parts)
{
if (currentType.GetAllMembers().FirstOrDefault(m => m.Name == part) is ISymbol member)
if (currentType.GetAllMembersWithName(part).FirstOrDefault() is ISymbol member)
{
var propertySymbol = member as IPropertySymbol;
var fieldSymbol = member as IFieldSymbol;
Expand Down Expand Up @@ -4483,7 +4483,7 @@ private bool IsInlineCollection(XamlMember member, IEnumerable<XamlObjectDefinit
{
var declaringType = member.DeclaringType;
var propertyName = member.Name;
var property = GetPropertyByName(declaringType, propertyName);
var property = GetPropertyWithName(declaringType, propertyName);

if (property?.Type is INamedTypeSymbol collectionType)
{
Expand Down

0 comments on commit 17e19f3

Please sign in to comment.