Browse Source

Fixed possible StackOverflowException in BooBinding. CodeGenerator can now created "Changed"-events and OnEvent-methods.

git-svn-id: svn://svn.sharpdevelop.net/sharpdevelop/trunk@615 1ccf3a8d-04fe-1044-b7c0-cef0b8235c61
shortcuts
Daniel Grunwald 20 years ago
parent
commit
10fce36f1f
  1. 5
      src/AddIns/BackendBindings/Boo/BooBinding/Project/Src/BooCodeGenerator.cs
  2. 6
      src/AddIns/BackendBindings/Boo/BooBinding/Project/Src/CodeCompletion/ConvertVisitor.cs
  3. 7
      src/AddIns/BackendBindings/Boo/BooBinding/Project/Src/CodeCompletion/ElementReturnType.cs
  4. 7
      src/AddIns/BackendBindings/Boo/BooBinding/Project/Src/CodeCompletion/InferredReturnType.cs
  5. 1
      src/AddIns/DisplayBindings/FormDesigner/Project/Src/FormDesigner/Services/DesignerResourceService.cs
  6. 8
      src/Libraries/NRefactory/Project/Src/Output/AbstractOutputFormatter.cs
  7. 14
      src/Libraries/NRefactory/Project/Src/Output/CSharp/CSharpOutputVisitor.cs
  8. 1
      src/Libraries/NRefactory/Project/Src/Output/IOutputASTVisitor.cs
  9. 4
      src/Libraries/NRefactory/Project/Src/Parser/AST/General/Statements/BlockStatement.cs
  10. 15
      src/Main/Base/Project/Src/Dom/Implementations/GetClassReturnType.cs
  11. 93
      src/Main/Base/Project/Src/Dom/Implementations/ProxyReturnType.cs
  12. 21
      src/Main/Base/Project/Src/Dom/Implementations/SearchClassReturnType.cs
  13. 1
      src/Main/Base/Project/Src/Dom/ModifierEnum.cs
  14. 83
      src/Main/Base/Project/Src/Services/RefactoringService/CodeGenerator.cs
  15. 2
      src/Main/Base/Project/Src/Services/RefactoringService/NRefactoryCodeGenerator.cs
  16. 37
      src/Main/Base/Project/Src/TextEditor/Commands/ClassMemberMenuBuilder.cs

5
src/AddIns/BackendBindings/Boo/BooBinding/Project/Src/BooCodeGenerator.cs

@ -25,9 +25,10 @@ namespace Grunwald.BooBinding
/// </summary> /// </summary>
public class BooCodeGenerator : CodeGenerator 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) public override string GenerateCode(AbstractNode node, string indentation)

6
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); DefaultProperty property = new DefaultProperty(node.Name, CreateReturnType(node), GetModifier(node), GetRegion(node), GetClientRegion(node), OuterClass);
ConvertAttributes(node, property); ConvertAttributes(node, property);
ConvertParameters(node.Parameters, 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); OuterClass.Properties.Add(property);
property.UserData = node; property.UserData = node;
} }

7
src/AddIns/BackendBindings/Boo/BooBinding/Project/Src/CodeCompletion/ElementReturnType.cs

@ -53,12 +53,5 @@ namespace Grunwald.BooBinding.CodeCompletion
return null; return null;
} }
} }
public override bool IsDefaultReturnType {
get {
IReturnType baseType = BaseType;
return (baseType != null) ? baseType.IsDefaultReturnType : false;
}
}
} }
} }

7
src/AddIns/BackendBindings/Boo/BooBinding/Project/Src/CodeCompletion/InferredReturnType.cs

