Пример #1
0
        public async Task<Solution> EnforceAsync(Document document)
        {
            if (document == null) { throw new ArgumentNullException(nameof(document)); }

            IReadOnlyList<string> headerComments = document.GetOption(HeaderComments);
            string newLineText = document.GetOption(GlobalOptions.NewLineText);
            SyntaxTriviaList commentTrivia = this.commentCache.GetOrAdd(
                headerComments, c => BuildCommentTrivia(headerComments, newLineText));

            SyntaxNode syntaxRoot = await document.GetSyntaxRootAsync();

            if (syntaxRoot.HasLeadingTrivia)
            {
                SyntaxTriviaList leadingTrivia = syntaxRoot.GetLeadingTrivia();
                if (!leadingTrivia.IsEquivalentTo(commentTrivia))
                {
                    Log.WriteInformation("{0}: Rewriting non-conforming header comment", document.Name);
                    syntaxRoot = syntaxRoot.WithLeadingTrivia().WithLeadingTrivia(commentTrivia);
                    document = document.WithSyntaxRoot(syntaxRoot);
                }
            }
            else if (commentTrivia.Count > 0)
            {
                Log.WriteInformation("{0}: Adding missing header comment", document.Name);
                syntaxRoot = syntaxRoot.WithLeadingTrivia(commentTrivia);
                document = document.WithSyntaxRoot(syntaxRoot);
            }

            return document.Project.Solution;
        }
 public async static Task<Solution> MakeAutoPropertyAsync(Document document, SyntaxNode root, PropertyDeclarationSyntax property, CancellationToken cancellationToken)
 {
     var semanticModel = await document.GetSemanticModelAsync(cancellationToken);
     var getterReturn = (ReturnStatementSyntax)property.AccessorList.Accessors.First(a => a.Keyword.ValueText == "get").Body.Statements.First();
     var returnIdentifier = (IdentifierNameSyntax)(getterReturn.Expression is MemberAccessExpressionSyntax ? ((MemberAccessExpressionSyntax)getterReturn.Expression).Name : getterReturn.Expression);
     var returnIdentifierSymbol = semanticModel.GetSymbolInfo(returnIdentifier).Symbol;
     var variableDeclarator = (VariableDeclaratorSyntax)returnIdentifierSymbol.DeclaringSyntaxReferences.First().GetSyntax();
     var fieldDeclaration = variableDeclarator.FirstAncestorOfType<FieldDeclarationSyntax>();
     root = root.TrackNodes(returnIdentifier, fieldDeclaration, property);
     document = document.WithSyntaxRoot(root);
     root = await document.GetSyntaxRootAsync(cancellationToken);
     semanticModel = await document.GetSemanticModelAsync(cancellationToken);
     returnIdentifier = root.GetCurrentNode(returnIdentifier);
     returnIdentifierSymbol = semanticModel.GetSymbolInfo(returnIdentifier).Symbol;
     var newProperty = GetSimpleProperty(property, variableDeclarator)
         .WithTriviaFrom(property)
         .WithAdditionalAnnotations(Formatter.Annotation);
     var newSolution = await Renamer.RenameSymbolAsync(document.Project.Solution, returnIdentifierSymbol, property.Identifier.ValueText, document.Project.Solution.Workspace.Options, cancellationToken);
     document = newSolution.GetDocument(document.Id);
     root = await document.GetSyntaxRootAsync(cancellationToken).ConfigureAwait(false);
     root = root.InsertNodesAfter(root.GetCurrentNode(property), new[] { newProperty });
     var multipleVariableDeclaration = fieldDeclaration.Declaration.Variables.Count > 1;
     if (multipleVariableDeclaration)
     {
         var newfieldDeclaration = fieldDeclaration.WithDeclaration(fieldDeclaration.Declaration.RemoveNode(variableDeclarator, SyntaxRemoveOptions.KeepNoTrivia));
         root = root.RemoveNode(root.GetCurrentNode<SyntaxNode>(property), SyntaxRemoveOptions.KeepNoTrivia);
         root = root.ReplaceNode(root.GetCurrentNode(fieldDeclaration), newfieldDeclaration);
     }
     else
     {
         root = root.RemoveNodes(root.GetCurrentNodes<SyntaxNode>(new SyntaxNode[] { fieldDeclaration, property }), SyntaxRemoveOptions.KeepNoTrivia);
     }
     document = document.WithSyntaxRoot(root);
     return document.Project.Solution;
 }
		static async Task<Document> Fix(Document document, AwaitExpressionSyntax node, CancellationToken cancellationToken)
		{
			var root = await document.GetSyntaxRootAsync(cancellationToken).ConfigureAwait(false);
			var expression = Checker.FindExpressionForConfigureAwait(node);
			if (expression != null)
			{
				if (!Checker.IsConfigureAwait(expression.Expression))
				{
					var falseExpression = SyntaxFactory.LiteralExpression(SyntaxKind.FalseLiteralExpression);
					var newExpression = SyntaxFactory.InvocationExpression(
						SyntaxFactory.MemberAccessExpression(SyntaxKind.SimpleMemberAccessExpression, expression, SyntaxFactory.IdentifierName(Checker.ConfigureAwaitIdentifier)),
						SyntaxFactory.ArgumentList(SyntaxFactory.SeparatedList(new[] { SyntaxFactory.Argument(falseExpression) })));
					return document.WithSyntaxRoot(root.ReplaceNode(expression, newExpression.WithAdditionalAnnotations(Formatter.Annotation)));
				}
				if (!Checker.HasFalseArgument(expression.ArgumentList))
				{
					var falseExpression = SyntaxFactory.LiteralExpression(SyntaxKind.FalseLiteralExpression);
					var newExpression = SyntaxFactory.InvocationExpression(expression.Expression,
						SyntaxFactory.ArgumentList(SyntaxFactory.SeparatedList(new[] { SyntaxFactory.Argument(falseExpression) })));
					return document.WithSyntaxRoot(root.ReplaceNode(expression, newExpression.WithAdditionalAnnotations(Formatter.Annotation)));
				}
			}
			else
			{
				var falseExpression = SyntaxFactory.LiteralExpression(SyntaxKind.FalseLiteralExpression);
				var newExpression = SyntaxFactory.InvocationExpression(
					SyntaxFactory.MemberAccessExpression(SyntaxKind.SimpleMemberAccessExpression, node.Expression, SyntaxFactory.IdentifierName(Checker.ConfigureAwaitIdentifier)),
					SyntaxFactory.ArgumentList(SyntaxFactory.SeparatedList(new[] { SyntaxFactory.Argument(falseExpression) })));
				return document.WithSyntaxRoot(root.ReplaceNode(node.Expression, newExpression.WithAdditionalAnnotations(Formatter.Annotation)));
			}
			throw new InvalidOperationException();
		}
 private async static Task<Document> UseEmptyStringAsync(Document document, Diagnostic diagnostic, CancellationToken cancellationToken)
 {
     var root = await document.GetSyntaxRootAsync(cancellationToken).ConfigureAwait(false);
     var literal = root.FindNode(diagnostic.Location.SourceSpan).DescendantNodesAndSelf().OfType<MemberAccessExpressionSyntax>().First();
     var newRoot = root.ReplaceNode(literal, SyntaxFactory.ParseExpression(EmptyString).WithLeadingTrivia(literal.GetLeadingTrivia()).WithTrailingTrivia(literal.GetTrailingTrivia()));
     var newDocument = document.WithSyntaxRoot(newRoot);
     return document.WithSyntaxRoot(newRoot);
 }
 public async static Task<Document> IntroduceFieldFromConstructorDocumentAsync(Document document, Diagnostic diagnostic, CancellationToken cancellationToken)
 {
     var root = await document.GetSyntaxRootAsync(cancellationToken).ConfigureAwait(false);
     var diagnosticSpan = diagnostic.Location.SourceSpan;
     var parameter = root.FindToken(diagnosticSpan.Start).Parent.AncestorsAndSelf().OfType<ParameterSyntax>().First();
     var constructor = root.FindToken(diagnosticSpan.Start).Parent.AncestorsAndSelf().OfType<ConstructorDeclarationSyntax>().First();
     var newRoot = IntroduceFieldFromConstructor(root, constructor, parameter);
     var newDocument = document.WithSyntaxRoot(newRoot);
     return document.WithSyntaxRoot(newRoot);
 }
        private static async Task<Document> GetTransformedDocumentAsync(Document document, Diagnostic diagnostic)
        {
            var syntaxRoot = await document.GetSyntaxRootAsync().ConfigureAwait(false);
            var node = syntaxRoot?.FindNode(diagnostic.Location.SourceSpan, findInsideTrivia: true, getInnermostNodeForTie: true);
            if (node != null && node.IsKind(SyntaxKind.RegionDirectiveTrivia))
            {
                var regionDirective = node as RegionDirectiveTriviaSyntax;

                var newSyntaxRoot = syntaxRoot.RemoveNodes(regionDirective.GetRelatedDirectives(), SyntaxRemoveOptions.AddElasticMarker);

                return document.WithSyntaxRoot(newSyntaxRoot);
            }

            return document.WithSyntaxRoot(syntaxRoot);
        }
        private static async Task<Document> CallAsExtensionAsync(Document document, Diagnostic diagnostic, CancellationToken cancellationToken)
        {
            var root = (CompilationUnitSyntax)await document.GetSyntaxRootAsync(cancellationToken).ConfigureAwait(false);
            var diagnosticSpan = diagnostic.Location.SourceSpan;
            var staticInvocationExpression = root
                .FindToken(diagnosticSpan.Start)
                .Parent.AncestorsAndSelf()
                .OfType<InvocationExpressionSyntax>()
                .First();

            var childNodes = staticInvocationExpression.ChildNodes();
            var parameterExpressions = CallExtensionMethodAsExtensionAnalyzer.GetParameterExpressions(childNodes);

            var firstArgument = parameterExpressions.FirstOrDefault();
            var callerMethod = childNodes.OfType<MemberAccessExpressionSyntax>().FirstOrDefault();

            root = ReplaceStaticCallWithExtionMethodCall(
                        root,
                        staticInvocationExpression,
                        firstArgument,
                        callerMethod.Name,
                        CallExtensionMethodAsExtensionAnalyzer.CreateArgumentListSyntaxFrom(parameterExpressions.Skip(1))
                   ).WithAdditionalAnnotations(Formatter.Annotation);

            var semanticModel = await document.GetSemanticModelAsync();
            root = ImportNeededNamespace(root, semanticModel, callerMethod).WithAdditionalAnnotations(Formatter.Annotation);
            var newDocument = document.WithSyntaxRoot(root);

            return newDocument;
        }
        private static async Task<Document> GetTransformedDocumentAsync(Document document, Diagnostic diagnostic, CancellationToken cancellationToken)
        {
            var indentationOptions = IndentationOptions.FromDocument(document);
            var syntaxRoot = await document.GetSyntaxRootAsync(cancellationToken).ConfigureAwait(false);

            var violatingTrivia = syntaxRoot.FindTrivia(diagnostic.Location.SourceSpan.Start);

            var stringBuilder = new StringBuilder();

            var column = violatingTrivia.GetLineSpan().StartLinePosition.Character;
            foreach (var c in violatingTrivia.ToFullString())
            {
                if (c == '\t')
                {
                    var offsetWithinTabColumn = column % indentationOptions.TabSize;
                    var spaceCount = indentationOptions.TabSize - offsetWithinTabColumn;

                    stringBuilder.Append(' ', spaceCount);
                    column += spaceCount;
                }
                else
                {
                    stringBuilder.Append(c);
                    column++;
                }
            }

            var newSyntaxRoot = syntaxRoot.ReplaceTrivia(violatingTrivia, SyntaxFactory.Whitespace(stringBuilder.ToString()));
            return document.WithSyntaxRoot(newSyntaxRoot);
        }
 private static async Task<Document> RemoveUnreachableCodeAsync(Document document, Diagnostic diagnostic, CancellationToken cancellationToken)
 {
     var root = await document.GetSyntaxRootAsync(cancellationToken).ConfigureAwait(false);
     var node = root.FindNode(diagnostic.Location.SourceSpan);
     var newDoc = document.WithSyntaxRoot(RemoveUnreachableStatement(root, node));
     return newDoc;
 }
		private async Task<Document> FormatXmlAsync(Document document, LiteralExpressionSyntax sleSyntax, CancellationToken cancellationToken)
		{
			var root = await document.GetSyntaxRootAsync(cancellationToken);
			var tree = root.SyntaxTree;

			//Get the character position of the LiteralExpressionSyntax
			FileLinePositionSpan position = tree.GetLineSpan(sleSyntax.Span);
			int cSpace = position.StartLinePosition.Character;

			//Figure out the preceeding trivia since we can't get the column position from GetLineSpan
			var parentTrivia = sleSyntax.GetLeadingTrivia().ToFullString();

			var xml = sleSyntax.GetFirstToken().ValueText;
			var newXmlText = FormatXml(xml);

			//Process each line of the formatted XML and prepend the parent trivia & spaces
			string[] xmlLines = newXmlText.Split(new string[] { "\r\n", "\n" }, StringSplitOptions.None);
			for (int i = 1; i < xmlLines.Length; i++)
			{
				xmlLines[i] = parentTrivia + new String(' ', (cSpace + 2)) + xmlLines[i];
			}

			newXmlText = String.Join("\r\n", xmlLines);
			var newXmlValue = "@\"" + newXmlText + "\"";

			var newNode = SyntaxFactory.LiteralExpression(SyntaxKind.StringLiteralExpression,
				SyntaxFactory.Token(SyntaxTriviaList.Empty, SyntaxKind.StringLiteralToken, newXmlValue, newXmlText, SyntaxTriviaList.Empty));
			var newRoot = root.ReplaceNode(sleSyntax, newNode);
			return document.WithSyntaxRoot(newRoot);
		}
