コード例 #1
0
        public static ConstructorDeclarationSyntax TryInferNonTrivialConstructor(TypeDeclarationSyntax syntax, ISemanticModel model = null)
        {
            var publicMutableFields =
                from d in syntax.Members.OfType<FieldDeclarationSyntax>()
                where !d.IsStatic()
                where !d.IsReadOnly()
                where d.IsPublic()
                from v in d.Declaration.Variables
                select new {
                    id = v.Identifier,
                    type = d.Declaration.Type,
                    init = v.Initializer ?? d.Declaration.Type.NiceDefaultInitializer(model, assumeImplicitConversion: true) };

            var uninitializedReadonlyFields =
                from d in syntax.Members.OfType<FieldDeclarationSyntax>()
                where !d.IsStatic()
                where d.IsReadOnly()
                from v in d.Declaration.Variables
                where v.Initializer == null
                select new {
                    id = v.Identifier,
                    type = d.Declaration.Type,
                    init = (EqualsValueClauseSyntax)null };

            var publicSetAutoProperties =
                from d in syntax.Members.OfType<PropertyDeclarationSyntax>()
                where !d.IsStatic()
                where d.IsPublicSettable()
                where d.IsAutoProperty()
                select new {
                    id = d.Identifier,
                    type = d.Type,
                    init = d.Type.NiceDefaultInitializer(model, assumeImplicitConversion: true) };

            var initializables = uninitializedReadonlyFields.Concat(publicMutableFields).Concat(publicSetAutoProperties).ToArray();
            if (initializables.Length == 0) return null; //trivial

            var pars = initializables.Select(e => Syntax.Parameter(e.id).WithType(e.type).WithDefault(e.init));
            var initStatements = initializables.Select(e => Syntax.ExpressionStatement(
                Syntax.IdentifierName(Syntax.Token(SyntaxKind.ThisKeyword))
                .Accessing(Syntax.IdentifierName(e.id))
                .BOpAssigned(Syntax.IdentifierName(e.id))));
            return Syntax.ConstructorDeclaration(syntax.Identifier)
                .WithModifiers(Syntax.TokenList(Syntax.Token(SyntaxKind.PublicKeyword)))
                .WithParameterList(pars.Pars())
                .WithBody(initStatements.Block());
        }
コード例 #2
0
        public Comment(string content, int lineNumber, MemberDeclarationSyntax methodOrPropertyIfAny, TypeDeclarationSyntax typeIfAny, NamespaceDeclarationSyntax namespaceIfAny)
        {
            if (string.IsNullOrEmpty(content))
            {
                throw new ArgumentException("Null/blank content specified");
            }
            if (lineNumber < 1)
            {
                throw new ArgumentOutOfRangeException("lineNumber");
            }

            Content               = content;
            LineNumber            = lineNumber;
            MethodOrPropertyIfAny = methodOrPropertyIfAny;
            TypeIfAny             = typeIfAny;
            NamespaceIfAny        = namespaceIfAny;
        }
コード例 #3
0
 private static IEnumerable <DeclarationTuple <IPropertySymbol> > GetInitializedPropertyDeclarations(TypeDeclarationSyntax declaration,
                                                                                                     SemanticModel semanticModel)
 {
     return(declaration.Members
            .OfType <PropertyDeclarationSyntax>()
            .Where(p => !p.Modifiers.Any(IsStaticOrConst) &&
                   p.Initializer != null &&
                   MemberInitializedToDefault.IsAutoProperty(p))
            .Select(p =>
                    new DeclarationTuple <IPropertySymbol>
     {
         Initializer = p.Initializer,
         SemanticModel = semanticModel,
         Symbol = semanticModel.GetDeclaredSymbol(p)
     })
            .Where(t =>
                   t.Symbol != null &&
                   !MemberInitializedToDefault.IsDefaultValueInitializer(t.Initializer, t.Symbol.Type)));
 }
コード例 #4
0
 private static bool CanOrder(TypeDeclarationSyntax typeDeclarationSyntax) => typeDeclarationSyntax != null && typeDeclarationSyntax.Members.Count > 1;
コード例 #5
0
        private void GenerateCode(GeneratorExecutionContext context, TypeDeclarationSyntax tds, Type attributeType)
        {
            // Field symbol
            var symbol = context.ParseSyntaxNode <INamedTypeSymbol>(tds);

            if (symbol == null || context.CancellationToken.IsCancellationRequested)
            {
                return;
            }

            // Attribute data
            var attributeData = symbol.GetAttributeData(attributeType.FullName);

            // Auto Utc datetime
            var utcDateTime = attributeData?.GetValue <bool>(nameof(AutoDataReaderGeneratorAttribute.UtcDateTime));

            // Name space and class name
            var(ns, className) = (symbol.ContainingNamespace.ToDisplayString(), symbol.Name);

            // Keyword
            var keyword = tds.Keyword.ToString();

            // Is Public
            var isPublic = tds.HasToken(SyntaxKind.PublicKeyword);

            // Name
            var name = tds.Identifier.ToString();

            // Inheritance
            var externals = new List <string>();

            // Body
            var body = GenerateBody(context, tds, utcDateTime.GetValueOrDefault(), externals, ns);

            if (context.CancellationToken.IsCancellationRequested)
            {
                return;
            }

            externals.Add($"com.etsoo.Utils.Serialization.IDataReaderParser<{name}>");

            // Source code
            var source = $@"#nullable enable
                using System;
                using System.Collections.Generic;
                using System.Data.Common;
                using System.Linq;
                using System.Threading.Tasks;
                using com.etsoo.Utils.Database;
                using com.etsoo.Utils.String;
                using com.etsoo.Utils.Localization;

                namespace {ns}
                {{
                    {(isPublic ? "public" : "internal")} partial {keyword} {className} : {string.Join(", ", externals)}
                    {{
                        public static async IAsyncEnumerable<{name}> CreateAsync(DbDataReader reader)
                        {{
                            // Column names
                            var names = reader.GetColumnNames().ToList();

                            while(await reader.ReadAsync())
                            {{
                                yield return new {name} {body};
                            }}
                        }}
                    }}
                }}
            ";

            context.AddSource($"{ns}.{className}.DataReader.Generated.cs", SourceText.From(source, Encoding.UTF8));
        }
