コード例 #1
1
		public async Task<IEnumerable<CodeAction>> GetRefactoringsAsync(Document document, TextSpan textSpan, CancellationToken cancellationToken)
		{
			var root = await document.GetSyntaxRootAsync(cancellationToken).ConfigureAwait(false);
			var node = root.FindNode(textSpan);
			var switchStatementNode = node as SwitchStatementSyntax;
			if (switchStatementNode == null)
				return null;

			var semanticModel = await document.GetSemanticModelAsync(cancellationToken).ConfigureAwait(false);

			var memberEx = switchStatementNode.Expression as MemberAccessExpressionSyntax;
			if (memberEx == null)
				return null;

			var symbolInfo = semanticModel.GetTypeInfo(memberEx.Name);
			var enumTypeInfo = symbolInfo.Type;
			if (enumTypeInfo.TypeKind != TypeKind.Enum)
				return null;

			var enumName = enumTypeInfo.Name;
			var nameSpace = enumTypeInfo.ContainingNamespace.Name;
			var enumType = Type.GetType(nameSpace + "." + enumName);
			if (enumType == null)
				return null;

			return new[] { CodeAction.Create("Explode Switch", c => ExplodeSwitch(document, root, semanticModel, switchStatementNode, c)) };
		}
コード例 #2
0
 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;
 }
コード例 #3
0
        private static async Task<Document> GetTransformedDocumentFromSingleLineAsync(Document document, Diagnostic diagnostic, CancellationToken cancellationToken)
        {
            var syntaxRoot = await document.GetSyntaxRootAsync(cancellationToken).ConfigureAwait(false);
            var queryExpression = (QueryExpressionSyntax)syntaxRoot.FindNode(diagnostic.Location.SourceSpan).Parent;
            var replaceMap = new Dictionary<SyntaxToken, SyntaxToken>();

            var nodeList = CreateQueryNodeList(queryExpression);

            for (var i = 0; i < nodeList.Length; i++)
            {
                var token = nodeList[i].GetFirstToken();
                var precedingToken = token.GetPreviousToken();

                var triviaList = precedingToken.TrailingTrivia.AddRange(token.LeadingTrivia);
                var processedTriviaList = triviaList
                    .Where(t => t.IsKind(SyntaxKind.MultiLineCommentTrivia))
                    .ToSyntaxTriviaList()
                    .Add(SyntaxFactory.Space);

                if (processedTriviaList.Count > 1)
                {
                    processedTriviaList = processedTriviaList.Insert(0, SyntaxFactory.Space);
                }

                replaceMap.Add(precedingToken, precedingToken.WithTrailingTrivia(processedTriviaList));
                replaceMap.Add(token, token.WithLeadingTrivia());
            }

            var newSyntaxRoot = syntaxRoot.ReplaceTokens(replaceMap.Keys, (t1, t2) => replaceMap[t1]).WithoutFormatting();
            return document.WithSyntaxRoot(newSyntaxRoot);
        }
コード例 #4
0
        protected override async Task<SignatureHelpItems> GetItemsWorkerAsync(Document document, int position, SignatureHelpTriggerInfo triggerInfo, CancellationToken cancellationToken)
        {
            var root = await document.GetSyntaxRootAsync(cancellationToken).ConfigureAwait(false);

            InvocationExpressionSyntax invocationExpression;
            if (!TryGetInvocationExpression(root, position, document.GetLanguageService<ISyntaxFactsService>(), triggerInfo.TriggerReason, cancellationToken, out invocationExpression))
            {
                return null;
            }

            var semanticModel = await document.GetSemanticModelForNodeAsync(invocationExpression, cancellationToken).ConfigureAwait(false);
            var within = semanticModel.GetEnclosingNamedTypeOrAssembly(position, cancellationToken);
            if (within == null)
            {
                return null;
            }

            // get the regular signature help items
            var symbolDisplayService = document.Project.LanguageServices.GetService<ISymbolDisplayService>();
            var methodGroup = semanticModel.GetMemberGroup(invocationExpression.Expression, cancellationToken)
                                           .OfType<IMethodSymbol>()
                                           .FilterToVisibleAndBrowsableSymbols(document.ShouldHideAdvancedMembers(), semanticModel.Compilation);

            // try to bind to the actual method
            var symbolInfo = semanticModel.GetSymbolInfo(invocationExpression, cancellationToken);
            var matchedMethodSymbol = symbolInfo.Symbol as IMethodSymbol;

            // if the symbol could be bound, replace that item in the symbol list
            if (matchedMethodSymbol != null && matchedMethodSymbol.IsGenericMethod)
            {
                methodGroup = methodGroup.Select(m => matchedMethodSymbol.OriginalDefinition == m ? matchedMethodSymbol : m);
            }

            methodGroup = methodGroup.Sort(symbolDisplayService, semanticModel, invocationExpression.SpanStart);

            var expressionType = semanticModel.GetTypeInfo(invocationExpression.Expression, cancellationToken).Type as INamedTypeSymbol;

            var anonymousTypeDisplayService = document.Project.LanguageServices.GetService<IAnonymousTypeDisplayService>();
            var documentationCommentFormattingService = document.Project.LanguageServices.GetService<IDocumentationCommentFormattingService>();

            var textSpan = SignatureHelpUtilities.GetSignatureHelpSpan(invocationExpression.ArgumentList);
            var syntaxFacts = document.GetLanguageService<ISyntaxFactsService>();

            if (methodGroup.Any())
            {
                return CreateSignatureHelpItems(
                    GetMethodGroupItems(invocationExpression, semanticModel, symbolDisplayService, anonymousTypeDisplayService, documentationCommentFormattingService, within, methodGroup, cancellationToken),
                    textSpan, GetCurrentArgumentState(root, position, syntaxFacts, textSpan, cancellationToken));
            }
            else if (expressionType != null && expressionType.TypeKind == TypeKind.Delegate)
            {
                return CreateSignatureHelpItems(
                    GetDelegateInvokeItems(invocationExpression, semanticModel, symbolDisplayService, anonymousTypeDisplayService, documentationCommentFormattingService, within, expressionType, cancellationToken),
                    textSpan, GetCurrentArgumentState(root, position, syntaxFacts, textSpan, cancellationToken));
            }
            else
            {
                return null;
            }
        }
