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)) };
		}
		protected override bool TryInitializeState(
			Document document, SemanticModel model, SyntaxNode node, CancellationToken cancellationToken,
			out INamedTypeSymbol classType, out INamedTypeSymbol abstractClassType)
		{
			var baseClassNode = node as TypeSyntax;
			if (baseClassNode != null && baseClassNode.Parent is BaseTypeSyntax &&
				baseClassNode.Parent.IsParentKind(SyntaxKind.BaseList) &&
				((BaseTypeSyntax)baseClassNode.Parent).Type == baseClassNode)
			{
				if (baseClassNode.Parent.Parent.IsParentKind(SyntaxKind.ClassDeclaration))
				{
					abstractClassType = model.GetTypeInfo(baseClassNode, cancellationToken).Type as INamedTypeSymbol;
					cancellationToken.ThrowIfCancellationRequested();

					if (abstractClassType.IsAbstractClass())
					{
						var classDecl = baseClassNode.Parent.Parent.Parent as ClassDeclarationSyntax;
						classType = model.GetDeclaredSymbol(classDecl, cancellationToken) as INamedTypeSymbol;

						return classType != null && abstractClassType != null;
					}
				}
			}

			classType = null;
			abstractClassType = null;
			return false;
		}
예제 #3
1
        private static async Task<Document> MakeMock(Document document, SyntaxNode invokationSyntax,
            CancellationToken cancellationToken)
        {
            var testSemanticModel = await document.GetSemanticModelAsync(cancellationToken).ConfigureAwait(false);

            var testInitMethodDecl = TestSemanticHelper.GetTestInitializeMethod(testSemanticModel);

            var declaredFields = testInitMethodDecl.Parent.ChildNodes().OfType<FieldDeclarationSyntax>().ToArray();

            var suts = testInitMethodDecl.GetSuts(testSemanticModel, declaredFields);

            var memberAccessExpressions = invokationSyntax.DescendantNodes()
                .OfType<ExpressionSyntax>()
                .Where(x => x is InvocationExpressionSyntax || x is MemberAccessExpressionSyntax)
                .Select(expr =>
                {
                    var memberAccess = expr as MemberAccessExpressionSyntax;
                    var invokationExpression = expr as InvocationExpressionSyntax;
                    var expression = invokationExpression == null ? memberAccess : invokationExpression.Expression;
                    return expression;
                });

            var invokedMethodsOfMocks = memberAccessExpressions.SelectMany(expressionSyntax => MocksAnalyzingEngine.GetInvokedMethodsOfMock(expressionSyntax, testSemanticModel, suts))
                                                               .DistinctBy(x => string.Join(",", x.FieldsToSetup.SelectMany(y => y.Field.Select(z => z))) + "," + x.MethodOrPropertySymbol)
                                                               .ToArray();

            if (invokedMethodsOfMocks.Length == 0)
                return document;

            var editor = await DocumentEditor.CreateAsync(document, cancellationToken).ConfigureAwait(false);

            ChangesMaker.ApplyChanges(invokationSyntax, editor, invokedMethodsOfMocks);

            return editor.GetChangedDocument();
        }
 private static Solution UpdateMainDocument(Document document, SyntaxNode root, MethodDeclarationSyntax method, IEnumerable<IGrouping<Document, ReferenceLocation>> documentGroups)
 {
     var mainDocGroup = documentGroups.FirstOrDefault(dg => dg.Key.Equals(document));
     SyntaxNode newRoot;
     if (mainDocGroup == null)
     {
         newRoot = root.ReplaceNode(method, method.AddModifiers(staticToken));
     }
     else
     {
         var diagnosticNodes = mainDocGroup.Select(referenceLocation => root.FindNode(referenceLocation.Location.SourceSpan)).ToList();
         newRoot = root.TrackNodes(diagnosticNodes.Union(new[] { method }));
         newRoot = newRoot.ReplaceNode(newRoot.GetCurrentNode(method), method.AddModifiers(staticToken));
         foreach (var diagnosticNode in diagnosticNodes)
         {
             var token = newRoot.FindToken(diagnosticNode.GetLocation().SourceSpan.Start);
             var tokenParent = token.Parent;
             if (token.Parent.IsKind(SyntaxKind.IdentifierName)) continue;
             var invocationExpression = newRoot.GetCurrentNode(diagnosticNode).FirstAncestorOrSelfOfType<InvocationExpressionSyntax>()?.Expression;
             if (invocationExpression == null || invocationExpression.IsKind(SyntaxKind.IdentifierName)) continue;
             var memberAccess = invocationExpression as MemberAccessExpressionSyntax;
             if (memberAccess == null) continue;
             var newMemberAccessParent = memberAccess.Parent.ReplaceNode(memberAccess, memberAccess.Name)
                 .WithAdditionalAnnotations(Formatter.Annotation);
             newRoot = newRoot.ReplaceNode(memberAccess.Parent, newMemberAccessParent);
         }
     }
     var newSolution = document.Project.Solution.WithDocumentSyntaxRoot(document.Id, newRoot);
     return newSolution;
 }
        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;
        }
            protected override async Task<SyntaxNode> FixAllInDocumentAsync(FixAllContext fixAllContext, Document document)
            {
                var diagnostics = await fixAllContext.GetDocumentDiagnosticsAsync(document).ConfigureAwait(false);
                if (diagnostics.IsEmpty)
                {
                    return null;
                }

                SyntaxNode syntaxRoot = await document.GetSyntaxRootAsync().ConfigureAwait(false);
                List<SyntaxNode> nodesNeedingQualification = new List<SyntaxNode>(diagnostics.Length);

                foreach (Diagnostic diagnostic in diagnostics)
                {
                    var node = syntaxRoot.FindNode(diagnostic.Location.SourceSpan, false, true) as SimpleNameSyntax;
                    if (node == null || node.IsMissing)
                    {
                        continue;
                    }

                    nodesNeedingQualification.Add(node);
                }

                return syntaxRoot.ReplaceNodes(nodesNeedingQualification, (originalNode, rewrittenNode) =>
                SyntaxFactory.MemberAccessExpression(SyntaxKind.SimpleMemberAccessExpression, ThisExpressionSyntax, (SimpleNameSyntax)rewrittenNode.WithoutTrivia().WithoutFormatting())
                .WithTriviaFrom(rewrittenNode)
                .WithoutFormatting());
            }
        protected override async Task<SyntaxNode> FixAllInDocumentAsync(FixAllContext fixAllContext, Document document)
        {
            var diagnostics = await fixAllContext.GetDocumentDiagnosticsAsync(document).ConfigureAwait(false);
            if (diagnostics.IsEmpty)
            {
                return null;
            }

            DocumentEditor editor = await DocumentEditor.CreateAsync(document, fixAllContext.CancellationToken).ConfigureAwait(false);

            SyntaxNode root = editor.GetChangedRoot();

            ImmutableList<SyntaxNode> nodesToChange = ImmutableList.Create<SyntaxNode>();

            // Make sure all nodes we care about are tracked
            foreach (var diagnostic in diagnostics)
            {
                var location = diagnostic.Location;
                var syntaxNode = root.FindNode(location.SourceSpan);
                if (syntaxNode != null)
                {
                    editor.TrackNode(syntaxNode);
                    nodesToChange = nodesToChange.Add(syntaxNode);
                }
            }

            foreach (var node in nodesToChange)
            {
                editor.ReplaceNode(node, node.WithLeadingTrivia(SyntaxFactory.ElasticCarriageReturnLineFeed));
            }

            return editor.GetChangedRoot();
        }
        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);
        }
 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;
 }
        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 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);
        }
        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);
        }
        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;
        }
        private static async Task<Document> GetTransformedDocumentAsync(Document document, Diagnostic diagnostic, CancellationToken token)
        {
            var sourceText = await document.GetTextAsync(token).ConfigureAwait(false);

            var startIndex = sourceText.Lines.IndexOf(diagnostic.Location.SourceSpan.Start);
            int endIndex = startIndex;

            for (var i = startIndex + 1; i < sourceText.Lines.Count; i++)
            {
                if (!string.IsNullOrWhiteSpace(sourceText.Lines[i].ToString()))
                {
                    endIndex = i - 1;
                    break;
                }
            }

            if (endIndex >= (startIndex + 1))
            {
                var replaceSpan = TextSpan.FromBounds(sourceText.Lines[startIndex + 1].SpanIncludingLineBreak.Start, sourceText.Lines[endIndex].SpanIncludingLineBreak.End);
                var newSourceText = sourceText.Replace(replaceSpan, string.Empty);
                return document.WithText(newSourceText);
            }

            return document;
        }
        /// <summary>
        /// Given an analyzer and a document to apply it to, run the analyzer and gather an array of diagnostics found in it.
        /// The returned diagnostics are then ordered by location in the source document.
        /// </summary>
        /// <param name="analyzer">The analyzer to run on the documents</param>
        /// <param name="documents">The Documents that the analyzer will be run on</param>
        /// <returns>An IEnumerable of Diagnostics that surfaced in the source code, sorted by Location</returns>
        protected static Diagnostic[] GetSortedDiagnosticsFromDocuments(DiagnosticAnalyzer analyzer, Document[] documents)
        {
            var projects = new HashSet<Project>();
            foreach (var document in documents) {
                projects.Add(document.Project);
            }

            var diagnostics = new List<Diagnostic>();
            foreach (var project in projects) {
                var compilationWithAnalyzers = project.GetCompilationAsync().Result.WithAnalyzers(ImmutableArray.Create(analyzer));
                var diags = compilationWithAnalyzers.GetAnalyzerDiagnosticsAsync().Result;
                foreach (var diag in diags) {
                    if (diag.Location == Location.None || diag.Location.IsInMetadata) {
                        diagnostics.Add(diag);
                    }
                    else {
                        for (int i = 0; i < documents.Length; i++) {
                            var document = documents[i];
                            var tree = document.GetSyntaxTreeAsync().Result;
                            if (tree == diag.Location.SourceTree) {
                                diagnostics.Add(diag);
                            }
                        }
                    }
                }
            }

            var results = SortDiagnostics(diagnostics);
            diagnostics.Clear();
            return results;
        }
        /// <summary>
        /// Given an analyzer and a collection of documents to apply it to, run the analyzer and gather an array of
        /// diagnostics found. The returned diagnostics are then ordered by location in the source documents.
        /// </summary>
        /// <param name="analyzers">The analyzer to run on the documents.</param>
        /// <param name="documents">The <see cref="Document"/>s that the analyzer will be run on.</param>
        /// <param name="cancellationToken">The <see cref="CancellationToken"/> that the task will observe.</param>
        /// <returns>A collection of <see cref="Diagnostic"/>s that surfaced in the source code, sorted by
        /// <see cref="Diagnostic.Location"/>.</returns>
        protected static async Task<ImmutableArray<Diagnostic>> GetSortedDiagnosticsFromDocumentsAsync(ImmutableArray<DiagnosticAnalyzer> analyzers, Document[] documents, CancellationToken cancellationToken)
        {
            var projects = new HashSet<Project>();
            foreach (var document in documents)
            {
                projects.Add(document.Project);
            }

            var supportedDiagnosticsSpecificOptions = new Dictionary<string, ReportDiagnostic>();
            foreach (var analyzer in analyzers)
            {
                foreach (var diagnostic in analyzer.SupportedDiagnostics)
                {
                    // make sure the analyzers we are testing are enabled
                    supportedDiagnosticsSpecificOptions[diagnostic.Id] = ReportDiagnostic.Default;
                }
            }

            // Report exceptions during the analysis process as errors
            supportedDiagnosticsSpecificOptions.Add("AD0001", ReportDiagnostic.Error);

            var diagnostics = ImmutableArray.CreateBuilder<Diagnostic>();
            foreach (var project in projects)
            {
                // update the project compilation options
                var modifiedSpecificDiagnosticOptions = supportedDiagnosticsSpecificOptions.ToImmutableDictionary().SetItems(project.CompilationOptions.SpecificDiagnosticOptions);
                var modifiedCompilationOptions = project.CompilationOptions.WithSpecificDiagnosticOptions(modifiedSpecificDiagnosticOptions);
                var processedProject = project.WithCompilationOptions(modifiedCompilationOptions);

                var compilation = await processedProject.GetCompilationAsync(cancellationToken).ConfigureAwait(false);
                var compilationWithAnalyzers = compilation.WithAnalyzers(analyzers, processedProject.AnalyzerOptions, cancellationToken);
                var compilerDiagnostics = compilation.GetDiagnostics(cancellationToken);
                var compilerErrors = compilerDiagnostics.Where(i => i.Severity == DiagnosticSeverity.Error);
                var diags = await compilationWithAnalyzers.GetAnalyzerDiagnosticsAsync().ConfigureAwait(false);
                var allDiagnostics = await compilationWithAnalyzers.GetAllDiagnosticsAsync().ConfigureAwait(false);
                var failureDiagnostics = allDiagnostics.Where(diagnostic => diagnostic.Id == "AD0001");
                foreach (var diag in diags.Concat(compilerErrors).Concat(failureDiagnostics))
                {
                    if (diag.Location == Location.None || diag.Location.IsInMetadata)
                    {
                        diagnostics.Add(diag);
                    }
                    else
                    {
                        for (int i = 0; i < documents.Length; i++)
                        {
                            var document = documents[i];
                            var tree = await document.GetSyntaxTreeAsync(cancellationToken).ConfigureAwait(false);
                            if (tree == diag.Location.SourceTree)
                            {
                                diagnostics.Add(diag);
                            }
                        }
                    }
                }
            }

            var results = SortDistinctDiagnostics(diagnostics);
            return results.ToImmutableArray();
        }
        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);

        }