コード例 #6
0
        public sealed override async Task RegisterCodeFixesAsync(CodeFixContext context)
        {
            SyntaxNode root = await context.GetSyntaxRootAsync().ConfigureAwait(false);

            if (!TryFindFirstAncestorOrSelf(root, context.Span, out ArgumentSyntax argument))
            {
                return;
            }

            foreach (Diagnostic diagnostic in context.Diagnostics)
            {
                switch (diagnostic.Id)
                {
                case CompilerDiagnosticIdentifiers.ArgumentMustBePassedWithRefOrOutKeyword:
                {
                    if (!Settings.IsEnabled(diagnostic.Id, CodeFixIdentifiers.AddOutModifierToArgument))
                    {
                        return;
                    }

                    SemanticModel semanticModel = await context.GetSemanticModelAsync().ConfigureAwait(false);

                    IParameterSymbol parameter = semanticModel.DetermineParameter(argument, allowCandidate: true, cancellationToken: context.CancellationToken);

                    if (parameter == null)
                    {
                        return;
                    }

                    SyntaxToken refOrOutKeyword = default;

                    if (parameter.RefKind == RefKind.Out)
                    {
                        refOrOutKeyword = Token(SyntaxKind.OutKeyword);
                    }
                    else if (parameter.RefKind == RefKind.Ref)
                    {
                        refOrOutKeyword = Token(SyntaxKind.RefKeyword);
                    }
                    else
                    {
                        return;
                    }

                    CodeAction codeAction = CodeAction.Create(
                        $"Add '{SyntaxFacts.GetText(refOrOutKeyword.Kind())}' modifier",
                        cancellationToken =>
                        {
                            ArgumentSyntax newArgument = argument
                                                         .WithRefOrOutKeyword(refOrOutKeyword)
                                                         .WithFormatterAnnotation();

                            return(context.Document.ReplaceNodeAsync(argument, newArgument, cancellationToken));
                        },
                        GetEquivalenceKey(diagnostic));

                    context.RegisterCodeFix(codeAction, diagnostic);
                    break;
                }

                case CompilerDiagnosticIdentifiers.ArgumentShouldNotBePassedWithRefOrOutKeyword:
                {
                    if (!Settings.IsEnabled(diagnostic.Id, CodeFixIdentifiers.RemoveRefModifier))
                    {
                        return;
                    }

                    CodeAction codeAction = CodeAction.Create(
                        "Remove 'ref' modifier",
                        cancellationToken =>
                        {
                            ArgumentSyntax newArgument = argument
                                                         .WithRefOrOutKeyword(default(SyntaxToken))
                                                         .PrependToLeadingTrivia(argument.RefOrOutKeyword.GetAllTrivia())
                                                         .WithFormatterAnnotation();

                            return(context.Document.ReplaceNodeAsync(argument, newArgument, cancellationToken));
                        },
                        GetEquivalenceKey(diagnostic));

                    context.RegisterCodeFix(codeAction, diagnostic);
                    break;
                }

                case CompilerDiagnosticIdentifiers.CannotConvertArgumentType:
                {
                    if (Settings.IsEnabled(diagnostic.Id, CodeFixIdentifiers.ReplaceNullLiteralExpressionWithDefaultValue))
                    {
                        ExpressionSyntax expression = argument.Expression;

                        if (expression.Kind() == SyntaxKind.NullLiteralExpression &&
                            argument.Parent is ArgumentListSyntax argumentList)
                        {
                            SemanticModel semanticModel = await context.GetSemanticModelAsync().ConfigureAwait(false);

                            ImmutableArray <IParameterSymbol> parameterSymbols = FindParameters(argumentList, semanticModel, context.CancellationToken);

                            if (!parameterSymbols.IsDefault)
                            {
                                int index = argumentList.Arguments.IndexOf(argument);

                                IParameterSymbol parameterSymbol = parameterSymbols[index];

                                ITypeSymbol typeSymbol = parameterSymbol.Type;

                                if (typeSymbol.IsValueType)
                                {
                                    CodeFixRegistrator.ReplaceNullWithDefaultValue(
                                        context,
                                        diagnostic,
                                        expression,
                                        typeSymbol,
                                        CodeFixIdentifiers.ReplaceNullLiteralExpressionWithDefaultValue);
                                }
                            }
                        }
                    }

                    if (Settings.IsEnabled(diagnostic.Id, CodeFixIdentifiers.AddArgumentList))
                    {
                        ExpressionSyntax expression = argument.Expression;

                        if (expression.IsKind(
                                SyntaxKind.IdentifierName,
                                SyntaxKind.GenericName,
                                SyntaxKind.SimpleMemberAccessExpression))
                        {
                            InvocationExpressionSyntax invocationExpression = InvocationExpression(
                                expression.WithoutTrailingTrivia(),
                                ArgumentList().WithTrailingTrivia(expression.GetTrailingTrivia()));

                            SemanticModel semanticModel = await context.GetSemanticModelAsync().ConfigureAwait(false);

                            if (semanticModel.GetSpeculativeMethodSymbol(expression.SpanStart, invocationExpression) != null)
                            {
                                CodeAction codeAction = CodeAction.Create(
                                    "Add argument list",
                                    cancellationToken =>
                                    {
                                        ArgumentSyntax newNode = argument.WithExpression(invocationExpression);

                                        return(context.Document.ReplaceNodeAsync(argument, newNode, cancellationToken));
                                    },
                                    GetEquivalenceKey(diagnostic, CodeFixIdentifiers.AddArgumentList));

                                context.RegisterCodeFix(codeAction, diagnostic);
                                break;
                            }
                        }
                    }

                    if (Settings.IsEnabled(diagnostic.Id, CodeFixIdentifiers.CreateSingletonArray))
                    {
                        ExpressionSyntax expression = argument.Expression;

                        if (expression?.IsMissing == false)
                        {
                            SemanticModel semanticModel = await context.GetSemanticModelAsync().ConfigureAwait(false);

                            ITypeSymbol typeSymbol = semanticModel.GetTypeSymbol(expression);

                            if (typeSymbol?.IsErrorType() == false)
                            {
                                foreach (ITypeSymbol typeSymbol2 in DetermineParameterTypeHelper.DetermineParameterTypes(argument, semanticModel, context.CancellationToken))
                                {
                                    if (!typeSymbol.Equals(typeSymbol2) &&
                                        typeSymbol2 is IArrayTypeSymbol arrayType &&
                                        semanticModel.IsImplicitConversion(expression, arrayType.ElementType))
                                    {
                                        CodeAction codeAction = CodeAction.Create(
                                            "Create singleton array",
                                            cancellationToken => CreateSingletonArrayRefactoring.RefactorAsync(context.Document, expression, arrayType.ElementType, semanticModel, cancellationToken),
                                            GetEquivalenceKey(diagnostic, CodeFixIdentifiers.CreateSingletonArray));

                                        context.RegisterCodeFix(codeAction, diagnostic);
                                        break;
                                    }
                                }
                            }
                        }
                    }

                    break;
                }

                case CompilerDiagnosticIdentifiers.ReadOnlyFieldCannotBePassedAsRefOrOutValue:
                {
                    if (!Settings.IsEnabled(diagnostic.Id, CodeFixIdentifiers.MakeFieldWritable))
                    {
                        return;
                    }

                    SemanticModel semanticModel = await context.GetSemanticModelAsync().ConfigureAwait(false);

                    SymbolInfo symbolInfo = semanticModel.GetSymbolInfo(argument.Expression, context.CancellationToken);

                    if (symbolInfo.CandidateReason != CandidateReason.NotAVariable)
                    {
                        return;
                    }

                    if (!(symbolInfo.CandidateSymbols.SingleOrDefault(shouldThrow: false) is IFieldSymbol fieldSymbol))
                    {
                        return;
                    }

                    if (fieldSymbol.DeclaredAccessibility != Accessibility.Private)
                    {
                        return;
                    }

                    if (!(fieldSymbol.GetSyntax().Parent.Parent is FieldDeclarationSyntax fieldDeclaration))
                    {
                        return;
                    }

                    TypeDeclarationSyntax containingTypeDeclaration = fieldDeclaration.FirstAncestor <TypeDeclarationSyntax>();

                    if (!argument.Ancestors().Any(f => f == containingTypeDeclaration))
                    {
                        return;
                    }

                    ModifiersCodeFixRegistrator.RemoveModifier(
                        context,
                        diagnostic,
                        fieldDeclaration,
                        SyntaxKind.ReadOnlyKeyword,
                        title: $"Make '{fieldSymbol.Name}' writable",
                        additionalKey: CodeFixIdentifiers.MakeFieldWritable);

                    break;
                }
                }
            }
        }
コード例 #7
0
 internal static ITypeSymbol GetDeclaredSymbolSafe(this SemanticModel semanticModel, TypeDeclarationSyntax node, CancellationToken cancellationToken)
 {
     return((ITypeSymbol)semanticModel.SemanticModelFor(node)
            ?.GetDeclaredSymbol(node, cancellationToken));
 }
コード例 #8
0
        private void VisitTypeDeclaration(TypeDeclarationSyntax node)
        {
            VisitBaseTypeDeclaration(node);

            _writer.PushBraceFormatting(_writer.Configuration.BracesLayout.TypeAndNamespaceDeclaration);

            if (node.Members.Count == 0)
            {
                _writer.EmptyBlock(_writer.Configuration.BlankLines.InsideType);
            }
            else
            {
                _writer.BeginBlock();

                _writer.WriteLine(_writer.Configuration.BlankLines.InsideType);

                int newline = 0;

                for (int i = 0; i < node.Members.Count; i++)
                {
                    var member = node.Members[i];

                    if (member.SyntaxKind == SyntaxKind.FieldDeclaration)
                        newline = Math.Max(newline, _writer.Configuration.BlankLines.AroundField);
                    else if (member is BaseTypeDeclarationSyntax)
                        newline = Math.Max(newline, _writer.Configuration.BlankLines.AroundType);
                    else
                        newline = Math.Max(newline, _writer.Configuration.BlankLines.AroundMethod);

                    if (i > 0)
                        _writer.WriteLine(newline);

                    member.Accept(this);

                    if (member.SyntaxKind == SyntaxKind.FieldDeclaration)
                        newline = _writer.Configuration.BlankLines.AroundField;
                    else if (member is BaseTypeDeclarationSyntax)
                        newline = _writer.Configuration.BlankLines.AroundType;
                    else
                        newline = _writer.Configuration.BlankLines.AroundMethod;
                }

                _writer.WriteLine(_writer.Configuration.BlankLines.InsideType);

                _writer.EndBlock();
            }

            _writer.PopBraceFormatting();

            WriteTrailingTrivia(node);
        }
コード例 #9
0
        private void CalculateRenameDocumentAction(CodeFixContext context, SyntaxNode root, Diagnostic diagnostic, TypeDeclarationSyntax typeDeclaration)
        {
            if (!options.IsFeatureEnabled(FeatureIdentifiers.RenameFileToMatchTypeNameCodeFix))
            {
                return;
            }

            var newDocumentName     = NameHelper.AddExtension(typeDeclaration.Identifier.ValueText);
            var renameDocumentTitle = string.Format(Resources.RenameAToB, context.Document.Name, newDocumentName);

            context.RegisterCodeFix(
                new RenameDocumentAction(renameDocumentTitle, context.Document, root, newDocumentName, renameDocumentTitle),
                diagnostic);
        }