@ -33,13 +33,6 @@ namespace Grunwald.BooBinding.CodeCompletion
this.block = block; this.block = block;
} }
public override bool IsDefaultReturnType {
get {
IReturnType baseType = BaseType;
return (baseType != null) ? baseType.IsDefaultReturnType : false;
}
}
public override IReturnType BaseType { public override IReturnType BaseType {
get { get {
// clear up references to method/expression after the type has been resolved // clear up references to method/expression after the type has been resolved

1
src/AddIns/DisplayBindings/FormDesigner/Project/Src/FormDesigner/Services/DesignerResourceService.cs

@ -154,7 +154,6 @@ namespace ICSharpCode.FormDesigner.Services
if (formFileNode != null) { if (formFileNode != null) {
FileNode fileNode = new FileNode(resourceFileName, FileNodeStatus.InProject); FileNode fileNode = new FileNode(resourceFileName, FileNodeStatus.InProject);
fileNode.AddTo(formFileNode.Parent); fileNode.AddTo(formFileNode.Parent);
fileNode.EnsureVisible();
IncludeFileInProject.IncludeFileNode(fileNode); IncludeFileInProject.IncludeFileNode(fileNode);
ProjectService.SaveSolution(); ProjectService.SaveSolution();
} }

8
src/Libraries/NRefactory/Project/Src/Output/AbstractOutputFormatter.cs

@ -93,6 +93,12 @@ namespace ICSharpCode.NRefactory.PrettyPrinter
int lastLineStart = 0; int lastLineStart = 0;
public bool LastCharacterIsNewLine {
get {
return text.Length == lastLineStart;
}
}
public virtual void NewLine() public virtual void NewLine()
{ {
if (DoNewLine) { if (DoNewLine) {
@ -107,7 +113,7 @@ namespace ICSharpCode.NRefactory.PrettyPrinter
protected void WriteInPreviousLine(string txt) protected void WriteInPreviousLine(string txt)
{ {
if (text.Length == lastLineStart) { if (LastCharacterIsNewLine) {
Indent(); Indent();
text.AppendLine(txt); text.AppendLine(txt);
lastLineStart = text.Length; lastLineStart = text.Length;

14
src/Libraries/NRefactory/Project/Src/Output/CSharp/CSharpOutputVisitor.cs

@ -808,6 +808,7 @@ namespace ICSharpCode.NRefactory.PrettyPrinter
foreach (Statement stmt in blockStatement.Children) { foreach (Statement stmt in blockStatement.Children) {
outputFormatter.Indent(); outputFormatter.Indent();
nodeTracker.TrackedVisit(stmt, null); nodeTracker.TrackedVisit(stmt, null);
if (!outputFormatter.LastCharacterIsNewLine)
outputFormatter.NewLine(); outputFormatter.NewLine();
} }
nodeTracker.EndNode(blockStatement); nodeTracker.EndNode(blockStatement);
@ -845,7 +846,6 @@ namespace ICSharpCode.NRefactory.PrettyPrinter
public object Visit(RaiseEventStatement raiseEventStatement, object data) public object Visit(RaiseEventStatement raiseEventStatement, object data)
{ {
outputFormatter.Indent();
outputFormatter.PrintToken(Tokens.If); outputFormatter.PrintToken(Tokens.If);
outputFormatter.Space(); outputFormatter.Space();
outputFormatter.PrintToken(Tokens.OpenParenthesis); outputFormatter.PrintToken(Tokens.OpenParenthesis);
@ -855,23 +855,19 @@ namespace ICSharpCode.NRefactory.PrettyPrinter
outputFormatter.Space(); outputFormatter.Space();
outputFormatter.PrintToken(Tokens.Null); outputFormatter.PrintToken(Tokens.Null);
outputFormatter.PrintToken(Tokens.CloseParenthesis); outputFormatter.PrintToken(Tokens.CloseParenthesis);
outputFormatter.Space();
outputFormatter.PrintToken(Tokens.OpenCurlyBrace);
outputFormatter.NewLine();
++outputFormatter.IndentationLevel; outputFormatter.BeginBrace(BraceStyle.EndOfLine);
outputFormatter.Indent(); outputFormatter.Indent();
outputFormatter.PrintIdentifier(raiseEventStatement.EventName); outputFormatter.PrintIdentifier(raiseEventStatement.EventName);
outputFormatter.PrintToken(Tokens.OpenParenthesis); outputFormatter.PrintToken(Tokens.OpenParenthesis);
this.AppendCommaSeparatedList(raiseEventStatement.Arguments); this.AppendCommaSeparatedList(raiseEventStatement.Arguments);
outputFormatter.PrintToken(Tokens.CloseParenthesis); outputFormatter.PrintToken(Tokens.CloseParenthesis);
outputFormatter.PrintToken(Tokens.Semicolon); outputFormatter.PrintToken(Tokens.Semicolon);
outputFormatter.NewLine();
--outputFormatter.IndentationLevel;
outputFormatter.Indent();
outputFormatter.PrintToken(Tokens.CloseCurlyBrace);
outputFormatter.NewLine(); outputFormatter.NewLine();
outputFormatter.EndBrace();
return null; return null;
} }

1
src/Libraries/NRefactory/Project/Src/Output/IOutputASTVisitor.cs

@ -47,6 +47,7 @@ namespace ICSharpCode.NRefactory.PrettyPrinter
get; get;
} }
void NewLine(); void NewLine();
void Indent();
void PrintComment(Comment comment); void PrintComment(Comment comment);
void PrintPreProcessingDirective(PreProcessingDirective directive); void PrintPreProcessingDirective(PreProcessingDirective directive);
} }

4
src/Libraries/NRefactory/Project/Src/Parser/AST/General/Statements/BlockStatement.cs

@ -66,6 +66,10 @@ namespace ICSharpCode.NRefactory.Parser.AST
{ {
return data; return data;
} }
public override void AddChild(INode childNode)
{
throw new InvalidOperationException();
}
public override string ToString() public override string ToString()
{ {

15
src/Main/Base/Project/Src/Dom/Implementations/GetClassReturnType.cs

@ -59,7 +59,6 @@ namespace ICSharpCode.SharpDevelop.Dom
return content.GetHashCode() ^ fullName.GetHashCode() ^ (typeParameterCount * 5); return content.GetHashCode() ^ fullName.GetHashCode() ^ (typeParameterCount * 5);
} }
// TODO: Cache BaseType until a new CompilationUnit is generated (static counter in ParserService)
public override IReturnType BaseType { public override IReturnType BaseType {
get { get {
IClass c = content.GetClass(fullName, typeParameterCount); IClass c = content.GetClass(fullName, typeParameterCount);
@ -93,15 +92,21 @@ namespace ICSharpCode.SharpDevelop.Dom
public override string Namespace { public override string Namespace {
get { get {
IReturnType baseType = BaseType; string tmp = base.Namespace;
return (baseType != null) ? baseType.Namespace : fullName.Substring(0, fullName.LastIndexOf('.')); if (tmp == "?") {
return fullName.Substring(0, fullName.LastIndexOf('.'));
}
return tmp;
} }
} }
public override string DotNetName { public override string DotNetName {
get { get {
IReturnType baseType = BaseType; string tmp = base.DotNetName;
return (baseType != null) ? baseType.DotNetName : fullName; if (tmp == "?") {
return fullName;
}
return tmp;
} }
} }

93
src/Main/Base/Project/Src/Dom/Implementations/ProxyReturnType.cs

@ -7,6 +7,7 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using ICSharpCode.Core;
namespace ICSharpCode.SharpDevelop.Dom namespace ICSharpCode.SharpDevelop.Dom
{ {
@ -20,108 +21,154 @@ namespace ICSharpCode.SharpDevelop.Dom
get; 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 { public virtual string FullyQualifiedName {
get { get {
IReturnType baseType = BaseType; IReturnType baseType = BaseType;
return (baseType != null) ? baseType.FullyQualifiedName : "?"; string tmp = (baseType != null && TryEnter()) ? baseType.FullyQualifiedName : "?";
busy = false;
return tmp;
} }
} }
public virtual string Name { public virtual string Name {
get { get {
IReturnType baseType = BaseType; IReturnType baseType = BaseType;
return (baseType != null) ? baseType.Name : "?"; string tmp = (baseType != null && TryEnter()) ? baseType.Name : "?";
busy = false;
return tmp;
} }
} }
public virtual string Namespace { public virtual string Namespace {
get { get {
IReturnType baseType = BaseType; IReturnType baseType = BaseType;
return (baseType != null) ? baseType.Namespace : "?"; string tmp = (baseType != null && TryEnter()) ? baseType.Namespace : "?";
busy = false;
return tmp;
} }
} }
public virtual string DotNetName { public virtual string DotNetName {
get { get {
IReturnType baseType = BaseType; IReturnType baseType = BaseType;
return (baseType != null) ? baseType.DotNetName : "?"; string tmp = (baseType != null && TryEnter()) ? baseType.DotNetName : "?";
busy = false;
return tmp;
} }
} }
public virtual int TypeParameterCount { public virtual int TypeParameterCount {
get { get {
IReturnType baseType = BaseType; IReturnType baseType = BaseType;
return (baseType != null) ? baseType.TypeParameterCount : 0; int tmp = (baseType != null && TryEnter()) ? baseType.TypeParameterCount : 0;
busy = false;
return tmp;
} }
} }
/// <summary>
/// Gets the array ranks of the return type.
/// When the return type is not an array, this property returns null.
/// </summary>
public virtual int ArrayDimensions { public virtual int ArrayDimensions {
get { get {
IReturnType baseType = BaseType; 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 { public virtual IReturnType ArrayElementType {
get { get {
IReturnType baseType = BaseType; 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 { public virtual IReturnType UnboundType {
get { get {
IReturnType baseType = BaseType; IReturnType baseType = BaseType;
return (baseType != null) ? baseType.UnboundType : null; IReturnType tmp = (baseType != null && TryEnter()) ? baseType.UnboundType : null;
busy = false;
return tmp;
} }
} }
public virtual IList<IReturnType> TypeArguments { public virtual IList<IReturnType> TypeArguments {
get { get {
IReturnType baseType = BaseType; IReturnType baseType = BaseType;
return (baseType != null) ? baseType.TypeArguments : null; IList<IReturnType> tmp = (baseType != null && TryEnter()) ? baseType.TypeArguments : null;
busy = false;
return tmp;
} }
} }
/// <summary>
/// Gets the underlying class of this return type.
/// </summary>
public virtual IClass GetUnderlyingClass() public virtual IClass GetUnderlyingClass()
{ {
IReturnType baseType = BaseType; IReturnType baseType = BaseType;
return (baseType != null) ? baseType.GetUnderlyingClass() : null; IClass tmp = (baseType != null && TryEnter()) ? baseType.GetUnderlyingClass() : null;
busy = false;
return tmp;
} }
public virtual List<IMethod> GetMethods() public virtual List<IMethod> GetMethods()
{ {
IReturnType baseType = BaseType; IReturnType baseType = BaseType;
return (baseType != null) ? baseType.GetMethods() : new List<IMethod>(); List<IMethod> tmp = (baseType != null && TryEnter()) ? baseType.GetMethods() : new List<IMethod>();
busy = false;
return tmp;
} }
public virtual List<IProperty> GetProperties() public virtual List<IProperty> GetProperties()
{ {
IReturnType baseType = BaseType; IReturnType baseType = BaseType;
return (baseType != null) ? baseType.GetProperties() : new List<IProperty>(); List<IProperty> tmp = (baseType != null && TryEnter()) ? baseType.GetProperties() : new List<IProperty>();
busy = false;
return tmp;
} }
public virtual List<IField> GetFields() public virtual List<IField> GetFields()
{ {
IReturnType baseType = BaseType; IReturnType baseType = BaseType;
return (baseType != null) ? baseType.GetFields() : new List<IField>(); List<IField> tmp = (baseType != null && TryEnter()) ? baseType.GetFields() : new List<IField>();
busy = false;
return tmp;
} }
public virtual List<IEvent> GetEvents() public virtual List<IEvent> GetEvents()
{ {
IReturnType baseType = BaseType; IReturnType baseType = BaseType;
return (baseType != null) ? baseType.GetEvents() : new List<IEvent>(); List<IEvent> tmp = (baseType != null && TryEnter()) ? baseType.GetEvents() : new List<IEvent>();
busy = false;
return tmp;
} }
public abstract bool IsDefaultReturnType { public virtual bool IsDefaultReturnType {
get; get {
IReturnType baseType = BaseType;
bool tmp = (baseType != null && TryEnter()) ? baseType.IsDefaultReturnType : false;
busy = false;
return tmp;
}
} }
} }
} }

21
src/Main/Base/Project/Src/Dom/Implementations/SearchClassReturnType.cs

@ -126,8 +126,11 @@ namespace ICSharpCode.SharpDevelop.Dom
public override string FullyQualifiedName { public override string FullyQualifiedName {
get { get {
IReturnType baseType = BaseType; string tmp = base.FullyQualifiedName;
return (baseType != null) ? baseType.FullyQualifiedName : name; 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 { public override string DotNetName {
get { get {
IReturnType baseType = BaseType; string tmp = base.DotNetName;
return (baseType != null) ? baseType.DotNetName : name; if (tmp == "?") {
return name;
}
return tmp;
} }
} }

1
src/Main/Base/Project/Src/Dom/ModifierEnum.cs

@ -42,5 +42,6 @@ namespace ICSharpCode.SharpDevelop.Dom
ProtectedAndInternal = Internal | Protected, ProtectedAndInternal = Internal | Protected,
ProtectedOrInternal = 0x80000, ProtectedOrInternal = 0x80000,
VisibilityMask = Private | Internal | Protected | Public,
} }
} }

83
src/Main/Base/Project/Src/Services/RefactoringService/CodeGenerator.cs

@ -6,10 +6,12 @@
*/ */
using System; using System;
using System.Collections;
using System.Collections.Generic; using System.Collections.Generic;
using System.IO; using System.IO;
using System.Text; using System.Text;
using ICSharpCode.SharpDevelop.Dom; using ICSharpCode.SharpDevelop.Dom;
using ICSharpCode.TextEditor;
using ICSharpCode.TextEditor.Document; using ICSharpCode.TextEditor.Document;
using ICSharpCode.NRefactory.Parser.AST; using ICSharpCode.NRefactory.Parser.AST;
@ -209,33 +211,49 @@ namespace ICSharpCode.SharpDevelop.Refactoring
#region Code generation / insertion #region Code generation / insertion
public virtual void InsertCodeAfter(IMember member, IDocument document, params AbstractNode[] nodes) 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) 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);
} }
/// <summary> /// <summary>
/// Generates code for <paramref name="nodes"/> and inserts it into <paramref name="document"/> /// Generates code for <paramref name="nodes"/> and inserts it into <paramref name="document"/>
/// after the line <paramref name="insertLine"/>. /// after the line <paramref name="insertLine"/>.
/// </summary> /// </summary>
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) // insert one line below field (text editor uses different coordinates)
lineSegment = document.GetLineSegment(insertLine); LineSegment lineSegment = document.GetLineSegment(insertLine);
StringBuilder b = new StringBuilder(); StringBuilder b = new StringBuilder();
foreach (AbstractNode node in nodes) { foreach (AbstractNode node in nodes) {
b.AppendLine(indentation); b.AppendLine(indentation);
b.Append(GenerateCode(node, indentation)); b.Append(GenerateCode(node, indentation));
} }
document.Insert(lineSegment.Offset, b.ToString()); document.Insert(lineSegment.Offset, b.ToString());
document.RequestUpdate(new TextAreaUpdate(TextAreaUpdateType.WholeTextArea));
document.CommitUpdate();
} }
/// <summary> /// <summary>
@ -273,11 +291,56 @@ namespace ICSharpCode.SharpDevelop.Refactoring
block.AddChild(new StatementExpression(new AssignmentExpression(left, AssignmentOperatorType.Assign, right))); block.AddChild(new StatementExpression(new AssignmentExpression(left, AssignmentOperatorType.Assign, right)));
property.SetRegion = new PropertySetRegion(block, null); property.SetRegion = new PropertySetRegion(block, null);
} }
property.Modifier = Modifier.Public;
InsertCodeAfter(field, document, property); InsertCodeAfter(field, document, property);
} }
#endregion #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<ParameterDeclarationExpression> parameters = new List<ParameterDeclarationExpression>(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 #region Interface implementation
protected string GetInterfaceName(IReturnType interf, IMember member, ClassFinder context) protected string GetInterfaceName(IReturnType interf, IMember member, ClassFinder context)
{ {
@ -337,7 +400,7 @@ namespace ICSharpCode.SharpDevelop.Refactoring
nodes.Add(md); nodes.Add(md);
} }
} }
InsertCodeAfter(targetClass.Region.BeginLine, document, true, nodes.ToArray()); InsertCodeInClass(targetClass, document, nodes.ToArray());
} }
#endregion #endregion
} }

2
src/Main/Base/Project/Src/Services/RefactoringService/NRefactoryCodeGenerator.cs

@ -28,6 +28,8 @@ namespace ICSharpCode.SharpDevelop.Refactoring
indentCount += 1; indentCount += 1;
} }
visitor.OutputFormatter.IndentationLevel = indentCount / 4; visitor.OutputFormatter.IndentationLevel = indentCount / 4;
if (node is Statement)
visitor.OutputFormatter.Indent();
node.AcceptVisitor(visitor, null); node.AcceptVisitor(visitor, null);
return visitor.Text; return visitor.Text;
} }

