public static bool ContainsEntity(this ITypeDescriptor typeDescriptor) { return(typeDescriptor switch { ListTypeDescriptor listTypeDescriptor => listTypeDescriptor.InnerType.ContainsEntity(), ComplexTypeDescriptor namedTypeDescriptor => namedTypeDescriptor.Properties .Any(prop => prop.Type.IsEntityType() || prop.Type.ContainsEntity()), NonNullTypeDescriptor nonNullTypeDescriptor => nonNullTypeDescriptor.InnerType.ContainsEntity(), _ => false });
public static bool ContainsEntity(this ITypeDescriptor typeDescriptor) { return(typeDescriptor switch { ListTypeDescriptor listTypeDescriptor => listTypeDescriptor.InnerType.ContainsEntity(), NamedTypeDescriptor namedTypeDescriptor => namedTypeDescriptor.Properties.Any(prop => prop.Type.IsEntityType() || prop.Type.ContainsEntity()), NonNullTypeDescriptor nonNullTypeDescriptor => nonNullTypeDescriptor.InnerType.ContainsEntity(), _ => throw new ArgumentOutOfRangeException(nameof(typeDescriptor)) });
private static ICode BuildProperty( ITypeDescriptor type, string propertyName) { return(BuildPropertyInternal(type, propertyName, true)); ICode BuildPropertyInternal( ITypeDescriptor currentType, string variableName, bool isNullable) { ICode check = currentType switch { NonNullTypeDescriptor d => BuildPropertyInternal(d.InnerType, variableName, false), INamedTypeDescriptor => AssignmentBuilder .New() .SetLefthandSide(HashCodeBuilder.VariableName) .SetOperator("^=") .SetRighthandSide(MethodCallBuilder .Inline() .SetPrefix($"{HashCodeBuilder.Prime} * ") .SetMethodName(variableName, nameof(GetHashCode))), ListTypeDescriptor d => ForEachBuilder .New() .SetLoopHeader($"var {variableName}_elm in {variableName}") .AddCode(BuildPropertyInternal(d.InnerType, variableName + "_elm", true)), _ => throw new ArgumentOutOfRangeException() }; if (isNullable && currentType is not NonNullTypeDescriptor) { return(IfBuilder .New() .SetCondition($"!({variableName} is null)") .AddCode(check)); } return(check); } } }
private static ICode BuildPropertyComparison( ITypeDescriptor type, string propertyName) { const string other = nameof(other); return(BuildPropertyInternal(type, true)); ICode BuildPropertyInternal( ITypeDescriptor currentType, bool isNullable) { return(currentType switch { NonNullTypeDescriptor d => BuildPropertyInternal(d.InnerType, false), ILeafTypeDescriptor d when d.SerializationType.IsValueType => CodeInlineBuilder .New() .SetText($"{propertyName} == {other}.{propertyName}"), INamedTypeDescriptor when isNullable => ConditionBuilder .New() .Set($"({propertyName} is null && {other}.{propertyName} is null) ||" + $"{propertyName} != null && {propertyName}.{nameof(Equals)}(" + $"{other}.{propertyName})"), INamedTypeDescriptor => MethodCallBuilder .Inline() .SetMethodName(propertyName, nameof(Equals)) .AddArgument($"{other}.{propertyName}"), ListTypeDescriptor => MethodCallBuilder .Inline() .SetMethodName(TypeNames.SequenceEqual) .AddArgument(propertyName) .AddArgument($"{other}.{propertyName}"), _ => throw new ArgumentOutOfRangeException() }); }