예제 #18
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);
        }
        private bool TryGetDocumentWithFullyQualifiedTypeName(Document document, out TextSpan updatedTextSpan, out Document documentWithFullyQualifiedTypeName)
        {
            documentWithFullyQualifiedTypeName = null;
            updatedTextSpan = default(TextSpan);

            var surfaceBufferFieldSpan = new VsTextSpan[1];
            if (snippetExpansionClient.ExpansionSession.GetFieldSpan(_fieldName, surfaceBufferFieldSpan) != VSConstants.S_OK)
            {
                return false;
            }

            if (!snippetExpansionClient.TryGetSubjectBufferSpan(surfaceBufferFieldSpan[0], out var subjectBufferFieldSpan))
            {
                return false;
            }

            var originalTextSpan = new TextSpan(subjectBufferFieldSpan.Start, subjectBufferFieldSpan.Length);
            updatedTextSpan = new TextSpan(subjectBufferFieldSpan.Start, _fullyQualifiedName.Length);

            var textChange = new TextChange(originalTextSpan, _fullyQualifiedName);
            var newText = document.GetTextAsync(CancellationToken.None).WaitAndGetResult(CancellationToken.None).WithChanges(textChange);

            documentWithFullyQualifiedTypeName = document.WithText(newText);
            return true;
        }
        protected override int GetAdjustedContextPoint(int contextPoint, Document document)
        {
            // Determine the position in the buffer at which to end the tracking span representing
            // the part of the imaginary buffer before the text in the view. 
            var tree = document.GetSyntaxTreeSynchronously(CancellationToken.None);
            var token = tree.FindTokenOnLeftOfPosition(contextPoint, CancellationToken.None);

            // Special case to handle class designer because it asks for debugger IntelliSense using
            // spans between members.
            if (contextPoint > token.Span.End &&
                token.IsKindOrHasMatchingText(SyntaxKind.CloseBraceToken) &&
                token.Parent.IsKind(SyntaxKind.Block) &&
                token.Parent.Parent is MemberDeclarationSyntax)
            {
                return contextPoint;
            }

            if (token.IsKindOrHasMatchingText(SyntaxKind.CloseBraceToken) &&
                token.Parent.IsKind(SyntaxKind.Block))
            {
                return token.SpanStart;
            }

            return token.FullSpan.End;
        }