コード例 #5
0
        /// <summary>
        /// Réordonne les membres d'un type.
        /// </summary>
        /// <param name="document">Le document.</param>
        /// <param name="type">Le type.</param>
        /// <param name="jetonAnnulation">Le jeton d'annulation.</param>
        /// <returns>Le nouveau document.</returns>
        private async Task<Document> OrdonnerMembres(Document document, TypeDeclarationSyntax type, CancellationToken jetonAnnulation)
        {
            // On récupère la racine.
            var racine = await document
                .GetSyntaxRootAsync(jetonAnnulation)
                .ConfigureAwait(false);
            var modèleSémantique = await document.GetSemanticModelAsync(jetonAnnulation);

            // Pour une raison étrange, TypeDeclarationSyntax n'expose pas WithMembers() alors que les trois classes qui en héritent l'expose.
            // Il faut donc gérer les trois cas différemment...
            SyntaxNode nouveauType;
            if (type is ClassDeclarationSyntax)
            {
                nouveauType = (type as ClassDeclarationSyntax)
                    .WithMembers(SyntaxFactory.List(Partagé.OrdonnerMembres(type.Members, modèleSémantique)));
            }
            else if (type is InterfaceDeclarationSyntax)
            {
                nouveauType = (type as InterfaceDeclarationSyntax)
                    .WithMembers(SyntaxFactory.List(Partagé.OrdonnerMembres(type.Members, modèleSémantique)));
            }
            else
            {
                nouveauType = (type as StructDeclarationSyntax)
                    .WithMembers(SyntaxFactory.List(Partagé.OrdonnerMembres(type.Members, modèleSémantique)));
            }

            // Et on met à jour la racine.
            var nouvelleRacine = racine.ReplaceNode(type, nouveauType);

            return document.WithSyntaxRoot(nouvelleRacine);
        }
コード例 #6
0
        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;
 }
コード例 #8
0
        private static async Task<Document> GetTransformedDocumentAsync(Document document, Diagnostic diagnostic, CancellationToken cancellationToken)
        {
            var syntaxRoot = await document.GetSyntaxRootAsync(cancellationToken).ConfigureAwait(false);
            var whereToken = syntaxRoot.FindToken(diagnostic.Location.SourceSpan.Start);
            var precedingToken = whereToken.GetPreviousToken();
            var endToken = syntaxRoot.FindToken(diagnostic.Location.SourceSpan.End);
            var afterEndToken = endToken.GetNextToken();

            var parentIndentation = GetParentIndentation(whereToken);
            var settings = SettingsHelper.GetStyleCopSettings(document.Project.AnalyzerOptions, cancellationToken);
            var indentationTrivia = SyntaxFactory.Whitespace(parentIndentation + IndentationHelper.GenerateIndentationString(settings.Indentation, 1));

            var replaceMap = new Dictionary<SyntaxToken, SyntaxToken>()
            {
                [precedingToken] = precedingToken.WithTrailingTrivia(SyntaxFactory.CarriageReturnLineFeed),
                [whereToken] = whereToken.WithLeadingTrivia(indentationTrivia),
                [endToken] = endToken.WithTrailingTrivia(RemoveUnnecessaryWhitespaceTrivia(endToken).Add(SyntaxFactory.CarriageReturnLineFeed)),
            };

            if (afterEndToken.IsKind(SyntaxKind.EqualsGreaterThanToken))
            {
                replaceMap.Add(afterEndToken, afterEndToken.WithLeadingTrivia(indentationTrivia));
            }
            else if (afterEndToken.IsKind(SyntaxKind.OpenBraceToken))
            {
                replaceMap.Add(afterEndToken, afterEndToken.WithLeadingTrivia(SyntaxFactory.Whitespace(parentIndentation)));
            }
            else if (afterEndToken.IsKind(SyntaxKind.WhereKeyword))
            {
                replaceMap.Add(afterEndToken, afterEndToken.WithLeadingTrivia(indentationTrivia));
            }

            var newSyntaxRoot = syntaxRoot.ReplaceTokens(replaceMap.Keys, (t1, t2) => replaceMap[t1]).WithoutFormatting();
            return document.WithSyntaxRoot(newSyntaxRoot);
        }
コード例 #9
0
            static async Task UpdateDocument(ConcurrentDictionary <DocumentId, Dictionary <DeclaredSymbolInfoKind, List <DeclaredSymbolInfoWrapper> > > result, Microsoft.CodeAnalysis.Document document, CancellationToken cancellationToken)
            {
                var syntaxFactsService = document.GetLanguageService <ISyntaxFactsService> ();
                var root = await document.GetSyntaxRootAsync(cancellationToken).ConfigureAwait(false);

                var infos = new Dictionary <DeclaredSymbolInfoKind, List <DeclaredSymbolInfoWrapper> > ();

                foreach (var kind in AllKinds)
                {
                    infos [kind] = new List <DeclaredSymbolInfoWrapper> ();
                }
                foreach (var current in root.DescendantNodesAndSelf(n => !(n is BlockSyntax)))
                {
                    cancellationToken.ThrowIfCancellationRequested();
                    var kind = current.Kind();
                    if (kind == SyntaxKind.ConstructorDeclaration ||
                        kind == SyntaxKind.IndexerDeclaration)
                    {
                        continue;
                    }
                    if (syntaxFactsService.TryGetDeclaredSymbolInfo(current, out DeclaredSymbolInfo info))
                    {
                        var declaredSymbolInfo = new DeclaredSymbolInfoWrapper(current, document.Id, info);
                        infos[info.Kind].Add(declaredSymbolInfo);
                    }
                }
                RemoveDocument(result, document.Id);
                result.TryAdd(document.Id, infos);
            }
		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> 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;
        }
