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; }
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); }
/// <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; }
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(); }
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; }
/// <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); } }
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; }
public MyCSharpCompletionData(Microsoft.CodeAnalysis.Document document, ITextSnapshot triggerSnapshot, CompletionService completionService, CompletionItem completionItem) : base(document, triggerSnapshot, completionService, completionItem) { }
/// <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); } }
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()); }
public override Task <IEnumerable <Diagnostic> > GetDocumentDiagnosticsAsync(Microsoft.CodeAnalysis.Document document, CancellationToken cancellationToken) { return(_getDocumentDiagnosticsAsync(document, _diagnosticIds, cancellationToken)); }
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)); }); }
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()); }
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); }