예제 #21
0
		public static SyntaxTree GetSyntaxTreeSynchronously(Document document, CancellationToken cancellationToken) {
			//TODO: Roslyn 2.0: use document.GetSyntaxTreeSynchronously()
			SyntaxTree syntaxTree;
			if (document.TryGetSyntaxTree(out syntaxTree))
				return syntaxTree;
			return document.GetSyntaxTreeAsync(cancellationToken).GetAwaiter().GetResult();
		}
        private static async Task<InconsistentAccessibilityInfo> GetInconsistentAccessibilityInfoAsync(Document document, Diagnostic diagnostic, CancellationToken cancellationToken)
        {
            InconsistentAccessibilityInfoProvider inconsistentAccessibilityProvider = null;

            switch (diagnostic.Id)
            {
                case InconsistentAccessibilityInMethodReturnTypeCompilerErrorNumber:
                    inconsistentAccessibilityProvider = new InconsistentAccessibilityInMethodReturnType();
                    break;
                case InconsistentAccessibilityInMethodParameterCompilerErrorNumber:
                    inconsistentAccessibilityProvider = new InconsistentAccessibilityInMethodParameter();
                    break;
                case InconsistentAccessibilityInFieldTypeCompilerErrorNumber:
                    inconsistentAccessibilityProvider = new InconsistentAccessibilityInFieldType();
                    break;
                case InconsistentAccessibilityInPropertyTypeCompilerErrorNumber:
                    inconsistentAccessibilityProvider = new InconsistentAccessibilityInPropertyType();
                    break;
                case InconsistentAccessibilityInIndexerReturnTypeCompilerErrorNumber:
                    inconsistentAccessibilityProvider = new InconsistentAccessibilityInIndexerReturnType();
                    break;
                case InconsistentAccessibilityInIndexerParameterCompilerErrorNumber:
                    inconsistentAccessibilityProvider = new InconsistentAccessibilityInIndexerParameter();
                    break;
            }

            return await inconsistentAccessibilityProvider.GetInconsistentAccessibilityInfoAsync(document, diagnostic, cancellationToken).ConfigureAwait(false);
        }
        private async Task<Document> RebuildClassAsync(Document document, ClassDeclarationSyntax classDeclaration, CancellationToken cancellationToken)
        {

            var newImplementation = @"
	private bool _isEnabled;

	private readonly Action _handler;
	public RelayCommand(Action handler)
	{
		_handler = handler;
	}

	public event EventHandler CanExecuteChanged;

	public bool IsEnabled {
		get { return _isEnabled; }
		set {
			if ((value != _isEnabled)) {
				_isEnabled = value;
				if (CanExecuteChanged != null) {
					CanExecuteChanged(this, EventArgs.Empty);
				}
			}
		}
	}

	public bool CanExecute(object parameter)
	{
		return IsEnabled;
	}

	public void Execute(object parameter)
	{
		_handler();
	}
";

            var newClassTree = SyntaxFactory.ParseSyntaxTree(newImplementation).
        GetRoot().DescendantNodes().
        Where(n => n.IsKind(SyntaxKind.FieldDeclaration) || n.IsKind(SyntaxKind.MethodDeclaration) || n.IsKind(SyntaxKind.PropertyDeclaration)
                || n.IsKind(SyntaxKind.ConstructorDeclaration) || n.IsKind(SyntaxKind.EventDeclaration) || n.IsKind(SyntaxKind.EventFieldDeclaration)).
        Cast<MemberDeclarationSyntax>().
        Select(decl => decl.WithAdditionalAnnotations(Formatter.Annotation, Simplifier.Annotation)).
        ToArray();


        ClassDeclarationSyntax newClassBlock = SyntaxFactory.ClassDeclaration("RelayCommand").AddTypeParameterListParameters(SyntaxFactory.TypeParameter("T")).WithOpenBraceToken(SyntaxFactory.ParseToken("{")).
                WithCloseBraceToken(SyntaxFactory.ParseToken("}").WithTrailingTrivia(SyntaxFactory.CarriageReturnLineFeed));

            newClassBlock = newClassBlock.AddBaseListTypes(SyntaxFactory.SimpleBaseType(SyntaxFactory.ParseTypeName("ICommand")));

            var newClassNode = newClassBlock.AddMembers(newClassTree);

            var root = await document.GetSyntaxRootAsync();

            var newRoot = root.ReplaceNode(classDeclaration, newClassNode);
            var newDocument = document.WithSyntaxRoot(newRoot);

            return newDocument;
        }
        private async Task<Document> ImplementOperatorEquals(Document document, SyntaxNode declaration, INamedTypeSymbol typeSymbol, CancellationToken cancellationToken)
        {
            DocumentEditor editor = await DocumentEditor.CreateAsync(document, cancellationToken).ConfigureAwait(false);
            var generator = editor.Generator;

            if (!typeSymbol.IsOperatorImplemented(WellKnownMemberNames.EqualityOperatorName))
            {
                var equalityOperator = GenerateOperatorDeclaration(generator.TypeExpression(SpecialType.System_Boolean),
                                                                   WellKnownMemberNames.EqualityOperatorName,
                                                                   new[]
                                                                   {
                                                                       generator.ParameterDeclaration("left", generator.TypeExpression(typeSymbol)),
                                                                       generator.ParameterDeclaration("right", generator.TypeExpression(typeSymbol)),
                                                                   },
                                                                   generator.ThrowStatement(generator.ObjectCreationExpression(generator.DottedName("System.NotImplementedException"))));
                editor.AddMember(declaration, equalityOperator);
            }

            if (!typeSymbol.IsOperatorImplemented(WellKnownMemberNames.InequalityOperatorName))
            {
                var inequalityOperator = GenerateOperatorDeclaration(generator.TypeExpression(SpecialType.System_Boolean),
                                                                   WellKnownMemberNames.InequalityOperatorName,
                                                                   new[]
                                                                   {
                                                                       generator.ParameterDeclaration("left", generator.TypeExpression(typeSymbol)),
                                                                       generator.ParameterDeclaration("right", generator.TypeExpression(typeSymbol)),
                                                                   },
                                                                   generator.ThrowStatement(generator.ObjectCreationExpression(generator.DottedName("System.NotImplementedException"))));
                editor.AddMember(declaration, inequalityOperator);
            }

            return editor.GetChangedDocument();

        }
 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);
 }
        public async Task<Document> AddSourceToAsync(Document document, ISymbol symbol, CancellationToken cancellationToken)
        {
            if (document == null)
            {
                throw new ArgumentNullException(nameof(document));
            }

            var newSemanticModel = await document.GetSemanticModelAsync(cancellationToken).ConfigureAwait(false);
            var rootNamespace = newSemanticModel.GetEnclosingNamespace(0, cancellationToken);

            // Add the interface of the symbol to the top of the root namespace
            document = await CodeGenerator.AddNamespaceOrTypeDeclarationAsync(
                document.Project.Solution,
                rootNamespace,
                CreateCodeGenerationSymbol(document, symbol),
                CreateCodeGenerationOptions(newSemanticModel.SyntaxTree.GetLocation(new TextSpan()), symbol),
                cancellationToken).ConfigureAwait(false);

            var docCommentFormattingService = document.GetLanguageService<IDocumentationCommentFormattingService>();
            var docWithDocComments = await ConvertDocCommentsToRegularComments(document, docCommentFormattingService, cancellationToken).ConfigureAwait(false);

            var docWithAssemblyInfo = await AddAssemblyInfoRegionAsync(docWithDocComments, symbol.GetOriginalUnreducedDefinition(), cancellationToken).ConfigureAwait(false);
            var node = await docWithAssemblyInfo.GetSyntaxRootAsync(cancellationToken).ConfigureAwait(false);
            var formattedDoc = await Formatter.FormatAsync(
                docWithAssemblyInfo, SpecializedCollections.SingletonEnumerable(node.FullSpan), options: null, rules: GetFormattingRules(docWithAssemblyInfo), cancellationToken: cancellationToken).ConfigureAwait(false);

            var reducers = this.GetReducers();
            return await Simplifier.ReduceAsync(formattedDoc, reducers, null, cancellationToken).ConfigureAwait(false);
        }
 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);
 }
 /// <summary>
 /// Given a document, turn it into a string based on the syntax root
 /// </summary>
 /// <param name="document">The Document to be converted to a string</param>
 /// <returns>A string containing the syntax of the Document after formatting</returns>
 private static string GetStringFromDocument(Document document)
 {
     var simplifiedDoc = Simplifier.ReduceAsync(document, Simplifier.Annotation).Result;
     var root = simplifiedDoc.GetSyntaxRootAsync().Result;
     root = Formatter.Format(root, Formatter.Annotation, simplifiedDoc.Project.Solution.Workspace);
     return root.GetText().ToString();
 }
 private async Task<Document> AddNonSerializedAttribute(Document document, SyntaxNode fieldNode, CancellationToken cancellationToken)
 {
     var editor = await DocumentEditor.CreateAsync(document, cancellationToken).ConfigureAwait(false);
     var attr = editor.Generator.Attribute(editor.Generator.TypeExpression(WellKnownTypes.NonSerializedAttribute(editor.SemanticModel.Compilation)));
     editor.AddAttribute(fieldNode, attr);
     return editor.GetChangedDocument();
 }