コード例 #10
0
        async Task <Solution> PerformAction(Document document, SemanticModel model, SyntaxNode root, TypeDeclarationSyntax enclosingTypeDeclaration, INamedTypeSymbol declaringTypeSymbol, MethodDeclarationSyntax methodDeclaration, IMethodSymbol methodSymbol, CancellationToken cancellationToken)
        {
            // Collect all invocations of changed method
            var methodReferencesVisitor = new MethodReferencesVisitor(document.Project.Solution, methodSymbol, methodDeclaration, cancellationToken);
            await methodReferencesVisitor.Collect();

            // Collect all references to type members and "this" expressions inside of changed method
            var memberReferencesVisitor = new MemberReferencesVisitor(model, declaringTypeSymbol.GetMembers().Where(m => m != methodSymbol), cancellationToken);

            memberReferencesVisitor.Collect(methodDeclaration.Body);

            Solution solution = document.Project.Solution;

            List <SyntaxNode> trackedNodesInMainDoc = new List <SyntaxNode>();

            trackedNodesInMainDoc.Add(methodDeclaration);
            var methodReferencesInMainDocument = methodReferencesVisitor.NodesToChange.FirstOrDefault(n => n.Document.Id == document.Id);

            if (methodReferencesInMainDocument != null)
            {
                trackedNodesInMainDoc.AddRange(methodReferencesInMainDocument.References.Select(r => r.InvocationExpression));
            }
            trackedNodesInMainDoc.AddRange(memberReferencesVisitor.NodesToChange);

            var newMainRoot = root.TrackNodes(trackedNodesInMainDoc);

            foreach (var invocationsInDocument in methodReferencesVisitor.NodesToChange)
            {
                SyntaxNode thisDocRoot    = null;
                var        thisDocumentId = invocationsInDocument.Document.Id;
                if (document.Id == thisDocumentId)
                {
                    // We are in same document as changed method declaration, reuse new root from outside
                    thisDocRoot = newMainRoot;
                }
                else
                {
                    thisDocRoot = await invocationsInDocument.Document.GetSyntaxRootAsync();

                    if (thisDocRoot == null)
                    {
                        continue;
                    }
                    thisDocRoot = thisDocRoot.TrackNodes(invocationsInDocument.References.Select(r => r.InvocationExpression));
                }

                foreach (var referencingInvocation in invocationsInDocument.References)
                {
                    // Change this method invocation to invocation of a static method with instance parameter
                    var thisInvocation = thisDocRoot.GetCurrentNode(referencingInvocation.InvocationExpression);

                    ExpressionSyntax invocationExpressionPart = null;
                    SimpleNameSyntax methodName = null;
                    var memberAccessExpr        = thisInvocation.Expression as MemberAccessExpressionSyntax;
                    if (memberAccessExpr != null)
                    {
                        invocationExpressionPart = memberAccessExpr.Expression;
                        methodName = memberAccessExpr.Name;
                    }

                    if (invocationExpressionPart == null)
                    {
                        var identifier = thisInvocation.Expression as IdentifierNameSyntax;
                        if (identifier != null)
                        {
                            // If changed method references itself, use "instance" as additional parameter! In other methods of affected class, use "this"!
                            if (referencingInvocation.IsInChangedMethod)
                            {
                                invocationExpressionPart = SyntaxFactory.IdentifierName("instance").WithLeadingTrivia(identifier.GetLeadingTrivia());
                            }
                            else
                            {
                                invocationExpressionPart = SyntaxFactory.ThisExpression().WithLeadingTrivia(identifier.GetLeadingTrivia());
                            }
                            methodName = identifier;
                        }
                    }

                    if (invocationExpressionPart == null)
                    {
                        continue;
                    }

                    List <ArgumentSyntax> invocationArguments = new List <ArgumentSyntax>();
                    invocationArguments.Add(SyntaxFactory.Argument(invocationExpressionPart.WithoutLeadingTrivia()));
                    invocationArguments.AddRange(referencingInvocation.InvocationExpression.ArgumentList.Arguments);

                    thisDocRoot = thisDocRoot.ReplaceNode(
                        thisInvocation,
                        SyntaxFactory.InvocationExpression(
                            SyntaxFactory.MemberAccessExpression(
                                SyntaxKind.SimpleMemberAccessExpression,
                                SyntaxFactory.IdentifierName(enclosingTypeDeclaration.Identifier.WithoutTrivia()).WithLeadingTrivia(invocationExpressionPart.GetLeadingTrivia()),
                                methodName.WithoutLeadingTrivia()
                                ),
                            SyntaxFactory.ArgumentList(SyntaxFactory.SeparatedList(invocationArguments)).WithAdditionalAnnotations(Formatter.Annotation)
                            ));
                }


                if (document.Id == thisDocumentId)
                {
                    // Write new root back to outside
                    newMainRoot = thisDocRoot;
                }
                else
                {
                    // Another document, replace it with modified version in solution
                    solution = solution.WithDocumentSyntaxRoot(thisDocumentId, thisDocRoot);
                }
            }

            foreach (var changedNode in memberReferencesVisitor.NodesToChange)
            {
                var trackedNode = newMainRoot.GetCurrentNode(changedNode);

                var thisExpression = trackedNode as ThisExpressionSyntax;
                if (thisExpression != null)
                {
                    // Replace "this" with instance parameter name
                    newMainRoot = newMainRoot.ReplaceNode(
                        thisExpression,
                        SyntaxFactory.IdentifierName("instance").WithLeadingTrivia(thisExpression.GetLeadingTrivia())
                        );
                }

                var memberIdentifier = trackedNode as IdentifierNameSyntax;
                if (memberIdentifier != null)
                {
                    newMainRoot = newMainRoot.ReplaceNode(
                        memberIdentifier,
                        SyntaxFactory.MemberAccessExpression(SyntaxKind.SimpleMemberAccessExpression,
                                                             SyntaxFactory.IdentifierName("instance").WithLeadingTrivia(memberIdentifier.GetLeadingTrivia()),
                                                             memberIdentifier.WithoutLeadingTrivia())
                        );
                }
            }

            List <ParameterSyntax> parameters = new List <ParameterSyntax>();

            parameters.Add(SyntaxFactory.Parameter(
                               SyntaxFactory.List <AttributeListSyntax>(),
                               SyntaxFactory.TokenList(),
                               SyntaxFactory.ParseTypeName(enclosingTypeDeclaration.Identifier.ValueText),
                               SyntaxFactory.Identifier("instance"), null)
                           .WithAdditionalAnnotations(Formatter.Annotation));
            parameters.AddRange(methodDeclaration.ParameterList.Parameters);

            var staticModifierLeadingTrivia =
                methodDeclaration.Modifiers.Any() ? SyntaxFactory.TriviaList() : methodDeclaration.GetLeadingTrivia();
            var methodDeclarationLeadingTrivia =
                methodDeclaration.Modifiers.Any() ? methodDeclaration.GetLeadingTrivia() : SyntaxFactory.TriviaList();

            var trackedMethodDeclaration = newMainRoot.GetCurrentNode(methodDeclaration);

            newMainRoot = newMainRoot.ReplaceNode((SyntaxNode)trackedMethodDeclaration, trackedMethodDeclaration
                                                  .WithLeadingTrivia(methodDeclarationLeadingTrivia)
                                                  .WithModifiers(trackedMethodDeclaration.Modifiers.Add(SyntaxFactory.Token(SyntaxKind.StaticKeyword).WithLeadingTrivia(staticModifierLeadingTrivia).WithTrailingTrivia(SyntaxFactory.TriviaList(SyntaxFactory.Whitespace(" ")))))
                                                  .WithParameterList(SyntaxFactory.ParameterList(SyntaxFactory.SeparatedList(parameters)).WithTrailingTrivia(trackedMethodDeclaration.ParameterList.GetTrailingTrivia())));
            return(solution.WithDocumentSyntaxRoot(document.Id, newMainRoot));
        }
コード例 #11
0
        private static string GetStyleCopFileName(TypeDeclarationSyntax typeDeclaration)
        {
            var typeParameterList = string.Join(",", typeDeclaration.TypeParameterList.Parameters.Select(p => p.Identifier.ValueText));

            return($"{typeDeclaration.Identifier.ValueText}{{{typeParameterList}}}");
        }
コード例 #12
0
 private static string GetMetadataFileName(TypeDeclarationSyntax typeDeclaration)
 {
     return($"{typeDeclaration.Identifier.ValueText}`{typeDeclaration.Arity}");
 }
コード例 #13
0
 private IList <bool> GetInsertionIndices(TypeDeclarationSyntax destination, CancellationToken cancellationToken)
 {
     return(destination.GetInsertionIndices(cancellationToken));
 }
コード例 #14
0
 private static SyntaxNode HandleTypeDeclaration(MemberOrderHelper memberOrder, TypeDeclarationSyntax typeDeclarationNode, ImmutableArray <OrderingTrait> elementOrder, SyntaxNode syntaxRoot, IndentationOptions indentationOptions)
 {
     return(OrderMember(memberOrder, typeDeclarationNode.Members, elementOrder, syntaxRoot, indentationOptions));
 }
コード例 #15
0
        protected override void Add(TypeDeclarationSyntax type, AttributeSyntax att)
        {
            var r = new ClassWithAttributeResult(type as ClassDeclarationSyntax, att);

            Results.Add(r);
        }
コード例 #16
0
 public static bool CanInferNonTrivialConstructor(TypeDeclarationSyntax syntax)
 {
     return syntax.Members.OfType<FieldDeclarationSyntax>().Any(d => !d.IsStatic() && !d.IsReadOnly() && d.IsPublic() && d.Declaration.Variables.Any())
         || syntax.Members.OfType<FieldDeclarationSyntax>().Any(d => !d.IsStatic() && d.IsReadOnly() && d.Declaration.Variables.Any(v => v.Initializer == null))
         || syntax.Members.OfType<PropertyDeclarationSyntax>().Any(d => !d.IsStatic() && d.IsPublicSettable() && d.IsAutoProperty());
 }
コード例 #17
0
        private void CalculateRenameTypeAction(CodeFixContext context, Diagnostic diagnostic, TypeDeclarationSyntax typeDeclaration)
        {
            if (!options.IsFeatureEnabled(FeatureIdentifiers.RenameTypeToMatchFileNameCodeFix))
            {
                return;
            }

            var documentName = NameHelper.RemoveExtension(context.Document.Name);

            if (documentName == null)
            {
                return;
            }

            if (!documentName.IsValidIdentifier())
            {
                return;
            }

            var renameTypeTitle = string.Format(Resources.RenameAToB, typeDeclaration.Identifier.ValueText, documentName);

            context.RegisterCodeFix(
                CodeAction.Create(
                    title: renameTypeTitle,
                    createChangedSolution: c => RenameTypeAsync(context.Document, typeDeclaration, documentName, c),
                    equivalenceKey: renameTypeTitle),
                diagnostic);
        }
コード例 #18
0
 public static bool IsPartial(this TypeDeclarationSyntax @this)
 {
     return(@this.Modifiers.Any(m => m.IsKind(SyntaxKind.PartialKeyword)));
 }
コード例 #19
0
ファイル: MySyntaxFactory.cs プロジェクト: vain0x/playground
        public ConstructorDeclarationSyntax CompleteConstructor(SemanticModel semanticModel, TypeDeclarationSyntax typeDecl, ImmutableArray <VariableMember> varMembers)
        {
            var typeSyntax         = TypeSyntax(semanticModel, typeDecl.SpanStart);
            var assignables        = Assignables(varMembers);
            var parameterList      = ParameterList(assignables, typeSyntax);
            var contractStatements = ContractStatements(semanticModel, assignables, typeSyntax);
            var assignments        = AssignmentStatements(assignables);
            var body     = Block(contractStatements.Concat(assignments));
            var typeName = typeDecl.Identifier.Text;

            return
                (ConstructorDeclaration(typeName)
                 .WithModifiers(
                     SyntaxTokenList.Create(
                         Token(SyntaxKind.PublicKeyword)
                         ))
                 .WithParameterList(parameterList)
                 .WithBody(body)
                 .WithLeadingTrivia(
                     TriviaList(
                         ElasticCarriageReturnLineFeed,
                         Comment($"// {MagicComment}"),
                         ElasticCarriageReturnLineFeed
                         )));
        }
