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); } } }
/// <summary> /// Returns a refactoring context for the file that contains the entity. /// This will open the file in the text editor if necessary. /// </summary> public static SDRefactoringContext CreateRefactoringContext(this IEntity entity) { var typeDef = entity as ITypeDefinition; DomRegion region; if (typeDef != null) { IUnresolvedTypeDefinition bestPart = null; foreach (var part in typeDef.Parts) { if (bestPart == null || EntityModelContextUtils.IsBetterPart(part, bestPart, ".al")) { bestPart = part; } } region = bestPart.Region; } else { region = entity.Region; } return(CreateRefactoringContext(region, entity.ParentAssembly.GetProject())); }
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); }
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 { } }