Пример #11
0
 private static async Task<Document> DeleteDeclarationFromDocument(SyntaxNode node, Document curentDocument)
 {
     var root = await curentDocument.GetSyntaxRootAsync();
     var newTypeDeclarationParent = node.Parent.RemoveNode(node, SyntaxRemoveOptions.KeepNoTrivia);
     var newRoot = root.ReplaceNode(node.Parent, newTypeDeclarationParent);
     return curentDocument.WithSyntaxRoot(newRoot);
 }
 private async static Task<Document> RemoveThrowAsync(Document document, Diagnostic diagnostic, CancellationToken cancellationToken)
 {
     var root = await document.GetSyntaxRootAsync(cancellationToken).ConfigureAwait(false);
     var sourceSpan = diagnostic.Location.SourceSpan;
     var finalizer = root.FindToken(sourceSpan.Start).Parent.AncestorsAndSelf().OfType<DestructorDeclarationSyntax>().First();
     return document.WithSyntaxRoot(root.RemoveNode(finalizer, SyntaxRemoveOptions.KeepNoTrivia));
 }
        private Task<Document> ConvertToInterpolatedString(Document document, SyntaxNode root, InvocationExpressionSyntax invocation, CancellationToken cancellationToken)
        {
            string previousString = null;
            var parts = new List<InterpolatedStringContentSyntax>(invocation.ArgumentList.Arguments.Count);
            for (int i = 0; i < invocation.ArgumentList.Arguments.Count; i++)
            {
                ArgumentSyntax argument = invocation.ArgumentList.Arguments[i];
                var literal = argument.Expression as LiteralExpressionSyntax;

                if (literal?.IsKind(SyntaxKind.StringLiteralExpression) ?? false)
                {
                    //strings needs to be collapsed, otherwise VS will insert additional whitespaces
                    previousString += literal.Token.Text.Substring(1, literal.Token.Text.Length - 2);
                }
                else
                {
                    if (previousString != null)
                    {
                        parts.Add(InterpolatedStringGenerator.TextPart(previousString));
                        previousString = null;
                    }
                    parts.Add(InterpolatedStringGenerator.ExpressionPart(argument.Expression.WithoutLeadingTrivia().WithoutTrailingTrivia()));
                }
            }
            if (previousString != null)
            {
                parts.Add(InterpolatedStringGenerator.TextPart(previousString));
            }

            SyntaxNode interpolated = InterpolatedStringGenerator.InterpolatedString(parts);

            root = root.ReplaceNode(invocation, interpolated);

            return Task.FromResult(document.WithSyntaxRoot(root));
        }
        private static async Task<Document> GetTransformedDocumentAsync(Document document, Diagnostic diagnostic, CancellationToken cancellationToken)
        {
            var root = await document.GetSyntaxRootAsync(cancellationToken).ConfigureAwait(false);
            SyntaxToken token = root.FindToken(diagnostic.Location.SourceSpan.Start);
            var replacements = new List<SyntaxToken>(2);

            if (!token.IsFirstInLine())
            {
                SyntaxToken precedingToken = token.GetPreviousToken();
                if (precedingToken.TrailingTrivia.Any(SyntaxKind.WhitespaceTrivia))
                {
                    replacements.Add(precedingToken);
                }
            }

            SyntaxTriviaList trailingTrivia = token.TrailingTrivia;
            if (!trailingTrivia.Any(SyntaxKind.EndOfLineTrivia) && trailingTrivia.Any(SyntaxKind.WhitespaceTrivia))
            {
                replacements.Add(token);
            }

            if (replacements.Count == 0)
            {
                return document;
            }

            var transformed = root.ReplaceTokens(replacements, (original, maybeRewritten) => maybeRewritten.WithoutTrailingWhitespace().WithoutFormatting());
            Document updatedDocument = document.WithSyntaxRoot(transformed);

            return updatedDocument;
        }
        private static async Task<Document> GetTransformedDocumentAsync(Document document, Diagnostic diagnostic, CancellationToken cancellationToken)
        {
            SyntaxNode root = await document.GetSyntaxRootAsync(cancellationToken).ConfigureAwait(false);
            SyntaxToken originalToken = root.FindToken(diagnostic.Location.SourceSpan.Start);

            SyntaxTree tree = root.SyntaxTree;
            SourceText sourceText = await tree.GetTextAsync(cancellationToken).ConfigureAwait(false);
            TextLine sourceLine = sourceText.Lines.GetLineFromPosition(originalToken.SpanStart);

            string lineText = sourceText.ToString(sourceLine.Span);
            int indentLength;
            for (indentLength = 0; indentLength < lineText.Length; indentLength++)
            {
                if (!char.IsWhiteSpace(lineText[indentLength]))
                {
                    break;
                }
            }

            IndentationOptions indentationOptions = IndentationOptions.FromDocument(document);
            SyntaxTriviaList newTrivia =
                SyntaxFactory.TriviaList(
                    SyntaxFactory.CarriageReturnLineFeed,
                    SyntaxFactory.Whitespace(lineText.Substring(0, indentLength) + IndentationHelper.GenerateIndentationString(indentationOptions, 1)));

            SyntaxToken updatedToken = originalToken.WithLeadingTrivia(originalToken.LeadingTrivia.AddRange(newTrivia));
            SyntaxNode updatedRoot = root.ReplaceToken(originalToken, updatedToken);
            return document.WithSyntaxRoot(updatedRoot);
        }
 private Task<Solution> MakePublicAsync(Document document, SyntaxNode root, MethodDeclarationSyntax method)
 {
     var generator = SyntaxGenerator.GetGenerator(document);
     var newMethod = generator.WithAccessibility(method, Accessibility.Public);
     var newRoot = root.ReplaceNode(method, newMethod);
     return Task.FromResult(document.WithSyntaxRoot(newRoot).Project.Solution);
 }
        private static async Task<Document> GetTransformedDocumentAsync(Document document, Diagnostic diagnostic, CancellationToken cancellationToken)
        {
            var syntaxRoot = await document.GetSyntaxRootAsync(cancellationToken).ConfigureAwait(false);

            var accessorToken = syntaxRoot.FindToken(diagnostic.Location.SourceSpan.Start);
            var accessorList = (AccessorListSyntax)accessorToken.Parent.Parent;

            var firstAccesor = accessorList.Accessors[0];
            var secondAccessor = accessorList.Accessors[1];
            var trackedRoot = syntaxRoot.TrackNodes(firstAccesor, secondAccessor);
            var trackedFirstAccessor = trackedRoot.GetCurrentNode(firstAccesor);
            var newAccessor = GetNewAccessor(accessorList, firstAccesor, secondAccessor);

            syntaxRoot = trackedRoot.InsertNodesBefore(trackedFirstAccessor, new[] { newAccessor });

            if (HasLeadingBlankLines(secondAccessor))
            {
                trackedFirstAccessor = syntaxRoot.GetCurrentNode(firstAccesor);
                var newFirstAccessor = trackedFirstAccessor.WithLeadingTrivia(new[] { SyntaxFactory.CarriageReturnLineFeed }.Concat(firstAccesor.GetFirstToken().WithoutLeadingBlankLines().LeadingTrivia));
                syntaxRoot = syntaxRoot.ReplaceNode(trackedFirstAccessor, newFirstAccessor);
            }

            var trackedLastAccessor = syntaxRoot.GetCurrentNode(secondAccessor);
            var keepTriviaOptions = AccessorsAreOnTheSameLine(firstAccesor, secondAccessor)
                ? SyntaxRemoveOptions.KeepEndOfLine
                : SyntaxRemoveOptions.KeepNoTrivia;

            syntaxRoot = syntaxRoot.RemoveNode(trackedLastAccessor, keepTriviaOptions);

            return document.WithSyntaxRoot(syntaxRoot);
        }
        private static async Task<Document> RemoveEmptyStatementAsync(Document document, SyntaxNode root, EmptyStatementSyntax node, CancellationToken cancellationToken)
        {
            SyntaxNode newRoot;

            switch (node.Parent.Kind())
            {
            case SyntaxKind.Block:
            case SyntaxKind.SwitchSection:
                // empty statements in a block or switch section can be removed
                return await RemoveSemicolonTextAsync(document, node.SemicolonToken, cancellationToken).ConfigureAwait(false);

            case SyntaxKind.IfStatement:
            case SyntaxKind.ElseClause:
            case SyntaxKind.ForStatement:
            case SyntaxKind.WhileStatement:
            case SyntaxKind.DoStatement:
                // these cases are always replaced with an empty block
                newRoot = root.ReplaceNode(node, SyntaxFactory.Block().WithTriviaFrom(node));
                return document.WithSyntaxRoot(newRoot);

            case SyntaxKind.LabeledStatement:
                // handle this case as a text manipulation for simplicity
                return await RemoveSemicolonTextAsync(document, node.SemicolonToken, cancellationToken).ConfigureAwait(false);

            default:
                return document;
            }
        }
 private static async Task<Document> ChangeToThenByAsync(Document document, SyntaxNode syntaxNode, CancellationToken cancellationToken)
 {
     var root = await document.GetSyntaxRootAsync(cancellationToken);
     var newRoot = root.ReplaceNode(syntaxNode,
         SyntaxFactory.IdentifierName("ThenBy"));
     return document.WithSyntaxRoot(newRoot);
 }
        private Task<Solution> UseExpressionBodiedMemberAsync(Document document, SyntaxNode root, SyntaxNode statement)
        {
            var returnStatement = (ReturnStatementSyntax) statement;
            var expression = returnStatement.Expression;
            var arrowClause = SyntaxFactory.ArrowExpressionClause(expression);

            var property = statement.AncestorsAndSelf().OfType<PropertyDeclarationSyntax>().FirstOrDefault();
            if (property != null)
            {
                var newProperty = property.RemoveNode(property.AccessorList, SyntaxRemoveOptions.KeepNoTrivia)
                                          .WithExpressionBody(arrowClause)
                                          .WithSemicolonToken(SyntaxFactory.Token(SyntaxKind.SemicolonToken));


                root = root.ReplaceNode(property, newProperty);
            }

            var method = statement.AncestorsAndSelf().OfType<MethodDeclarationSyntax>().FirstOrDefault();
            if (method != null)
            {
                root = root.ReplaceNode(method, method.RemoveNode(method.Body, SyntaxRemoveOptions.KeepNoTrivia)
                                                      .WithExpressionBody(arrowClause)
                                                      .WithSemicolonToken(SyntaxFactory.Token(SyntaxKind.SemicolonToken)));
            }

            return Task.FromResult(document.WithSyntaxRoot(root).Project.Solution);
        }
        private static async Task<Document> RemoveRedundantComparisonAsync(Document document, Diagnostic diagnostic, CancellationToken cancellationToken)
        {
            var root = await document.GetSyntaxRootAsync(cancellationToken).ConfigureAwait(false);
            var comparison = root.FindToken(diagnostic.Location.SourceSpan.Start).Parent.AncestorsAndSelf().OfType<BinaryExpressionSyntax>().First();
            var semanticModel = await document.GetSemanticModelAsync(cancellationToken);
            bool constValue;
            ExpressionSyntax replacer;
            var rightConst = semanticModel.GetConstantValue(comparison.Right);
            if (rightConst.HasValue)
            {
                constValue = (bool)rightConst.Value;
                replacer = comparison.Left;
            }
            else
            {
                var leftConst = semanticModel.GetConstantValue(comparison.Left);
                constValue = (bool)leftConst.Value;
                replacer = comparison.Right;
            }


            if ((!constValue && comparison.IsKind(SyntaxKind.EqualsExpression)) || (constValue && comparison.IsKind(SyntaxKind.NotEqualsExpression)))
                replacer = SyntaxFactory.PrefixUnaryExpression(SyntaxKind.LogicalNotExpression, replacer);
            replacer = replacer.WithAdditionalAnnotations(Formatter.Annotation);

            var newRoot = root.ReplaceNode(comparison, replacer);
            var newDocument = document.WithSyntaxRoot(newRoot);
            return newDocument;
        }
 private static async Task<Document> RemoveTrailingWhiteSpaceAsync(Document document, Diagnostic diagnostic, CancellationToken cancellationToken)
 {
     var root = await document.GetSyntaxRootAsync(cancellationToken).ConfigureAwait(false);
     var trivia = root.FindTrivia(diagnostic.Location.SourceSpan.End - 1);
     SyntaxNode newRoot;
     if (trivia.IsKind(SyntaxKind.WhitespaceTrivia))
     {
         newRoot = root.ReplaceTrivia(trivia, new SyntaxTrivia[] { });
     }
     else if (trivia.IsKind(SyntaxKind.SingleLineDocumentationCommentTrivia, SyntaxKind.MultiLineDocumentationCommentTrivia))
     {
         var commentText = trivia.ToFullString();
         var commentLines = commentText.Split(new[] { Environment.NewLine }, StringSplitOptions.None);
         var newComment = "";
         var builder = new System.Text.StringBuilder();
         builder.Append(newComment);
         for (int i = 0; i < commentLines.Length; i++)
         {
             var commentLine = commentLines[i];
             builder.Append(Regex.Replace(commentLine, @"\s+$", ""));
             if (i < commentLines.Length - 1) builder.Append(Environment.NewLine);
         }
         newComment = builder.ToString();
         newRoot = root.ReplaceTrivia(trivia, SyntaxFactory.SyntaxTrivia(SyntaxKind.DocumentationCommentExteriorTrivia, newComment));
     }
     else
     {
         var triviaNoTrailingWhiteSpace = Regex.Replace(trivia.ToFullString(), @"\s+$", "");
         newRoot = root.ReplaceTrivia(trivia, SyntaxFactory.ParseTrailingTrivia(triviaNoTrailingWhiteSpace));
     }
     return document.WithSyntaxRoot(newRoot);
 }
        private static async Task<Document> GetTransformedDocumentAsync(Document document, Diagnostic diagnostic, CancellationToken cancellationToken)
        {
            var root = await document.GetSyntaxRootAsync(cancellationToken).ConfigureAwait(false);

            SyntaxToken token = root.FindToken(diagnostic.Location.SourceSpan.Start);
            if (!token.IsKind(SyntaxKind.CloseBracketToken))
            {
                return document;
            }

            if (token.IsFirstInLine())
            {
                return document;
            }

            SyntaxToken precedingToken = token.GetPreviousToken();
            if (!precedingToken.TrailingTrivia.Any(SyntaxKind.WhitespaceTrivia))
            {
                return document;
            }

            SyntaxToken corrected = precedingToken.WithoutTrailingWhitespace().WithoutFormatting();
            SyntaxNode transformed = root.ReplaceToken(precedingToken, corrected);
            Document updatedDocument = document.WithSyntaxRoot(transformed);

            return updatedDocument;
        }
        private async Task<Document> MakeLambdaExpressionAsync(Document document, AnonymousMethodExpressionSyntax anonMethod, CancellationToken cancellationToken)
        {
            
            var parent = anonMethod.Parent;

            var parameterList = anonMethod.ParameterList != null ? anonMethod.ParameterList : SyntaxFactory.ParameterList();

            SyntaxNode body;

            if (anonMethod.Block != null && anonMethod.Block.Statements.Count == 1)
            {
                body = anonMethod.Block.Statements.ElementAt(0).ChildNodes().ElementAt(0);
            }
            else if (anonMethod.Block != null)
            {
                body = anonMethod.Body;
            }
            else
            {
                body = SyntaxFactory.Block();
            }

            var lambdaExpr = SyntaxFactory.
                ParenthesizedLambdaExpression(parameterList, (CSharpSyntaxNode)body);

            var newParent = parent.ReplaceNode(anonMethod, lambdaExpr);

            var root = await document.GetSyntaxRootAsync(cancellationToken).ConfigureAwait(false);

            var newRoot = root.ReplaceNode(parent, newParent);

            return document.WithSyntaxRoot(newRoot);

        }
        private static async Task<Document> GetTransformedDocumentAsync(Document document, Diagnostic diagnostic, CancellationToken cancellationToken)
        {
            var syntaxRoot = await document.GetSyntaxRootAsync(cancellationToken).ConfigureAwait(false);
            var settings = SettingsHelper.GetStyleCopSettings(document.Project.AnalyzerOptions, cancellationToken);

            var enumMemberDeclaration = (EnumMemberDeclarationSyntax)syntaxRoot.FindNode(diagnostic.Location.SourceSpan);
            var enumDeclaration = (EnumDeclarationSyntax)enumMemberDeclaration.Parent;

            var memberIndex = enumDeclaration.Members.IndexOf(enumMemberDeclaration);
            var precedingSeparatorToken = enumDeclaration.Members.GetSeparator(memberIndex - 1);

            // determine the indentation for enum members (which is parent + 1 step)
            var parentIndentationSteps = IndentationHelper.GetIndentationSteps(settings.Indentation, enumDeclaration);
            var indentation = IndentationHelper.GenerateWhitespaceTrivia(settings.Indentation, parentIndentationSteps + 1);

            // combine all trivia between the separator and the enum member and place them after the separator, followed by a new line.
            var enumMemberDeclarationFirstToken = enumMemberDeclaration.GetFirstToken();
            var sharedTrivia = TriviaHelper.MergeTriviaLists(precedingSeparatorToken.TrailingTrivia, enumMemberDeclarationFirstToken.LeadingTrivia);

            var newTrailingTrivia = SyntaxFactory.TriviaList(sharedTrivia)
                .WithoutTrailingWhitespace()
                .Add(SyntaxFactory.CarriageReturnLineFeed);

            // replace the trivia for the tokens
            var replacements = new Dictionary<SyntaxToken, SyntaxToken>
            {
                [precedingSeparatorToken] = precedingSeparatorToken.WithTrailingTrivia(newTrailingTrivia),
                [enumMemberDeclarationFirstToken] = enumMemberDeclarationFirstToken.WithLeadingTrivia(indentation),
            };

            var newSyntaxRoot = syntaxRoot.ReplaceTokens(replacements.Keys, (original, rewritten) => replacements[original]);
            var newDocument = document.WithSyntaxRoot(newSyntaxRoot.WithoutFormatting());

            return newDocument;
        }
 public static async Task<Document> ReplaceNodeAsync(Document document, SyntaxNode @old, SyntaxNode @new, CancellationToken cancellationToken)
 {
     var root = await document.GetSyntaxRootAsync(cancellationToken);
     var newRoot = root.ReplaceNode(@old, @new);
     var newDocument = document.WithSyntaxRoot(newRoot);
     return newDocument;
 }
        private static async Task<Document> GetTransformedDocumentAsync(Document document, Diagnostic diagnostic, CancellationToken cancellationToken)
        {
            var syntaxRoot = await document.GetSyntaxRootAsync(cancellationToken).ConfigureAwait(false);

            var token = syntaxRoot.FindToken(diagnostic.Location.SourceSpan.Start);
            var triviaList = token.LeadingTrivia;

            var index = triviaList.Count - 1;
            while (!triviaList[index].IsKind(SyntaxKind.EndOfLineTrivia))
            {
                index--;
            }

            var lastEndOfLine = index;

            while (!triviaList[index].IsKind(SyntaxKind.SingleLineDocumentationCommentTrivia))
            {
                index--;
            }

            var lastDocumentation = index;

            var newLeadingTrivia = triviaList.Take(lastDocumentation + 1).Concat(triviaList.Skip(lastEndOfLine + 1));
            var newSyntaxRoot = syntaxRoot.ReplaceToken(token, token.WithLeadingTrivia(newLeadingTrivia));

            return document.WithSyntaxRoot(newSyntaxRoot);
        }
        private static async Task<Document> AddConfigureAwaitAsync(Document document, Diagnostic diagnostic, CancellationToken cancellationToken, bool continueOnCapturedContext)
        {
            SyntaxKind continueOnCapturedContextSyntax;
            switch (continueOnCapturedContext)
            {
                case true:
                    continueOnCapturedContextSyntax = SyntaxKind.TrueLiteralExpression;
                    break;
                default:
                    continueOnCapturedContextSyntax = SyntaxKind.FalseLiteralExpression;
                    break;
            }

            var root = await document.GetSyntaxRootAsync(cancellationToken).ConfigureAwait(false);
            var awaitExpression = (AwaitExpressionSyntax)root.FindNode(diagnostic.Location.SourceSpan);
            var expression = awaitExpression.Expression;

            var newExpression = SyntaxFactory.InvocationExpression(
                SyntaxFactory.MemberAccessExpression(
                    SyntaxKind.SimpleMemberAccessExpression,
                    expression,
                    SyntaxFactory.IdentifierName(nameof(Task.ConfigureAwait))),
                SyntaxFactory.ArgumentList(
                    SyntaxFactory.SingletonSeparatedList(
                        SyntaxFactory.Argument(
                            SyntaxFactory.LiteralExpression(continueOnCapturedContextSyntax)))));

            var newRoot = root.ReplaceNode(expression, newExpression);
            var newDocument = document.WithSyntaxRoot(newRoot);
            return newDocument;
        }
