public static async Task RenameSymbolAsync(ISymbol symbol, string newName, IProgressMonitor progressMonitor, Action <Error> errorCallback) { if (symbol == null) { throw new ArgumentNullException("symbol"); } if (progressMonitor == null) { throw new ArgumentNullException("progressMonitor"); } SD.MainThread.VerifyAccess(); if (SD.ParserService.LoadSolutionProjectsThread.IsRunning) { progressMonitor.ShowingDialog = true; MessageService.ShowMessage("${res:SharpDevelop.Refactoring.LoadSolutionProjectsThreadRunning}"); progressMonitor.ShowingDialog = false; return; } double totalWorkAmount; List <ISymbolSearch> symbolSearches = PrepareSymbolSearch(symbol, progressMonitor.CancellationToken, out totalWorkAmount); double workDone = 0; ParseableFileContentFinder parseableFileContentFinder = new ParseableFileContentFinder(); var errors = new List <Error>(); var changes = new List <PatchedFile>(); foreach (ISymbolSearch s in symbolSearches) { progressMonitor.CancellationToken.ThrowIfCancellationRequested(); using (var childProgressMonitor = progressMonitor.CreateSubTask(s.WorkAmount / totalWorkAmount)) { var args = new SymbolRenameArgs(newName, childProgressMonitor, parseableFileContentFinder); args.ProvideHighlightedLine = false; await s.RenameAsync(args, file => changes.Add(file), error => errors.Add(error)); } workDone += s.WorkAmount; progressMonitor.Progress = workDone / totalWorkAmount; } if (errors.Count == 0) { foreach (var file in changes) { ApplyChanges(file); } } else { foreach (var error in errors) { errorCallback(error); } } }
void RenameReferencesInFile(SymbolRenameArgs args, IList<IFindReferenceSearchScope> searchScopeList, FileName fileName, Action<PatchedFile> callback, Action<Error> errorCallback, bool isNameValid, CancellationToken cancellationToken) { ITextSource textSource = args.ParseableFileContentFinder.Create(fileName); if (textSource == null) return; if (searchScopeList != null) { if (!searchScopeList.DistinctBy(scope => scope.SearchTerm ?? String.Empty).Any( scope => (scope.SearchTerm == null) || (textSource.IndexOf(scope.SearchTerm, 0, textSource.TextLength, StringComparison.Ordinal) >= 0))) return; } var parseInfo = SD.ParserService.Parse(fileName, textSource) as CSharpFullParseInformation; if (parseInfo == null) return; ReadOnlyDocument document = null; IHighlighter highlighter = null; List<RenameResultMatch> results = new List<RenameResultMatch>(); // Grab the unresolved file matching the compilation version // (this may differ from the version created by re-parsing the project) CSharpUnresolvedFile unresolvedFile = null; IProjectContent pc = compilation.MainAssembly.UnresolvedAssembly as IProjectContent; if (pc != null) { unresolvedFile = pc.GetFile(fileName) as CSharpUnresolvedFile; } CSharpAstResolver resolver = new CSharpAstResolver(compilation, parseInfo.SyntaxTree, unresolvedFile); fr.RenameReferencesInFile( searchScopeList, args.NewName, resolver, delegate (RenameCallbackArguments callbackArgs) { var node = callbackArgs.NodeToReplace; string newCode = callbackArgs.NewNode.ToString(); if (document == null) { document = new ReadOnlyDocument(textSource, fileName); if (args.ProvideHighlightedLine) { highlighter = SD.EditorControlService.CreateHighlighter(document); highlighter.BeginHighlighting(); } } var startLocation = node.StartLocation; var endLocation = node.EndLocation; int offset = document.GetOffset(startLocation); int length = document.GetOffset(endLocation) - offset; if (args.ProvideHighlightedLine) { var builder = SearchResultsPad.CreateInlineBuilder(node.StartLocation, node.EndLocation, document, highlighter); var defaultTextColor = highlighter != null ? highlighter.DefaultTextColor : null; results.Add(new RenameResultMatch(fileName, startLocation, endLocation, offset, length, newCode, builder, defaultTextColor)); } else { results.Add(new RenameResultMatch(fileName, startLocation, endLocation, offset, length, newCode)); } }, errorCallback, cancellationToken); if (highlighter != null) { highlighter.Dispose(); } if (results.Count > 0) { if (!isNameValid) { errorCallback(new Error(ErrorType.Error, string.Format("The name '{0}' is not valid in the current context!", args.NewName), new DomRegion(fileName, results[0].StartLocation))); return; } IDocument changedDocument = new TextDocument(document); var oldVersion = changedDocument.Version; List<SearchResultMatch> fixedResults = new List<SearchResultMatch>(); int lastStartOffset = changedDocument.TextLength + 1; foreach (var result in results.OrderByDescending(m => m.StartOffset)) { if (result.EndOffset <= lastStartOffset) { changedDocument.Replace(result.StartOffset, result.Length, result.NewCode); fixedResults.Add(result); lastStartOffset = result.StartOffset; } } callback(new PatchedFile(fileName, fixedResults, oldVersion, changedDocument.Version)); } }
public Task RenameAsync(SymbolRenameArgs args, Action<PatchedFile> callback, Action<Error> errorCallback) { if (callback == null) throw new ArgumentNullException("callback"); var cancellationToken = args.ProgressMonitor.CancellationToken; return Task.Run( () => { bool isNameValid = ICSharpCode.NRefactory.MonoCSharp.Tokenizer.IsValidIdentifier(args.NewName); object progressLock = new object(); Parallel.ForEach( searchScopesPerFile.Keys, new ParallelOptions { MaxDegreeOfParallelism = Environment.ProcessorCount, CancellationToken = cancellationToken }, delegate (string fileName) { RenameReferencesInFile(args, searchScopesPerFile[fileName], FileName.Create(fileName), callback, errorCallback, isNameValid, cancellationToken); lock (progressLock) args.ProgressMonitor.Progress += workAmountInverse; }); }, cancellationToken ); }
public Task RenameAsync(SymbolRenameArgs renameArguments, Action<PatchedFile> callback, Action<Error> errorCallback) { return Task.WhenAll(symbolSearches.Select(s => s.RenameAsync(renameArguments, callback, errorCallback))); }
public static async Task RenameSymbolAsync(ISymbol symbol, string newName, IProgressMonitor progressMonitor, Action<Error> errorCallback) { if (symbol == null) throw new ArgumentNullException("symbol"); if (progressMonitor == null) throw new ArgumentNullException("progressMonitor"); SD.MainThread.VerifyAccess(); if (SD.ParserService.LoadSolutionProjectsThread.IsRunning) { progressMonitor.ShowingDialog = true; MessageService.ShowMessage("${res:SharpDevelop.Refactoring.LoadSolutionProjectsThreadRunning}"); progressMonitor.ShowingDialog = false; return; } double totalWorkAmount; List<ISymbolSearch> symbolSearches = PrepareSymbolSearch(symbol, progressMonitor.CancellationToken, out totalWorkAmount); double workDone = 0; ParseableFileContentFinder parseableFileContentFinder = new ParseableFileContentFinder(); var errors = new List<Error>(); var changes = new List<PatchedFile>(); foreach (ISymbolSearch s in symbolSearches) { progressMonitor.CancellationToken.ThrowIfCancellationRequested(); using (var childProgressMonitor = progressMonitor.CreateSubTask(s.WorkAmount / totalWorkAmount)) { var args = new SymbolRenameArgs(newName, childProgressMonitor, parseableFileContentFinder); args.ProvideHighlightedLine = false; await s.RenameAsync(args, file => changes.Add(file), error => errors.Add(error)); } workDone += s.WorkAmount; progressMonitor.Progress = workDone / totalWorkAmount; } if (errors.Count == 0) { foreach (var file in changes) { ApplyChanges(file); } } else { foreach (var error in errors) { errorCallback(error); } } }
void RenameReferencesInFile(SymbolRenameArgs args, FileName fileName, Action<PatchedFile> callback, Action<Error> errorCallback, bool isNameValid, CancellationToken cancellationToken) { ITextSource textSource = args.ParseableFileContentFinder.Create(fileName); if (textSource == null) return; int offset = textSource.IndexOf(entity.Name, 0, textSource.TextLength, StringComparison.Ordinal); if (offset < 0) return; var parseInfo = SD.ParserService.Parse(fileName, textSource) as XamlFullParseInformation; if (parseInfo == null) return; ReadOnlyDocument document = null; IHighlighter highlighter = null; List<RenameResultMatch> results = new List<RenameResultMatch>(); XamlAstResolver resolver = new XamlAstResolver(compilation, parseInfo); string newCode = args.NewName; do { if (document == null) { document = new ReadOnlyDocument(textSource, fileName); highlighter = SD.EditorControlService.CreateHighlighter(document); highlighter.BeginHighlighting(); } var result = resolver.ResolveAtLocation(document.GetLocation(offset + entity.Name.Length / 2 + 1), cancellationToken); int length = entity.Name.Length; if ((result is TypeResolveResult && ((TypeResolveResult)result).Type.Equals(entity)) || (result is MemberResolveResult && ((MemberResolveResult)result).Member.Equals(entity))) { var region = new DomRegion(fileName, document.GetLocation(offset), document.GetLocation(offset + length)); var builder = SearchResultsPad.CreateInlineBuilder(region.Begin, region.End, document, highlighter); results.Add(new RenameResultMatch(fileName, document.GetLocation(offset), document.GetLocation(offset + length), offset, length, newCode, builder, highlighter.DefaultTextColor)); } offset = textSource.IndexOf(entity.Name, offset + length, textSource.TextLength - offset - length, StringComparison.OrdinalIgnoreCase); } while (offset > 0); if (highlighter != null) { highlighter.Dispose(); } if (results.Count > 0) { if (!isNameValid) { errorCallback(new Error(ErrorType.Error, string.Format("The name '{0}' is not valid in the current context!", args.NewName), new DomRegion(fileName, results[0].StartLocation))); return; } IDocument changedDocument = new TextDocument(document); var oldVersion = changedDocument.Version; foreach (var result in results.OrderByDescending(m => m.StartOffset)) { changedDocument.Replace(result.StartOffset, result.Length, result.NewCode); } callback(new PatchedFile(fileName, results, oldVersion, changedDocument.Version)); } }
public Task RenameAsync(SymbolRenameArgs args, Action<PatchedFile> callback, Action<Error> errorCallback) { if (callback == null) throw new ArgumentNullException("callback"); var cancellationToken = args.ProgressMonitor.CancellationToken; return Task.Run( () => { bool isNameValid = XmlReader.IsNameToken(args.NewName); object progressLock = new object(); Parallel.ForEach( interestingFileNames, new ParallelOptions { MaxDegreeOfParallelism = Environment.ProcessorCount, CancellationToken = cancellationToken }, delegate (FileName fileName) { RenameReferencesInFile(args, fileName, callback, errorCallback, isNameValid, cancellationToken); lock (progressLock) args.ProgressMonitor.Progress += workAmountInverse; }); }, cancellationToken ); }
public Task RenameAsync(SymbolRenameArgs args, Action<PatchedFile> callback, Action<Error> errorCallback) { if (callback == null) throw new ArgumentNullException("callback"); var cancellationToken = args.ProgressMonitor.CancellationToken; return Task.Run( () => { bool isNameValid = Mono.CSharp.Tokenizer.IsValidIdentifier(args.NewName); for (int i = 0; i < searchScopes.Count; i++) { IFindReferenceSearchScope searchScope = searchScopes[i]; object progressLock = new object(); Parallel.ForEach( interestingFileNames[i], new ParallelOptions { MaxDegreeOfParallelism = Environment.ProcessorCount, CancellationToken = cancellationToken }, delegate (string fileName) { RenameReferencesInFile(args, searchScope, FileName.Create(fileName), callback, errorCallback, isNameValid, cancellationToken); lock (progressLock) args.ProgressMonitor.Progress += workAmountInverse; }); } }, cancellationToken ); }
public Task RenameAsync(SymbolRenameArgs args, Action<PatchedFile> callback, Action<Error> errorCallback) { // TODO implement Rename for XAML return Task.Run(() => {}); }
public Task RenameAsync(SymbolRenameArgs renameArguments, Action <PatchedFile> callback, Action <Error> errorCallback) { return(Task.WhenAll(symbolSearches.Select(s => s.RenameAsync(renameArguments, callback, errorCallback)))); }