コード例 #20
0
        private static async Task <Document> MakeDataContractAndMembersExplicit(
            Document document, TypeDeclarationSyntax typeDeclaration, CancellationToken cancellationToken)
        {
            var semanticModel = await document.GetSemanticModelAsync(cancellationToken).ConfigureAwait(false);

            var typeDeclarationSymbol = semanticModel.GetDeclaredSymbol(typeDeclaration, cancellationToken);
            var dataContractAttribute = typeDeclarationSymbol.GetAttribute(MetadataNames.System_Runtime_Serialization_DataContractAttribute);

            const string Name  = "Name";
            const string Order = "Order";

            var replacementNodes = new List <(SyntaxNode oldNode, SyntaxNode newNode)>();

            // Add name argument to DataContract if missing and sort argument list
            var dataContractAttributeSyntax = (AttributeSyntax)dataContractAttribute.ApplicationSyntaxReference.GetSyntax(cancellationToken);
            var dcArgList = dataContractAttributeSyntax.ArgumentList;

            var dcNameArgument   = dcArgList?.Arguments.SingleOrDefault(a => a.NameEquals?.Name.Identifier.ValueText == Name);
            var dcNameExpression = dcNameArgument?.Expression as LiteralExpressionSyntax;

            if (dcArgList == null || dcNameArgument == null || string.IsNullOrWhiteSpace(dcNameExpression?.Token.ValueText))
            {
                var newNameArgument = AttributeArgument(NameEquals(IdentifierName(Name)), StringLiteralExpression(typeDeclaration.Identifier.ValueText));

                var arguments = (dcArgList == null) ? new[] { newNameArgument } :
                (IEnumerable <AttributeArgumentSyntax>)(dcArgList.Arguments.Where(a => a != dcNameArgument)).Concat(new[] { newNameArgument }).OrderBy(a => a.NameEquals.Name.Identifier.ValueText);

                var newDataContractAttribute = Attribute(IdentifierName(dataContractAttributeSyntax.Name.ToString()), AttributeArgumentList(arguments.ToArray()));

                replacementNodes.Add((dataContractAttributeSyntax, newDataContractAttribute));
            }

            // Add name and order to DataMembers
            var members = typeDeclarationSymbol.GetMembers()
                          .Where(m => m.IsKind(SymbolKind.Field) || m.IsKind(SymbolKind.Property))
                          .Where(m => m.HasAttribute(MetadataNames.System_Runtime_Serialization_DataMemberAttribute))
                          .Select(m =>
            {
                var dataMemberAttributeSyntax = (AttributeSyntax)(m.GetAttribute(MetadataNames.System_Runtime_Serialization_DataMemberAttribute).ApplicationSyntaxReference.GetSyntax(cancellationToken));
                var dmArgList = dataMemberAttributeSyntax.ArgumentList;

                var dmNameExpression  = dmArgList?.Arguments.SingleOrDefault(a => a.NameEquals?.Name.Identifier.ValueText == Name)?.Expression as LiteralExpressionSyntax;
                var dmOrderExpression = dmArgList?.Arguments.SingleOrDefault(a => a.NameEquals?.Name.Identifier.ValueText == Order)?.Expression as LiteralExpressionSyntax;

                return(new
                {
                    dataMemberAttributeSyntax,

                    Name = (string.IsNullOrWhiteSpace(dmNameExpression?.Token.ValueText)) ? m.Name : dmNameExpression?.Token.ValueText,
                    Order = (int?)dmOrderExpression?.Token.Value
                });
            })
                          // Members without an explit Order come first
                          .OrderByDescending(m => m.Order == null)
                          // Then by explicit order
                          .ThenBy(m => m.Order)
                          // Then by name (ordinal)
                          .ThenBy(m => m.Name, StringComparer.Ordinal)
                          .Select((m, i) => new
            {
                DataMemberAttributeSyntax = m.dataMemberAttributeSyntax,
                m.Name,
                // Apply an explicit order
                Order = i + 1
            })
                          .ToList();

            foreach (var m in members)
            {
                var dataMemberAttributeSyntax = m.DataMemberAttributeSyntax;

                var newNameArgument  = AttributeArgument(NameEquals(IdentifierName(Name)), StringLiteralExpression(m.Name));
                var newOrderArgument = AttributeArgument(NameEquals(IdentifierName(Order)), NumericLiteralExpression(m.Order));

                IEnumerable <AttributeArgumentSyntax> newArgs = new List <AttributeArgumentSyntax> {
                    newNameArgument, newOrderArgument
                };

                if (dataMemberAttributeSyntax.ArgumentList != null)
                {
                    newArgs = newArgs
                              .Concat(dataMemberAttributeSyntax.ArgumentList.Arguments
                                      .Where(a => (a.NameEquals?.Name.Identifier.ValueText != Name) && (a.NameEquals?.Name.Identifier.ValueText != Order)));
                }

                var arguments = newArgs.OrderBy(a => a.NameEquals.Name.Identifier.ValueText);

                var newDataMemberAttribute = Attribute(IdentifierName(dataMemberAttributeSyntax.Name.ToString()), AttributeArgumentList(arguments.ToArray()));

                replacementNodes.Add((dataMemberAttributeSyntax, newDataMemberAttribute));
            }

            return(await document.ReplaceNodesAsync(replacementNodes.Select(r => r.oldNode), GetReplacement, cancellationToken).ConfigureAwait(false));

            SyntaxNode GetReplacement(SyntaxNode n1, SyntaxNode _) => replacementNodes.Single(r => r.oldNode == n1).newNode;
        }
コード例 #21
0
        /// <summary>
        /// Add the field and respect StyleCop ordering.
        /// </summary>
        /// <param name="generator">The <see cref="SyntaxGenerator"/>.</param>
        /// <param name="containingType">The containing type.</param>
        /// <param name="member">The <see cref="MemberDeclarationSyntax"/>.</param>
        /// <param name="comparer">The <see cref="IComparer{MemberDeclarationSyntax}"/>. If null <see cref="MemberDeclarationComparer.Default"/> is used.</param>
        /// <returns>The <paramref name="containingType"/> with <paramref name="member"/>.</returns>
        public static TypeDeclarationSyntax AddSorted(this SyntaxGenerator generator, TypeDeclarationSyntax containingType, MemberDeclarationSyntax member, IComparer <MemberDeclarationSyntax>?comparer = null)
        {
            if (generator is null)
            {
                throw new System.ArgumentNullException(nameof(generator));
            }

            if (containingType is null)
            {
                throw new System.ArgumentNullException(nameof(containingType));
            }

            if (member is null)
            {
                throw new System.ArgumentNullException(nameof(member));
            }

            return(containingType.AddSorted(member, comparer));
        }
コード例 #22
0
        private static async Task <Solution> GetTransformedSolutionAsync(Document document, Diagnostic diagnostic, CancellationToken cancellationToken)
        {
            var root = await document.GetSyntaxRootAsync(cancellationToken).ConfigureAwait(false);

            SyntaxNode node = root.FindNode(diagnostic.Location.SourceSpan, getInnermostNodeForTie: true);
            BaseTypeDeclarationSyntax baseTypeDeclarationSyntax = node as BaseTypeDeclarationSyntax;
            DelegateDeclarationSyntax delegateDeclarationSyntax = node as DelegateDeclarationSyntax;

            if (baseTypeDeclarationSyntax == null && delegateDeclarationSyntax == null)
            {
                return(document.Project.Solution);
            }

            DocumentId extractedDocumentId   = DocumentId.CreateNewId(document.Project.Id);
            string     extractedDocumentName = baseTypeDeclarationSyntax.Identifier.ValueText;

            if (baseTypeDeclarationSyntax != null)
            {
                TypeDeclarationSyntax typeDeclarationSyntax = baseTypeDeclarationSyntax as TypeDeclarationSyntax;
                if (typeDeclarationSyntax?.TypeParameterList?.Parameters.Count > 0)
                {
                    extractedDocumentName += "`" + typeDeclarationSyntax.TypeParameterList.Parameters.Count;
                }
            }
            else
            {
                if (delegateDeclarationSyntax.TypeParameterList?.Parameters.Count > 0)
                {
                    extractedDocumentName += "`" + delegateDeclarationSyntax.TypeParameterList.Parameters.Count;
                }
            }

            extractedDocumentName += ".cs";

            List <SyntaxNode> nodesToRemoveFromExtracted = new List <SyntaxNode>();
            SyntaxNode        previous = node;

            for (SyntaxNode current = node.Parent; current != null; previous = current, current = current.Parent)
            {
                foreach (SyntaxNode child in current.ChildNodes())
                {
                    if (child == previous)
                    {
                        continue;
                    }

                    switch (child.Kind())
                    {
                    case SyntaxKind.NamespaceDeclaration:
                    case SyntaxKind.ClassDeclaration:
                    case SyntaxKind.StructDeclaration:
                    case SyntaxKind.InterfaceDeclaration:
                    case SyntaxKind.EnumDeclaration:
                    case SyntaxKind.DelegateDeclaration:
                        nodesToRemoveFromExtracted.Add(child);
                        break;

                    default:
                        break;
                    }
                }
            }

            SyntaxNode extractedDocumentNode = root.RemoveNodes(nodesToRemoveFromExtracted, SyntaxRemoveOptions.KeepUnbalancedDirectives);

            Solution updatedSolution = document.Project.Solution.AddDocument(extractedDocumentId, extractedDocumentName, extractedDocumentNode, document.Folders);

            // Make sure to also add the file to linked projects
            foreach (var linkedDocumentId in document.GetLinkedDocumentIds())
            {
                DocumentId linkedExtractedDocumentId = DocumentId.CreateNewId(linkedDocumentId.ProjectId);
                updatedSolution = updatedSolution.AddDocument(linkedExtractedDocumentId, extractedDocumentName, extractedDocumentNode, document.Folders);
            }

            // Remove the type from its original location
            updatedSolution = updatedSolution.WithDocumentSyntaxRoot(document.Id, root.RemoveNode(node, SyntaxRemoveOptions.KeepUnbalancedDirectives));

            return(updatedSolution);
        }