コード例 #12
0
 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 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);
 }
コード例 #14
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);
 }
コード例 #15
0
        private async Task<Document> GetTransformedDocumentAsync(Document document, Diagnostic diagnostic, CancellationToken token)
        {
            var syntaxRoot = await document.GetSyntaxRootAsync(token).ConfigureAwait(false);
            var newDocument = this.CreateCodeFix(document, diagnostic, syntaxRoot);

            return newDocument;
        }
コード例 #16
0
        private static async Task<Document> GetTransformedDocumentAsync(Document document, CancellationToken cancellationToken)
        {
            var root = await document.GetSyntaxRootAsync(cancellationToken).ConfigureAwait(false);
            var settings = document.Project.AnalyzerOptions.GetStyleCopSettings();

            var fileHeader = FileHeaderHelpers.ParseFileHeader(root);
            SyntaxNode newSyntaxRoot;
            if (fileHeader.IsMissing)
            {
                newSyntaxRoot = AddHeader(document, root, document.Name, settings);
            }
            else
            {
                var trivia = root.GetLeadingTrivia();
                var commentIndex = TriviaHelper.IndexOfFirstNonWhitespaceTrivia(trivia, false);

                // Safe to do this as fileHeader.IsMissing is false.
                var isMultiLineComment = trivia[commentIndex].IsKind(SyntaxKind.MultiLineCommentTrivia);

                var xmlFileHeader = FileHeaderHelpers.ParseXmlFileHeader(root);
                if (isMultiLineComment && !xmlFileHeader.IsMalformed)
                {
                    newSyntaxRoot = ReplaceWellFormedMultiLineCommentHeader(document, root, settings, commentIndex, xmlFileHeader);
                }
                else
                {
                    newSyntaxRoot = ReplaceHeader(document, root, settings, xmlFileHeader.IsMalformed);
                }
            }

            return document.WithSyntaxRoot(newSyntaxRoot);
        }
コード例 #17
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 async Task<Document> FormatXmlAsync(Document document, ArgumentSyntax argSntax, CancellationToken cancellationToken)
		{
			var root = await document.GetSyntaxRootAsync(cancellationToken);
			var tree = root.SyntaxTree;

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

			//Get the parent VariableDeclaration to figure out the preceeding trivia since we can't 
			//get the column position from GetLineSpan (bug?)
			var parent = argSntax.Ancestors().Where(t => t.IsKind(SyntaxKind.VariableDeclaration)).FirstOrDefault();
			var parentTrivia = parent.GetLeadingTrivia().ToFullString();

			var xml = argSntax.Expression.GetFirstToken().ValueText;
			var newXml = FormatXml(xml);

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

			newXml = String.Join("\r\n", xmlLines);
			newXml = "@\"" + newXml + "\"";

			var newNode = SyntaxFactory.Argument(null, SyntaxFactory.Token(SyntaxKind.None), SyntaxFactory.IdentifierName(newXml));
			var newRoot = root.ReplaceNode(argSntax, newNode);
			return document.WithSyntaxRoot(newRoot);
		}
コード例 #19
0
		static async Task<SyntaxNode> GetNewRootWithAddedNamespaces(Document document, SyntaxNode relativeToNode,
			CancellationToken cancellationToken, ImmutableHashSet<string> namespaceQualifiedStrings)
		{
			var namespaceWithUsings = relativeToNode
				.GetAncestorsOrThis<NamespaceDeclarationSyntax>()
				.FirstOrDefault(ns => ns.DescendantNodes().OfType<UsingDirectiveSyntax>().Any());

			var root = await document.GetSyntaxRootAsync(cancellationToken);
			SyntaxNode newRoot;

			var usings = namespaceQualifiedStrings
				.Select(ns => UsingDirective(ParseName(ns).WithAdditionalAnnotations(Simplifier.Annotation)));

			if (namespaceWithUsings != null)
			{
				var newNamespaceDeclaration = namespaceWithUsings.WithUsings(namespaceWithUsings.Usings.AddRange(usings));
				newRoot = root.ReplaceNode(namespaceWithUsings, newNamespaceDeclaration);
			}
			else
			{
				var compilationUnit = (CompilationUnitSyntax)root;
				newRoot = compilationUnit.WithUsings(compilationUnit.Usings.AddRange(usings));
			}
			return newRoot;
		}
コード例 #20
0
 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;
 }
コード例 #21
0
        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);
        }
コード例 #22
0
        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);
        }
コード例 #23
0
        public async Task<bool> IsValidAsync(
            Document document,
            int position,
            string expressionValue,
            CancellationToken cancellationToken)
        {
            var expression = SyntaxFactory.ParseExpression(expressionValue);
            var root = await document.GetSyntaxRootAsync(cancellationToken).ConfigureAwait(false);
            var token = root.FindToken(position);
            if (token.Kind() == SyntaxKind.CloseBraceToken && token.GetPreviousToken().Kind() != SyntaxKind.None)
            {
                token = token.GetPreviousToken();
            }

            var semanticModel = await document.GetSemanticModelAsync(cancellationToken).ConfigureAwait(false);
            var info = semanticModel.GetSpeculativeSymbolInfo(token.SpanStart, expression, SpeculativeBindingOption.BindAsExpression);
            if (info.Symbol == null)
            {
                return false;
            }

            // We seem to have bound successfully.  However, if it bound to a local, then make
            // sure that that local isn't after the statement that we're currently looking at.  
            if (info.Symbol.Kind == SymbolKind.Local)
            {
                var statement = info.Symbol.Locations.First().FindToken(cancellationToken).GetAncestor<StatementSyntax>();
                if (statement != null && position < statement.SpanStart)
                {
                    return false;
                }
            }

            return true;
        }
        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;
        }
