Пример #1
0
		public EditorScript(ITextEditor editor, SDRefactoringContext context, CSharpFormattingOptions formattingOptions)
			: base(editor.Document, formattingOptions, context.TextEditorOptions)
		{
			this.editor = editor;
			this.context = context;
			this.textSegmentCollection = new TextSegmentCollection<TextSegment>((TextDocument)editor.Document);
		}
Пример #2
0
		CodeIssue CreateCodeIssue(Error error, SDRefactoringContext context)
		{
			IDocument document = context.Document;
			TextLocation begin = error.Region.Begin;
			if (begin.Line <= 0 || begin.Line > document.LineCount)
				return null;
			
			int offset = document.GetOffset(begin.Line, begin.Column);
			// the parser sometimes reports errors in the whitespace prior to the invalid token, so search for the next word:
			while (offset < document.TextLength && IsSpaceOrTab(document.GetCharAt(offset)))
				offset++;
			int endOffset = TextUtilities.GetNextCaretPosition(document, offset, System.Windows.Documents.LogicalDirection.Forward, CaretPositioningMode.WordBorderOrSymbol);
			if (endOffset < 0) endOffset = document.TextLength;
			int length = endOffset - offset;

			if (length < 1) {
				// marker should be at least 1 characters long,
				// but take care that we don't make it longer than the document
				length = Math.Min(1, document.TextLength - offset);
			}
			
			TextLocation start = document.GetLocation(offset);
			TextLocation end = document.GetLocation(offset + length);
			return new CodeIssue(start, end, error.Message);
		}
		public void Execute(EditorRefactoringContext context)
		{
			var resolver = context.GetAstResolverAsync().Result;
			var refactoringContext = new SDRefactoringContext(context.Editor, resolver, context.CaretLocation);
			var action = getUpdatedCodeAction(refactoringContext);
			if (action != null) {
				using (var script = refactoringContext.StartScript()) {
					action.Run(script);
				}
			}
		}
		public static SDRefactoringContext Create(FileName fileName, ITextSource textSource, TextLocation location = default(TextLocation), CancellationToken cancellationToken = default(CancellationToken))
		{
			var parseInfo = SD.ParserService.Parse(fileName, textSource, cancellationToken: cancellationToken) as CSharpFullParseInformation;
			var compilation = SD.ParserService.GetCompilationForFile(fileName);
			CSharpAstResolver resolver;
			if (parseInfo != null) {
				resolver = parseInfo.GetResolver(compilation);
			} else {
				// create dummy refactoring context
				resolver = new CSharpAstResolver(compilation, new SyntaxTree());
			}
			var context = new SDRefactoringContext(textSource, resolver, location, 0, 0, cancellationToken);
			return context;
		}
		public static SDRefactoringContext Create(ITextEditor editor, CancellationToken cancellationToken)
		{
			var parseInfo = SD.ParserService.Parse(editor.FileName, editor.Document, cancellationToken: cancellationToken) as CSharpFullParseInformation;
			var compilation = SD.ParserService.GetCompilationForFile(editor.FileName);
			CSharpAstResolver resolver;
			if (parseInfo != null) {
				resolver = parseInfo.GetResolver(compilation);
			} else {
				// create dummy refactoring context
				resolver = new CSharpAstResolver(compilation, new SyntaxTree());
			}
			var context = new SDRefactoringContext(editor, resolver, editor.Caret.Location, cancellationToken);
			return context;
		}
Пример #6
0
		CodeIssue CreateCodeIssue(Error error, SDRefactoringContext context)
		{
			IDocument document = context.Document;
			TextLocation begin = error.Region.Begin;
			
			int offset = document.GetOffset(begin.Line, begin.Column);
			int endOffset = TextUtilities.GetNextCaretPosition(document, offset, System.Windows.Documents.LogicalDirection.Forward, CaretPositioningMode.WordBorderOrSymbol);
			if (endOffset < 0) endOffset = document.TextLength;
			int length = endOffset - offset;
			
			if (length < 2) {
				// marker should be at least 2 characters long, but take care that we don't make
				// it longer than the document
				length = Math.Min(2, document.TextLength - offset);
			}
			
			TextLocation end = document.GetLocation(offset + length);
			return new CodeIssue(begin, end, error.Message);
		}
		protected virtual void Initialize()
		{
			this.refactoringContext = SDRefactoringContext.Create(editor, CancellationToken.None);
		}
			public Task<IContextAction[]> GetAvailableActionsAsync(EditorRefactoringContext context, CancellationToken cancellationToken)
			{
				ITextEditor editor = context.Editor;
				// grab SelectionStart/SelectionLength while we're still on the main thread
				int selectionStart = editor.SelectionStart;
				int selectionLength = editor.SelectionLength;
				return Task.Run(
					async delegate {
						try {
							if (!CreateCodeActionProvider())
								return new IContextAction[0];
							CSharpAstResolver resolver = await context.GetAstResolverAsync().ConfigureAwait(false);
							var refactoringContext = new SDRefactoringContext(context.TextSource, resolver, context.CaretLocation, selectionStart, selectionLength, cancellationToken);
							return codeActionProvider.GetActions(refactoringContext).Select(Wrap).ToArray();
						} catch (Exception ex) {
							SD.Log.WarnFormatted("CSharpContextActionProviderWrapper crashed: {0}", ex);
							SD.AnalyticsMonitor.TrackException(ex);
							return new IContextAction[0];
						}
					}, cancellationToken);
			}
Пример #9
0
        public override void InsertEventHandler(ITypeDefinition target, string name, IEvent eventDefinition, bool jumpTo)
        {
            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);

            using (Script script = context.StartScript()) {
                // FIXME : will not work properly if there are no members.
                if (last == match)
                {
                    throw new NotImplementedException();
                    // TODO InsertWithCursor not implemented!
                    //script.InsertWithCursor("Insert event handler", Script.InsertPosition.End, decl).RunSynchronously();
                }
                else
                {
                    // TODO does not jump correctly...
                    script.InsertAfter(node, decl);
                    editor.JumpTo(throwStmt.StartLocation.Line, throwStmt.StartLocation.Column);
                }
            }
        }
Пример #10
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, ".cs"))
                {
                    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);
        }
Пример #11
0
		async void RunAnalysis(ITextSource textSource, CSharpFullParseInformation 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;
			}
		}
        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 (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>());
            }
        }
        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);

            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;
                }
            }
        }
Пример #14
0
        async void RunAnalysis(ITextSource textSource, CSharpFullParseInformation 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;
            }
        }
			public Task<IContextAction[]> GetAvailableActionsAsync(EditorRefactoringContext context, CancellationToken cancellationToken)
			{
				ITextEditor editor = context.Editor;
				// grab SelectionStart/SelectionLength while we're still on the main thread
				int selectionStart = editor.SelectionStart;
				int selectionLength = editor.SelectionLength;
				return Task.Run(
					async delegate {
						if (!CreateCodeActionProvider())
							return new IContextAction[0];
						CSharpAstResolver resolver = await context.GetAstResolverAsync().ConfigureAwait(false);
						var refactoringContext = new SDRefactoringContext(context.TextSource, resolver, context.CaretLocation, selectionStart, selectionLength, cancellationToken);
						return codeActionProvider.GetActions(refactoringContext).Select(Wrap).ToArray();
					}, cancellationToken);
			}