コード例 #23
0
 private CSharpSyntaxContext(
     Workspace workspace,
     SemanticModel semanticModel,
     int position,
     SyntaxToken leftToken,
     SyntaxToken targetToken,
     TypeDeclarationSyntax containingTypeDeclaration,
     BaseTypeDeclarationSyntax containingTypeOrEnumDeclaration,
     bool isInNonUserCode,
     bool isPreProcessorDirectiveContext,
     bool isPreProcessorKeywordContext,
     bool isPreProcessorExpressionContext,
     bool isTypeContext,
     bool isNamespaceContext,
     bool isNamespaceDeclarationNameContext,
     bool isStatementContext,
     bool isGlobalStatementContext,
     bool isAnyExpressionContext,
     bool isNonAttributeExpressionContext,
     bool isConstantExpressionContext,
     bool isAttributeNameContext,
     bool isEnumTypeMemberAccessContext,
     bool isNameOfContext,
     bool isInQuery,
     bool isInImportsDirective,
     bool isLabelContext,
     bool isTypeArgumentOfConstraintContext,
     bool isRightOfDotOrArrowOrColonColon,
     bool isIsOrAsContext,
     bool isObjectCreationTypeContext,
     bool isDefiniteCastTypeContext,
     bool isGenericTypeArgumentContext,
     bool isEnumBaseListContext,
     bool isIsOrAsTypeContext,
     bool isLocalVariableDeclarationContext,
     bool isDeclarationExpressionContext,
     bool isFixedVariableDeclarationContext,
     bool isParameterTypeContext,
     bool isPossibleLambdaOrAnonymousMethodParameterTypeContext,
     bool isImplicitOrExplicitOperatorTypeContext,
     bool isPrimaryFunctionExpressionContext,
     bool isDelegateReturnTypeContext,
     bool isTypeOfExpressionContext,
     ISet <SyntaxKind> precedingModifiers,
     bool isInstanceContext,
     bool isCrefContext,
     bool isCatchFilterContext,
     bool isDestructorTypeContext,
     bool isPossibleTupleContext,
     CancellationToken cancellationToken)
     : base(workspace, semanticModel, position, leftToken, targetToken,
            isTypeContext, isNamespaceContext, isNamespaceDeclarationNameContext,
            isPreProcessorDirectiveContext,
            isRightOfDotOrArrowOrColonColon, isStatementContext, isAnyExpressionContext,
            isAttributeNameContext, isEnumTypeMemberAccessContext, isNameOfContext,
            isInQuery, isInImportsDirective, IsWithinAsyncMethod(), isPossibleTupleContext, cancellationToken)
 {
     this.ContainingTypeDeclaration       = containingTypeDeclaration;
     this.ContainingTypeOrEnumDeclaration = containingTypeOrEnumDeclaration;
     this.IsInNonUserCode = isInNonUserCode;
     this.IsPreProcessorKeywordContext    = isPreProcessorKeywordContext;
     this.IsPreProcessorExpressionContext = isPreProcessorExpressionContext;
     this.IsGlobalStatementContext        = isGlobalStatementContext;
     this.IsNonAttributeExpressionContext = isNonAttributeExpressionContext;
     this.IsConstantExpressionContext     = isConstantExpressionContext;
     this.IsLabelContext = isLabelContext;
     this.IsTypeArgumentOfConstraintContext = isTypeArgumentOfConstraintContext;
     this.IsIsOrAsContext                   = isIsOrAsContext;
     this.IsObjectCreationTypeContext       = isObjectCreationTypeContext;
     this.IsDefiniteCastTypeContext         = isDefiniteCastTypeContext;
     this.IsGenericTypeArgumentContext      = isGenericTypeArgumentContext;
     this.IsEnumBaseListContext             = isEnumBaseListContext;
     this.IsIsOrAsTypeContext               = isIsOrAsTypeContext;
     this.IsLocalVariableDeclarationContext = isLocalVariableDeclarationContext;
     this.IsDeclarationExpressionContext    = isDeclarationExpressionContext;
     this.IsFixedVariableDeclarationContext = isFixedVariableDeclarationContext;
     this.IsParameterTypeContext            = isParameterTypeContext;
     this.IsPossibleLambdaOrAnonymousMethodParameterTypeContext = isPossibleLambdaOrAnonymousMethodParameterTypeContext;
     this.IsImplicitOrExplicitOperatorTypeContext = isImplicitOrExplicitOperatorTypeContext;
     this.IsPrimaryFunctionExpressionContext      = isPrimaryFunctionExpressionContext;
     this.IsDelegateReturnTypeContext             = isDelegateReturnTypeContext;
     this.IsTypeOfExpressionContext = isTypeOfExpressionContext;
     this.PrecedingModifiers        = precedingModifiers;
     this.IsInstanceContext         = isInstanceContext;
     this.IsCrefContext             = isCrefContext;
     this.IsCatchFilterContext      = isCatchFilterContext;
     this.IsDestructorTypeContext   = isDestructorTypeContext;
 }
コード例 #24
0
        private string GenerateBody(GeneratorExecutionContext context, TypeDeclarationSyntax tds, bool utcDateTime, List <string> externalInheritances, string ns)
        {
            var body = new List <string>();

            var members = context.ParseMembers(tds, false, externalInheritances, out bool isPositionalRecord);

            if (!context.CancellationToken.IsCancellationRequested)
            {
                var arrayPropertyType = typeof(ArrayPropertyAttribute);

                foreach (var member in members)
                {
                    var(symbol, typeSymbol, nullable) = member;

                    // Object field name
                    var fieldName = symbol.Name;

                    // Field type name
                    var typeName = typeSymbol.GetTypeName(nullable, ns);

                    // ArrayProperty attribute data
                    var arrayData = symbol.GetAttributeData(arrayPropertyType.FullName);

                    // Value part
                    string valuePart;

                    if (typeSymbol.IsSimpleType())
                    {
                        valuePart = $@"(await reader.GetValueAsync<{typeName}>(""{fieldName}"", names))";

                        if (utcDateTime && typeSymbol.Name == "DateTime")
                        {
                            valuePart = $"LocalizationUtils.SetUtcKind{valuePart}";
                        }
                        else if (typeSymbol.Name == "String" && !nullable)
                        {
                            valuePart += "!";
                        }
                    }
                    else if (typeSymbol.TypeKind == TypeKind.Enum)
                    {
                        // Enum item type
                        var enumSymbol = (INamedTypeSymbol)typeSymbol;
                        var enumType   = enumSymbol.EnumUnderlyingType?.Name ?? "Byte";
                        valuePart = $@"({typeName})(await reader.GetValueAsync<{enumType}>(""{fieldName}"", names))";
                    }
                    else if (typeSymbol.TypeKind == TypeKind.Array)
                    {
                        // Array type
                        var arraySymbol    = (IArrayTypeSymbol)typeSymbol;
                        var itemTypeSymbol = arraySymbol.ElementType;
                        if (!itemTypeSymbol.IsSimpleType())
                        {
                            continue;
                        }

                        // Splitter
                        var splitter = Extensions.CharToString(arrayData?.GetValue <char?>("Splitter") ?? ',');

                        var arrayType = itemTypeSymbol.Name;
                        if (arrayType.Equals("String"))
                        {
                            valuePart = $@"StringUtils.AsEnumerable(await reader.GetValueAsync<string>(""{fieldName}"", names), '{splitter}').ToArray()";
                        }
                        else
                        {
                            valuePart = $@"StringUtils.AsEnumerable<{arrayType}>(await reader.GetValueAsync<string>(""{fieldName}"", names), '{splitter}').ToArray()";
                        }
                    }
                    else if (typeSymbol.IsList())
                    {
                        // Item type
                        var listSymbol     = (INamedTypeSymbol)typeSymbol;
                        var itemTypeSymbol = listSymbol.TypeArguments[0];
                        if (!itemTypeSymbol.IsSimpleType())
                        {
                            continue;
                        }

                        // Splitter
                        var splitter = Extensions.CharToString(arrayData?.GetValue <char?>("Splitter") ?? ',');

                        var listType = itemTypeSymbol.Name;
                        if (listType.Equals("String"))
                        {
                            valuePart = $@"StringUtils.AsEnumerable(await reader.GetValueAsync<string>(""{fieldName}"", names), '{splitter}').ToList()";
                        }
                        else
                        {
                            valuePart = $@"StringUtils.AsEnumerable<{listType}>(await reader.GetValueAsync<string>(""{fieldName}"", names), '{splitter}').ToList()";
                        }
                    }
                    else
                    {
                        continue;
                    }

                    if (isPositionalRecord)
                    {
                        body.Add($@"{fieldName}: {valuePart}");
                    }
                    else
                    {
                        body.Add($@"{fieldName} = {valuePart}");
                    }
                }
            }

            // Limitation: When inheritanted, please keep the same style
            // Define constructor for Positional Record
            if (isPositionalRecord)
            {
                return("(" + string.Join(",\n", body) + ")");
            }

            return("{\n" + string.Join(",\n", body) + "\n}");
        }
コード例 #25
0
 internal ClassMappingContext(Compilation compilation, SourceGenerationOptions sourceGenerationOptions, TypeDeclarationSyntax typeSyntax)
     : base(compilation, sourceGenerationOptions, typeSyntax)
 {
 }