コード例 #25
0
 private IEnumerable<BinaryExpressionSyntax> FindArithmeticOperationsOnVariables(Document document)
 {
     var root = document.GetSyntaxRootAsync().Result;
     return root.DescendantNodes().OfType<BinaryExpressionSyntax>()
         .Where(exp => exp.OperatorToken.RawKind == PlusToken || exp.OperatorToken.RawKind == MinusToken ||
         exp.OperatorToken.RawKind == AsteriskToken || exp.OperatorToken.RawKind == SlashToken);
 }
コード例 #26
0
		async Task<Document> MakeUppercaseAsync(Document document, InvocationExpressionSyntax invocation,
			CancellationToken cancellationToken)
		{
			var semanticModel = await document.GetSemanticModelAsync(cancellationToken).ConfigureAwait(false);
			var typeSymbol = semanticModel.GetSymbolInfo(invocation.Expression, cancellationToken).Symbol;
			var nfluentCheck = semanticModel.Compilation.NFluentCheckType();

			if (typeSymbol == null || nfluentCheck == null) return document;

			var newMethod = typeSymbol.Name == "AreEqual" ? "IsEqualTo" : "IsNotEqualTo";

			var checkThat = CheckThat(nfluentCheck, invocation.ArgumentList.Arguments[1]);

			var replacement = InvocationExpression(
				MemberAccessExpression(
					SyntaxKind.SimpleMemberAccessExpression,
					checkThat,
					IdentifierName(newMethod)),
				ArgumentList(SingletonSeparatedList(invocation.ArgumentList.Arguments[0])))
				.WithTriviaFrom(invocation);

			var syntaxRoot = await document.GetSyntaxRootAsync(cancellationToken).ConfigureAwait(false);
			var newSyntaxRoot = syntaxRoot.ReplaceNode(invocation, replacement);
			var newDocument = document.WithSyntaxRoot(newSyntaxRoot);

			var withUsings = await UsingHelpers.AddUsingsAsync(newDocument, replacement, cancellationToken,
				nfluentCheck.ContainingNamespace);

			return withUsings;
		}
コード例 #27
0
        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> 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;
        }
コード例 #29
0
        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;
        }
コード例 #30
0
		public static new async Task<SemanticDocument> CreateAsync(Document document, CancellationToken cancellationToken)
		{
			var text = await document.GetTextAsync(cancellationToken).ConfigureAwait(false);
			var root = await document.GetSyntaxRootAsync(cancellationToken).ConfigureAwait(false);
			var model = await document.GetSemanticModelAsync(cancellationToken).ConfigureAwait(false);
			return new SemanticDocument(document, text, root.SyntaxTree, root, model);
		}
コード例 #31
0
            static async Task UpdateDocument(ConcurrentDictionary <DocumentId, Dictionary <DeclaredSymbolInfoKind, List <DeclaredSymbolInfo> > > result, Microsoft.CodeAnalysis.Document document, CancellationToken cancellationToken)
            {
                var root = await document.GetSyntaxRootAsync(cancellationToken).ConfigureAwait(false);

                var infos = new Dictionary <DeclaredSymbolInfoKind, List <DeclaredSymbolInfo> > ();

                foreach (var kind in AllKinds)
                {
                    infos [kind] = new List <DeclaredSymbolInfo> ();
                }
                foreach (var current in root.DescendantNodesAndSelf(n => !(n is BlockSyntax)))
                {
                    cancellationToken.ThrowIfCancellationRequested();
                    DeclaredSymbolInfo declaredSymbolInfo;
                    if (current.TryGetDeclaredSymbolInfo(out declaredSymbolInfo))
                    {
                        var kind = declaredSymbolInfo.Kind;
                        if (kind == DeclaredSymbolInfoKind.Constructor ||
                            kind == DeclaredSymbolInfoKind.Module ||
                            kind == DeclaredSymbolInfoKind.Indexer)
                        {
                            continue;
                        }
                        declaredSymbolInfo.DocumentId = document.Id;
                        infos[kind].Add(declaredSymbolInfo);
                    }
                }
                RemoveDocument(result, document.Id);
                result.TryAdd(document.Id, infos);
            }
コード例 #32
0
        private async Task<Document> FixSpacingAsync(Document document, IfStatementSyntax ifStatement, CancellationToken c)
        {
            // This method will generate a new if-statement node with a single space between the if-keyword and the opening parenthesis.
            var generator = SyntaxGenerator.GetGenerator(document);
        
            // The new if-statement will need to retain the same statements as the old if-statement.
            var ifBlock = ifStatement.Statement as BlockSyntax;
            var ifBlockStatements = ifBlock.Statements;

            // The new if-statement should retain the formatting of the trivia before and after the if-statement.
            // The following statements extract the original trivia.
            var ifKeyword = ifStatement.IfKeyword;
            var leadingTrivia = ifKeyword.LeadingTrivia;
            var closeBrace = ifBlock.CloseBraceToken;
            var trailingTrivia = closeBrace.TrailingTrivia;

            // If-statements generated using SyntaxGenerator are formatted with the desired spacing by default so this is not specified explicitly.
            var newIfStatement = generator.IfStatement(ifStatement.Condition, ifBlockStatements).WithLeadingTrivia(leadingTrivia).WithTrailingTrivia(trailingTrivia);

            // This statement gets the top of the syntax tree so that the old if-statement node can be replaced with the new one.
            var root = await document.GetSyntaxRootAsync();

            // A new root is created with the old if-statement replaced by the new one.
            var newRoot = root.ReplaceNode(ifStatement, newIfStatement);

            // A new document with the new root is returned.
            var newDocument = document.WithSyntaxRoot(newRoot);
            return newDocument;
    }