37
src/Main/Base/Project/Src/TextEditor/Commands/ClassMemberMenuBuilder.cs

@ -41,6 +41,10 @@ namespace ICSharpCode.SharpDevelop.DefaultEditor.Commands
IMethod method = member as IMethod; IMethod method = member as IMethod;
List<ToolStripItem> list = new List<ToolStripItem>(); List<ToolStripItem> list = new List<ToolStripItem>();
bool canGenerateCode =
member.DeclaringType.ProjectContent.Language.CodeGenerator != null
&& !FindReferencesAndRenameHelper.IsReadOnly(member.DeclaringType);
if (method == null || !method.IsConstructor) { if (method == null || !method.IsConstructor) {
if (!FindReferencesAndRenameHelper.IsReadOnly(member.DeclaringType)) { if (!FindReferencesAndRenameHelper.IsReadOnly(member.DeclaringType)) {
cmd = new MenuCommand("${res:SharpDevelop.Refactoring.RenameCommand}", Rename); cmd = new MenuCommand("${res:SharpDevelop.Refactoring.RenameCommand}", Rename);
@ -70,7 +74,7 @@ namespace ICSharpCode.SharpDevelop.DefaultEditor.Commands
cmd.Tag = foundProperty; cmd.Tag = foundProperty;
list.Add(cmd); list.Add(cmd);
} else { } else {
if (!FindReferencesAndRenameHelper.IsReadOnly(member.DeclaringType)) { if (canGenerateCode) {
cmd = new MenuCommand("${res:SharpDevelop.Refactoring.CreateGetter}", CreateGetter); cmd = new MenuCommand("${res:SharpDevelop.Refactoring.CreateGetter}", CreateGetter);
cmd.Tag = member; cmd.Tag = member;
list.Add(cmd); 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(); return list.ToArray();
} }
@ -116,7 +134,22 @@ namespace ICSharpCode.SharpDevelop.DefaultEditor.Commands
TextEditorControl textEditor = FindReferencesAndRenameHelper.JumpBehindDefinition(member); TextEditorControl textEditor = FindReferencesAndRenameHelper.JumpBehindDefinition(member);
member.DeclaringType.ProjectContent.Language.CodeGenerator.CreateProperty(member, textEditor.Document, true, includeSetter); 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) void GotoTagMember(object sender, EventArgs e)

Loading…
Cancel
Save