Пример #29
0
        public async Task<Solution> EnforceAsync(Document document)
        {
            if (document == null) { throw new ArgumentNullException(nameof(document)); }

            // The compiler will actually do the heavy lifting for us on this one: when it generates the semantic model
            // it creates diagnostic notes for usings that are unused with the id "CS8019".
            SemanticModel semanticModel = await document.GetSemanticModelAsync();
            IEnumerable<Diagnostic> diagnostics = semanticModel.GetDiagnostics().Where(d => d.Id == "CS8019");

            // Save the leading trivia to reattach after we have removed the unused roots
            SyntaxNode oldRoot = await document.GetSyntaxRootAsync();
            SyntaxTriviaList leadingTrivia = oldRoot.GetLeadingTrivia();

            // Now we need to go through the diagnostics in reverse order (so we don't corrupt our spans), find the
            // relevant SyntaxNodes, and remove them.
            diagnostics = diagnostics.OrderByDescending(d => d.Location.SourceSpan.Start);
            SyntaxNode newRoot = oldRoot;

            foreach (Diagnostic diagnostic in diagnostics)
            {
                newRoot = newRoot.RemoveNodes(
                    newRoot.DescendantNodes(diagnostic.Location.SourceSpan),
                    SyntaxRemoveOptions.KeepNoTrivia);
            }

            if (newRoot != oldRoot)
            {
                Log.WriteInformation("{0}: Removing unused usings", document.Name);
                document = document.WithSyntaxRoot(newRoot.WithLeadingTrivia(leadingTrivia));
            }

            return document.Project.Solution;
        }
        private Document CreateCodeFix(Document document, Diagnostic diagnostic, SyntaxNode syntaxRoot)
        {
            SyntaxNode newSyntaxRoot = syntaxRoot;
            var node = syntaxRoot.FindNode(diagnostic.Location.SourceSpan);
            var indentationOptions = IndentationOptions.FromDocument(document);

            switch (node.Kind())
            {
            case SyntaxKind.ClassDeclaration:
            case SyntaxKind.InterfaceDeclaration:
            case SyntaxKind.StructDeclaration:
            case SyntaxKind.EnumDeclaration:
                newSyntaxRoot = this.RegisterBaseTypeDeclarationCodeFix(syntaxRoot, (BaseTypeDeclarationSyntax)node, indentationOptions);
                break;

            case SyntaxKind.AccessorList:
                newSyntaxRoot = this.RegisterPropertyLikeDeclarationCodeFix(syntaxRoot, (BasePropertyDeclarationSyntax)node.Parent, indentationOptions);
                break;

            case SyntaxKind.Block:
                newSyntaxRoot = this.RegisterMethodLikeDeclarationCodeFix(syntaxRoot, (BaseMethodDeclarationSyntax)node.Parent, indentationOptions);
                break;

            case SyntaxKind.NamespaceDeclaration:
                newSyntaxRoot = this.RegisterNamespaceDeclarationCodeFix(syntaxRoot, (NamespaceDeclarationSyntax)node, indentationOptions);
                break;
            }

            return document.WithSyntaxRoot(newSyntaxRoot);
        }