コード例 #33
0
        public (SyntaxTree syntaxTree, SemanticModel semModel) GetDocumentModels(Microsoft.CodeAnalysis.Document document)
        {
            var root       = document.GetSyntaxRootAsync().Result;
            var syntaxTree = root.SyntaxTree;

            var semModel = document.GetSemanticModelAsync().Result;

            return(syntaxTree, semModel);
        }
コード例 #34
0
        protected override void CommandCallback(object sender, EventArgs e)
        {
            IWpfTextView textView = ServiceProvider.GetWpfTextView();

            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;
            }

            (SyntaxNode syntaxRoot, SemanticModel semanticModel) = ThreadHelper.JoinableTaskFactory.Run(
                async() => (await document.GetSyntaxRootAsync(), 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;
            }

            PXContext context = new PXContext(semanticModel.Compilation);

            if (!context.IsPlatformReferenced)
            {
                return;
            }

            ISymbol memberSymbol = GetMemberSymbol(memberNode, semanticModel, caretPosition);

            if (!CheckMemberSymbol(memberSymbol, context))
            {
                return;
            }

            NavigateToHandlerOrDeclaration(document, textView, memberSymbol, memberNode, semanticModel, context);
        }
コード例 #35
0
        public async Task <(SyntaxTree syntaxTree, SemanticModel semModel)> GetDocumentModelsAsync(Microsoft.CodeAnalysis.Document document)
        {
            var root = await document.GetSyntaxRootAsync();

            var syntaxTree = root.SyntaxTree;

            var semModel = await document.GetSemanticModelAsync();

            return(syntaxTree, semModel);
        }
コード例 #36
0
        /// <summary>
        /// Get the Type of the selected text. e.g. for a local variable, we need to get the type of the
        /// variable instead of the variable itself
        /// </summary>
        /// <returns></returns>
        private ISymbol getChosenSymbol()
        {
            ISymbol selected = null;

            var textView = getTextView();

            Microsoft.CodeAnalysis.Document codeDoc = GetRoslynDocument();
            //textfeature extension method
            var semanticModel = codeDoc.GetSemanticModelAsync().Result;

            SyntaxNode rootNode = codeDoc.GetSyntaxRootAsync().Result;
            var        pos      = textView.Caret.Position.BufferPosition;

            var st = rootNode.FindToken(pos);

            var curNode = rootNode.FindNode(
                new Microsoft.CodeAnalysis.Text.TextSpan(pos.Position, 0));

            if (curNode == null)
            {
                curNode = st.Parent;
            }

            var sym = GetSymbolResolvableByILSpy(semanticModel, curNode);

            if (sym != null)
            {
                return(sym);
            }

            var parentKind = st.Parent.RawKind;

            //credit: https://github.com/verysimplenick/GoToDnSpy/blob/master/GoToDnSpy/GoToDnSpy.cs
            //a SyntaxNode is parent of a SyntaxToken
            if (st.RawKind == (int)SyntaxKind.IdentifierToken)
            {
                selected = semanticModel.LookupSymbols(pos.Position, name: st.Text).FirstOrDefault();
            }
            else
            {
                var symbolInfo = semanticModel.GetSymbolInfo(st.Parent);
                selected = symbolInfo.Symbol ?? (symbolInfo.GetType().GetProperty("CandidateSymbols")
                                                 .GetValue(symbolInfo) as IEnumerable <ISymbol>)?.FirstOrDefault();
            }


            var localSymbol = selected as ILocalSymbol;

            var rs = (localSymbol == null) ? selected : localSymbol.Type;

            return(rs);
        }
コード例 #37
0
        protected virtual async Task CommandCallbackAsync()
        {
            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 || !document.SupportsSyntaxTree /*|| document.SourceCodeKind ==*/)
            {
                return;
            }

            Task <SyntaxNode>    syntaxRootTask    = document.GetSyntaxRootAsync(Package.DisposalToken);
            Task <SemanticModel> semanticModelTask = document.GetSemanticModelAsync(Package.DisposalToken);
            await Task.WhenAll(syntaxRootTask, semanticModelTask);

#pragma warning disable VSTHRD002, VSTHRD103 // Avoid problematic synchronous waits - the results are already obtained
            SyntaxNode    syntaxRoot    = syntaxRootTask.Result;
            SemanticModel semanticModel = semanticModelTask.Result;
#pragma warning restore VSTHRD002, VSTHRD103

            if (syntaxRoot == null || semanticModel == null || !IsPlatformReferenced(semanticModel) ||
                Package.DisposalToken.IsCancellationRequested)
            {
                return;
            }

            TextSpan caretSpan = GetTextSpanFromCaret(caretPosition, caretLine);
            List <DiagnosticData> diagnosticData = await GetDiagnosticsAsync(document, caretSpan);

            SyntaxNode nodeWithDiagnostic = syntaxRoot.FindNode(caretSpan);

            if (nodeWithDiagnostic != null)
            {
                await SuppressDiagnosticsAsync(diagnosticData, document, syntaxRoot, semanticModel, nodeWithDiagnostic);
            }
        }
コード例 #38
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));
        }
コード例 #39
0
            static async Task UpdateDocument(ConcurrentDictionary <DocumentId, List <DeclaredSymbolInfo> > result, Microsoft.CodeAnalysis.Document document, CancellationToken cancellationToken)
            {
                var root = await document.GetSyntaxRootAsync(cancellationToken).ConfigureAwait(false);

                var infos = new List <DeclaredSymbolInfo> ();

                foreach (var current in root.DescendantNodesAndSelf(CSharpSyntaxFactsService.DescentIntoSymbolForDeclarationSearch))
                {
                    cancellationToken.ThrowIfCancellationRequested();
                    DeclaredSymbolInfo declaredSymbolInfo;
                    if (current.TryGetDeclaredSymbolInfo(out declaredSymbolInfo))
                    {
                        declaredSymbolInfo.Document = document;
                        infos.Add(declaredSymbolInfo);
                    }
                }
                RemoveDocument(result, document.Id);
                result.TryAdd(document.Id, infos);
            }
