public override Task <Script> InsertWithCursor(string operation, ITypeDefinition parentType, Func <Script, RefactoringContext, IList <AstNode> > nodeCallback) { // TODO : Use undo group var tcs = new TaskCompletionSource <Script>(); if (parentType == null) { return(tcs.Task); } IUnresolvedTypeDefinition part = null; foreach (var p in parentType.Parts) { if (part == null || EntityModelContextUtils.IsBetterPart(p, part, ".al")) { part = p; } } if (part == null) { return(tcs.Task); } var fileName = new ICSharpCode.Core.FileName(part.Region.FileName); IViewContent document = SD.FileService.OpenFile(fileName); var area = document.GetService <TextArea>(); if (area == null) { return(tcs.Task); } var loc = part.Region.Begin; var parsedFile = SD.ParserService.ParseFile(fileName, area.Document, cancellationToken: context.CancellationToken); var declaringType = parsedFile.GetInnermostTypeDefinition(loc); EditorScript script; if (area.Document != context.Document) { script = new EditorScript(area.GetService <ITextEditor>(), SDRefactoringContext.Create(fileName, area.Document, loc, context.CancellationToken), FormattingOptions); startedScripts.Add(script); } else { script = this; } var nodes = nodeCallback(script, script.context); var insertionPoints = InsertionPoint.GetInsertionPoints(area.Document, part); if (insertionPoints.Count == 0) { SD.MessageService.ShowErrorFormatted("No valid insertion point can be found in type '{0}'.", part.Name); return(tcs.Task); } var layer = new InsertionCursorLayer(area, operation, insertionPoints); area.Dispatcher.BeginInvoke(DispatcherPriority.Background, (Action)area.TextView.InvalidateVisual); InsertWithCursorOnLayer(script, layer, tcs, nodes, area.Document); return(tcs.Task); }
IEnumerable <SearchResultMatch> FindAndFixIssues(FileName fileName, List <IssueManager.IssueProvider> providers, CancellationToken cancellationToken, ref int fixedIssueCount) { cancellationToken.ThrowIfCancellationRequested(); var openedFile = SD.FileService.GetOpenedFile(fileName); bool documentWasLoadedFromDisk = false; IDocument document = null; if (openedFile != null && openedFile.CurrentView != null) { var provider = openedFile.CurrentView.GetService <IFileDocumentProvider>(); if (provider != null) { document = provider.GetDocumentForFile(openedFile); } } if (document == null) { documentWasLoadedFromDisk = true; document = new TextDocument(SD.FileService.GetFileContent(fileName)) { FileName = fileName }; } var context = SDRefactoringContext.Create(fileName, document, TextLocation.Empty, cancellationToken); List <CodeIssue> allIssues = new List <CodeIssue>(); bool documentWasChanged = false; foreach (var provider in providers) { cancellationToken.ThrowIfCancellationRequested(); var issues = provider.GetIssues(context).ToList(); // Fix issues, if possible: if (provider.Attribute.SupportsAutoFix && issues.Any(i => i.Actions.Count > 0)) { using (var script = context.StartScript()) { foreach (var issue in issues) { if (issue.Actions.Count > 0) { fixedIssueCount++; issue.Actions[0].Run(script); } } } documentWasChanged = true; // Update context now that we've modified the document context = SDRefactoringContext.Create(fileName, document, TextLocation.Empty, cancellationToken); // Find remaining issues: allIssues.AddRange(provider.GetIssues(context)); } else { allIssues.AddRange(issues); } } if (documentWasChanged && documentWasLoadedFromDisk) { // Save changes back to disk using (var writer = new StreamWriter(fileName, false, SD.FileService.DefaultFileEncoding)) { document.WriteTextTo(writer); } } if (allIssues.Count > 0) { using (var highlighter = SD.EditorControlService.CreateHighlighter(document)) { highlighter.BeginHighlighting(); return(allIssues.Select(issue => SearchResultMatch.Create(document, issue.Start, issue.End, highlighter)).ToList()); } } else { return(Enumerable.Empty <SearchResultMatch>()); } }
protected virtual void Initialize() { this.refactoringContext = SDRefactoringContext.Create(editor, CancellationToken.None); }
public override void InsertEventHandler(ITypeDefinition target, string name, IEvent eventDefinition, bool jumpTo, InsertEventHandlerBodyKind bodyKind = InsertEventHandlerBodyKind.ThrowNotImplementedException) { IUnresolvedTypeDefinition match = null; foreach (var part in target.Parts) { if (match == null || EntityModelContextUtils.IsBetterPart(part, match, ".cs")) { match = part; } } if (match == null) { return; } var view = SD.FileService.OpenFile(new FileName(match.Region.FileName), jumpTo); var editor = view.GetRequiredService <ITextEditor>(); var last = match.Members.LastOrDefault() ?? (IUnresolvedEntity)match; editor.Caret.Location = last.BodyRegion.End; var context = SDRefactoringContext.Create(editor, CancellationToken.None); var node = context.RootNode.GetNodeAt <EntityDeclaration>(last.Region.Begin); var resolver = context.GetResolverStateAfter(node); var builder = new TypeSystemAstBuilder(resolver); var invokeMethod = eventDefinition.ReturnType.GetDelegateInvokeMethod(); if (invokeMethod == null) { return; } var importedMethod = resolver.Compilation.Import(invokeMethod); var delegateDecl = builder.ConvertEntity(importedMethod) as MethodDeclaration; if (delegateDecl == null) { return; } var throwStmt = new ThrowStatement(new ObjectCreateExpression(context.CreateShortType("System", "NotImplementedException"))); var decl = new MethodDeclaration() { ReturnType = delegateDecl.ReturnType.Clone(), Name = name, Body = new BlockStatement() { throwStmt } }; var param = delegateDecl.Parameters.Select(p => p.Clone()).ToArray(); decl.Parameters.AddRange(param); try { using (Script script = context.StartScript()) { int eolLen = 0; if (last == match) { eolLen = 2; script.AddTo((TypeDeclaration)node, decl); } else { script.InsertAfter(node, decl); } switch (bodyKind) { case InsertEventHandlerBodyKind.TodoComment: Comment comment = new Comment(" TODO: Implement " + name); script.Replace(throwStmt, comment); script.Select(comment); break; case InsertEventHandlerBodyKind.Nothing: var segment = script.GetSegment(throwStmt); if (script is DocumentScript && eolLen > 0) { eolLen = ((DocumentScript)script).CurrentDocument.GetLineByOffset(segment.Offset).DelimiterLength; } script.RemoveText(segment.Offset, segment.Length - eolLen); script.Select(segment.Offset, segment.Offset); break; case InsertEventHandlerBodyKind.ThrowNotImplementedException: script.Select(throwStmt); break; } } } catch { } }
async void RunAnalysis(ITextSource textSource, AlFullParseInformation parseInfo) { if (markerService == null) { return; } if (cancellationTokenSource != null) { cancellationTokenSource.Cancel(); } cancellationTokenSource = new CancellationTokenSource(); var cancellationToken = cancellationTokenSource.Token; List <InspectionTag> results = new List <InspectionTag>(); try { await Task.Run( delegate { var compilation = SD.ParserService.GetCompilationForFile(parseInfo.FileName); var resolver = parseInfo.GetResolver(compilation); var context = new SDRefactoringContext(textSource, resolver, new TextLocation(0, 0), 0, 0, cancellationToken); foreach (var issueProvider in issueProviders.Value) { if (issueProvider.CurrentSeverity == Severity.None) { continue; } foreach (var issue in issueProvider.GetIssues(context)) { if (issue.Start.IsEmpty || issue.End.IsEmpty) { // Issues can occur on invalid locations when analyzing incomplete code. // We'll just ignore them. continue; } results.Add(new InspectionTag( this, issueProvider, textSource.Version, issue.Description, context.GetOffset(issue.Start), context.GetOffset(issue.End), issue.IssueMarker, issue.Actions)); } } }, cancellationToken); } catch (TaskCanceledException) { } catch (OperationCanceledException) { } catch (Exception ex) { SD.Log.WarnFormatted("IssueManager crashed: {0}", ex); SD.AnalyticsMonitor.TrackException(ex); } if (!cancellationToken.IsCancellationRequested) { analyzedVersion = textSource.Version; Clear(); foreach (var newResult in results) { newResult.CreateMarker(editor.Document, markerService); } existingResults = results; } if (cancellationTokenSource != null && cancellationTokenSource.Token == cancellationToken) { // Dispose the cancellation token source if it's still the same one as we originally created cancellationTokenSource.Dispose(); cancellationTokenSource = null; } }