예제 #30
0
 private static string GetNewFilePath(Document document, TypeDeclarationSyntax declaration)
 {
     var oldFilePath = document.FilePath;
     var oldFileDirectory = Path.GetDirectoryName(document.FilePath);
     var newFilePath = Path.Combine(oldFileDirectory, declaration.Identifier.Text + ".cs");
     return newFilePath;
 }
 public DebuggerCompletionProvider(Document document, ITextBuffer textBuffer)
 {
     this.document   = document;
     this.textBuffer = textBuffer;
 }
예제 #32
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>
        private async void MenuItemCallback(object sender, EventArgs e)
        {
            try
            {
                var componentModel = (IComponentModel)Microsoft.VisualStudio.Shell.Package.GetGlobalService(typeof(SComponentModel));
                var workspace      = componentModel.GetService <VisualStudioWorkspace>();

                var selectedItem = this.GetSelectedSolutionExplorerItem();
                Microsoft.CodeAnalysis.Document doc = null;

                if (selectedItem != null && selectedItem.Name != null && !selectedItem.Name.EndsWith(".cs"))
                {
                    VsShellUtilities.ShowMessageBox(this.package, "Generate DTO action can only be invoked on CSharp files.", "Error",
                                                    OLEMSGICON.OLEMSGICON_WARNING,
                                                    OLEMSGBUTTON.OLEMSGBUTTON_OK,
                                                    OLEMSGDEFBUTTON.OLEMSGDEFBUTTON_FIRST);

                    return;
                }

                if (selectedItem?.Document != null)
                {
                    doc = workspace.CurrentSolution.GetDocumentByFilePath(selectedItem.Document.FullName);
                }
                else if (selectedItem != null)
                {
                    var file        = selectedItem.Name;
                    var projectName = selectedItem.ContainingProject.Name;

                    var docs = workspace.CurrentSolution.Projects
                               .Where(p => p.Name == projectName)
                               .SelectMany(p => p.Documents)
                               .Where(d => d.Name == file)
                               .ToList();

                    if (docs.Count == 0)
                    {
                        VsShellUtilities.ShowMessageBox(this.package, "Shitty exception - cannot get current selected solution item :/// . Try opening desired document, and then activating this command.", "Error",
                                                        OLEMSGICON.OLEMSGICON_WARNING,
                                                        OLEMSGBUTTON.OLEMSGBUTTON_OK,
                                                        OLEMSGDEFBUTTON.OLEMSGDEFBUTTON_FIRST);
                    }

                    if (docs.Count > 1)
                    {
                        VsShellUtilities.ShowMessageBox(this.package, "Multiple documents with same name exist - cannot get current selected solution item. Try opening desired document, and then activating this command.", "Error",
                                                        OLEMSGICON.OLEMSGICON_WARNING,
                                                        OLEMSGBUTTON.OLEMSGBUTTON_OK,
                                                        OLEMSGDEFBUTTON.OLEMSGDEFBUTTON_FIRST);
                    }

                    doc = docs.FirstOrDefault();
                }
                else
                {
                    VsShellUtilities.ShowMessageBox(this.package, "Shitty exception - cannot get current selected solution item :/// . Try opening desired document, and then activating this command.", "Error",
                                                    OLEMSGICON.OLEMSGICON_WARNING,
                                                    OLEMSGBUTTON.OLEMSGBUTTON_OK,
                                                    OLEMSGDEFBUTTON.OLEMSGDEFBUTTON_FIRST);

                    return;
                }
                var possibleProjects = doc.GetPossibleProjects();

                var vmBasic = BasicOptionsViewModel.Create(possibleProjects, doc.Name.Replace(".cs", ""), doc.Project.Solution.GetMostLikelyDtoLocation());
                var shouldProceed = new BasicOptionsWindow {
                    DataContext = vmBasic
                }.ShowModal();

                if (shouldProceed != true)
                {
                    return;
                }

                var existingDoc = doc.Project.Solution.GetDocumentByLocation(vmBasic.DtoLocation, vmBasic.DtoName);
                if (existingDoc != null)
                {
                    var result = VsShellUtilities.ShowMessageBox(this.package, "There is already a DTO class in the specified location. Press OK if you would like to regenerate it, or cancel to choose different name.", "Warninig - regenerate DTO?",
                                                                 OLEMSGICON.OLEMSGICON_WARNING,
                                                                 OLEMSGBUTTON.OLEMSGBUTTON_OKCANCEL,
                                                                 OLEMSGDEFBUTTON.OLEMSGDEFBUTTON_FIRST);

                    if (result != 1)
                    {
                        return;
                    }
                }

                var vm = await PropertySelectorViewModel.Create(doc, vmBasic.DtoName, vmBasic.DtoLocation, existingDto : existingDoc);

                var isConfirmed = new PropertySelectorWindow()
                {
                    DataContext = vm
                }.ShowModal();

                if (isConfirmed == true)
                {
                    var modifiedSolution = await doc.Project.Solution
                                           .WriteDto(vm.DtoLocation, vm.EntityModel.ConvertToMetadata(), vm.GenerateMapper, vm.AddDataContract, vm.AddDataAnnotations);

                    var changedDocIds = SolutionParser.GetDocumentIdsToOpen(modifiedSolution, workspace.CurrentSolution);

                    var ok = workspace.TryApplyChanges(modifiedSolution);

                    if (!ok)
                    {
                        VsShellUtilities.ShowMessageBox(this.package, "Unable to generate DTO. Please try again (could not apply changes).", "Error", OLEMSGICON.OLEMSGICON_WARNING, OLEMSGBUTTON.OLEMSGBUTTON_OK, OLEMSGDEFBUTTON.OLEMSGDEFBUTTON_FIRST);
                    }
                    else
                    {
                        foreach (var docId in changedDocIds)
                        {
                            try
                            {
                                workspace.OpenDocument(docId);
                            }
                            catch (Exception)
                            {
                                // Do nothing, unable to open the document.
                            }
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                try
                {
                    VsShellUtilities.ShowMessageBox(this.package, ex.Message, "An exception has occurred. Please c/p stack trace to project website (https://github.com/yohney/dto-generator), with brief description of the problem.",
                                                    OLEMSGICON.OLEMSGICON_WARNING,
                                                    OLEMSGBUTTON.OLEMSGBUTTON_OK,
                                                    OLEMSGDEFBUTTON.OLEMSGDEFBUTTON_FIRST);

                    var tmpFile = Path.GetTempFileName();

                    string stackTrace = "";

                    Exception tmp = ex;
                    while (tmp != null)
                    {
                        stackTrace += tmp.StackTrace;
                        stackTrace += "\n----------------------------\n\n";
                        tmp         = ex.InnerException;
                    }


                    File.WriteAllText(tmpFile, stackTrace);

                    VsShellUtilities.OpenBrowser("file:///" + tmpFile);
                }
                catch (Exception innerEx)
                {
                    VsShellUtilities.ShowMessageBox(this.package, innerEx.Message, "An exception has occurred. Unable to write stack trace to TEMP directory.",
                                                    OLEMSGICON.OLEMSGICON_WARNING,
                                                    OLEMSGBUTTON.OLEMSGBUTTON_OK,
                                                    OLEMSGDEFBUTTON.OLEMSGDEFBUTTON_FIRST);
                }
            }
        }
        /// <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 async void MenuItemCallback(object sender, EventArgs e)
        {
            try
            {
                var componentModel = (IComponentModel)Microsoft.VisualStudio.Shell.Package.GetGlobalService(typeof(SComponentModel));
                var workspace      = componentModel.GetService <VisualStudioWorkspace>();

                var selectedItem = this.GetSelectedSolutionExplorerItem();
                Microsoft.CodeAnalysis.Document doc = null;

                if (selectedItem != null && selectedItem.Name != null && !selectedItem.Name.EndsWith(".cs"))
                {
                    VsShellUtilities.ShowMessageBox(this.package, "Generate DTO action can only be invoked on CSharp files.", "Error",
                                                    OLEMSGICON.OLEMSGICON_WARNING,
                                                    OLEMSGBUTTON.OLEMSGBUTTON_OK,
                                                    OLEMSGDEFBUTTON.OLEMSGDEFBUTTON_FIRST);

                    return;
                }

                if (selectedItem?.Document != null)
                {
                    doc = workspace.CurrentSolution.GetDocumentByFilePath(selectedItem.Document.FullName);
                }
                else if (selectedItem != null)
                {
                    var file        = selectedItem.Name;
                    var projectName = selectedItem.ContainingProject.Name;

                    var docs = workspace.CurrentSolution.Projects
                               .Where(p => p.Name == projectName)
                               .SelectMany(p => p.Documents)
                               .Where(d => d.Name == file)
                               .ToList();

                    if (docs.Count == 0)
                    {
                        VsShellUtilities.ShowMessageBox(this.package, "Shitty exception - cannot get current selected solution item :/// . Try opening desired document, and then activating this command.", "Error",
                                                        OLEMSGICON.OLEMSGICON_WARNING,
                                                        OLEMSGBUTTON.OLEMSGBUTTON_OK,
                                                        OLEMSGDEFBUTTON.OLEMSGDEFBUTTON_FIRST);
                    }

                    if (docs.Count > 1)
                    {
                        VsShellUtilities.ShowMessageBox(this.package, "Multiple documents with same name exist - cannot get current selected solution item. Try opening desired document, and then activating this command.", "Error",
                                                        OLEMSGICON.OLEMSGICON_WARNING,
                                                        OLEMSGBUTTON.OLEMSGBUTTON_OK,
                                                        OLEMSGDEFBUTTON.OLEMSGDEFBUTTON_FIRST);
                    }

                    doc = docs.FirstOrDefault();
                }
                else
                {
                    VsShellUtilities.ShowMessageBox(this.package, "Shitty exception - cannot get current selected solution item :/// . Try opening desired document, and then activating this command.", "Error",
                                                    OLEMSGICON.OLEMSGICON_WARNING,
                                                    OLEMSGBUTTON.OLEMSGBUTTON_OK,
                                                    OLEMSGDEFBUTTON.OLEMSGDEFBUTTON_FIRST);

                    return;
                }
                var possibleProjects = doc.GetPossibleProjects();

                var vmBasic = BasicOptionsViewModel.Create(possibleProjects, doc.Name.Replace(".cs", ""), doc.Project.Solution.GetMostLikelyDtoLocation());
                var shouldProceed = new BasicOptionsWindow {
                    DataContext = vmBasic
                }.ShowModal();

                if (shouldProceed != true)
                {
                    return;
                }

                var existingDoc = doc.Project.Solution.GetDocumentByLocation(vmBasic.DtoLocation, vmBasic.DtoName);
                if (existingDoc != null)
                {
                    var result = VsShellUtilities.ShowMessageBox(this.package, "There is already a DTO class in the specified location. Press OK if you would like to regenerate it, or cancel to choose different name.", "Warninig - regenerate DTO?",
                                                                 OLEMSGICON.OLEMSGICON_WARNING,
                                                                 OLEMSGBUTTON.OLEMSGBUTTON_OKCANCEL,
                                                                 OLEMSGDEFBUTTON.OLEMSGDEFBUTTON_FIRST);

                    if (result != 1)
                    {
                        return;
                    }
                }

                var vm = await PropertySelectorViewModel.Create(doc, vmBasic.DtoName, vmBasic.DtoLocation, existingDto : existingDoc);

                var isConfirmed = new PropertySelectorWindow()
                {
                    DataContext = vm
                }.ShowModal();

                if (isConfirmed == true)
                {
                    var modifiedSolution = await doc.Project.Solution.WriteDto(vm.DtoLocation, vm.EntityModel.ConvertToMetadata(), vm.GenerateMapper);

                    var ok = workspace.TryApplyChanges(modifiedSolution);

                    if (!ok)
                    {
                        VsShellUtilities.ShowMessageBox(this.package, "Unable to generate DTO.", "Error", OLEMSGICON.OLEMSGICON_WARNING, OLEMSGBUTTON.OLEMSGBUTTON_OK, OLEMSGDEFBUTTON.OLEMSGDEFBUTTON_FIRST);
                    }
                }
            }
            catch (Exception ex)
            {
                VsShellUtilities.ShowMessageBox(this.package, ex.Message, "An exception has occurred",
                                                OLEMSGICON.OLEMSGICON_WARNING,
                                                OLEMSGBUTTON.OLEMSGBUTTON_OK,
                                                OLEMSGDEFBUTTON.OLEMSGDEFBUTTON_FIRST);
            }
        }
예제 #34
0
 public IEnumerable <Microsoft.CodeAnalysis.CodeActions.CodeIssue> GetIssues(Microsoft.CodeAnalysis.Document document, CommonSyntaxToken syntax, CancellationToken cancellationToken)
 {
     throw new NotImplementedException();
 }
 public CSharpDocumentationFile(Document document, Dictionary <string, Project> projects)
     : base(new FileInfo(document.FilePath))
 {
     _document = document;
     _projects = projects;
 }
예제 #36
0
 public MyCSharpCompletionData(Microsoft.CodeAnalysis.Document document, ITextSnapshot triggerSnapshot, CompletionService completionService, CompletionItem completionItem) :
     base(document, triggerSnapshot, completionService, completionItem)
 {
 }
예제 #37
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>
        private void MenuItemCallback(object sender, EventArgs e)
        {
            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();
                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 = document.GetSyntaxRootAsync().Result;
                SyntaxToken   st             = rootSyntaxNode.FindToken(caretPosition);
                SemanticModel semanticModel  = document.GetSemanticModelAsync().Result;
                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);

                INamedTypeSymbol typeSymbol = null;
                string           memberName = null;

                MemberType memberType = 0;

                // todo: view SLaks.Ref12.Services.RoslynSymbolResolver
                if ((symbol == null) || ((!TryHandleAsType(symbol, out 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);
            }
        }
예제 #38
0
        static async Task <ImmutableArray <Diagnostic> > GetDiagnosticsForDocument(ImmutableArray <DiagnosticAnalyzer> analyzers, Microsoft.CodeAnalysis.Document doc, ImmutableHashSet <string> diagnostics, CancellationToken token)
        {
            var options = new CompilationWithAnalyzersOptions(
                new WorkspaceAnalyzerOptions(
                    new AnalyzerOptions(ImmutableArray <AdditionalText> .Empty),
                    doc.Project.Solution.Workspace),
                delegate(Exception exception, DiagnosticAnalyzer analyzer, Diagnostic diag) {
                LoggingService.LogError("Exception in diagnostic analyzer " + diag.Id + ":" + diag.GetMessage(), exception);
            },
                true,
                false
                );

            var model = await doc.GetSemanticModelAsync(token).ConfigureAwait(false);

            var compilationWithAnalyzer = model.Compilation.WithAnalyzers(analyzers, options);

            var diagnosticList = new List <Diagnostic> ();

            diagnosticList.AddRange(await compilationWithAnalyzer.GetAnalyzerSemanticDiagnosticsAsync(model, null, token).ConfigureAwait(false));
            diagnosticList.AddRange(await compilationWithAnalyzer.GetAnalyzerSemanticDiagnosticsAsync(model, null, token).ConfigureAwait(false));

            return(diagnosticList.ToImmutableArray());
        }
예제 #39
0
 public override Task <IEnumerable <Diagnostic> > GetDocumentDiagnosticsAsync(Microsoft.CodeAnalysis.Document document, CancellationToken cancellationToken)
 {
     return(_getDocumentDiagnosticsAsync(document, _diagnosticIds, cancellationToken));
 }
예제 #40
0
 public CSharpCompletionData(Microsoft.CodeAnalysis.Document document, ITextSnapshot triggerSnapshot, CompletionService completionService, CompletionItem completionItem) : base(document, triggerSnapshot, completionService, completionItem)
 {
     provider = new Lazy <CompletionProvider> (delegate {
         return(((CSharpCompletionService)completionService).GetProvider(CompletionItem));
     });
 }
예제 #41
0
        private static async Task <ImmutableArray <TextChange> > AddDocumentMergeChangesAsync(
            Document oldDocument,
            Document newDocument,
            List <TextChange> cumulativeChanges,
            List <UnmergedDocumentChanges> unmergedChanges,
            LinkedFileGroupSessionInfo groupSessionInfo,
            IDocumentTextDifferencingService textDiffService,
            CancellationToken cancellationToken)
        {
            var unmergedDocumentChanges   = new List <TextChange>();
            var successfullyMergedChanges = ArrayBuilder <TextChange> .GetInstance();

            var cumulativeChangeIndex = 0;

            var textchanges = await textDiffService.GetTextChangesAsync(oldDocument, newDocument, cancellationToken).ConfigureAwait(false);

            foreach (var change in textchanges)
            {
                while (cumulativeChangeIndex < cumulativeChanges.Count && cumulativeChanges[cumulativeChangeIndex].Span.End < change.Span.Start)
                {
                    // Existing change that does not overlap with the current change in consideration
                    successfullyMergedChanges.Add(cumulativeChanges[cumulativeChangeIndex]);
                    cumulativeChangeIndex++;

                    groupSessionInfo.IsolatedDiffs++;
                }

                if (cumulativeChangeIndex < cumulativeChanges.Count)
                {
                    var cumulativeChange = cumulativeChanges[cumulativeChangeIndex];
                    if (!cumulativeChange.Span.IntersectsWith(change.Span))
                    {
                        // The current change in consideration does not intersect with any existing change
                        successfullyMergedChanges.Add(change);

                        groupSessionInfo.IsolatedDiffs++;
                    }
                    else
                    {
                        if (change.Span != cumulativeChange.Span || change.NewText != cumulativeChange.NewText)
                        {
                            // The current change in consideration overlaps an existing change but
                            // the changes are not identical.
                            unmergedDocumentChanges.Add(change);

                            groupSessionInfo.OverlappingDistinctDiffs++;
                            if (change.Span == cumulativeChange.Span)
                            {
                                groupSessionInfo.OverlappingDistinctDiffsWithSameSpan++;
                                if (change.NewText.Contains(cumulativeChange.NewText) || cumulativeChange.NewText.Contains(change.NewText))
                                {
                                    groupSessionInfo.OverlappingDistinctDiffsWithSameSpanAndSubstringRelation++;
                                }
                            }
                        }
                        else
                        {
                            // The current change in consideration is identical to an existing change
                            successfullyMergedChanges.Add(change);
                            cumulativeChangeIndex++;

                            groupSessionInfo.IdenticalDiffs++;
                        }
                    }
                }
                else
                {
                    // The current change in consideration does not intersect with any existing change
                    successfullyMergedChanges.Add(change);

                    groupSessionInfo.IsolatedDiffs++;
                }
            }

            while (cumulativeChangeIndex < cumulativeChanges.Count)
            {
                // Existing change that does not overlap with the current change in consideration
                successfullyMergedChanges.Add(cumulativeChanges[cumulativeChangeIndex]);
                cumulativeChangeIndex++;
                groupSessionInfo.IsolatedDiffs++;
            }

            if (unmergedDocumentChanges.Any())
            {
                unmergedChanges.Add(new UnmergedDocumentChanges(
                                        unmergedDocumentChanges.AsEnumerable(),
                                        oldDocument.Project.Name,
                                        oldDocument.Id));
            }

            return(successfullyMergedChanges.ToImmutableAndFree());
        }
예제 #42
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.DocumentId = document.Id;
                        infos.Add(declaredSymbolInfo);
                    }
                }
                RemoveDocument(result, document.Id);
                result.TryAdd(document.Id, infos);
            }