コード例 #40
0
 // Helpers/Refactoring
 private static async Task GetRefactoringActionsAsync(CodeRefactoringProvider refactorer, Document document, List <CodeAction> actions, CancellationToken cancellationToken)
 {
     var root    = await document.GetSyntaxRootAsync(cancellationToken).ConfigureAwait(false) ?? throw new Exception("Document is not found");;
     var context = new CodeRefactoringContext(document, root.FullSpan, action => actions.Add(action), cancellationToken);
     await refactorer.ComputeRefactoringsAsync(context).ConfigureAwait(false);
 }
コード例 #41
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);
            }
        }
コード例 #42
0
        private async Task CommandCallbackAsync()
        {
            IWpfTextView textView = await ServiceProvider.GetWpfTextViewAsync();

            if (textView == null || Package.DisposalToken.IsCancellationRequested)
            {
                return;
            }

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

            if (caretLine == null)
            {
                return;
            }

            Document document = caretPosition.Snapshot.GetOpenDocumentInCurrentContextWithChanges();

            if (document == null || Package.DisposalToken.IsCancellationRequested)
            {
                return;
            }

            Task <SyntaxNode>    syntaxRootTask    = document.GetSyntaxRootAsync();
            Task <SemanticModel> semanticModelTask = document.GetSemanticModelAsync();
            await Task.WhenAll(syntaxRootTask, semanticModelTask);

                        #pragma warning disable VSTHRD002, VSTHRD103 // Avoid problematic synchronous waits - the results are already obtained
            SyntaxNode    syntaxRoot    = syntaxRootTask.Result;
            SemanticModel semanticModel = semanticModelTask.Result;
                        #pragma warning restore VSTHRD002, VSTHRD103

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

            TextSpan lineSpan = TextSpan.FromBounds(caretLine.Start.Position, caretLine.End.Position);

            if (!(syntaxRoot.FindNode(lineSpan) is MemberDeclarationSyntax memberNode))
            {
                return;
            }

            PXContext context = new PXContext(semanticModel.Compilation, Acuminator.Utilities.CodeAnalysisSettings.Default);

            if (!context.IsPlatformReferenced || Package.DisposalToken.IsCancellationRequested)
            {
                return;
            }

            ISymbol memberSymbol = GetMemberSymbol(memberNode, semanticModel, caretPosition);

            if (!CheckMemberSymbol(memberSymbol, context))
            {
                return;
            }

            await NavigateToHandlerOrDeclarationAsync(document, textView, memberSymbol, memberNode, semanticModel, context);
        }
コード例 #43
0
        private async Task AddNamespaces(Project project, MSDocument msDocument)
        {
            // We use the syntax tree to find all declareded classes inside this dockument
            var syntaxRoot = await msDocument.GetSyntaxRootAsync();

            // We need the semanic model to query some informations of nodes
            var semanticModel = await msDocument.GetSemanticModelAsync();

            var referencedNamespaces = GetRelatedNamespaces(syntaxRoot, semanticModel);

            // Use the syntax tree to get all namepace definitions inside
            var namespaces = syntaxRoot.DescendantNodesAndSelf().OfType <NamespaceDeclarationSyntax>();

            foreach (var namespaceDeclarationSyntax in namespaces)
            {
                // Get the symbol for namespace from model to get full name of namespace
                var namespaceSymbol = semanticModel.GetDeclaredSymbol(namespaceDeclarationSyntax);

                var namespaceName = namespaceSymbol.ToDisplayString(SymbolDisplayFormat.CSharpErrorMessageFormat);

                // Check for exisiting namespace
                var @namespace = project.Namespaces.FirstOrDefault(x => x.Name.Equals(namespaceName));
                if (@namespace == null)
                {
                    @namespace = new Namespace(Guid.NewGuid(), namespaceName, project);
                    project.Namespaces.Add(@namespace);
                    _namespaceToNamespaceMapping.Add(@namespace, referencedNamespaces);
                }
                else
                {
                    _namespaceToNamespaceMapping[@namespace] = _namespaceToNamespaceMapping[@namespace]
                                                               .Union(referencedNamespaces).ToList();
                }

                // Use the syntax tree to get all classes declarations inside
                var classes = namespaceDeclarationSyntax.DescendantNodes().OfType <ClassDeclarationSyntax>();

                // Handle each class declaration inside the namespace
                foreach (var classDeclaration in classes)
                {
                    var symbol            = semanticModel.GetDeclaredSymbol(classDeclaration);
                    var baseList          = classDeclaration.BaseList;
                    var referencedClasses = GetReturnType(baseList, semanticModel);

                    CreateClass(classDeclaration, symbol, @namespace, referencedClasses, referencedNamespaces,
                                semanticModel, msDocument.FilePath);
                }

                // Use the syntax tree to get all interface declations inside
                var interfaces = namespaceDeclarationSyntax.DescendantNodes().OfType <InterfaceDeclarationSyntax>();

                foreach (var interfaceDeclaration in interfaces)
                {
                    var symbol            = semanticModel.GetDeclaredSymbol(interfaceDeclaration);
                    var baseList          = interfaceDeclaration.BaseList;
                    var referencedClasses = GetReturnType(baseList, semanticModel);

                    CreateClass(interfaceDeclaration, symbol, @namespace, referencedClasses, referencedNamespaces,
                                semanticModel, msDocument.FilePath);
                }
            }
        }
コード例 #44
0
        /// <summary>
        /// This function is the callback used to execute the command when the menu item is clicked.
        /// See the constructor to see how the menu item is associated with this function using
        /// OleMenuCommandService service and MenuCommand class.
        /// </summary>
        /// <param name="sender">Event sender.</param>
        /// <param name="e">Event args.</param>
