private static IList <SyntaxNode> CreateGetHashCodeMethodStatements( ISyntaxFactoryService factory, Compilation compilation, INamedTypeSymbol containingType, IList <ISymbol> members, CancellationToken cancellationToken) { const string HashCodeName = "hashCode"; // -1521134295 var permuteValue = factory.CreateNegateExpression( factory.CreateConstantExpression(1521134295)); var statements = new List <SyntaxNode>(); var hashCodeNameExpression = factory.CreateIdentifierName(HashCodeName); var firstHashValue = ComputeHashValue(factory, compilation, members[0]); if (members.Count == 1) { #if false return(this.S1.GetHashCode()); #endif statements.Add(factory.CreateReturnStatement(firstHashValue)); } else { #if false var hashCode = this.S1.GetHashCode(); #endif statements.Add(factory.CreateLocalDeclarationStatement( factory.CreateVariableDeclarator(HashCodeName, firstHashValue))); for (var i = 1; i < members.Count; i++) { #if false hashCode = hashCode * 0xA5555529 + value #endif statements.Add(factory.CreateExpressionStatement( factory.CreateAssignExpression(hashCodeNameExpression, factory.CreateAddExpression( factory.CreateMultiplyExpression(hashCodeNameExpression, permuteValue), ComputeHashValue(factory, compilation, members[i]))))); } #if false return(hashCode); #endif statements.Add(factory.CreateReturnStatement(hashCodeNameExpression)); } return(statements); }
private static IList<SyntaxNode> CreateGetHashCodeMethodStatements( ISyntaxFactoryService factory, Compilation compilation, INamedTypeSymbol containingType, IList<ISymbol> members, CancellationToken cancellationToken) { const string HashCodeName = "hashCode"; // -1521134295 var permuteValue = factory.CreateNegateExpression( factory.CreateConstantExpression(1521134295)); var statements = new List<SyntaxNode>(); var hashCodeNameExpression = factory.CreateIdentifierName(HashCodeName); var firstHashValue = ComputeHashValue(factory, compilation, members[0]); if (members.Count == 1) { #if false return this.S1.GetHashCode(); #endif statements.Add(factory.CreateReturnStatement(firstHashValue)); } else { #if false var hashCode = this.S1.GetHashCode(); #endif statements.Add(factory.CreateLocalDeclarationStatement( factory.CreateVariableDeclarator(HashCodeName, firstHashValue))); for (var i = 1; i < members.Count; i++) { #if false hashCode = hashCode * 0xA5555529 + value #endif statements.Add(factory.CreateExpressionStatement( factory.CreateAssignExpression(hashCodeNameExpression, factory.CreateAddExpression( factory.CreateMultiplyExpression(hashCodeNameExpression, permuteValue), ComputeHashValue(factory, compilation, members[i]))))); } #if false return hashCode; #endif statements.Add(factory.CreateReturnStatement(hashCodeNameExpression)); } return statements; }
public static IMethodSymbol OverrideMethod( this ISyntaxFactoryService codeFactory, IMethodSymbol overriddenMethod, SymbolModifiers modifiers, INamedTypeSymbol newContainingType, Document newDocument, CancellationToken cancellationToken) { // Abstract: Throw not implemented if (overriddenMethod.IsAbstract) { return(CodeGenerationSymbolFactory.CreateMethodSymbol( overriddenMethod, accessibility: overriddenMethod.ComputeResultantAccessibility(newContainingType), modifiers: modifiers, statements: new[] { codeFactory.CreateThrowNotImplementStatement(newDocument.Project.GetCompilationAsync(cancellationToken).WaitAndGetResult(cancellationToken)) })); } else { // Otherwise, call the base method with the same parameters var typeParams = overriddenMethod.GetTypeArguments(); var body = codeFactory.CreateInvocationExpression( codeFactory.CreateMemberAccessExpression(codeFactory.CreateBaseExpression(), typeParams.IsDefaultOrEmpty ? codeFactory.CreateIdentifierName(overriddenMethod.Name) : codeFactory.CreateGenericName(overriddenMethod.Name, typeParams)), codeFactory.CreateArguments(overriddenMethod.GetParameters())); return(CodeGenerationSymbolFactory.CreateMethodSymbol( method: overriddenMethod, accessibility: overriddenMethod.ComputeResultantAccessibility(newContainingType), modifiers: modifiers, statements: ((IMethodSymbol)overriddenMethod).ReturnsVoid ? new SyntaxNode[] { codeFactory.CreateExpressionStatement(body) } : new SyntaxNode[] { codeFactory.CreateReturnStatement(body) })); } }
private static IList <SyntaxNode> CreateEqualsMethodStatements( ISyntaxFactoryService 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.CreateIdentifierName(localName); var objNameExpression = factory.CreateIdentifierName(ObjName); var expressions = new List <SyntaxNode>(); if (containingType.IsValueType) { #if false if (!(obj is MyType)) { return(false); } #endif var ifStatement = factory.CreateIfStatement( factory.CreateLogicalNotExpression( factory.CreateIsExpression( objNameExpression, containingType)), new[] { factory.CreateReturnStatement(factory.CreateFalseExpression()) }); #if false var myType = (MyType)obj; #endif var localDeclaration = factory.CreateLocalDeclarationStatement( factory.CreateVariableDeclarator(localName, factory.CreateCastExpression(containingType, objNameExpression))); statements.Add(ifStatement); statements.Add(localDeclaration); } else { #if false var myType = obj as MyType; #endif var localDeclaration = factory.CreateLocalDeclarationStatement( factory.CreateVariableDeclarator(localName, factory.CreateAsExpression(objNameExpression, containingType))); statements.Add(localDeclaration); #if false myType != null #endif expressions.Add(factory.CreateReferenceNotEqualsExpression(localNameExpression, factory.CreateNullExpression())); if (HasExistingBaseEqualsMethod(containingType, cancellationToken)) { #if false base.Equals(obj) #endif expressions.Add(factory.CreateInvocationExpression( factory.CreateMemberAccessExpression( factory.CreateBaseExpression(), factory.CreateIdentifierName(EqualsName)), objNameExpression)); } } foreach (var member in members) { var symbolNameExpression = factory.CreateIdentifierName(member.Name); var thisSymbol = factory.CreateMemberAccessExpression(factory.CreateThisExpression(), symbolNameExpression).WithAdditionalAnnotations(Simplification.Simplifier.Annotation); var otherSymbol = factory.CreateMemberAccessExpression(localNameExpression, symbolNameExpression); #if false EqualityComparer <SType> .Default.Equals(this.S1, myType.S1) #endif var expression = factory.CreateInvocationExpression( factory.CreateMemberAccessExpression( GetDefaultEqualityComparer(factory, compilation, member), factory.CreateIdentifierName(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.CreateReturnStatement( expressions.Aggregate(factory.CreateLogicalAndExpression))); return(statements); }
private static IList<SyntaxNode> CreateEqualsMethodStatements( ISyntaxFactoryService 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.CreateIdentifierName(localName); var objNameExpression = factory.CreateIdentifierName(ObjName); var expressions = new List<SyntaxNode>(); if (containingType.IsValueType) { #if false if (!(obj is MyType)) { return false; } #endif var ifStatement = factory.CreateIfStatement( factory.CreateLogicalNotExpression( factory.CreateIsExpression( objNameExpression, containingType)), new[] { factory.CreateReturnStatement(factory.CreateFalseExpression()) }); #if false var myType = (MyType)obj; #endif var localDeclaration = factory.CreateLocalDeclarationStatement( factory.CreateVariableDeclarator(localName, factory.CreateCastExpression(containingType, objNameExpression))); statements.Add(ifStatement); statements.Add(localDeclaration); } else { #if false var myType = obj as MyType; #endif var localDeclaration = factory.CreateLocalDeclarationStatement( factory.CreateVariableDeclarator(localName, factory.CreateAsExpression(objNameExpression, containingType))); statements.Add(localDeclaration); #if false myType != null #endif expressions.Add(factory.CreateReferenceNotEqualsExpression(localNameExpression, factory.CreateNullExpression())); if (HasExistingBaseEqualsMethod(containingType, cancellationToken)) { #if false base.Equals(obj) #endif expressions.Add(factory.CreateInvocationExpression( factory.CreateMemberAccessExpression( factory.CreateBaseExpression(), factory.CreateIdentifierName(EqualsName)), objNameExpression)); } } foreach (var member in members) { var symbolNameExpression = factory.CreateIdentifierName(member.Name); var thisSymbol = factory.CreateMemberAccessExpression(factory.CreateThisExpression(), symbolNameExpression).WithAdditionalAnnotations(Simplification.Simplifier.Annotation); var otherSymbol = factory.CreateMemberAccessExpression(localNameExpression, symbolNameExpression); #if false EqualityComparer<SType>.Default.Equals(this.S1, myType.S1) #endif var expression = factory.CreateInvocationExpression( factory.CreateMemberAccessExpression( GetDefaultEqualityComparer(factory, compilation, member), factory.CreateIdentifierName(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.CreateReturnStatement( expressions.Aggregate(factory.CreateLogicalAndExpression))); return statements; }
public static IPropertySymbol OverrideProperty( this ISyntaxFactoryService codeFactory, IPropertySymbol overriddenProperty, SymbolModifiers modifiers, INamedTypeSymbol containingType, Document document, CancellationToken cancellationToken) { var getAccessibility = overriddenProperty.GetMethod.ComputeResultantAccessibility(containingType); var setAccessibility = overriddenProperty.SetMethod.ComputeResultantAccessibility(containingType); SyntaxNode getBody = null; SyntaxNode setBody = null; // Implement an abstract property by throwing not implemented in accessors. if (overriddenProperty.IsAbstract) { getBody = codeFactory.CreateThrowNotImplementStatement(document.Project.GetCompilationAsync(cancellationToken).WaitAndGetResult(cancellationToken)); setBody = getBody; } else if (overriddenProperty.IsIndexer() && document.Project.Language == LanguageNames.CSharp) { // Indexer: return or set base[]. Only in C#, since VB must refer to these by name. getBody = codeFactory.CreateReturnStatement( codeFactory.CreateElementAccessExpression( codeFactory.CreateBaseExpression(), codeFactory.CreateArguments(overriddenProperty.Parameters))); setBody = codeFactory.CreateExpressionStatement( codeFactory.CreateAssignExpression( codeFactory.CreateElementAccessExpression( codeFactory.CreateBaseExpression(), codeFactory.CreateArguments(overriddenProperty.Parameters)), codeFactory.CreateIdentifierName("value"))); } else if (overriddenProperty.GetParameters().Any()) { // Call accessors directly if C# overriding VB if (document.Project.Language == LanguageNames.CSharp && SymbolFinder.FindSourceDefinitionAsync(overriddenProperty, document.Project.Solution) .WaitAndGetResult(CancellationToken.None).Language == LanguageNames.VisualBasic) { var getName = overriddenProperty.GetMethod != null ? overriddenProperty.GetMethod.Name : null; var setName = overriddenProperty.SetMethod != null ? overriddenProperty.SetMethod.Name : null; getBody = getName == null ? null : codeFactory.CreateReturnStatement( codeFactory.CreateInvocationExpression( codeFactory.CreateMemberAccessExpression( codeFactory.CreateBaseExpression(), codeFactory.CreateIdentifierName(getName)), codeFactory.CreateArguments(overriddenProperty.Parameters))); setBody = setName == null ? null : codeFactory.CreateExpressionStatement( codeFactory.CreateInvocationExpression( codeFactory.CreateMemberAccessExpression( codeFactory.CreateBaseExpression(), codeFactory.CreateIdentifierName(setName)), codeFactory.CreateArguments(overriddenProperty.SetMethod.GetParameters()))); } else { getBody = codeFactory.CreateReturnStatement( codeFactory.CreateInvocationExpression( codeFactory.CreateMemberAccessExpression( codeFactory.CreateBaseExpression(), codeFactory.CreateIdentifierName(overriddenProperty.Name)), codeFactory.CreateArguments(overriddenProperty.Parameters))); setBody = codeFactory.CreateExpressionStatement( codeFactory.CreateAssignExpression( codeFactory.CreateInvocationExpression( codeFactory.CreateMemberAccessExpression( codeFactory.CreateBaseExpression(), codeFactory.CreateIdentifierName(overriddenProperty.Name)), codeFactory.CreateArguments(overriddenProperty.Parameters)), codeFactory.CreateIdentifierName("value"))); } } else { // Regular property: return or set the base property getBody = codeFactory.CreateReturnStatement( codeFactory.CreateMemberAccessExpression( codeFactory.CreateBaseExpression(), codeFactory.CreateIdentifierName(overriddenProperty.Name))); setBody = codeFactory.CreateExpressionStatement( codeFactory.CreateAssignExpression( codeFactory.CreateMemberAccessExpression( codeFactory.CreateBaseExpression(), codeFactory.CreateIdentifierName(overriddenProperty.Name)), codeFactory.CreateIdentifierName("value"))); } // Only generate a getter if the base getter is accessible. IMethodSymbol accessorGet = null; if (overriddenProperty.GetMethod != null && overriddenProperty.GetMethod.IsAccessibleWithin(containingType)) { accessorGet = CodeGenerationSymbolFactory.CreateMethodSymbol( overriddenProperty.GetMethod, accessibility: getAccessibility, statements: new[] { getBody }, modifiers: modifiers); } // Only generate a setter if the base setter is accessible. IMethodSymbol accessorSet = null; if (overriddenProperty.SetMethod != null && overriddenProperty.SetMethod.IsAccessibleWithin(containingType) && overriddenProperty.SetMethod.DeclaredAccessibility != Accessibility.Private) { accessorSet = CodeGenerationSymbolFactory.CreateMethodSymbol( overriddenProperty.SetMethod, accessibility: setAccessibility, statements: new[] { setBody }, modifiers: modifiers); } return(CodeGenerationSymbolFactory.CreatePropertySymbol( overriddenProperty, accessibility: overriddenProperty.ComputeResultantAccessibility(containingType), modifiers: modifiers, name: overriddenProperty.Name, isIndexer: overriddenProperty.IsIndexer(), getMethod: accessorGet, setMethod: accessorSet)); }