private static MethodDeclarationSyntax EqualsImplementation(EquatableGenerationContext context) { return(MethodDeclaration( PredefinedType(Token(SyntaxKind.BoolKeyword)), Identifier("Equals") ).AddModifiers( Token(SyntaxKind.PublicKeyword), Token(SyntaxKind.OverrideKeyword) ).AddParameterListParameters( Parameter(Identifier("obj")) .WithType(PredefinedType(Token(SyntaxKind.ObjectKeyword))) ).AddBodyStatements( ReturnStatement( InvocationExpression(IdentifierName("Equals")) .AddArgumentListArguments( Argument( BinaryExpression( SyntaxKind.AsExpression, IdentifierName("obj"), IdentifierName(context.ClassIdentifier) ) ) ) ) )); }
private static MethodDeclarationSyntax GetHashCode(EquatableGenerationContext context) { var statements = new List <StatementSyntax>() { LocalDeclarationStatement( VariableDeclaration(PredefinedType(Token(SyntaxKind.IntKeyword))) .AddVariables( VariableDeclarator(Identifier("HashingBase")) .WithInitializer(EqualsValueClause(CastExpression( PredefinedType(Token(SyntaxKind.IntKeyword)), LiteralExpression(SyntaxKind.NumericLiteralExpression, Literal(2166136261)) ))) ) ).AddModifiers(Token(SyntaxKind.ConstKeyword)), LocalDeclarationStatement( VariableDeclaration(PredefinedType(Token(SyntaxKind.IntKeyword))) .AddVariables( VariableDeclarator(Identifier("HashingMultiplier")) .WithInitializer( EqualsValueClause( LiteralExpression(SyntaxKind.NumericLiteralExpression, Literal(16777619)) ) ) ) ).AddModifiers(Token(SyntaxKind.ConstKeyword)), LocalDeclarationStatement( VariableDeclaration(IdentifierName("var")) .AddVariables( VariableDeclarator(Identifier("hashCode")) .WithInitializer(EqualsValueClause(IdentifierName("HashingBase"))) ) ) }; statements.AddRange(context.Properties.Select(property => HashCodeForProperty(property, context.CanBeNull(property)))); statements.Add(ReturnStatement(IdentifierName("hashCode"))); return(MethodDeclaration(PredefinedType(Token(SyntaxKind.IntKeyword)), Identifier("GetHashCode")) .AddModifiers(Token(SyntaxKind.PublicKeyword)) .AddModifiers(Token(SyntaxKind.OverrideKeyword)) .AddBodyStatements( CheckedStatement( SyntaxKind.UncheckedStatement, Block(statements.ToArray()) ) )); }
public Task <SyntaxList <MemberDeclarationSyntax> > GenerateAsync(TransformationContext context, IProgress <Diagnostic> progress, CancellationToken cancellationToken) { var targetClass = (ClassDeclarationSyntax)context.ProcessingNode; var equatableContext = EquatableGenerationContext.Create(targetClass, context.Compilation, context.SemanticModel); var resultClass = targetClass .WithBaseList(GetBaseList(equatableContext)) .WithAttributeLists(List(new AttributeListSyntax[0])) .WithModifiers(TokenList(Token(SyntaxKind.PartialKeyword))) .WithMembers(List(new MemberDeclarationSyntax[] { EqualsImplementation(equatableContext), EquatableImplementation(equatableContext), GetHashCode(equatableContext) })); return(Task.FromResult(List <MemberDeclarationSyntax>().Add(resultClass))); }
private BaseListSyntax GetBaseList(EquatableGenerationContext context) { if (context.IsIEquatableTDefined) { return(null); } return(BaseList( SingletonSeparatedList <BaseTypeSyntax>( SimpleBaseType( QualifiedName(IdentifierName("System"), GenericName(Identifier("IEquatable")) .WithTypeArgumentList( TypeArgumentList( SingletonSeparatedList <TypeSyntax>(IdentifierName(context.ClassIdentifier)) ) ) ) ) ) )); }
private static MethodDeclarationSyntax EquatableImplementation(EquatableGenerationContext context) { var notNullCheck = BinaryExpression(SyntaxKind.NotEqualsExpression, IdentifierName("other"), LiteralExpression(SyntaxKind.NullLiteralExpression) ); var body = context.Properties.Select(property => EqualsCondition(property, context.IsEnumerable(property))) .Aggregate( notNullCheck, (prev, curr) => BinaryExpression(SyntaxKind.LogicalAndExpression, prev, curr) ); return(MethodDeclaration( PredefinedType(Token(SyntaxKind.BoolKeyword)), Identifier("Equals") ) .AddModifiers(Token(SyntaxKind.PublicKeyword)) .AddParameterListParameters( Parameter(Identifier("other")).WithType(IdentifierName(context.ClassIdentifier)) ) .AddBodyStatements(ReturnStatement(body))); }