Пример #31
0
        private static async Task <Document> AddMigrationMethod(Document document, TypeDeclarationSyntax typeDecl, CancellationToken ct)
        {
            var semanticModel = await document.GetSemanticModelAsync(ct);

            var typeSymbol            = semanticModel.GetDeclaredSymbol(typeDecl, ct);
            var latestMigrationMethod = MigrationHashHelper.GetMigrationMethods(typeSymbol).LastOrDefault();

            var latestVersion        = latestMigrationMethod?.ToVersion ?? 0;
            var dataArgumentTypeName = latestMigrationMethod?.ReturnType.Name ?? "JToken";
            var method = GetMigrationMethod(latestVersion + 1, dataArgumentTypeName, ct);
            var typeDeclWithUpdatedMigrationHash = MigrationHashHelper.UpdateMigrationHash(typeDecl, ct, semanticModel);
            var typeDeclWithAddedMigrationMethod = AddMember(typeDeclWithUpdatedMigrationHash, method);

            var root = (CompilationUnitSyntax)await document.GetSyntaxRootAsync(ct);

            var rootWithNewTypeDecl = root.ReplaceNode(typeDecl, typeDeclWithAddedMigrationMethod);

            return(document.WithSyntaxRoot(rootWithNewTypeDecl));
        }
 private static Task <Document> FixMissingStatic(Document contextDocument, SyntaxNode root, MethodDeclarationSyntax method)
 {
     return(Task.FromResult(contextDocument.WithSyntaxRoot(root.ReplaceNode(method, method.AddModifiers(Token(SyntaxKind.StaticKeyword))))));
 }
