private ExpressionSyntax BuildFieldHashCodeCall(ISymbol fieldSymbol) { ITypeSymbol fieldType = (fieldSymbol as IFieldSymbol)?.Type ?? (fieldSymbol as IPropertySymbol).Type; MemberAccessExpressionSyntax defaultComparer = DefaultEqualityComparer.AccessExpression(fieldType); MemberAccessExpressionSyntax defaultGetHashCodeMethod = MemberAccessExpression(SyntaxKind.SimpleMemberAccessExpression, defaultComparer, _getHashCodeName); MemberAccessExpressionSyntax fieldAccess = MemberAccessExpression(SyntaxKind.SimpleMemberAccessExpression, ThisExpression(), IdentifierName(fieldSymbol.Name)); InvocationExpressionSyntax getHashCodeCall = InvocationExpression(defaultGetHashCodeMethod).AddArgumentListArguments(Argument(fieldAccess)); return(getHashCodeCall); }
private static ExpressionSyntax BuildFieldEqualityCall(ISymbol fieldSymbol) { ITypeSymbol fieldType = (fieldSymbol as IFieldSymbol)?.Type ?? (fieldSymbol as IPropertySymbol).Type; bool declaresEqualityOperator = fieldType .GetMembers() .OfType <IMethodSymbol>() .Where(m => m.MethodKind == MethodKind.BuiltinOperator || m.MethodKind == MethodKind.UserDefinedOperator) .Where(m => m.Name == "op_Equality") .Any(); // If the field type declares == operator, we can safely use it. // This provides better readability in a lot of cases. if (declaresEqualityOperator) { return(BinaryExpression ( SyntaxKind.EqualsExpression, MemberAccessExpression(SyntaxKind.SimpleMemberAccessExpression, ThisExpression(), IdentifierName(fieldSymbol.Name)), MemberAccessExpression(SyntaxKind.SimpleMemberAccessExpression, IdentifierName(_otherArg), IdentifierName(fieldSymbol.Name)) )); } // Otherwise, we have to resort to EqualityComparer<T>.Default.Equals( this._field, other._field ) MemberAccessExpressionSyntax defaultProperty = DefaultEqualityComparer.AccessExpression(fieldType); MemberAccessExpressionSyntax equalsMethod = MemberAccessExpression(SyntaxKind.SimpleMemberAccessExpression, defaultProperty, IdentifierName("Equals")); InvocationExpressionSyntax invocation = InvocationExpression(equalsMethod); invocation = invocation .AddArgumentListArguments ( Argument(MemberAccessExpression(SyntaxKind.SimpleMemberAccessExpression, ThisExpression(), IdentifierName(fieldSymbol.Name))), Argument(MemberAccessExpression(SyntaxKind.SimpleMemberAccessExpression, IdentifierName(_otherArg), IdentifierName(fieldSymbol.Name))) ); return(invocation); }