#pragma warning disable VSTHRD100 // Avoid async void methods
        private async void MenuItemCallback(object sender, EventArgs e)
#pragma warning restore VSTHRD100 // Avoid async void methods
        {
            try
            {
                await ThreadHelper.JoinableTaskFactory.SwitchToMainThreadAsync();

                _statusBar.SetText("");
                var dnSpyPath    = ReadDnSpyPath()?.Trim(_pathTrimChars);
                var loadPrevious = ReadLoadPrevious();
                if (string.IsNullOrWhiteSpace(dnSpyPath))
                {
                    MessageBox.Show("You must specify dnSpy path in options", "[GoToDnSpy] Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    return;
                }

                if (!File.Exists(dnSpyPath))
                {
                    MessageBox.Show($"File '{dnSpyPath}' doesn't exist!", "[GoToDnSpy] Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    return;
                }

                var textView = GetTextView();
                if (textView == null)
                {
                    _statusBar.SetText("Can't get a text view, please open the file and execute the command while a document window is active.");
                    return;
                }
                SnapshotPoint caretPosition = textView.Caret.Position.BufferPosition;
                Microsoft.CodeAnalysis.Document document = caretPosition.Snapshot.GetOpenDocumentInCurrentContextWithChanges();
                if (document == null)
                {
                    _statusBar.SetText("You should execute the command while a document window is active.");
                    return;
                }

                SyntaxNode rootSyntaxNode = await document.GetSyntaxRootAsync().ConfigureAwait(true);

                SyntaxToken   st            = rootSyntaxNode.FindToken(caretPosition);
                SemanticModel semanticModel = await document.GetSemanticModelAsync().ConfigureAwait(true);

                ISymbol symbol     = null;
                var     parentKind = st.Parent.Kind();
                if (st.Kind() == SyntaxKind.IdentifierToken && (
                        parentKind == SyntaxKind.PropertyDeclaration ||
                        parentKind == SyntaxKind.FieldDeclaration ||
                        parentKind == SyntaxKind.MethodDeclaration ||
                        parentKind == SyntaxKind.NamespaceDeclaration ||
                        parentKind == SyntaxKind.DestructorDeclaration ||
                        parentKind == SyntaxKind.ConstructorDeclaration ||
                        parentKind == SyntaxKind.OperatorDeclaration ||
                        parentKind == SyntaxKind.ConversionOperatorDeclaration ||
                        parentKind == SyntaxKind.EnumDeclaration ||
                        parentKind == SyntaxKind.EnumMemberDeclaration ||
                        parentKind == SyntaxKind.ClassDeclaration ||
                        parentKind == SyntaxKind.EventDeclaration ||
                        parentKind == SyntaxKind.EventFieldDeclaration ||
                        parentKind == SyntaxKind.InterfaceDeclaration ||
                        parentKind == SyntaxKind.StructDeclaration ||
                        parentKind == SyntaxKind.DelegateDeclaration ||
                        parentKind == SyntaxKind.IndexerDeclaration ||
                        parentKind == SyntaxKind.VariableDeclarator
                        ))
                {
                    symbol = semanticModel.LookupSymbols(caretPosition.Position, name: st.Text).FirstOrDefault();
                }
                else
                {
                    SymbolInfo si = semanticModel.GetSymbolInfo(st.Parent);
                    symbol = si.Symbol ?? si.CandidateSymbols.FirstOrDefault();
                }

                TryPreprocessLocal(ref symbol);

                string memberName = null;

                MemberType memberType = 0;

                // todo: view SLaks.Ref12.Services.RoslynSymbolResolver
                if (symbol == null || (
                        (!TryHandleAsType(symbol, out INamedTypeSymbol typeSymbol)) &&
                        (!TryHandleAsMember(symbol, out typeSymbol, out memberName, out memberType))
                        ))
                {
                    var msg = $"{st.Text} is not a valid identifier. token: {st}, Kind: {st.Kind()}";
                    _statusBar.SetText(msg);
                    Debug.WriteLine(msg);
                    return;
                }

                string typeNamespace = GetFullNamespace(typeSymbol);
                string typeName      = typeNamespace + "." + typeSymbol.MetadataName;
                string asmDef        = GetAssemblyDefinition(typeSymbol.ContainingAssembly);
                string asmPath       = GetAssemblyPath(semanticModel, asmDef);

                if (string.IsNullOrWhiteSpace(asmPath))
                {
                    _statusBar.SetText($"Assembly '{asmDef}' with type {typeName} not found;");
                    return;
                }
                else if (!File.Exists(asmPath))
                {
                    MessageBox.Show($"Try build project first;\nAssembly '{asmDef}' with type {typeName} not found, path:\n{asmPath}", "[GoToDnSpy] Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    return;
                }
                // for netstandard path will be c:\▮▮▮▮\dotnet\sdk\packs\NETStandard.Library.Ref\2.1.0\ref\netstandard2.1\
                // also can be with netstandard.library (via nupkg)
                if (asmPath.IndexOf("NETStandard.Library.Ref", StringComparison.Ordinal) > 0 ||
                    asmPath.IndexOf("netstandard.library", StringComparison.Ordinal) > 0 ||
                    asmPath.IndexOf("microsoft.netcore.app.ref", StringComparison.Ordinal) > 0)
                {
                    const string baseUrl      = "https://source.dot.net";
                    var          docId        = GetDocumentationCommentId(memberName is null ? typeSymbol : symbol);
                    var          assemblyName = NetstandardMapper.Get(typeNamespace, typeName);
                    if (assemblyName != null)
                    {
                        var url = baseUrl + "/" + assemblyName + "/a.html#" + GetMD5Hash(docId, 16);
                        System.Diagnostics.Process.Start(new ProcessStartInfo()
                        {
                            UseShellExecute = true,
                            FileName        = url,
                        });
                        return;
                    }
                }
                System.Diagnostics.Process.Start(dnSpyPath, BuildDnSpyArguments(asmPath, typeName, memberName, memberType, loadPrevious));
            }
            catch (Exception ex)
            {
                _statusBar.SetText(ex.Message);
                MessageBox.Show($"Some error in GoToDnSpy extensiton.\n Please take a screenshot and create issue on github with this error\n{ex}", "[GoToDnSpy] Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }
コード例 #45
0
ファイル: GoToDnSpy.cs プロジェクト: xuan2261/GoToDnSpy
        /// <summary>
        /// This function is the callback used to execute the command when the menu item is clicked.
        /// See the constructor to see how the menu item is associated with this function using
        /// OleMenuCommandService service and MenuCommand class.
        /// </summary>
        /// <param name="sender">Event sender.</param>
        /// <param name="e">Event args.</param>
        private void MenuItemCallback(object sender, EventArgs e)
        {
            ThreadHelper.ThrowIfNotOnUIThread();
            try
            {
                _statusBar.SetText("");
                var dnSpyPath = ReadDnSpyPath()?.Trim(new [] { '\r', '\n', ' ', '\'', '\"' });
                if (string.IsNullOrWhiteSpace(dnSpyPath))
                {
                    MessageBox.Show("Set dnSpy path in options first!", "[GoToDnSpy] Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    return;
                }

                if (!File.Exists(dnSpyPath))
                {
                    MessageBox.Show($"File '{dnSpyPath}' not exists!", "[GoToDnSpy] Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    return;
                }

                var textView = GetTextView();
                if (textView == null)
                {
                    _statusBar.SetText("Can't get text view, please open the file and execute the function while a document window is active.");
                    return;
                }
                SnapshotPoint caretPosition = textView.Caret.Position.BufferPosition;
                Microsoft.CodeAnalysis.Document document = caretPosition.Snapshot.GetOpenDocumentInCurrentContextWithChanges();
                if (document == null)
                {
                    _statusBar.SetText("Execute the function while a document window is active.");
                    return;
                }

                SyntaxNode    rootSyntaxNode = ThreadHelper.JoinableTaskFactory.Run(() => document.GetSyntaxRootAsync());
                SyntaxToken   st             = rootSyntaxNode.FindToken(caretPosition);
                SemanticModel semanticModel  = ThreadHelper.JoinableTaskFactory.Run(() => document.GetSemanticModelAsync());

                ISymbol symbol     = null;
                var     parentKind = st.Parent.Kind();
                if (st.Kind() == SyntaxKind.IdentifierToken && (
                        parentKind == SyntaxKind.PropertyDeclaration ||
                        parentKind == SyntaxKind.FieldDeclaration ||
                        parentKind == SyntaxKind.MethodDeclaration ||
                        parentKind == SyntaxKind.NamespaceDeclaration ||
                        parentKind == SyntaxKind.DestructorDeclaration ||
                        parentKind == SyntaxKind.ConstructorDeclaration ||
                        parentKind == SyntaxKind.OperatorDeclaration ||
                        parentKind == SyntaxKind.ConversionOperatorDeclaration ||
                        parentKind == SyntaxKind.EnumDeclaration ||
                        parentKind == SyntaxKind.EnumMemberDeclaration ||
                        parentKind == SyntaxKind.ClassDeclaration ||
                        parentKind == SyntaxKind.EventDeclaration ||
                        parentKind == SyntaxKind.EventFieldDeclaration ||
                        parentKind == SyntaxKind.InterfaceDeclaration ||
                        parentKind == SyntaxKind.StructDeclaration ||
                        parentKind == SyntaxKind.DelegateDeclaration ||
                        parentKind == SyntaxKind.IndexerDeclaration ||
                        parentKind == SyntaxKind.VariableDeclarator
                        ))
                {
                    symbol = semanticModel.LookupSymbols(caretPosition.Position, name: st.Text).FirstOrDefault();
                }
                else
                {
                    SymbolInfo si = semanticModel.GetSymbolInfo(st.Parent);
                    symbol = si.Symbol ?? (si.GetType().GetProperty("CandidateSymbols").GetValue(si) as IEnumerable <ISymbol>)?.FirstOrDefault();
                }

                TryPreprocessLocal(ref symbol);

                string memberName = null;

                MemberType memberType = 0;

                // todo: view SLaks.Ref12.Services.RoslynSymbolResolver
                if (symbol == null || (
                        (!TryHandleAsType(symbol, out INamedTypeSymbol typeSymbol)) &&
                        (!TryHandleAsMember(symbol, out typeSymbol, out memberName, out memberType))
                        ))
                {
                    var msg = $"{st.Text} is not a valid identifier. token: {st.ToString()}, Kind: {st.Kind()}";
                    _statusBar.SetText(msg);
                    Debug.WriteLine(msg);
                    return;
                }

                string typeNamespace = GetFullNamespace(typeSymbol);
                string typeName      = typeNamespace + "." + typeSymbol.MetadataName;
                string asmDef        = GetAssemblyDefinition(typeSymbol.ContainingAssembly);
                string asmPath       = GetAssemblyPath(semanticModel, asmDef);

                if (string.IsNullOrWhiteSpace(asmPath))
                {
                    _statusBar.SetText($"Assembly '{asmDef}' with type {typeName} not found;");
                    return;
                }
                else if (!File.Exists(asmPath))
                {
                    MessageBox.Show($"Try build project first;\nAssembly '{asmDef}' with type {typeName} not found, path:\n{asmPath}", "[GoToDnSpy] Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    return;
                }

                System.Diagnostics.Process.Start(dnSpyPath, BuildDnSpyArguments(asmPath, typeName, memberName, memberType));
            }
            catch (Exception ex)
            {
                _statusBar.SetText(ex.Message.ToString());
                MessageBox.Show($"Some error in GoToDnSpy extensiton.\n Please take screenshot and create issue on github with this error\n{ex.ToString()}", "[GoToDnSpy] Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }