/// <summary> /// Changes the base type of the symbol. /// </summary> public static async Task <ISymbol> SetBaseTypeAsync( this SymbolEditor editor, INamedTypeSymbol symbol, Func <SyntaxGenerator, SyntaxNode> getNewBaseType, CancellationToken cancellationToken = default(CancellationToken)) { var baseType = symbol.BaseType; if (baseType != null) { // find existing declaration of the base type var typeRef = await editor.GetBaseOrInterfaceDeclarationReferenceAsync(symbol, baseType, cancellationToken).ConfigureAwait(false); if (typeRef != null) { return(await editor.EditOneDeclarationAsync( symbol, typeRef.GetLocation(), (e, d) => e.ReplaceNode(typeRef, getNewBaseType(e.Generator)), cancellationToken).ConfigureAwait(false)); } } // couldn't find the existing reference to change, so add it to one of the declarations return(await editor.EditOneDeclarationAsync(symbol, (e, decl) => { var newBaseType = getNewBaseType(e.Generator); if (newBaseType != null) { e.ReplaceNode(decl, (d, g) => g.AddBaseType(d, newBaseType)); } }, cancellationToken).ConfigureAwait(false)); }
/// <summary> /// Gets the reference to the declaration of the base or interface type as part of the symbol's declaration. /// </summary> public static async Task <SyntaxNode> GetBaseOrInterfaceDeclarationReferenceAsync( this SymbolEditor editor, ISymbol symbol, ITypeSymbol baseOrInterfaceType, CancellationToken cancellationToken = default(CancellationToken)) { if (baseOrInterfaceType == null) { throw new ArgumentNullException(nameof(baseOrInterfaceType)); } if (baseOrInterfaceType.TypeKind != TypeKind.Error) { baseOrInterfaceType = (ITypeSymbol)(await editor.GetCurrentSymbolAsync(baseOrInterfaceType, cancellationToken).ConfigureAwait(false)); } // look for the base or interface declaration in all declarations of the symbol var currentDecls = await editor.GetCurrentDeclarationsAsync(symbol, cancellationToken).ConfigureAwait(false); foreach (var decl in currentDecls) { var doc = editor.OriginalSolution.GetDocument(decl.SyntaxTree); var model = await doc.GetSemanticModelAsync(cancellationToken).ConfigureAwait(false); var gen = SyntaxGenerator.GetGenerator(doc); var typeRef = gen.GetBaseAndInterfaceTypes(decl).FirstOrDefault(r => model.GetTypeInfo(r, cancellationToken).Type.Equals(baseOrInterfaceType)); if (typeRef != null) { return(typeRef); } } return(null); }
/// <summary> /// Changes the base type of the symbol. /// </summary> public static Task <ISymbol> SetBaseTypeAsync( this SymbolEditor editor, INamedTypeSymbol symbol, ITypeSymbol newBaseType, CancellationToken cancellationToken = default) { return(editor.SetBaseTypeAsync(symbol, g => newBaseType != null ? g.TypeExpression(newBaseType) : null, cancellationToken)); }
private async Task ApplyRuleNameMultipleZeroAsync(SymbolEditor editor, INamedTypeSymbol enumType, CancellationToken cancellationToken) { // 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 = CA1008DiagnosticAnalyzer.GetZeroValuedFields(enumType).ToSet(); bool makeNextFieldExplicit = false; 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) { if (makeNextFieldExplicit) { await editor.EditOneDeclarationAsync(field, (e, d) => e.ReplaceNode(d, GetExplicitlyAssignedField(field, d, e.Generator)), cancellationToken); makeNextFieldExplicit = false; } if (isZeroValuedNamedNone) { needsNewZeroValuedNoneField = false; } } else { await editor.EditOneDeclarationAsync(field, (e, d) => e.RemoveNode(d), cancellationToken); // removes the field declaration makeNextFieldExplicit = true; } } if (needsNewZeroValuedNoneField) { await editor.EditOneDeclarationAsync(enumType, (e, d) => e.InsertMembers(d, 0, new[] { e.Generator.EnumMember("None") }), cancellationToken); } }
private async Task ApplyRuleNameNoZeroValueAsync(SymbolEditor editor, INamedTypeSymbol enumType, CancellationToken cancellationToken) { // remove any non-zero member named 'None' foreach (IFieldSymbol field in enumType.GetMembers().Where(m => m.Kind == SymbolKind.Field)) { if (CA1008DiagnosticAnalyzer.IsMemberNamedNone(field)) { await editor.EditOneDeclarationAsync(field, (e, d) => e.RemoveNode(d), cancellationToken); } } // insert zero-valued member 'None' to top await editor.EditOneDeclarationAsync(enumType, (e, d) => e.InsertMembers(d, 0, new[] { e.Generator.EnumMember("None") }), cancellationToken); }