Exemplo n.º 1
0
        /// <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));
        }
Exemplo n.º 2
0
        /// <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);
        }
Exemplo n.º 3
0
 /// <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);
        }