SearchedFile SearchForIssues(FileName fileName, ITextSource fileContent, IEnumerable <IssueManager.IssueProvider> providers, CancellationToken cancellationToken) { cancellationToken.ThrowIfCancellationRequested(); var context = SDRefactoringContext.Create(fileName, fileContent, TextLocation.Empty, cancellationToken); ReadOnlyDocument document = null; IHighlighter highlighter = null; var results = new List <SearchResultMatch>(); foreach (var provider in providers) { cancellationToken.ThrowIfCancellationRequested(); foreach (var issue in provider.GetIssues(context)) { if (document == null) { document = new ReadOnlyDocument(fileContent, fileName); highlighter = SD.EditorControlService.CreateHighlighter(document); highlighter.BeginHighlighting(); } results.Add(SearchResultMatch.Create(document, issue.Start, issue.End, highlighter)); } } if (highlighter != null) { highlighter.Dispose(); } if (results.Count > 0) { return(new SearchedFile(fileName, results)); } else { return(null); } }
public override void Execute(EditorRefactoringContext context) { CSharpFullParseInformation parseInformation = context.GetParseInformation() as CSharpFullParseInformation; if (parseInformation != null) { SyntaxTree st = parseInformation.SyntaxTree; Identifier identifier = (Identifier)st.GetNodeAt(context.CaretLocation, node => node.Role == Roles.Identifier); if (identifier == null) { return; } TypeDeclaration interfaceTypeDeclaration = identifier.Parent as TypeDeclaration; if (interfaceTypeDeclaration != null) { // Generate abstract class from interface and abstract members from interface members TypeDeclaration abstractClassTypeNode = (TypeDeclaration)interfaceTypeDeclaration.Clone(); abstractClassTypeNode.ClassType = ClassType.Class; abstractClassTypeNode.Modifiers |= Modifiers.Abstract; foreach (var entity in abstractClassTypeNode.Children.OfType <EntityDeclaration>()) { entity.Modifiers |= Modifiers.Abstract | Modifiers.Public; } var refactoringContext = SDRefactoringContext.Create(context.Editor, CancellationToken.None); using (Script script = refactoringContext.StartScript()) { // Replace interface node with node of abstract class script.Replace(interfaceTypeDeclaration, abstractClassTypeNode); } } } }
public override void Execute(EditorRefactoringContext context) { CSharpFullParseInformation parseInformation = context.GetParseInformation() as CSharpFullParseInformation; if (parseInformation != null) { SyntaxTree st = parseInformation.SyntaxTree; Identifier identifier = (Identifier)st.GetNodeAt(context.CaretLocation, node => node.Role == Roles.Identifier); if (identifier == null) { return; } ParameterDeclaration parameterDeclaration = identifier.Parent as ParameterDeclaration; if (parameterDeclaration == null) { return; } AstNode grandparent = identifier.Parent.Parent; if ((grandparent is MethodDeclaration) || (grandparent is ConstructorDeclaration)) { // Range check condition var rangeCheck = new IfElseStatement( new BinaryOperatorExpression( new BinaryOperatorExpression(new IdentifierExpression(identifier.Name), BinaryOperatorType.LessThan, new IdentifierExpression("lower")), BinaryOperatorType.ConditionalOr, new BinaryOperatorExpression(new IdentifierExpression(identifier.Name), BinaryOperatorType.GreaterThan, new IdentifierExpression("upper")) ), new ThrowStatement( new ObjectCreateExpression( new SimpleType("ArgumentOutOfRangeException"), new List <Expression>() { new PrimitiveExpression(identifier.Name, '"' + identifier.Name + '"'), new IdentifierExpression(identifier.Name), new BinaryOperatorExpression(new PrimitiveExpression("Value must be between "), BinaryOperatorType.Add, new BinaryOperatorExpression(new IdentifierExpression("lower"), BinaryOperatorType.Add, new BinaryOperatorExpression(new PrimitiveExpression(" and "), BinaryOperatorType.Add, new IdentifierExpression("upper")))) } ) ) ); // Add range check as first statement in method's/constructor's body var refactoringContext = SDRefactoringContext.Create(context.Editor, CancellationToken.None); using (Script script = refactoringContext.StartScript()) { if (grandparent is MethodDeclaration) { var methodDeclaration = (MethodDeclaration)grandparent; script.AddTo(methodDeclaration.Body, rangeCheck); } else if (grandparent is ConstructorDeclaration) { var ctorDeclaration = (ConstructorDeclaration)grandparent; script.AddTo(ctorDeclaration.Body, rangeCheck); } } } } }
public override void Execute(EditorRefactoringContext context) { var myContext = SDRefactoringContext.Create(context.Editor, default(CancellationToken)); var currentNode = myContext.RootNode.GetNodeAt <Statement>(context.CaretLocation); if (currentNode == null) { return; } using (var script = myContext.StartScript()) { script.InsertBefore(currentNode, new Comment(string.Format(" disable{1}{0}", issueName, type == SuppressType.Once ? " once " : " "))); } }
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); } } }
void AddAttribute(DomRegion region, IAttribute attribute, string target = "") { var view = SD.FileService.OpenFile(new FileName(region.FileName), false); var editor = view.GetRequiredService <ITextEditor>(); var context = SDRefactoringContext.Create(editor.FileName, editor.Document, region.Begin, CancellationToken.None); var node = context.RootNode.GetNodeAt <EntityDeclaration>(region.Begin); var resolver = context.GetResolverStateBefore(node); var builder = new TypeSystemAstBuilder(resolver); using (Script script = context.StartScript()) { var attr = new AttributeSection(); attr.AttributeTarget = target; attr.Attributes.Add(builder.ConvertAttribute(attribute)); script.AddAttribute(node, attr); } }
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); if (declaringType.Kind == TypeKind.Enum) { foreach (var node in nodes.Reverse()) { int indentLevel = GetIndentLevelAt(area.Document.GetOffset(declaringType.BodyRegion.Begin)); var output = OutputNode(indentLevel, node); var point = insertionPoints[0]; var offset = area.Document.GetOffset(point.Location); var text = output.Text + ","; var delta = point.Insert(area.Document, text); output.RegisterTrackedSegments(script, delta + offset); } tcs.SetResult(script); return(tcs.Task); } InsertWithCursorOnLayer(script, layer, tcs, nodes, area.Document); return(tcs.Task); }
protected virtual void Initialize() { this.refactoringContext = SDRefactoringContext.Create(editor, CancellationToken.None); }
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; } } }