コード例 #26
0
 private GenericInfo(TypeDeclarationSyntax typeDeclaration)
     : this(typeDeclaration, typeDeclaration.TypeParameterList, typeDeclaration.ConstraintClauses)
 {
 }
コード例 #27
0
        private async Task <Solution> ExtractTypeToNewDocumentAsync(Document document, CompilationUnitSyntax root, TypeDeclarationSyntax typeDecl, CancellationToken cancellationToken)
        {
            var extractedType = await ExtractTypeAsync(document, root, typeDecl, cancellationToken).ConfigureAwait(false);

            document = await RemoveTypeAsync(typeDecl, document);

            return(document
                   .Project
                   .AddDocument(typeDecl.Identifier.Text + ".cs", extractedType.GetText())
                   .Project
                   .Solution);
        }
コード例 #28
0
 private static IEnumerable <DeclarationTuple <TSymbol> > GetInitializedFieldLikeDeclarations <TDeclarationType, TSymbol>(TypeDeclarationSyntax declaration,
                                                                                                                          SemanticModel semanticModel, Func <TSymbol, ITypeSymbol> typeSelector)
     where TDeclarationType : BaseFieldDeclarationSyntax
     where TSymbol : class, ISymbol
 {
     return(declaration.Members
            .OfType <TDeclarationType>()
            .Where(fd => !fd.Modifiers.Any(IsStaticOrConst))
            .SelectMany(fd => fd.Declaration.Variables
                        .Where(v => v.Initializer != null)
                        .Select(v =>
                                new DeclarationTuple <TSymbol>
     {
         Initializer = v.Initializer,
         SemanticModel = semanticModel,
         Symbol = semanticModel.GetDeclaredSymbol(v) as TSymbol
     }))
            .Where(t =>
                   t.Symbol != null &&
                   !MemberInitializedToDefault.IsDefaultValueInitializer(t.Initializer, typeSelector(t.Symbol))));
 }
コード例 #29
0
        private async Task <Document> RemoveTypeAsync(TypeDeclarationSyntax typeDecl, Document document)
        {
            var root = await document.GetSyntaxRootAsync().ConfigureAwait(false);

            return(document.WithSyntaxRoot(root.RemoveNode(typeDecl, SyntaxRemoveOptions.KeepNoTrivia)));
        }
