Пример #1
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);
				}
			}
		}
Пример #2
0
        /// <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()));
        }
Пример #3
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);

            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);
        }
Пример #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
            {
            }
        }