Skip to content

Commit

Permalink
Optimized some parsing logic.
Browse files Browse the repository at this point in the history
  • Loading branch information
MeltyPlayer committed Aug 2, 2023
1 parent 24e69b8 commit cfd1d4d
Show file tree
Hide file tree
Showing 3 changed files with 102 additions and 29 deletions.
11 changes: 5 additions & 6 deletions Schema/src/binary/BinarySchemaStructureParser.cs
Original file line number Diff line number Diff line change
Expand Up @@ -153,7 +153,7 @@ public IBinarySchemaStructure ParseStructure(
}

var localPositions =
structureSymbol.HasAttribute<LocalPositionsAttribute>(diagnostics);
structureSymbol.HasAttribute<LocalPositionsAttribute>();
var structureEndianness =
new EndiannessParser().GetEndianness(diagnostics, structureSymbol);

Expand All @@ -173,7 +173,7 @@ public IBinarySchemaStructure ParseStructure(
var methodSymbol = memberSymbol as IMethodSymbol;
var isMethod = methodSymbol != null;
var hasRunAtReadTimeAttribute =
memberSymbol.HasAttribute<ReadLogicAttribute>(diagnostics);
memberSymbol.HasAttribute<ReadLogicAttribute>();
if (hasRunAtReadTimeAttribute) {
if (isMethod) {
if (methodSymbol.Parameters.Length == 1 && methodSymbol
Expand All @@ -198,7 +198,7 @@ public IBinarySchemaStructure ParseStructure(
}

bool isIgnored =
memberSymbol.HasAttribute<IgnoreAttribute>(diagnostics) ||
memberSymbol.HasAttribute<IgnoreAttribute>() ||
(memberSymbol.Name == nameof(IChildOf<IBinaryConvertible>.Parent)
&& parentTypeSymbol != null);

Expand Down Expand Up @@ -516,9 +516,8 @@ memberType is BinarySchemaStructureParser.PrimitiveMemberType
.GetAttribute<RStringLengthSourceAttribute>(
diagnostics,
memberSymbol);
var isNullTerminatedString =
memberSymbol.HasAttribute<NullTerminatedStringAttribute>(
diagnostics);
var isNullTerminatedString = memberSymbol
.HasAttribute<NullTerminatedStringAttribute>();
var hasStringLengthAttribute =
stringLengthSourceAttribute != null || isNullTerminatedString;

Expand Down
106 changes: 90 additions & 16 deletions Schema/src/binary/SymbolTypeUtil.cs
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
using System;
using System.Collections.Generic;
using System.Collections.Immutable;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Text;

using Microsoft.CodeAnalysis;
Expand All @@ -15,17 +17,20 @@

namespace schema.binary {
internal static class SymbolTypeUtil {
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static ISymbol GetSymbolFromType(SemanticModel semanticModel,
Type type)
=> SymbolTypeUtil.GetSymbolFromIdentifier(semanticModel, type.FullName);

[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static ISymbol GetSymbolFromIdentifier(
SemanticModel semanticModel,
string identifier) {
var symbol = semanticModel.LookupSymbols(0, null, identifier);
return symbol.First();
}

[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static bool CanBeStoredAs<TType>(this ITypeSymbol symbol)
=> symbol.CanBeStoredAs(typeof(TType));

Expand All @@ -44,6 +49,7 @@ public static bool CanBeStoredAs(this ITypeSymbol symbol, Type type) {
}


[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static bool ImplementsGeneric(this ITypeSymbol symbol, Type type)
=> symbol.ImplementsGeneric(type, out _);

Expand All @@ -62,19 +68,76 @@ public static bool ImplementsGeneric(this ITypeSymbol symbol,
}


[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static bool IsBinaryDeserializable(this ITypeSymbol symbol)
=> symbol.Implements<IBinaryDeserializable>();

[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static bool IsBinarySerializable(this ITypeSymbol symbol)
=> symbol.Implements<IBinarySerializable>();

[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static bool Implements<TType>(this ITypeSymbol symbol)
=> symbol.Implements(typeof(TType));

[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static bool Implements(this ITypeSymbol symbol, Type type)
=> symbol.AllInterfaces.Any(i => i.IsExactlyType(type));


// Namespace
[MethodImpl(MethodImplOptions.AggressiveInlining)]
internal static bool IsInSameNamespaceAs(this ISymbol symbol, ISymbol other)
=> symbol.ContainingNamespace.Equals(other.ContainingNamespace);

[MethodImpl(MethodImplOptions.AggressiveInlining)]
internal static bool IsInSameNamespaceAs(this ISymbol symbol, Type other)
=> symbol.IsInNamespace(other.Namespace);

[MethodImpl(MethodImplOptions.AggressiveInlining)]
internal static bool IsInNamespace(
this ISymbol symbol,
string fullNamespacePath) {
var fullNamespacePathLength = fullNamespacePath.Length;

var currentNamespace = symbol.ContainingNamespace;
var currentNamespaceName = currentNamespace.Name;
var currentNamespaceNameLength = currentNamespaceName.Length;

if (fullNamespacePathLength == 0 && currentNamespaceNameLength == 0) {
return true;
}

var fullNamespaceI = fullNamespacePathLength - 1;
var currentNamespaceI = currentNamespaceNameLength - 1;

for (; fullNamespaceI >= 0; --fullNamespaceI, --currentNamespaceI) {
if (currentNamespaceI == -1) {
if (fullNamespacePath[fullNamespaceI] != '.') {
return false;
}

--fullNamespaceI;
currentNamespace = currentNamespace.ContainingNamespace;
currentNamespaceName = currentNamespace.Name;
currentNamespaceNameLength = currentNamespaceName.Length;
if (currentNamespaceNameLength == 0) {
return false;
}

currentNamespaceI = currentNamespaceNameLength - 1;
}

if (fullNamespacePath[fullNamespaceI] !=
currentNamespaceName[currentNamespaceI]) {
return false;
}
}

return fullNamespaceI == -1 && currentNamespaceI == -1 &&
currentNamespace.ContainingNamespace.Name.Length == 0;
}

public static string[]? GetContainingNamespaces(this ISymbol symbol) {
var namespaceSymbol = symbol.ContainingNamespace;
if (namespaceSymbol == null) {
Expand All @@ -93,6 +156,7 @@ public static bool Implements(this ITypeSymbol symbol, Type type)
return namespaces.ToArray();
}

[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static string? MergeContainingNamespaces(ISymbol symbol)
=> MergeNamespaceParts(GetContainingNamespaces(symbol));

Expand Down Expand Up @@ -138,38 +202,43 @@ public static bool MatchesGeneric(this INamedTypeSymbol symbol,
return sameName && sameNamespace && sameTypeArguments;
}

[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static bool IsExactlyType(this ISymbol symbol, Type expectedType)
=> symbol.Name == expectedType.Name &&
SymbolTypeUtil.MergeContainingNamespaces(symbol) ==
expectedType.Namespace;
symbol.IsInSameNamespaceAs(expectedType);


[MethodImpl(MethodImplOptions.AggressiveInlining)]
internal static ImmutableArray<AttributeData> GetAttributeData(
this ISymbol symbol)
=> symbol.GetAttributes();


[MethodImpl(MethodImplOptions.AggressiveInlining)]
internal static bool HasAttribute(this ISymbol symbol, Type expectedType)
=> symbol.GetAttributes()
=> symbol.GetAttributeData()
.Any(attributeData
=> attributeData.AttributeClass!.IsExactlyType(
expectedType));

[MethodImpl(MethodImplOptions.AggressiveInlining)]
internal static IEnumerable<AttributeData>
GetAttributeData<TAttribute>(this ISymbol symbol) {
var attributeType = typeof(TAttribute);
return symbol.GetAttributes()
.Where(attributeData => {
var attributeSymbol = attributeData.AttributeClass;
return attributeSymbol.Name == attributeType.Name &&
SymbolTypeUtil.MergeContainingNamespaces(
attributeSymbol) ==
attributeType.Namespace;
});
return symbol
.GetAttributeData()
.Where(attributeData
=> attributeData.AttributeClass?.IsExactlyType(
attributeType) ?? false);
}


internal static bool HasAttribute<TAttribute>(
this ISymbol symbol,
IList<Diagnostic> diagnostics)
[MethodImpl(MethodImplOptions.AggressiveInlining)]
internal static bool HasAttribute<TAttribute>(this ISymbol symbol)
where TAttribute : Attribute
=> symbol.GetAttribute<TAttribute>(diagnostics) != null;
=> symbol.GetAttributeData<TAttribute>().Any();

[MethodImpl(MethodImplOptions.AggressiveInlining)]
internal static TAttribute? GetAttribute<TAttribute>(
this ISymbol symbol,
IList<Diagnostic> diagnostics)
Expand All @@ -178,13 +247,15 @@ internal static bool HasAttribute<TAttribute>(
.SingleOrDefault();


[MethodImpl(MethodImplOptions.AggressiveInlining)]
internal static TAttribute? GetAttribute<TAttribute>(
IList<Diagnostic> diagnostics,
ISymbol symbol)
where TAttribute : Attribute
=> symbol.GetAttributes<TAttribute>(diagnostics)
.SingleOrDefault();

[MethodImpl(MethodImplOptions.AggressiveInlining)]
internal static IEnumerable<TAttribute> GetAttributes<TAttribute>(
this ISymbol symbol,
IList<Diagnostic> diagnostics)
Expand Down Expand Up @@ -275,6 +346,7 @@ public static string GetQualifiersAndNameFor(
return sb.ToString();
}

[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static string GetSymbolQualifiers(this INamedTypeSymbol typeSymbol)
=> (typeSymbol.IsStatic ? "static " : "") +
SymbolTypeUtil.AccessibilityToModifier(
Expand All @@ -284,6 +356,7 @@ public static string GetSymbolQualifiers(this INamedTypeSymbol typeSymbol)
"partial " +
(typeSymbol.TypeKind == TypeKind.Class ? "class" : "struct");

[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static string AccessibilityToModifier(
Accessibility accessibility)
=> accessibility switch {
Expand Down Expand Up @@ -371,6 +444,7 @@ or SpecialType.System_Boolean
$"{mergedNamespaceText}{mergedContainersText}{referencedSymbol.Name}";
}

[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static void GetMemberInStructure(
this ITypeSymbol structureSymbol,
string memberName,
Expand Down
14 changes: 7 additions & 7 deletions Schema/src/binary/attributes/BMemberAttribute.cs
Original file line number Diff line number Diff line change
Expand Up @@ -177,13 +177,13 @@ protected IMemberReference<T> GetReadTimeOnlySourceRelativeToStructure<T>(

private bool IsMemberWritePrivateOrIgnored_(ISymbol symbol)
=> symbol switch {
IPropertySymbol propertySymbol
=> (propertySymbol.SetMethod
?.DeclaredAccessibility ??
Accessibility.Private) == Accessibility.Private,
IFieldSymbol fieldSymbol
=> fieldSymbol.DeclaredAccessibility == Accessibility.Private,
} || symbol.HasAttribute<IgnoreAttribute>(this.diagnostics_);
IPropertySymbol propertySymbol
=> (propertySymbol.SetMethod
?.DeclaredAccessibility ??
Accessibility.Private) == Accessibility.Private,
IFieldSymbol fieldSymbol
=> fieldSymbol.DeclaredAccessibility == Accessibility.Private,
} || symbol.HasAttribute<IgnoreAttribute>();
}


Expand Down

0 comments on commit cfd1d4d

Please sign in to comment.