internal SyntaxNode CreateOrdinalMemberAccess(SyntaxGenerator syntaxFactoryService, SemanticModel model) { var stringComparisonType = WellKnownTypes.StringComparison(model.Compilation); return syntaxFactoryService.MemberAccessExpression( syntaxFactoryService.TypeExpression(stringComparisonType), syntaxFactoryService.IdentifierName(CA1309DiagnosticAnalyzer.OrdinalText)); }
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 IFieldSymbol GetExplicitlyAssignedField(IFieldSymbol originalField, SyntaxGenerator syntaxFactoryService) { var originalInitializer = GetFieldInitializer(originalField); if (originalInitializer != null || !originalField.HasConstantValue) { return originalField; } var constantValueExpression = syntaxFactoryService.LiteralExpression(originalField.ConstantValue); var newInitializer = CreateConstantValueInitializer(constantValueExpression); return CodeGenerationSymbolFactory.CreateFieldSymbol(originalField.GetAttributes(), originalField.DeclaredAccessibility, originalField.GetSymbolModifiers(), originalField.Type, originalField.Name, originalField.HasConstantValue, originalField.ConstantValue, newInitializer); }
public static SyntaxNode GenerateThrowStatement( SyntaxGenerator factory, SemanticDocument document, string exceptionMetadataName, CancellationToken cancellationToken) { var compilation = document.SemanticModel.Compilation; var exceptionType = compilation.GetTypeByMetadataName(exceptionMetadataName); // If we can't find the Exception, we obviously can't generate anything. if (exceptionType == null) { return null; } var exceptionCreationExpression = factory.ObjectCreationExpression( exceptionType, SpecializedCollections.EmptyList<SyntaxNode>()); return factory.ThrowStatement(exceptionCreationExpression); }
internal SyntaxNode CreateEqualsExpression(SyntaxGenerator syntaxFactoryService, SemanticModel model, SyntaxNode operand1, SyntaxNode operand2, bool isEquals) { var stringType = model.Compilation.GetSpecialType(SpecialType.System_String); var memberAccess = syntaxFactoryService.MemberAccessExpression( syntaxFactoryService.TypeExpression(stringType), syntaxFactoryService.IdentifierName(CA1309DiagnosticAnalyzer.EqualsMethodName)); var ordinal = CreateOrdinalMemberAccess(syntaxFactoryService, model); var invocation = syntaxFactoryService.InvocationExpression( memberAccess, operand1, operand2.WithTrailingTrivia(), ordinal) .WithAdditionalAnnotations(Formatter.Annotation); if (!isEquals) { invocation = syntaxFactoryService.LogicalNotExpression(invocation); } invocation = invocation.WithTrailingTrivia(operand2.GetTrailingTrivia()); return invocation; }
protected IMethodSymbol CreateGet(string originalFieldName, IFieldSymbol field, SyntaxGenerator factory) { var body = factory.ReturnStatement( factory.IdentifierName(originalFieldName)); return CodeGenerationSymbolFactory.CreateAccessorSymbol(SpecializedCollections.EmptyList<AttributeData>(), Accessibility.NotApplicable, new[] { body }.ToList()); }
protected IMethodSymbol CreateSet(string originalFieldName, IFieldSymbol field, SyntaxGenerator factory) { var assigned = !field.IsStatic ? factory.MemberAccessExpression( factory.ThisExpression(), factory.IdentifierName(originalFieldName)) : factory.IdentifierName(originalFieldName); var body = factory.ExpressionStatement( factory.AssignmentStatement( assigned.WithAdditionalAnnotations(Simplifier.Annotation), factory.IdentifierName("value"))); return CodeGenerationSymbolFactory.CreateAccessorSymbol(SpecializedCollections.EmptyList<AttributeData>(), Accessibility.NotApplicable, new[] { body }.ToList()); }
internal SyntaxNode CreateCharSetArgument(SyntaxGenerator syntaxFactoryService, INamedTypeSymbol charSetType) { return syntaxFactoryService.MemberAccessExpression( syntaxFactoryService.TypeExpression(charSetType), syntaxFactoryService.IdentifierName(UnicodeText)); }
internal SyntaxNode CreateMarshalAsArgument(SyntaxGenerator syntaxFactoryService, INamedTypeSymbol unmanagedType) { return syntaxFactoryService.MemberAccessExpression( syntaxFactoryService.TypeExpression(unmanagedType), syntaxFactoryService.IdentifierName(LPWStrText)); }
private SyntaxNode GenerateName(SyntaxGenerator factory, bool isGenericType) { return isGenericType ? factory.GenericName(State.ClassOrStructType.Name, State.ClassOrStructType.TypeArguments) : factory.IdentifierName(State.ClassOrStructType.Name); }
private SyntaxNode CreateThroughExpression(SyntaxGenerator factory) { var through = ThroughMember.IsStatic ? GenerateName(factory, State.ClassOrStructType.IsGenericType) : factory.ThisExpression(); through = factory.MemberAccessExpression( through, factory.IdentifierName(ThroughMember.Name)); var throughMemberType = ThroughMember.GetMemberType(); if ((State.InterfaceTypes != null) && (throughMemberType != null)) { // In the case of 'implement interface through field / property' , we need to know what // interface we are implementing so that we can insert casts to this interface on every // usage of the field in the generated code. Without these casts we would end up generating // code that fails compilation in certain situations. // // For example consider the following code. // class C : IReadOnlyList<int> { int[] field; } // When applying the 'implement interface through field' code fix in the above example, // we need to generate the following code to implement the Count property on IReadOnlyList<int> // class C : IReadOnlyList<int> { int[] field; int Count { get { ((IReadOnlyList<int>)field).Count; } ...} // as opposed to the following code which will fail to compile (because the array field // doesn't have a property named .Count) - // class C : IReadOnlyList<int> { int[] field; int Count { get { field.Count; } ...} // // The 'InterfaceTypes' property on the state object always contains only one item // in the case of C# i.e. it will contain exactly the interface we are trying to implement. // This is also the case most of the time in the case of VB, except in certain error conditions // (recursive / circular cases) where the span of the squiggle for the corresponding // diagnostic (BC30149) changes and 'InterfaceTypes' ends up including all interfaces // in the Implements clause. For the purposes of inserting the above cast, we ignore the // uncommon case and optimize for the common one - in other words, we only apply the cast // in cases where we can unambiguously figure out which interface we are trying to implement. var interfaceBeingImplemented = State.InterfaceTypes.SingleOrDefault(); if ((interfaceBeingImplemented != null) && (!throughMemberType.Equals(interfaceBeingImplemented))) { through = factory.CastExpression(interfaceBeingImplemented, through.WithAdditionalAnnotations(Simplifier.Annotation)); var facts = this.Document.GetLanguageService<ISyntaxFactsService>(); through = facts.Parenthesize(through); } } return through.WithAdditionalAnnotations(Simplifier.Annotation); }
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; }
private static SyntaxNode GetDefaultEqualityComparer( SyntaxGenerator factory, Compilation compilation, ISymbol member) { var equalityComparerType = compilation.EqualityComparerOfTType(); var constructedType = equalityComparerType.Construct(GetType(compilation, member)); return factory.MemberAccessExpression( factory.TypeExpression(constructedType), factory.IdentifierName(DefaultName)); }
private static SyntaxNode ComputeHashValue( SyntaxGenerator factory, Compilation compilation, ISymbol member) { var getHashCodeNameExpression = factory.IdentifierName(GetHashCodeName); var thisSymbol = factory.MemberAccessExpression(factory.ThisExpression(), factory.IdentifierName(member.Name)).WithAdditionalAnnotations(Simplification.Simplifier.Annotation); #if false EqualityComparer<SType>.Default.GetHashCode(this.S1) #endif return factory.InvocationExpression( factory.MemberAccessExpression( GetDefaultEqualityComparer(factory, compilation, member), getHashCodeNameExpression), thisSymbol); }
private IList<ISymbol> GetNewFieldsForRuleNameNoZeroValue(INamedTypeSymbol enumType, SyntaxGenerator syntaxFactoryService) { // Diagnostic: Add a member to '{0}' that has a value of zero with a suggested name of 'None'. // Fix: Add a zero-valued member 'None' to enum. var newFields = new List<ISymbol>(); var constantValueExpression = syntaxFactoryService.LiteralExpression(0); var newInitializer = CreateConstantValueInitializer(constantValueExpression); var newField = CodeGenerationSymbolFactory.CreateFieldSymbol(SpecializedCollections.EmptyList<AttributeData>(), Accessibility.Public, default(SymbolModifiers), enumType.EnumUnderlyingType, "None", true, 0, newInitializer); newFields.Add(newField); foreach (var member in enumType.GetMembers()) { if (!CA1008DiagnosticAnalyzer.IsMemberNamedNone(member)) { newFields.Add(member); } } return newFields; }
private IList<ISymbol> GetNewFieldsForRuleNameMultipleZero(INamedTypeSymbol enumType, IEnumerable<IFieldSymbol> zeroValuedFields, SyntaxGenerator syntaxFactoryService) { // Diagnostic: Remove all members that have the value zero from '{0}' except for one member that is named 'None'. // Fix: Remove all members that have the value zero except for one member that is named 'None'. bool needsNewZeroValuedNoneField = true; var set = zeroValuedFields.ToSet(); bool makeNextFieldExplicit = false; var newFields = new List<ISymbol>(); foreach (IFieldSymbol field in enumType.GetMembers().Where(m => m.Kind == SymbolKind.Field)) { var isZeroValued = set.Contains(field); var isZeroValuedNamedNone = isZeroValued && CA1008DiagnosticAnalyzer.IsMemberNamedNone(field); if (!isZeroValued || isZeroValuedNamedNone) { var newField = field; if (makeNextFieldExplicit) { newField = GetExplicitlyAssignedField(field, syntaxFactoryService); makeNextFieldExplicit = false; } newFields.Add(newField); if (isZeroValuedNamedNone) { needsNewZeroValuedNoneField = false; } } else { makeNextFieldExplicit = true; } } if (needsNewZeroValuedNoneField) { var firstZeroValuedField = zeroValuedFields.First(); var constantValueExpression = syntaxFactoryService.LiteralExpression(firstZeroValuedField.ConstantValue); var newInitializer = CreateConstantValueInitializer(constantValueExpression); var newField = CodeGenerationSymbolFactory.CreateFieldSymbol(firstZeroValuedField.GetAttributes(), firstZeroValuedField.DeclaredAccessibility, firstZeroValuedField.GetSymbolModifiers(), firstZeroValuedField.Type, "None", firstZeroValuedField.HasConstantValue, firstZeroValuedField.ConstantValue, newInitializer); newFields.Insert(0, newField); } return newFields; }