Пример #33
0
        private async System.Threading.Tasks.Task CommandCallbackAsync()
        {
            await ThreadHelper.JoinableTaskFactory.SwitchToMainThreadAsync();

            IWpfTextView textView = await ServiceProvider.GetWpfTextViewAsync();

            if (textView == null)
            {
                return;
            }

            SnapshotPoint     caretPosition = textView.Caret.Position.BufferPosition;
            ITextSnapshotLine caretLine     = caretPosition.GetContainingLine();

            if (caretLine == null)
            {
                return;
            }

            Document document = caretPosition.Snapshot.GetOpenDocumentInCurrentContextWithChanges();

            if (document == null)
            {
                return;
            }

            await TaskScheduler.Default;                //Go to background thread

            SyntaxNode syntaxRoot = await document.GetSyntaxRootAsync();

            SemanticModel semanticModel = await document.GetSemanticModelAsync();

            if (syntaxRoot == null || semanticModel == null)
            {
                return;
            }

            //TextSpan lineSpan = TextSpan.FromBounds(caretLine.Start.Position, caretLine.End.Position);
            //var memberNode = syntaxRoot.FindNode(lineSpan) as MemberDeclarationSyntax;

            //         if (memberNode == null)
            //             return;

            SyntaxNode fixedRoot;

            #region todo
            if (textView.Selection.IsActive && !textView.Selection.IsEmpty)             // if has selection
            {
                // todo: check selection

                //// Find all nodes within the span and format them
                //var selectionSpan = TextSpan.FromBounds(textView.Selection.Start.Position, textView.Selection.End.Position);
                //SyntaxNode topNode = syntaxRoot.FindNode(selectionSpan); // can, return top node that intersects with selectionSpan, so we need SpanWalker here

                //if (topNode == null)
                //	return; // nothing to format (e.g. selection contains only trivia)

                //var spanWalker = new SpanWalker(selectionSpan);
                //spanWalker.Visit(topNode);

                //if (spanWalker.NodesWithinSpan.Count == 0)
                //	return;

                //fixedRoot = syntaxRoot.ReplaceNodes(spanWalker.NodesWithinSpan, (o, r) => formatter.Format(o, semanticModel));
            }
            else
            {
            }
            #endregion
            fixedRoot = new AngleBracesBqlRewriter(semanticModel).Visit(syntaxRoot);
            var        newDocument   = document.WithSyntaxRoot(fixedRoot);
            SyntaxNode newSyntaxRoot = await newDocument.GetSyntaxRootAsync();

            SemanticModel newSemanticModel = await newDocument.GetSemanticModelAsync();

            if (newSyntaxRoot == null || newSemanticModel == null)
            {
                return;
            }

            // have to format, because cannot save all original indention
            BqlFormatter formatter    = BqlFormatter.FromTextView(textView);
            var          formatedRoot = formatter.Format(newSyntaxRoot, newSemanticModel);

            await ThreadHelper.JoinableTaskFactory.SwitchToMainThreadAsync();             // Return to UI thread

            if (!textView.TextBuffer.EditInProgress)
            {
                var formattedDocument = document.WithSyntaxRoot(formatedRoot);
                ApplyChanges(document, formattedDocument);
            }
        }
 private static Task <Document> FixMissingPartial(Document contextDocument, SyntaxNode root, ClassDeclarationSyntax @class)
 {
     return(Task.FromResult(contextDocument.WithSyntaxRoot(root.ReplaceNode(@class, @class.AddModifiers(Token(SyntaxKind.PartialKeyword))))));
 }