diff --git a/src/AddIns/BackendBindings/Boo/BooBinding/Project/Src/BooCodeGenerator.cs b/src/AddIns/BackendBindings/Boo/BooBinding/Project/Src/BooCodeGenerator.cs index ba2dbc7134..4791dc4a38 100644 --- a/src/AddIns/BackendBindings/Boo/BooBinding/Project/Src/BooCodeGenerator.cs +++ b/src/AddIns/BackendBindings/Boo/BooBinding/Project/Src/BooCodeGenerator.cs @@ -25,9 +25,10 @@ namespace Grunwald.BooBinding /// public class BooCodeGenerator : CodeGenerator { - public override void InsertCodeInClass(IClass c, IDocument document, params AbstractNode[] nodes) + public override void InsertCodeAtEnd(DomRegion region, IDocument document, params AbstractNode[] nodes) { - InsertCodeAfter(c.Region.BeginLine, document, true, nodes); + InsertCodeAfter(region.EndLine, document, + GetIndentation(document, region.BeginLine) + '\t', nodes); } public override string GenerateCode(AbstractNode node, string indentation) diff --git a/src/AddIns/BackendBindings/Boo/BooBinding/Project/Src/CodeCompletion/ConvertVisitor.cs b/src/AddIns/BackendBindings/Boo/BooBinding/Project/Src/CodeCompletion/ConvertVisitor.cs index b6ac136eff..d71b388b75 100644 --- a/src/AddIns/BackendBindings/Boo/BooBinding/Project/Src/CodeCompletion/ConvertVisitor.cs +++ b/src/AddIns/BackendBindings/Boo/BooBinding/Project/Src/CodeCompletion/ConvertVisitor.cs @@ -406,6 +406,12 @@ namespace Grunwald.BooBinding.CodeCompletion DefaultProperty property = new DefaultProperty(node.Name, CreateReturnType(node), GetModifier(node), GetRegion(node), GetClientRegion(node), OuterClass); ConvertAttributes(node, property); ConvertParameters(node.Parameters, property); + if (node.Getter != null && node.Getter.Body != null) { + property.GetterRegion = GetClientRegion(node.Getter); + } + if (node.Setter != null && node.Setter.Body != null) { + property.SetterRegion = GetClientRegion(node.Setter); + } OuterClass.Properties.Add(property); property.UserData = node; } diff --git a/src/AddIns/BackendBindings/Boo/BooBinding/Project/Src/CodeCompletion/ElementReturnType.cs b/src/AddIns/BackendBindings/Boo/BooBinding/Project/Src/CodeCompletion/ElementReturnType.cs index 5bb523774b..94afbe5c95 100644 --- a/src/AddIns/BackendBindings/Boo/BooBinding/Project/Src/CodeCompletion/ElementReturnType.cs +++ b/src/AddIns/BackendBindings/Boo/BooBinding/Project/Src/CodeCompletion/ElementReturnType.cs @@ -53,12 +53,5 @@ namespace Grunwald.BooBinding.CodeCompletion return null; } } - - public override bool IsDefaultReturnType { - get { - IReturnType baseType = BaseType; - return (baseType != null) ? baseType.IsDefaultReturnType : false; - } - } } } diff --git a/src/AddIns/BackendBindings/Boo/BooBinding/Project/Src/CodeCompletion/InferredReturnType.cs b/src/AddIns/BackendBindings/Boo/BooBinding/Project/Src/CodeCompletion/InferredReturnType.cs index 234e0b7d9c..98ecc4b8d3 100644 --- a/src/AddIns/BackendBindings/Boo/BooBinding/Project/Src/CodeCompletion/InferredReturnType.cs +++ b/src/AddIns/BackendBindings/Boo/BooBinding/Project/Src/CodeCompletion/InferredReturnType.cs @@ -33,13 +33,6 @@ namespace Grunwald.BooBinding.CodeCompletion this.block = block; } - public override bool IsDefaultReturnType { - get { - IReturnType baseType = BaseType; - return (baseType != null) ? baseType.IsDefaultReturnType : false; - } - } - public override IReturnType BaseType { get { // clear up references to method/expression after the type has been resolved diff --git a/src/AddIns/DisplayBindings/FormDesigner/Project/Src/FormDesigner/Services/DesignerResourceService.cs b/src/AddIns/DisplayBindings/FormDesigner/Project/Src/FormDesigner/Services/DesignerResourceService.cs index 37454df403..2f32f7e005 100644 --- a/src/AddIns/DisplayBindings/FormDesigner/Project/Src/FormDesigner/Services/DesignerResourceService.cs +++ b/src/AddIns/DisplayBindings/FormDesigner/Project/Src/FormDesigner/Services/DesignerResourceService.cs @@ -154,10 +154,9 @@ namespace ICSharpCode.FormDesigner.Services if (formFileNode != null) { FileNode fileNode = new FileNode(resourceFileName, FileNodeStatus.InProject); fileNode.AddTo(formFileNode.Parent); - fileNode.EnsureVisible(); IncludeFileInProject.IncludeFileNode(fileNode); ProjectService.SaveSolution(); - } + } } } } diff --git a/src/Libraries/NRefactory/Project/Src/Output/AbstractOutputFormatter.cs b/src/Libraries/NRefactory/Project/Src/Output/AbstractOutputFormatter.cs index 698567f551..ce989e7095 100644 --- a/src/Libraries/NRefactory/Project/Src/Output/AbstractOutputFormatter.cs +++ b/src/Libraries/NRefactory/Project/Src/Output/AbstractOutputFormatter.cs @@ -93,6 +93,12 @@ namespace ICSharpCode.NRefactory.PrettyPrinter int lastLineStart = 0; + public bool LastCharacterIsNewLine { + get { + return text.Length == lastLineStart; + } + } + public virtual void NewLine() { if (DoNewLine) { @@ -107,7 +113,7 @@ namespace ICSharpCode.NRefactory.PrettyPrinter protected void WriteInPreviousLine(string txt) { - if (text.Length == lastLineStart) { + if (LastCharacterIsNewLine) { Indent(); text.AppendLine(txt); lastLineStart = text.Length; diff --git a/src/Libraries/NRefactory/Project/Src/Output/CSharp/CSharpOutputVisitor.cs b/src/Libraries/NRefactory/Project/Src/Output/CSharp/CSharpOutputVisitor.cs index 787a914798..8f102e63bc 100644 --- a/src/Libraries/NRefactory/Project/Src/Output/CSharp/CSharpOutputVisitor.cs +++ b/src/Libraries/NRefactory/Project/Src/Output/CSharp/CSharpOutputVisitor.cs @@ -808,7 +808,8 @@ namespace ICSharpCode.NRefactory.PrettyPrinter foreach (Statement stmt in blockStatement.Children) { outputFormatter.Indent(); nodeTracker.TrackedVisit(stmt, null); - outputFormatter.NewLine(); + if (!outputFormatter.LastCharacterIsNewLine) + outputFormatter.NewLine(); } nodeTracker.EndNode(blockStatement); outputFormatter.EndBrace(); @@ -845,7 +846,6 @@ namespace ICSharpCode.NRefactory.PrettyPrinter public object Visit(RaiseEventStatement raiseEventStatement, object data) { - outputFormatter.Indent(); outputFormatter.PrintToken(Tokens.If); outputFormatter.Space(); outputFormatter.PrintToken(Tokens.OpenParenthesis); @@ -855,23 +855,19 @@ namespace ICSharpCode.NRefactory.PrettyPrinter outputFormatter.Space(); outputFormatter.PrintToken(Tokens.Null); outputFormatter.PrintToken(Tokens.CloseParenthesis); - outputFormatter.Space(); - outputFormatter.PrintToken(Tokens.OpenCurlyBrace); - outputFormatter.NewLine(); - ++outputFormatter.IndentationLevel; + outputFormatter.BeginBrace(BraceStyle.EndOfLine); + outputFormatter.Indent(); outputFormatter.PrintIdentifier(raiseEventStatement.EventName); outputFormatter.PrintToken(Tokens.OpenParenthesis); this.AppendCommaSeparatedList(raiseEventStatement.Arguments); outputFormatter.PrintToken(Tokens.CloseParenthesis); outputFormatter.PrintToken(Tokens.Semicolon); - outputFormatter.NewLine(); - --outputFormatter.IndentationLevel; - outputFormatter.Indent(); - outputFormatter.PrintToken(Tokens.CloseCurlyBrace); outputFormatter.NewLine(); + outputFormatter.EndBrace(); + return null; } diff --git a/src/Libraries/NRefactory/Project/Src/Output/IOutputASTVisitor.cs b/src/Libraries/NRefactory/Project/Src/Output/IOutputASTVisitor.cs index f753fc8993..38d8035236 100644 --- a/src/Libraries/NRefactory/Project/Src/Output/IOutputASTVisitor.cs +++ b/src/Libraries/NRefactory/Project/Src/Output/IOutputASTVisitor.cs @@ -47,6 +47,7 @@ namespace ICSharpCode.NRefactory.PrettyPrinter get; } void NewLine(); + void Indent(); void PrintComment(Comment comment); void PrintPreProcessingDirective(PreProcessingDirective directive); } diff --git a/src/Libraries/NRefactory/Project/Src/Parser/AST/General/Statements/BlockStatement.cs b/src/Libraries/NRefactory/Project/Src/Parser/AST/General/Statements/BlockStatement.cs index 38ab003f11..014738cc09 100644 --- a/src/Libraries/NRefactory/Project/Src/Parser/AST/General/Statements/BlockStatement.cs +++ b/src/Libraries/NRefactory/Project/Src/Parser/AST/General/Statements/BlockStatement.cs @@ -33,7 +33,7 @@ namespace ICSharpCode.NRefactory.Parser.AST public override string ToString() { - return String.Format("[BlockStatement: Children={0}]", + return String.Format("[BlockStatement: Children={0}]", GetCollectionString(base.Children)); } } @@ -66,6 +66,10 @@ namespace ICSharpCode.NRefactory.Parser.AST { return data; } + public override void AddChild(INode childNode) + { + throw new InvalidOperationException(); + } public override string ToString() { diff --git a/src/Main/Base/Project/Src/Dom/Implementations/GetClassReturnType.cs b/src/Main/Base/Project/Src/Dom/Implementations/GetClassReturnType.cs index 8a99c1e426..a86c1e9e41 100644 --- a/src/Main/Base/Project/Src/Dom/Implementations/GetClassReturnType.cs +++ b/src/Main/Base/Project/Src/Dom/Implementations/GetClassReturnType.cs @@ -59,7 +59,6 @@ namespace ICSharpCode.SharpDevelop.Dom return content.GetHashCode() ^ fullName.GetHashCode() ^ (typeParameterCount * 5); } - // TODO: Cache BaseType until a new CompilationUnit is generated (static counter in ParserService) public override IReturnType BaseType { get { IClass c = content.GetClass(fullName, typeParameterCount); @@ -93,15 +92,21 @@ namespace ICSharpCode.SharpDevelop.Dom public override string Namespace { get { - IReturnType baseType = BaseType; - return (baseType != null) ? baseType.Namespace : fullName.Substring(0, fullName.LastIndexOf('.')); + string tmp = base.Namespace; + if (tmp == "?") { + return fullName.Substring(0, fullName.LastIndexOf('.')); + } + return tmp; } } public override string DotNetName { get { - IReturnType baseType = BaseType; - return (baseType != null) ? baseType.DotNetName : fullName; + string tmp = base.DotNetName; + if (tmp == "?") { + return fullName; + } + return tmp; } } diff --git a/src/Main/Base/Project/Src/Dom/Implementations/ProxyReturnType.cs b/src/Main/Base/Project/Src/Dom/Implementations/ProxyReturnType.cs index f89a98fab8..827af1e6fb 100644 --- a/src/Main/Base/Project/Src/Dom/Implementations/ProxyReturnType.cs +++ b/src/Main/Base/Project/Src/Dom/Implementations/ProxyReturnType.cs @@ -7,6 +7,7 @@ using System; using System.Collections.Generic; +using ICSharpCode.Core; namespace ICSharpCode.SharpDevelop.Dom { @@ -20,108 +21,154 @@ namespace ICSharpCode.SharpDevelop.Dom get; } + // Required to prevent stack overflow on inferrence cycles + bool busy = false; + + // keep this method as small as possible, it should be inlined! + bool TryEnter() + { + if (busy) { + PrintTryEnterWarning(); + return false; + } else { + busy = true; + return true; + } + } + + void PrintTryEnterWarning() + { + LoggingService.Info("TryEnter failed on " + ToString()); + } + public virtual string FullyQualifiedName { get { IReturnType baseType = BaseType; - return (baseType != null) ? baseType.FullyQualifiedName : "?"; + string tmp = (baseType != null && TryEnter()) ? baseType.FullyQualifiedName : "?"; + busy = false; + return tmp; } } public virtual string Name { get { IReturnType baseType = BaseType; - return (baseType != null) ? baseType.Name : "?"; + string tmp = (baseType != null && TryEnter()) ? baseType.Name : "?"; + busy = false; + return tmp; } } public virtual string Namespace { get { IReturnType baseType = BaseType; - return (baseType != null) ? baseType.Namespace : "?"; + string tmp = (baseType != null && TryEnter()) ? baseType.Namespace : "?"; + busy = false; + return tmp; } } public virtual string DotNetName { get { IReturnType baseType = BaseType; - return (baseType != null) ? baseType.DotNetName : "?"; + string tmp = (baseType != null && TryEnter()) ? baseType.DotNetName : "?"; + busy = false; + return tmp; } } public virtual int TypeParameterCount { get { IReturnType baseType = BaseType; - return (baseType != null) ? baseType.TypeParameterCount : 0; + int tmp = (baseType != null && TryEnter()) ? baseType.TypeParameterCount : 0; + busy = false; + return tmp; } } - /// - /// Gets the array ranks of the return type. - /// When the return type is not an array, this property returns null. - /// public virtual int ArrayDimensions { get { IReturnType baseType = BaseType; - return (baseType != null) ? baseType.ArrayDimensions : 0; + int tmp = (baseType != null && TryEnter()) ? baseType.ArrayDimensions : 0; + busy = false; + return tmp; } } public virtual IReturnType ArrayElementType { get { IReturnType baseType = BaseType; - return (baseType != null) ? baseType.ArrayElementType : null; + IReturnType tmp = (baseType != null && TryEnter()) ? baseType.ArrayElementType : null; + busy = false; + return tmp; } } public virtual IReturnType UnboundType { get { IReturnType baseType = BaseType; - return (baseType != null) ? baseType.UnboundType : null; + IReturnType tmp = (baseType != null && TryEnter()) ? baseType.UnboundType : null; + busy = false; + return tmp; } } public virtual IList TypeArguments { get { IReturnType baseType = BaseType; - return (baseType != null) ? baseType.TypeArguments : null; + IList tmp = (baseType != null && TryEnter()) ? baseType.TypeArguments : null; + busy = false; + return tmp; } } - /// - /// Gets the underlying class of this return type. - /// public virtual IClass GetUnderlyingClass() { IReturnType baseType = BaseType; - return (baseType != null) ? baseType.GetUnderlyingClass() : null; + IClass tmp = (baseType != null && TryEnter()) ? baseType.GetUnderlyingClass() : null; + busy = false; + return tmp; } public virtual List GetMethods() { IReturnType baseType = BaseType; - return (baseType != null) ? baseType.GetMethods() : new List(); + List tmp = (baseType != null && TryEnter()) ? baseType.GetMethods() : new List(); + busy = false; + return tmp; } public virtual List GetProperties() { IReturnType baseType = BaseType; - return (baseType != null) ? baseType.GetProperties() : new List(); + List tmp = (baseType != null && TryEnter()) ? baseType.GetProperties() : new List(); + busy = false; + return tmp; } public virtual List GetFields() { IReturnType baseType = BaseType; - return (baseType != null) ? baseType.GetFields() : new List(); + List tmp = (baseType != null && TryEnter()) ? baseType.GetFields() : new List(); + busy = false; + return tmp; } public virtual List GetEvents() { IReturnType baseType = BaseType; - return (baseType != null) ? baseType.GetEvents() : new List(); + List tmp = (baseType != null && TryEnter()) ? baseType.GetEvents() : new List(); + busy = false; + return tmp; } - public abstract bool IsDefaultReturnType { - get; + public virtual bool IsDefaultReturnType { + get { + IReturnType baseType = BaseType; + bool tmp = (baseType != null && TryEnter()) ? baseType.IsDefaultReturnType : false; + busy = false; + return tmp; + } } } } diff --git a/src/Main/Base/Project/Src/Dom/Implementations/SearchClassReturnType.cs b/src/Main/Base/Project/Src/Dom/Implementations/SearchClassReturnType.cs index 93533cd98f..0ebf9c3512 100644 --- a/src/Main/Base/Project/Src/Dom/Implementations/SearchClassReturnType.cs +++ b/src/Main/Base/Project/Src/Dom/Implementations/SearchClassReturnType.cs @@ -126,8 +126,11 @@ namespace ICSharpCode.SharpDevelop.Dom public override string FullyQualifiedName { get { - IReturnType baseType = BaseType; - return (baseType != null) ? baseType.FullyQualifiedName : name; + string tmp = base.FullyQualifiedName; + if (tmp == "?") { + return name; + } + return tmp; } } @@ -137,17 +140,13 @@ namespace ICSharpCode.SharpDevelop.Dom } } - public override string Namespace { - get { - IReturnType baseType = BaseType; - return (baseType != null) ? baseType.Namespace : "?"; - } - } - public override string DotNetName { get { - IReturnType baseType = BaseType; - return (baseType != null) ? baseType.DotNetName : name; + string tmp = base.DotNetName; + if (tmp == "?") { + return name; + } + return tmp; } } diff --git a/src/Main/Base/Project/Src/Dom/ModifierEnum.cs b/src/Main/Base/Project/Src/Dom/ModifierEnum.cs index 4ef79839c8..fee08577d3 100644 --- a/src/Main/Base/Project/Src/Dom/ModifierEnum.cs +++ b/src/Main/Base/Project/Src/Dom/ModifierEnum.cs @@ -42,5 +42,6 @@ namespace ICSharpCode.SharpDevelop.Dom ProtectedAndInternal = Internal | Protected, ProtectedOrInternal = 0x80000, + VisibilityMask = Private | Internal | Protected | Public, } } diff --git a/src/Main/Base/Project/Src/Services/RefactoringService/CodeGenerator.cs b/src/Main/Base/Project/Src/Services/RefactoringService/CodeGenerator.cs index 26661c17d4..05da417bc6 100644 --- a/src/Main/Base/Project/Src/Services/RefactoringService/CodeGenerator.cs +++ b/src/Main/Base/Project/Src/Services/RefactoringService/CodeGenerator.cs @@ -6,10 +6,12 @@ */ using System; +using System.Collections; using System.Collections.Generic; using System.IO; using System.Text; using ICSharpCode.SharpDevelop.Dom; +using ICSharpCode.TextEditor; using ICSharpCode.TextEditor.Document; using ICSharpCode.NRefactory.Parser.AST; @@ -209,33 +211,49 @@ namespace ICSharpCode.SharpDevelop.Refactoring #region Code generation / insertion public virtual void InsertCodeAfter(IMember member, IDocument document, params AbstractNode[] nodes) { - InsertCodeAfter(member.Region.EndLine, document, false, nodes); + if (member is IMethodOrProperty) { + InsertCodeAfter(((IMethodOrProperty)member).BodyRegion.EndLine, document, + GetIndentation(document, member.Region.BeginLine), nodes); + } else { + InsertCodeAfter(member.Region.EndLine, document, + GetIndentation(document, member.Region.BeginLine), nodes); + } + } + + public virtual void InsertCodeAtEnd(DomRegion region, IDocument document, params AbstractNode[] nodes) + { + InsertCodeAfter(region.EndLine - 1, document, + GetIndentation(document, region.BeginLine) + '\t', nodes); } public virtual void InsertCodeInClass(IClass c, IDocument document, params AbstractNode[] nodes) { - InsertCodeAfter(c.Region.EndLine - 1, document, false, nodes); + InsertCodeAtEnd(c.Region, document, nodes); + } + + protected string GetIndentation(IDocument document, int line) + { + LineSegment lineSegment = document.GetLineSegment(line - 1); + string lineText = document.GetText(lineSegment.Offset, lineSegment.Length); + return lineText.Substring(0, lineText.Length - lineText.TrimStart().Length); } /// /// Generates code for and inserts it into /// after the line . /// - public virtual void InsertCodeAfter(int insertLine, IDocument document, bool addIndentation, params AbstractNode[] nodes) + protected void InsertCodeAfter(int insertLine, IDocument document, string indentation, params AbstractNode[] nodes) { - LineSegment lineSegment = document.GetLineSegment(insertLine - 1); - string lineText = document.GetText(lineSegment.Offset, lineSegment.Length); - string indentation = lineText.Substring(0, lineText.Length - lineText.TrimStart().Length); - if (addIndentation) - indentation += '\t'; // insert one line below field (text editor uses different coordinates) - lineSegment = document.GetLineSegment(insertLine); + LineSegment lineSegment = document.GetLineSegment(insertLine); StringBuilder b = new StringBuilder(); foreach (AbstractNode node in nodes) { b.AppendLine(indentation); b.Append(GenerateCode(node, indentation)); } document.Insert(lineSegment.Offset, b.ToString()); + document.RequestUpdate(new TextAreaUpdate(TextAreaUpdateType.WholeTextArea)); + document.CommitUpdate(); } /// @@ -273,11 +291,56 @@ namespace ICSharpCode.SharpDevelop.Refactoring block.AddChild(new StatementExpression(new AssignmentExpression(left, AssignmentOperatorType.Assign, right))); property.SetRegion = new PropertySetRegion(block, null); } + property.Modifier = Modifier.Public; InsertCodeAfter(field, document, property); } #endregion + #region Generate Changed Event + public virtual void CreateChangedEvent(IProperty property, IDocument document) + { + string name = property.Name + "Changed"; + EventDeclaration ed = new EventDeclaration(new TypeReference("EventHandler"), name, + ConvertModifier(property.Modifiers & (ModifierEnum.VisibilityMask | ModifierEnum.Static)) + , null); + InsertCodeAfter(property, document, ed); + + ArrayList parameters = new ArrayList(2); + if (property.IsStatic) + parameters.Add(new PrimitiveExpression(null, "null")); + else + parameters.Add(new ThisReferenceExpression()); + parameters.Add(new FieldReferenceExpression(new IdentifierExpression("EventArgs"), "Empty")); + InsertCodeAtEnd(property.SetterRegion, document, + new RaiseEventStatement(name, parameters)); + } + #endregion + + #region Generate OnEventMethod + public virtual void CreateOnEventMethod(IEvent e, IDocument document) + { + TypeReference type = ConvertType(e.ReturnType, new ClassFinder(e)); + if (type.Type.EndsWith("Handler")) + type.Type = type.Type.Substring(0, type.Type.Length - 7) + "Args"; + + List parameters = new List(1); + parameters.Add(new ParameterDeclarationExpression(type, "e")); + MethodDeclaration method = new MethodDeclaration("On" + e.Name, + ConvertModifier(e.Modifiers | ModifierEnum.Virtual), + new TypeReference("System.Void"), + parameters, null); + + ArrayList arguments = new ArrayList(2); + arguments.Add(new ThisReferenceExpression()); + arguments.Add(new IdentifierExpression("e")); + method.Body = new BlockStatement(); + method.Body.AddChild(new RaiseEventStatement(e.Name, arguments)); + + InsertCodeAfter(e, document, method); + } + #endregion + #region Interface implementation protected string GetInterfaceName(IReturnType interf, IMember member, ClassFinder context) { @@ -337,7 +400,7 @@ namespace ICSharpCode.SharpDevelop.Refactoring nodes.Add(md); } } - InsertCodeAfter(targetClass.Region.BeginLine, document, true, nodes.ToArray()); + InsertCodeInClass(targetClass, document, nodes.ToArray()); } #endregion } diff --git a/src/Main/Base/Project/Src/Services/RefactoringService/NRefactoryCodeGenerator.cs b/src/Main/Base/Project/Src/Services/RefactoringService/NRefactoryCodeGenerator.cs index c8ddc7ae7e..f58c0f04a1 100644 --- a/src/Main/Base/Project/Src/Services/RefactoringService/NRefactoryCodeGenerator.cs +++ b/src/Main/Base/Project/Src/Services/RefactoringService/NRefactoryCodeGenerator.cs @@ -28,6 +28,8 @@ namespace ICSharpCode.SharpDevelop.Refactoring indentCount += 1; } visitor.OutputFormatter.IndentationLevel = indentCount / 4; + if (node is Statement) + visitor.OutputFormatter.Indent(); node.AcceptVisitor(visitor, null); return visitor.Text; } diff --git a/src/Main/Base/Project/Src/TextEditor/Commands/ClassMemberMenuBuilder.cs b/src/Main/Base/Project/Src/TextEditor/Commands/ClassMemberMenuBuilder.cs index f9fef6e9ca..a424e12668 100644 --- a/src/Main/Base/Project/Src/TextEditor/Commands/ClassMemberMenuBuilder.cs +++ b/src/Main/Base/Project/Src/TextEditor/Commands/ClassMemberMenuBuilder.cs @@ -41,6 +41,10 @@ namespace ICSharpCode.SharpDevelop.DefaultEditor.Commands IMethod method = member as IMethod; List list = new List(); + bool canGenerateCode = + member.DeclaringType.ProjectContent.Language.CodeGenerator != null + && !FindReferencesAndRenameHelper.IsReadOnly(member.DeclaringType); + if (method == null || !method.IsConstructor) { if (!FindReferencesAndRenameHelper.IsReadOnly(member.DeclaringType)) { cmd = new MenuCommand("${res:SharpDevelop.Refactoring.RenameCommand}", Rename); @@ -70,7 +74,7 @@ namespace ICSharpCode.SharpDevelop.DefaultEditor.Commands cmd.Tag = foundProperty; list.Add(cmd); } else { - if (!FindReferencesAndRenameHelper.IsReadOnly(member.DeclaringType)) { + if (canGenerateCode) { cmd = new MenuCommand("${res:SharpDevelop.Refactoring.CreateGetter}", CreateGetter); cmd.Tag = member; list.Add(cmd); @@ -80,6 +84,20 @@ namespace ICSharpCode.SharpDevelop.DefaultEditor.Commands } } } + if (member is IProperty) { + if (((IProperty)member).CanSet && canGenerateCode) { + cmd = new MenuCommand("${res:SharpDevelop.Refactoring.CreateChangedEvent}", CreateChangedEvent); + cmd.Tag = member; + list.Add(cmd); + } + } + if (member is IEvent) { + if (canGenerateCode) { + cmd = new MenuCommand("${res:SharpDevelop.Refactoring.CreateOnEventMethod}", CreateOnEventMethod); + cmd.Tag = member; + list.Add(cmd); + } + } return list.ToArray(); } @@ -116,7 +134,22 @@ namespace ICSharpCode.SharpDevelop.DefaultEditor.Commands TextEditorControl textEditor = FindReferencesAndRenameHelper.JumpBehindDefinition(member); member.DeclaringType.ProjectContent.Language.CodeGenerator.CreateProperty(member, textEditor.Document, true, includeSetter); - textEditor.Refresh(); + } + + void CreateChangedEvent(object sender, EventArgs e) + { + MenuCommand item = (MenuCommand)sender; + IProperty member = (IProperty)item.Tag; + TextEditorControl textEditor = FindReferencesAndRenameHelper.JumpBehindDefinition(member); + member.DeclaringType.ProjectContent.Language.CodeGenerator.CreateChangedEvent(member, textEditor.Document); + } + + void CreateOnEventMethod(object sender, EventArgs e) + { + MenuCommand item = (MenuCommand)sender; + IEvent member = (IEvent)item.Tag; + TextEditorControl textEditor = FindReferencesAndRenameHelper.JumpBehindDefinition(member); + member.DeclaringType.ProjectContent.Language.CodeGenerator.CreateOnEventMethod(member, textEditor.Document); } void GotoTagMember(object sender, EventArgs e)