private static IList<SyntaxNode> CreateGetHashCodeMethodStatements( SyntaxGenerator factory, Compilation compilation, INamedTypeSymbol containingType, IList<ISymbol> members, CancellationToken cancellationToken) { const string HashCodeName = "hashCode"; // -1521134295 var permuteValue = factory.NegateExpression( factory.LiteralExpression(1521134295)); var statements = new List<SyntaxNode>(); var hashCodeNameExpression = factory.IdentifierName(HashCodeName); var firstHashValue = ComputeHashValue(factory, compilation, members[0]); if (members.Count == 1) { #if false return this.S1.GetHashCode(); #endif statements.Add(factory.ReturnStatement(firstHashValue)); } else { #if false var hashCode = this.S1.GetHashCode(); #endif statements.Add(factory.LocalDeclarationStatement(HashCodeName, firstHashValue)); for (var i = 1; i < members.Count; i++) { #if false hashCode = hashCode * 0xA5555529 + value #endif statements.Add(factory.ExpressionStatement( factory.AssignmentStatement(hashCodeNameExpression, factory.AddExpression( factory.MultiplyExpression(hashCodeNameExpression, permuteValue), ComputeHashValue(factory, compilation, members[i]))))); } #if false return hashCode; #endif statements.Add(factory.ReturnStatement(hashCodeNameExpression)); } return statements; }
private static IList<SyntaxNode> CreateEqualsMethodStatements( SyntaxGenerator factory, Compilation compilation, INamedTypeSymbol containingType, IEnumerable<ISymbol> members, CancellationToken cancellationToken) { var statements = new List<SyntaxNode>(); var parts = StringBreaker.BreakIntoWordParts(containingType.Name); string localName = "v"; for (int i = parts.Count - 1; i >= 0; i--) { var p = parts[i]; if (char.IsLetter(containingType.Name[p.Start])) { localName = containingType.Name.Substring(p.Start, p.Length).ToCamelCase(); break; } } var localNameExpression = factory.IdentifierName(localName); var objNameExpression = factory.IdentifierName(ObjName); var expressions = new List<SyntaxNode>(); if (containingType.IsValueType) { #if false if (!(obj is MyType)) { return false; } #endif var ifStatement = factory.IfStatement( factory.LogicalNotExpression( factory.IsTypeExpression( objNameExpression, containingType)), new[] { factory.ReturnStatement(factory.FalseLiteralExpression()) }); #if false var myType = (MyType)obj; #endif var localDeclaration = factory.LocalDeclarationStatement(localName, factory.CastExpression(containingType, objNameExpression)); statements.Add(ifStatement); statements.Add(localDeclaration); } else { #if false var myType = obj as MyType; #endif var localDeclaration = factory.LocalDeclarationStatement(localName, factory.TryCastExpression(objNameExpression, containingType)); statements.Add(localDeclaration); #if false myType != null #endif expressions.Add(factory.ReferenceNotEqualsExpression(localNameExpression, factory.NullLiteralExpression())); if (HasExistingBaseEqualsMethod(containingType, cancellationToken)) { #if false base.Equals(obj) #endif expressions.Add(factory.InvocationExpression( factory.MemberAccessExpression( factory.BaseExpression(), factory.IdentifierName(EqualsName)), objNameExpression)); } } foreach (var member in members) { var symbolNameExpression = factory.IdentifierName(member.Name); var thisSymbol = factory.MemberAccessExpression(factory.ThisExpression(), symbolNameExpression).WithAdditionalAnnotations(Simplification.Simplifier.Annotation); var otherSymbol = factory.MemberAccessExpression(localNameExpression, symbolNameExpression); #if false EqualityComparer<SType>.Default.Equals(this.S1, myType.S1) #endif var expression = factory.InvocationExpression( factory.MemberAccessExpression( GetDefaultEqualityComparer(factory, compilation, member), factory.IdentifierName(EqualsName)), thisSymbol, otherSymbol); expressions.Add(expression); } #if false return myType != null && base.Equals(obj) && EqualityComparer<int>.Default.Equals(this.S1, myType.S1) && ...; #endif statements.Add(factory.ReturnStatement( expressions.Aggregate(factory.LogicalAndExpression))); return statements; }