Пример #1
0
        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>());
            }
        }
Пример #3
0
 protected virtual void Initialize()
 {
     this.refactoringContext = SDRefactoringContext.Create(editor, CancellationToken.None);
 }
Пример #4
0
        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
            {
            }
        }
Пример #5
0
        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;
            }
        }