コード例 #30
0
        public sealed override async Task RegisterCodeFixesAsync(CodeFixContext context)
        {
            SyntaxNode root = await context.GetSyntaxRootAsync().ConfigureAwait(false);

            if (!TryFindNode(root, context.Span, out ExpressionSyntax expression))
            {
                return;
            }

            foreach (Diagnostic diagnostic in context.Diagnostics)
            {
                switch (diagnostic.Id)
                {
                case CompilerDiagnosticIdentifiers.CannotImplicitlyConvertTypeExplicitConversionExists:
                {
                    SemanticModel semanticModel = await context.GetSemanticModelAsync().ConfigureAwait(false);

                    TypeInfo typeInfo = semanticModel.GetTypeInfo(expression, context.CancellationToken);

                    ITypeSymbol type          = typeInfo.Type;
                    ITypeSymbol convertedType = typeInfo.ConvertedType;

                    if ((type is INamedTypeSymbol namedType) &&
                        namedType.IsNullableType())
                    {
                        if (convertedType?.SpecialType == SpecialType.System_Boolean ||
                            AddComparisonWithBooleanLiteralRefactoring.IsCondition(expression))
                        {
                            if (Settings.IsEnabled(diagnostic.Id, CodeFixIdentifiers.AddComparisonWithBooleanLiteral))
                            {
                                CodeAction codeAction = CodeAction.Create(
                                    AddComparisonWithBooleanLiteralRefactoring.GetTitle(expression),
                                    cancellationToken => AddComparisonWithBooleanLiteralRefactoring.RefactorAsync(context.Document, expression, cancellationToken),
                                    GetEquivalenceKey(diagnostic, CodeFixIdentifiers.AddComparisonWithBooleanLiteral));

                                context.RegisterCodeFix(codeAction, diagnostic);
                            }
                        }
                        else if (namedType.TypeArguments[0].Equals(convertedType))
                        {
                            if (Settings.IsEnabled(diagnostic.Id, CodeFixIdentifiers.UseCoalesceExpression))
                            {
                                CodeAction codeAction = CodeAction.Create(
                                    "Use coalesce expression",
                                    cancellationToken =>
                                    {
                                        ExpressionSyntax defaultValue = convertedType.GetDefaultValueSyntax(context.Document.GetDefaultSyntaxOptions());

                                        ExpressionSyntax newNode = CoalesceExpression(expression.WithoutTrivia(), defaultValue)
                                                                   .WithTriviaFrom(expression)
                                                                   .Parenthesize()
                                                                   .WithFormatterAnnotation();

                                        return(context.Document.ReplaceNodeAsync(expression, newNode, cancellationToken));
                                    },
                                    GetEquivalenceKey(diagnostic, CodeFixIdentifiers.UseCoalesceExpression));

                                context.RegisterCodeFix(codeAction, diagnostic);
                            }
                        }
                    }

                    if (Settings.IsEnabled(diagnostic.Id, CodeFixIdentifiers.ChangeMemberTypeAccordingToReturnExpression) &&
                        expression.IsParentKind(SyntaxKind.ReturnStatement, SyntaxKind.YieldReturnStatement))
                    {
                        ChangeMemberTypeRefactoring.ComputeCodeFix(context, diagnostic, expression, semanticModel);
                    }

                    if (Settings.IsEnabled(diagnostic.Id, CodeFixIdentifiers.AddCastExpression))
                    {
                        CodeFixRegistrator.AddCastExpression(context, diagnostic, expression, convertedType, semanticModel);
                    }

                    if (Settings.IsEnabled(diagnostic.Id, CodeFixIdentifiers.ChangeTypeAccordingToInitializer))
                    {
                        ChangeTypeAccordingToInitializerRefactoring.ComputeCodeFix(context, diagnostic, expression, semanticModel);
                    }

                    if (Settings.IsEnabled(diagnostic.Id, CodeFixIdentifiers.CreateSingletonArray) &&
                        type?.IsErrorType() == false &&
                        !type.Equals(convertedType) &&
                        (convertedType is IArrayTypeSymbol arrayType) &&
                        semanticModel.IsImplicitConversion(expression, arrayType.ElementType))
                    {
                        CodeAction codeAction = CodeAction.Create(
                            "Create singleton array",
                            cancellationToken => CreateSingletonArrayRefactoring.RefactorAsync(context.Document, expression, arrayType.ElementType, semanticModel, cancellationToken),
                            GetEquivalenceKey(diagnostic, CodeFixIdentifiers.CreateSingletonArray));

                        context.RegisterCodeFix(codeAction, diagnostic);
                    }

                    break;
                }

                case CompilerDiagnosticIdentifiers.ConstantValueCannotBeConverted:
                {
                    if (!Settings.IsEnabled(diagnostic.Id, CodeFixIdentifiers.UseUncheckedExpression))
                    {
                        break;
                    }

                    CodeAction codeAction = CodeAction.Create(
                        "Use 'unchecked'",
                        cancellationToken =>
                        {
                            CheckedExpressionSyntax newNode = CSharpFactory.UncheckedExpression(expression.WithoutTrivia());

                            newNode = newNode.WithTriviaFrom(expression);

                            return(context.Document.ReplaceNodeAsync(expression, newNode, cancellationToken));
                        },
                        GetEquivalenceKey(diagnostic));

                    context.RegisterCodeFix(codeAction, diagnostic);
                    break;
                }

                case CompilerDiagnosticIdentifiers.ExpressionBeingAssignedMustBeConstant:
                {
                    SyntaxNode parent = expression.Parent;

                    if (parent?.IsKind(SyntaxKind.EqualsValueClause) != true)
                    {
                        break;
                    }

                    parent = parent.Parent;

                    if (parent?.IsKind(SyntaxKind.VariableDeclarator) != true)
                    {
                        break;
                    }

                    parent = parent.Parent;

                    if (!(parent is VariableDeclarationSyntax variableDeclaration))
                    {
                        break;
                    }

                    if (Settings.IsEnabled(diagnostic.Id, CodeFixIdentifiers.RemoveConstModifier) &&
                        variableDeclaration.Parent is LocalDeclarationStatementSyntax localDeclarationStatement)
                    {
                        SyntaxTokenList modifiers = localDeclarationStatement.Modifiers;

                        if (!modifiers.Contains(SyntaxKind.ConstKeyword))
                        {
                            break;
                        }

                        ModifiersCodeFixRegistrator.RemoveModifier(context, diagnostic, localDeclarationStatement, SyntaxKind.ConstKeyword);
                    }
                    else if (Settings.IsEnabled(diagnostic.Id, CodeFixIdentifiers.ReplaceConstantWithField) &&
                             variableDeclaration.Variables.Count == 1 &&
                             (variableDeclaration.Parent is FieldDeclarationSyntax fieldDeclaration) &&
                             fieldDeclaration.Modifiers.Contains(SyntaxKind.ConstKeyword))
                    {
                        CodeAction codeAction = CodeAction.Create(
                            ReplaceConstantWithFieldRefactoring.Title,
                            cancellationToken => ReplaceConstantWithFieldRefactoring.RefactorAsync(context.Document, fieldDeclaration, cancellationToken),
                            GetEquivalenceKey(diagnostic));

                        context.RegisterCodeFix(codeAction, diagnostic);
                        break;
                    }

                    break;
                }

                case CompilerDiagnosticIdentifiers.CannotConvertNullToTypeBecauseItIsNonNullableValueType:
                case CompilerDiagnosticIdentifiers.CannotConvertNullToTypeParameterBecauseItCouldBeNonNullableValueType:
                {
                    if (!Settings.IsEnabled(diagnostic.Id, CodeFixIdentifiers.ReplaceNullLiteralExpressionWithDefaultValue))
                    {
                        break;
                    }

                    SemanticModel semanticModel = await context.GetSemanticModelAsync().ConfigureAwait(false);

                    CodeFixRegistrator.ReplaceNullWithDefaultValue(context, diagnostic, expression, semanticModel);
                    break;
                }

                case CompilerDiagnosticIdentifiers.ResultOfExpressionIsAlwaysConstantSinceValueIsNeverEqualToNull:
                {
                    if (!Settings.IsEnabled(diagnostic.Id, CodeFixIdentifiers.RemoveConditionThatIsAlwaysEqualToTrueOrFalse))
                    {
                        break;
                    }

                    NullCheckExpressionInfo nullCheck = SyntaxInfo.NullCheckExpressionInfo(expression, allowedStyles: NullCheckStyles.ComparisonToNull);

                    if (!nullCheck.Success)
                    {
                        break;
                    }

                    CodeAction codeAction = CodeAction.Create(
                        "Remove condition",
                        cancellationToken =>
                        {
                            cancellationToken.ThrowIfCancellationRequested();

                            SyntaxNode newRoot = RemoveCondition(root, expression, nullCheck.Style == NullCheckStyles.NotEqualsToNull);

                            cancellationToken.ThrowIfCancellationRequested();

                            return(Task.FromResult(context.Document.WithSyntaxRoot(newRoot)));
                        },
                        GetEquivalenceKey(diagnostic));

                    context.RegisterCodeFix(codeAction, diagnostic);

                    break;
                }

                case CompilerDiagnosticIdentifiers.OnlyAssignmentCallIncrementDecrementAndNewObjectExpressionsCanBeUsedAsStatement:
                {
                    if (Settings.IsEnabled(diagnostic.Id, CodeFixIdentifiers.RemoveParentheses) &&
                        expression is ParenthesizedExpressionSyntax parenthesizedExpression &&
                        parenthesizedExpression?.IsMissing == false)
                    {
                        CodeAction codeAction = CodeAction.Create(
                            "Remove parentheses",
                            cancellationToken => RemoveRedundantParenthesesRefactoring.RefactorAsync(context.Document, parenthesizedExpression, cancellationToken),
                            GetEquivalenceKey(diagnostic));

                        context.RegisterCodeFix(codeAction, diagnostic);
                        break;
                    }

                    SemanticModel semanticModel = await context.GetSemanticModelAsync().ConfigureAwait(false);

                    if (expression.Parent is ArrowExpressionClauseSyntax arrowExpresssionClause)
                    {
                        if (!Settings.IsEnabled(diagnostic.Id, CodeFixIdentifiers.ChangeMemberTypeAccordingToReturnExpression))
                        {
                            break;
                        }

                        ChangeMemberTypeRefactoring.ComputeCodeFix(context, diagnostic, expression, semanticModel);
                    }
                    else if (expression.Parent is ExpressionStatementSyntax expressionStatement)
                    {
                        if (Settings.IsEnabled(diagnostic.Id, CodeFixIdentifiers.AddArgumentList) &&
                            expression.IsKind(
                                SyntaxKind.IdentifierName,
                                SyntaxKind.SimpleMemberAccessExpression))
                        {
                            SyntaxNode invocationExpression = InvocationExpression(expression);

                            if (semanticModel.GetSpeculativeMethodSymbol(expression.SpanStart, invocationExpression) != null)
                            {
                                CodeAction codeAction = CodeAction.Create(
                                    "Add argument list",
                                    cancellationToken => context.Document.ReplaceNodeAsync(expression, invocationExpression, cancellationToken),
                                    GetEquivalenceKey(diagnostic, CodeFixIdentifiers.AddArgumentList));

                                context.RegisterCodeFix(codeAction, diagnostic);
                            }
                        }

                        if (Settings.IsEnabled(diagnostic.Id, CodeFixIdentifiers.ReplaceComparisonWithAssignment) &&
                            expression.IsKind(SyntaxKind.EqualsExpression))
                        {
                            BinaryExpressionInfo info = SyntaxInfo.BinaryExpressionInfo(expression);

                            if (!info.Success)
                            {
                                break;
                            }

                            ITypeSymbol leftTypeSymbol = semanticModel.GetTypeSymbol(info.Left, context.CancellationToken);

                            if (leftTypeSymbol?.IsErrorType() != false)
                            {
                                break;
                            }

                            if (!semanticModel.IsImplicitConversion(info.Right, leftTypeSymbol))
                            {
                                break;
                            }

                            CodeAction codeAction = CodeAction.Create(
                                "Replace comparison with assignment",
                                cancellationToken =>
                                {
                                    AssignmentExpressionSyntax simpleAssignment = SimpleAssignmentExpression(info.Left, info.Right).WithTriviaFrom(expression);
                                    return(context.Document.ReplaceNodeAsync(expression, simpleAssignment, cancellationToken));
                                },
                                GetEquivalenceKey(diagnostic, CodeFixIdentifiers.ReplaceComparisonWithAssignment));

                            context.RegisterCodeFix(codeAction, diagnostic);
                        }

                        if (Settings.IsEnabled(diagnostic.Id, CodeFixIdentifiers.ReplaceConditionalExpressionWithIfElse) &&
                            (expression is ConditionalExpressionSyntax conditionalExpression) &&
                            conditionalExpression.Condition != null)
                        {
                            ExpressionSyntax whenTrue  = conditionalExpression.WhenTrue;
                            ExpressionSyntax whenFalse = conditionalExpression.WhenFalse;

                            if (whenTrue != null &&
                                whenFalse != null &&
                                semanticModel.GetTypeSymbol(whenTrue, context.CancellationToken)?.SpecialType == SpecialType.System_Void &&
                                semanticModel.GetTypeSymbol(whenFalse, context.CancellationToken)?.SpecialType == SpecialType.System_Void)
                            {
                                CodeAction codeAction = CodeAction.Create(
                                    "Replace ?: with if-else",
                                    cancellationToken =>
                                    {
                                        IfStatementSyntax newNode = IfStatement(
                                            conditionalExpression.Condition.WalkDownParentheses(),
                                            Block(ExpressionStatement(whenTrue)),
                                            ElseClause(Block(ExpressionStatement(whenFalse))));

                                        newNode = newNode
                                                  .WithTriviaFrom(expressionStatement)
                                                  .WithFormatterAnnotation();

                                        return(context.Document.ReplaceNodeAsync(expressionStatement, newNode, cancellationToken));
                                    },
                                    GetEquivalenceKey(diagnostic, CodeFixIdentifiers.ReplaceConditionalExpressionWithIfElse));

                                context.RegisterCodeFix(codeAction, diagnostic);
                            }
                        }

                        if (semanticModel.GetSymbol(expression, context.CancellationToken)?.IsErrorType() != false)
                        {
                            break;
                        }

                        ITypeSymbol typeSymbol = semanticModel.GetTypeSymbol(expression, context.CancellationToken);

                        if (typeSymbol?.IsErrorType() != false)
                        {
                            break;
                        }

                        if (Settings.IsEnabled(diagnostic.Id, CodeFixIdentifiers.IntroduceLocalVariable) &&
                            !expressionStatement.IsEmbedded())
                        {
                            bool addAwait = typeSymbol.OriginalDefinition.EqualsOrInheritsFromTaskOfT() &&
                                            semanticModel.GetEnclosingSymbol(expressionStatement.SpanStart, context.CancellationToken).IsAsyncMethod();

                            CodeAction codeAction = CodeAction.Create(
                                IntroduceLocalVariableRefactoring.GetTitle(expression),
                                cancellationToken => IntroduceLocalVariableRefactoring.RefactorAsync(context.Document, expressionStatement, typeSymbol, addAwait, semanticModel, cancellationToken),
                                GetEquivalenceKey(diagnostic, CodeFixIdentifiers.IntroduceLocalVariable));

                            context.RegisterCodeFix(codeAction, diagnostic);
                        }

                        if (Settings.IsEnabled(diagnostic.Id, CodeFixIdentifiers.IntroduceField))
                        {
                            CodeAction codeAction = CodeAction.Create(
                                $"Introduce field for '{expression}'",
                                cancellationToken => IntroduceFieldRefactoring.RefactorAsync(context.Document, expressionStatement, typeSymbol, semanticModel, cancellationToken),
                                GetEquivalenceKey(diagnostic, CodeFixIdentifiers.IntroduceField));

                            context.RegisterCodeFix(codeAction, diagnostic);
                        }
                    }

                    break;
                }

                case CompilerDiagnosticIdentifiers.CannotImplicitlyConvertType:
                {
                    if (Settings.IsEnabled(diagnostic.Id, CodeFixIdentifiers.ReplaceYieldReturnWithForEach) &&
                        expression.IsParentKind(SyntaxKind.YieldReturnStatement))
                    {
                        SemanticModel semanticModel = await context.GetSemanticModelAsync().ConfigureAwait(false);

                        ReplaceYieldReturnWithForEachRefactoring.ComputeCodeFix(context, diagnostic, expression, semanticModel);
                        break;
                    }

                    if (Settings.IsEnabled(diagnostic.Id, CodeFixIdentifiers.ChangeMemberTypeAccordingToReturnExpression) &&
                        expression.IsParentKind(SyntaxKind.ReturnStatement, SyntaxKind.YieldReturnStatement))
                    {
                        SemanticModel semanticModel = await context.GetSemanticModelAsync().ConfigureAwait(false);

                        ChangeMemberTypeRefactoring.ComputeCodeFix(context, diagnostic, expression, semanticModel);
                        break;
                    }

                    if (Settings.IsEnabled(diagnostic.Id, CodeFixIdentifiers.ChangeTypeAccordingToInitializer))
                    {
                        SemanticModel semanticModel = await context.GetSemanticModelAsync().ConfigureAwait(false);

                        CodeFixRegistrationResult result = ChangeTypeAccordingToInitializerRefactoring.ComputeCodeFix(context, diagnostic, expression, semanticModel);

                        if (!result.Success)
                        {
                            RemoveAssignmentOfVoidExpression(context, diagnostic, expression, semanticModel);
                        }

                        break;
                    }

                    if (Settings.IsEnabled(diagnostic.Id, CodeFixIdentifiers.ReplaceStringLiteralWithCharacterLiteral) &&
                        expression?.Kind() == SyntaxKind.StringLiteralExpression)
                    {
                        var literalExpression = (LiteralExpressionSyntax)expression;

                        if (literalExpression.Token.ValueText.Length == 1)
                        {
                            SemanticModel semanticModel = await context.GetSemanticModelAsync().ConfigureAwait(false);

                            if (semanticModel.GetTypeInfo(expression, context.CancellationToken).ConvertedType?.SpecialType == SpecialType.System_Char)
                            {
                                CodeAction codeAction = CodeAction.Create(
                                    "Replace string literal with character literal",
                                    cancellationToken => ReplaceStringLiteralWithCharacterLiteralRefactoring.RefactorAsync(context.Document, literalExpression, cancellationToken),
                                    GetEquivalenceKey(diagnostic, CodeFixIdentifiers.ReplaceStringLiteralWithCharacterLiteral));

                                context.RegisterCodeFix(codeAction, diagnostic);
                            }
                        }
                    }

                    if (Settings.IsEnabled(diagnostic.Id, CodeFixIdentifiers.UseYieldReturnInsteadOfReturn) &&
                        expression.IsParentKind(SyntaxKind.ReturnStatement))
                    {
                        var returnStatement = (ReturnStatementSyntax)expression.Parent;

                        SemanticModel semanticModel = await context.GetSemanticModelAsync().ConfigureAwait(false);

                        ISymbol containingSymbol = semanticModel.GetEnclosingSymbol(returnStatement.SpanStart, context.CancellationToken);

                        if (containingSymbol?.Kind == SymbolKind.Method &&
                            ((IMethodSymbol)containingSymbol).ReturnType.OriginalDefinition.IsIEnumerableOrIEnumerableOfT())
                        {
                            CodeAction codeAction = CodeAction.Create(
                                "Use yield return instead of return",
                                cancellationToken => UseYieldReturnInsteadOfReturnRefactoring.RefactorAsync(context.Document, returnStatement, SyntaxKind.YieldReturnStatement, semanticModel, cancellationToken),
                                GetEquivalenceKey(diagnostic, CodeFixIdentifiers.UseYieldReturnInsteadOfReturn));

                            context.RegisterCodeFix(codeAction, diagnostic);
                        }
                    }

                    break;
                }

                case CompilerDiagnosticIdentifiers.LeftHandSideOfAssignmentMustBeVariablePropertyOrIndexer:
                {
                    if (!Settings.IsEnabled(diagnostic.Id, CodeFixIdentifiers.RemoveConstModifier))
                    {
                        return;
                    }

                    if (!expression.IsKind(SyntaxKind.IdentifierName))
                    {
                        return;
                    }

                    if (!expression.IsParentKind(SyntaxKind.SimpleAssignmentExpression))
                    {
                        return;
                    }

                    SemanticModel semanticModel = await context.GetSemanticModelAsync().ConfigureAwait(false);

                    SymbolInfo symbolInfo = semanticModel.GetSymbolInfo(expression, context.CancellationToken);

                    if (symbolInfo.CandidateReason != CandidateReason.NotAVariable)
                    {
                        return;
                    }

                    if (!(symbolInfo.CandidateSymbols.SingleOrDefault(shouldThrow: false) is ILocalSymbol localSymbol))
                    {
                        return;
                    }

                    if (!localSymbol.IsConst)
                    {
                        return;
                    }

                    SyntaxNode node = localSymbol.GetSyntaxOrDefault(context.CancellationToken);

                    if (!node.IsKind(SyntaxKind.VariableDeclarator))
                    {
                        return;
                    }

                    node = node.Parent;

                    if (!node.IsKind(SyntaxKind.VariableDeclaration))
                    {
                        return;
                    }

                    node = node.Parent;

                    if (!(node is LocalDeclarationStatementSyntax localDeclaration))
                    {
                        return;
                    }

                    SyntaxToken constModifier = localDeclaration.Modifiers.Find(SyntaxKind.ConstKeyword);

                    if (!constModifier.IsKind(SyntaxKind.ConstKeyword))
                    {
                        return;
                    }

                    ModifiersCodeFixRegistrator.RemoveModifier(context, diagnostic, localDeclaration, constModifier);

                    break;
                }

                case CompilerDiagnosticIdentifiers.ReadOnlyFieldCannotBeAssignedTo:
                {
                    if (!Settings.IsEnabled(diagnostic.Id, CodeFixIdentifiers.MakeFieldWritable))
                    {
                        break;
                    }

                    SimpleAssignmentExpressionInfo simpleAssignment = SyntaxInfo.SimpleAssignmentExpressionInfo(expression.Parent);

                    if (!simpleAssignment.Success)
                    {
                        return;
                    }

                    if (simpleAssignment.Left != expression)
                    {
                        return;
                    }

                    SemanticModel semanticModel = await context.GetSemanticModelAsync().ConfigureAwait(false);

                    SymbolInfo symbolInfo = semanticModel.GetSymbolInfo(expression, context.CancellationToken);

                    if (symbolInfo.CandidateReason != CandidateReason.NotAVariable)
                    {
                        return;
                    }

                    if (!(symbolInfo.CandidateSymbols.SingleOrDefault(shouldThrow: false) is IFieldSymbol fieldSymbol))
                    {
                        return;
                    }

                    if (fieldSymbol.DeclaredAccessibility != Accessibility.Private)
                    {
                        return;
                    }

                    if (!(fieldSymbol.GetSyntax().Parent.Parent is FieldDeclarationSyntax fieldDeclaration))
                    {
                        return;
                    }

                    TypeDeclarationSyntax containingTypeDeclaration = fieldDeclaration.FirstAncestor <TypeDeclarationSyntax>();

                    if (!expression.Ancestors().Any(f => f == containingTypeDeclaration))
                    {
                        return;
                    }

                    ModifiersCodeFixRegistrator.RemoveModifier(
                        context,
                        diagnostic,
                        fieldDeclaration,
                        SyntaxKind.ReadOnlyKeyword,
                        title: $"Make '{fieldSymbol.Name}' writable");

                    break;
                }
                }
            }
        }
