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);
                }
            }
        }
Пример #2
0
		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));
			}
		}
Пример #3
0
		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);
				}
			}
		}
Пример #6
0
		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));
			}
		}
Пример #7
0
		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
			);
		}
Пример #8
0
		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
			);
		}
Пример #9
0
		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))));
 }