private async Task UpdateStateMachineWorkerAsync(CancellationToken cancellationToken) { var options = _workspace.Options; var lastStatus = options.GetOption(KeybindingResetOptions.ReSharperStatus); ReSharperStatus currentStatus; try { currentStatus = await IsReSharperRunningAsync(lastStatus, cancellationToken) .ConfigureAwait(false); } catch (OperationCanceledException) { return; } if (currentStatus == lastStatus) { return; } options = options.WithChangedOption(KeybindingResetOptions.ReSharperStatus, currentStatus); switch (lastStatus) { case ReSharperStatus.NotInstalledOrDisabled: case ReSharperStatus.Suspended: if (currentStatus == ReSharperStatus.Enabled) { // N->E or S->E. If ReSharper was just installed and is enabled, reset NeedsReset. options = options.WithChangedOption(KeybindingResetOptions.NeedsReset, false); } // Else is N->N, N->S, S->N, S->S. N->S can occur if the user suspends ReSharper, then disables // the extension, then reenables the extension. We will show the gold bar after the switch // if there is still a pending show. break; case ReSharperStatus.Enabled: if (currentStatus != ReSharperStatus.Enabled) { // E->N or E->S. Set NeedsReset. Pop the gold bar to the user. options = options.WithChangedOption(KeybindingResetOptions.NeedsReset, true); } // Else is E->E. No actions to take break; } _workspace.TryApplyChanges(_workspace.CurrentSolution.WithOptions(options)); if (options.GetOption(KeybindingResetOptions.NeedsReset)) { ShowGoldBar(); } }
private bool saveCodeBehind(RoslynDocument doc, bool mapLines) { doc.SyntaxRoot = doc.SyntaxRoot .NormalizeWhitespace(elasticTrivia: true); //td: optimize var solution = _workspace.CurrentSolution; if (mapLines) { var mapper = doc.Mapper; var vsDocument = solution.GetDocument(_id); var filePath = vsDocument?.FilePath; if (filePath != null) { filePath = filePath.Remove(filePath.Length - ".cs".Length); } solution = solution.WithDocumentText(_id, SourceText.From(doc.Mapper .RenderMapping(doc.SyntaxRoot, filePath))); } else { solution = solution.WithDocumentSyntaxRoot(_id, _document.SyntaxRoot); } return(_workspace.TryApplyChanges(solution)); }
private void SyncNamespaces(ImmutableArray <Project> projects) { if (projects.IsEmpty) { return; } var syncService = projects[0].GetRequiredLanguageService <ISyncNamespacesService>(); Solution?solution = null; var status = _threadOperationExecutor.Execute(ServicesVSResources.Sync_Namespaces, ServicesVSResources.Updating_namspaces, allowCancellation: true, showProgress: true, (operationContext) => { solution = ThreadHelper.JoinableTaskFactory.Run(() => syncService.SyncNamespacesAsync(projects, operationContext.UserCancellationToken)); }); if (status != UIThreadOperationStatus.Canceled && solution is not null) { if (_workspace.CurrentSolution.GetChanges(solution).GetProjectChanges().Any()) { _workspace.TryApplyChanges(solution); MessageDialog.Show(ServicesVSResources.Sync_Namespaces, ServicesVSResources.Namespaces_have_been_updated, MessageDialogCommandSet.Ok); } else { MessageDialog.Show(ServicesVSResources.Sync_Namespaces, ServicesVSResources.No_namespaces_needed_updating, MessageDialogCommandSet.Ok); } } }
public bool ExecuteRename(KeyValuePair <IndexerKey, List <CSharpQuery> > codeKeyValuePair, RenameViewModel renameViewModel, VisualStudioWorkspace workspace) { bool result = true; foreach (var file in codeKeyValuePair.Value.GroupBy(x => x.DocumentId, x => x)) { var doc = workspace.CurrentSolution.GetDocument(file.Key); SemanticModel semModel = ThreadHelper.JoinableTaskFactory.Run(async() => await doc.GetSemanticModelAsync()); NodeHelpers helper = new NodeHelpers(semModel); doc.TryGetSyntaxTree(out SyntaxTree synTree); var root = (CompilationUnitSyntax)synTree.GetRoot(); var newArgumentSyntax = SyntaxFactory.Argument(SyntaxFactory.LiteralExpression(SyntaxKind.StringLiteralExpression, SyntaxFactory.Literal(renameViewModel.QueryText))); foreach (var query in file) { var span = synTree.GetText().Lines[query.QueryLineNumber - 1].Span; var nodes = root.DescendantNodesAndSelf(span); var existingQueryArgumentSyntax = helper.GetProperArgumentNodeInNodes(nodes); var newRoot = root.ReplaceNode(existingQueryArgumentSyntax, newArgumentSyntax); root = newRoot; doc = doc.WithText(newRoot.GetText()); var applyResult = workspace.TryApplyChanges(doc.Project.Solution); result = result && applyResult; } } return(result); }
private bool IsCandidate(SuggestedAction action) { // Candidates fill the following criteria: // 1: Are a Dotnet user (as evidenced by the fact that this code is being run) // 2: Have triggered a lightbulb on 3 separate days or if this is a code quality suggested action. // If the user hasn't met candidacy conditions, then we check them. Otherwise, proceed // to info bar check var options = _workspace.Options; var isCandidate = options.GetOption(FxCopAnalyzersInstallOptions.HasMetCandidacyRequirements); if (!isCandidate) { // We store in UTC to avoid any timezone offset weirdness var lastTriggeredTimeBinary = options.GetOption(FxCopAnalyzersInstallOptions.LastDateTimeUsedSuggestionAction); FxCopAnalyzersInstallLogger.LogCandidacyRequirementsTracking(lastTriggeredTimeBinary); var lastTriggeredTime = DateTime.FromBinary(lastTriggeredTimeBinary); var currentTime = DateTime.UtcNow; var span = currentTime - lastTriggeredTime; if (span.TotalDays >= 1) { options = options.WithChangedOption(FxCopAnalyzersInstallOptions.LastDateTimeUsedSuggestionAction, currentTime.ToBinary()); var usageCount = options.GetOption(FxCopAnalyzersInstallOptions.UsedSuggestedActionCount); options = options.WithChangedOption(FxCopAnalyzersInstallOptions.UsedSuggestedActionCount, ++usageCount); // Candidate if user has invoked the light bulb 3 times or if this is a code quality suggested action. if (usageCount >= 3 || action.IsForCodeQualityImprovement) { isCandidate = true; options = options.WithChangedOption(FxCopAnalyzersInstallOptions.HasMetCandidacyRequirements, true); FxCopAnalyzersInstallLogger.Log(nameof(FxCopAnalyzersInstallOptions.HasMetCandidacyRequirements)); } _workspace.TryApplyChanges(_workspace.CurrentSolution.WithOptions(options)); } } return(isCandidate); }
internal async static Task <bool> ApplyDocumentChangesAsync(Document document) { if (document == null) { return(false); } VisualStudioWorkspace workspace = await GetVisualStudioWorkspaceAsync(); Solution newSolution = document.Project.Solution; if (workspace.CanApplyChange(ApplyChangesKind.ChangeDocument)) { return(workspace.TryApplyChanges(newSolution)); } return(false); }
private void OnDocumentSaved(Document dteDocument) { var documentIds = _workspace.CurrentSolution.GetDocumentIdsWithFilePath(dteDocument.FullName); if (documentIds == null || documentIds.Length != 1) { return; } var documentId = documentIds[0]; var document = _workspace.CurrentSolution.GetDocument(documentId); if (Path.GetExtension(document.FilePath) != ".cs") { return; } SyntaxNode root; if (!document.TryGetSyntaxRoot(out root)) { return; } var newRoot = root.RemoveComments(); if (newRoot == root) { return; } var newSolution = document.Project.Solution.WithDocumentSyntaxRoot(document.Id, newRoot); _workspace.TryApplyChanges(newSolution); dteDocument.Save(); }
private void OnWorkspaceChanged(object sender, WorkspaceChangeEventArgs e) { switch (e.Kind) { case WorkspaceChangeKind.SolutionAdded: _infoBarShownForCurrentSolution = false; return; // Check if a new analyzer config document was added case WorkspaceChangeKind.AnalyzerConfigDocumentAdded: break; default: return; } // Bail out if we have a null DTE instance or we have already shown the info bar for current solution. if (_dte == null || _infoBarShownForCurrentSolution) { return; } // Check if added analyzer config document is at the root of the current solution. var analyzerConfigDocumentFilePath = e.NewSolution.GetAnalyzerConfigDocument(e.DocumentId)?.FilePath; var analyzerConfigDirectory = PathUtilities.GetDirectoryName(analyzerConfigDocumentFilePath); var solutionDirectory = PathUtilities.GetDirectoryName(e.NewSolution.FilePath); if (analyzerConfigDocumentFilePath == null || analyzerConfigDirectory == null || analyzerConfigDirectory != solutionDirectory) { return; } // Check if user has explicitly disabled the suggestion to add newly added analyzer config document as solution item. if (_workspace.Options.GetOption(NeverShowAgain)) { return; } // Kick off a task to show info bar to make it a solution item. Task.Run(async() => { await _threadingContext.JoinableTaskFactory.SwitchToMainThreadAsync(); var solution = (Solution2)_dte.Solution; if (VisualStudioAddSolutionItemService.TryGetExistingSolutionItemsFolder(solution, analyzerConfigDocumentFilePath, out _, out var hasExistingSolutionItem) && hasExistingSolutionItem) { return; } if (!_infoBarShownForCurrentSolution) { _infoBarShownForCurrentSolution = true; var infoBarService = _workspace.Services.GetRequiredService <IInfoBarService>(); infoBarService.ShowInfoBarInGlobalView( ServicesVSResources.A_new_editorconfig_file_was_detected_at_the_root_of_your_solution_Would_you_like_to_make_it_a_solution_item, GetInfoBarUIItems().ToArray()); } }); return; // Local functions IEnumerable <InfoBarUI> GetInfoBarUIItems() { // Yes - add editorconfig solution item. yield return(new InfoBarUI( title: ServicesVSResources.Yes, kind: InfoBarUI.UIKind.Button, action: AddEditorconfigSolutionItem, closeAfterAction: true)); // No - do not add editorconfig solution item. yield return(new InfoBarUI( title: ServicesVSResources.No, kind: InfoBarUI.UIKind.Button, action: () => { }, closeAfterAction: true)); // Don't show the InfoBar again link yield return(new InfoBarUI(title: ServicesVSResources.Never_show_this_again, kind: InfoBarUI.UIKind.Button, action: () => _workspace.TryApplyChanges(_workspace.CurrentSolution.WithOptions(_workspace.Options.WithChangedOption(NeverShowAgain, true))), closeAfterAction: true)); } void AddEditorconfigSolutionItem() { var addSolutionItemService = _workspace.Services.GetRequiredService <IAddSolutionItemService>(); addSolutionItemService.AddSolutionItemAsync(analyzerConfigDocumentFilePath, CancellationToken.None).Wait(); } }
private void DocumentEvents_DocumentSaved(EnvDTE.Document Document) { EnvDTE.Project project; Microsoft.CodeAnalysis.Project proj; //string fileName = null; if (Document.Name.EndsWith("Controller.cs", StringComparison.OrdinalIgnoreCase)) { project = Document.ProjectItem.ContainingProject; string parentName = Document.ProjectItem.Name; string parentFileName = Document.ProjectItem.FileNames[0]; string parentPath = Path.GetDirectoryName(parentFileName); workspace = componentModel.GetService <VisualStudioWorkspace>(); proj = workspace.CurrentSolution.Projects.Where(doc => doc.FilePath == project.FileName).FirstOrDefault(); CSharpCompilation cSharpCompilation = null; Compilation compilation = null; if (cSharpCompilation == null) { if (proj.TryGetCompilation(out compilation)) { cSharpCompilation = (CSharpCompilation)compilation; } else { cSharpCompilation = (CSharpCompilation)proj.GetCompilationAsync().Result; } } string structFileName = Path.Combine(parentPath, Path.GetFileNameWithoutExtension(parentName) + ".model.cs"); ProjectItem projectItem = Helper.ProjectHelpers.FindInProject(structFileName); projectItem?.Document?.Close(vsSaveChanges.vsSaveChangesNo); //projectItem?.Remove(); using (StreamWriter sw = new StreamWriter(structFileName, false, System.Text.Encoding.UTF8)) { var document = proj.Documents.Single(doc => { return(doc.FilePath == parentFileName); }); Controller.StructModel model = new Controller.StructModel(); var tree = document.GetSyntaxTreeAsync().Result; SyntaxNode root = tree.GetRoot(); SemanticModel semanticModel = cSharpCompilation.GetSemanticModel(tree); model.WriteDocument(sw, tree, semanticModel); sw.Close(); OutPutString("生成控制器实体类成功:\"" + structFileName + "\""); } if (File.Exists(structFileName)) { Helper.ProjectHelpers.AddNestedFile(Document.ProjectItem, structFileName, "Compile", false); } } else if (Document.Name.EndsWith(".cshtml")) { project = Document.ProjectItem.ContainingProject; string parentName = Document.ProjectItem.Name; string parentFileName = Document.ProjectItem.FileNames[0]; string parentPath = Path.GetDirectoryName(parentFileName); workspace = componentModel.GetService <VisualStudioWorkspace>(); proj = workspace.CurrentSolution.Projects.Where(doc => doc.FilePath == project.FileName).FirstOrDefault(); string fileName = Path.Combine(parentPath, Path.GetFileNameWithoutExtension(parentName) + ".template.cs"); ProjectItem projectItem = Helper.ProjectHelpers.FindInProject(fileName); projectItem?.Document?.Close(vsSaveChanges.vsSaveChangesNo); projectItem?.Remove(); Document.ProjectItem.ContainingProject.Save(); using (StreamWriter sw = new StreamWriter(fileName, false, System.Text.Encoding.UTF8)) { string nameSpace = GetNameSpace(Document); string className = Path.GetFileNameWithoutExtension(parentName); Razor.RazorWriter writer = new Razor.RazorWriter(parentFileName); writer.WriteTemplate(sw, nameSpace, className); sw.Close(); OutPutString("生成模板类成功:\"" + fileName + "\""); } if (File.Exists(fileName)) { projectItem = Helper.ProjectHelpers.AddNestedFile(Document.ProjectItem, fileName, "Compile", false); //添加<Content Include="Views\Index.cshtml">BrowseToURL workspace.TryApplyChanges(proj.Solution); //代码结构 projectItem?.Document?.NewWindow(); workspace = componentModel.GetService <VisualStudioWorkspace>(); proj = workspace.CurrentSolution.Projects.Where(x => x.FilePath == project.FileName).FirstOrDefault(); Microsoft.CodeAnalysis.Document codeDocument = proj.Documents.FirstOrDefault((doc => { if (doc.FilePath == fileName) { return(true); } else { return(false); } })); //格式化 Microsoft.CodeAnalysis.Document formatDocument = Microsoft.CodeAnalysis.Formatting.Formatter.FormatAsync(codeDocument).Result; //更改 workspace.TryApplyChanges(formatDocument.Project.Solution); } } else if (Document.Name.EndsWith(".nf.json")) { project = Document.ProjectItem.ContainingProject; string parentName = Document.ProjectItem.Name; string parentFileName = Document.ProjectItem.FileNames[0]; string inputFileContent = null; using (StreamReader sr = new StreamReader(parentFileName, System.Text.Encoding.UTF8)) { inputFileContent = sr.ReadToEnd(); } string nameSpace = GetNameSpace(Document); string className = parentName.TrimSuffix(".nf.json").Replace('-', '_'); string outPutFileName = parentFileName.TrimSuffix(".nf.json") + ".cs"; ProjectItem projectItem = Helper.ProjectHelpers.FindInProject(outPutFileName); projectItem?.Document?.Close(vsSaveChanges.vsSaveChangesNo); if (inputFileContent != null) { using (StreamWriter sw = new StreamWriter(outPutFileName, false, System.Text.Encoding.UTF8)) { Xamasoft.JsonClassGenerator.JsonClassGenerator gen = new Xamasoft.JsonClassGenerator.JsonClassGenerator(); gen.Example = inputFileContent; gen.InternalVisibility = false; gen.CodeWriter = new Xamasoft.JsonClassGenerator.CodeWriters.CSharpCodeWriter(); gen.ExplicitDeserialization = false; gen.Namespace = nameSpace; gen.NoHelperClass = true; gen.SecondaryNamespace = nameSpace; gen.TargetFolder = null; gen.UseProperties = false; gen.MainClass = className; gen.UsePascalCase = false; gen.UseNestedClasses = false; gen.ApplyObfuscationAttributes = false; gen.SingleFile = true; gen.ExamplesInDocumentation = true; gen.OutputStream = sw; gen.GenerateClasses(); OutPutString("生成JSON对应实体类成功:\"" + outPutFileName + "\""); } } if (File.Exists(outPutFileName)) { Helper.ProjectHelpers.AddNestedFile(Document.ProjectItem, outPutFileName, "Compile", false); } } else if (Document.Name.EndsWith(".nf.sql")) { string parentName = Document.ProjectItem.Name; string parentFileName = Document.ProjectItem.FileNames[0]; string nameSpace = GetNameSpace(Document); string fileContent = null; using (StreamReader sr = new StreamReader(parentFileName, System.Text.Encoding.UTF8)) { fileContent = sr.ReadToEnd(); } if (fileContent != null) { Sql.SqlDocument sqlDocument = new Sql.SqlDocument(parentFileName, nameSpace, fileContent); foreach (var model in sqlDocument.modelFileDataList) { ProjectItem projectItem = Helper.ProjectHelpers.FindInProject(model.fileName); projectItem?.Document?.Close(vsSaveChanges.vsSaveChangesNo); using (StreamWriter sw = new StreamWriter(model.fileName, false, System.Text.Encoding.UTF8)) { sw.Write(model.content); sw.Close(); OutPutString("生成sql对应实体类成功:\"" + model.fileName + "\""); } if (File.Exists(model.fileName)) { Helper.ProjectHelpers.AddNestedFile(Document.ProjectItem, model.fileName, "Compile", false); } } } } }
private async Task RemoveEmptyUsingStatementsAsync( ) { foreach (var documentFilePath in _workspace.EnumerateAllDocumentFilePaths(Predicate.IsProjectInScope, Predicate.IsDocumentInScope)) { if (documentFilePath == null) { continue; } bool r = true; do { var document = _workspace.GetDocument(documentFilePath); if (document == null) { continue; } var syntaxRoot = await document.GetSyntaxRootAsync(); if (syntaxRoot == null) { continue; } var namespaces = syntaxRoot .DescendantNodes() .OfType <UsingDirectiveSyntax>() .ToList() ; if (namespaces.Count == 0) { continue; } var toRemove = new List <SyntaxNode>(); foreach (var n in namespaces) { var nname = n.Name.ToString(); if (!_namespaceCenter.NamespacesToRemove.Contains(nname)) { //there is a types in this namespace continue; } toRemove.Add(n); } if (toRemove.Count > 0) { syntaxRoot = syntaxRoot !.RemoveNodes(toRemove, SyntaxRemoveOptions.KeepNoTrivia); if (syntaxRoot != null) { var changedDocument = document.WithSyntaxRoot(syntaxRoot); r = _workspace.TryApplyChanges(changedDocument.Project.Solution); } } }while (!r); } }
private bool saveCodeBehind(SyntaxNode node) { var solution = _workspace.CurrentSolution.WithDocumentSyntaxRoot(_id, _document.SyntaxRoot); return(_workspace.TryApplyChanges(solution)); }