コード例 #31
0
        private async Task <SyntaxNode> ExtractTypeAsync(Document document, CompilationUnitSyntax root, TypeDeclarationSyntax typeDecl, CancellationToken cancellationToken)
        {
            var semanticModel = await document.GetSemanticModelAsync(cancellationToken).ConfigureAwait(false);

            var typeSymbol = semanticModel.GetDeclaredSymbol(typeDecl, cancellationToken);

            var child = typeDecl
                        .Ancestors()
                        .OfType <NamespaceDeclarationSyntax>()
                        .Aggregate(
                (MemberDeclarationSyntax)typeDecl,
                (acc, nsDecl) => nsDecl.WithMembers(SyntaxFactory.List(new MemberDeclarationSyntax[] { acc })));

            return(root.WithMembers(SyntaxFactory.List(new[] { child })));
        }
コード例 #32
0
ファイル: SyntaxTreeBinding.cs プロジェクト: EkardNT/Roslyn
        /// <summary>
        /// Given a type declaration, get the corresponding type symbol.
        /// </summary>
        public NamedTypeSymbol GetTypeFromDeclaration(TypeDeclarationSyntax declarationSyntax)
        {
            var outer = GetEnclosingContext(declarationSyntax);
            var nameStart = declarationSyntax.Identifier.Span.Start;

            var result = LookupResult.GetInstance();
            outer.LookupType(result, declarationSyntax.Identifier.ValueText, declarationSyntax.Arity, outer, null);
            var symbols = result.Symbols;

            for (int i = 0; i < symbols.Count; i++)
            {
                var t = symbols[i];
                foreach (var l in t.Locations)
                {
                    if (l.SourceTree == tree && l.SourceSpan.Start == nameStart)
                    {
                        result.Free();
                        return (NamedTypeSymbol)t;
                    }
                }
            }
            result.Free();
            return null;
        }
コード例 #33
0
        private async Task <Solution> MoveTypeAsync(Document document, CompilationUnitSyntax root, TypeDeclarationSyntax typeDecl, CancellationToken cancellationToken)
        {
            var extractedType = await ExtractTypeAsync(document, root, typeDecl, cancellationToken).ConfigureAwait(false);

            document = await RemoveTypeAsync(typeDecl, document).ConfigureAwait(false);

            var existingDocument = GetDocument(document.Project, typeDecl);

            existingDocument = await IntegrateTypeAsync(extractedType, existingDocument).ConfigureAwait(false);

            var solution = existingDocument.Project.Solution.RemoveDocument(document.Id);

            return(solution);
        }
コード例 #34
0
 public static bool IsAbstract(this TypeDeclarationSyntax @this)
 {
     return(@this.Modifiers.Any(m => m.IsKind(SyntaxKind.AbstractKeyword)));
 }
コード例 #35
0
        private SyntaxNode VisitTypeDeclaration(TypeDeclarationSyntax node, INamedTypeSymbol symbol)
        {
            if (node == null || symbol == null || symbol.AllInterfaces.Count != 1)
                return node;

            var face = symbol.AllInterfaces.Single();
            if (!face.HasDocumentationComment())
                return node;

            if (symbol.GetDocumentationComment().Equals(face.GetDocumentationComment()))
                return node;

            var facenode = face.GetSyntaxNodes().Single();
            return node.WithDocumentationComment(facenode.GetDocumentationCommentText());
        }