Browse Source
git-svn-id: svn://svn.sharpdevelop.net/sharpdevelop/trunk@6389 1ccf3a8d-04fe-1044-b7c0-cef0b8235c61pull/1/head
7 changed files with 160 additions and 120 deletions
@ -0,0 +1,49 @@ |
|||||||
|
// <file>
|
||||||
|
// <copyright see="prj:///doc/copyright.txt"/>
|
||||||
|
// <license see="prj:///doc/license.txt"/>
|
||||||
|
// <owner name="Martin Konicek" email="martin.konicek@gmail.com"/>
|
||||||
|
// <version>$Revision: $</version>
|
||||||
|
// </file>
|
||||||
|
using System; |
||||||
|
using ICSharpCode.SharpDevelop.Dom; |
||||||
|
using ICSharpCode.SharpDevelop.Refactoring; |
||||||
|
|
||||||
|
namespace SharpRefactoring.ContextActions |
||||||
|
{ |
||||||
|
/// <summary>
|
||||||
|
/// Description of ParamCheck.
|
||||||
|
/// </summary>
|
||||||
|
public abstract class ParamCheck : ContextAction |
||||||
|
{ |
||||||
|
public LocalResolveResult GetParameterAtCaret(ResolveResult symbol) |
||||||
|
{ |
||||||
|
LocalResolveResult param = symbol as LocalResolveResult; |
||||||
|
if (param == null || param.CallingClass == null || param.ResolvedType == null) |
||||||
|
return null; |
||||||
|
if (param.CallingClass.ProjectContent.Language != LanguageProperties.CSharp) |
||||||
|
return null; |
||||||
|
if (!param.IsParameter) |
||||||
|
return null; |
||||||
|
return param; |
||||||
|
} |
||||||
|
|
||||||
|
public override bool IsAvailable(EditorContext context) |
||||||
|
{ |
||||||
|
var paramAtCaret = GetParameterAtCaret(context.CurrentSymbol); |
||||||
|
if (paramAtCaret == null) |
||||||
|
return false; |
||||||
|
|
||||||
|
return IsAvailable(paramAtCaret.ResolvedType); |
||||||
|
} |
||||||
|
|
||||||
|
public override void Execute(EditorContext context) |
||||||
|
{ |
||||||
|
var paramAtCaret = GetParameterAtCaret(context.CurrentSymbol); |
||||||
|
Extensions.AddCodeToMethodStart(paramAtCaret.CallingMember, context.Editor, GetCodeToInsert(paramAtCaret.VariableName)); |
||||||
|
} |
||||||
|
|
||||||
|
public abstract bool IsAvailable(IReturnType parameterType); |
||||||
|
|
||||||
|
public abstract string GetCodeToInsert(string parameterName); |
||||||
|
} |
||||||
|
} |
||||||
@ -0,0 +1,34 @@ |
|||||||
|
// <file>
|
||||||
|
// <copyright see="prj:///doc/copyright.txt"/>
|
||||||
|
// <license see="prj:///doc/license.txt"/>
|
||||||
|
// <owner name="Martin Konicek" email="martin.konicek@gmail.com"/>
|
||||||
|
// <version>$Revision: $</version>
|
||||||
|
// </file>
|
||||||
|
using System; |
||||||
|
using ICSharpCode.SharpDevelop.Dom; |
||||||
|
using ICSharpCode.SharpDevelop.Refactoring; |
||||||
|
|
||||||
|
namespace SharpRefactoring.ContextActions |
||||||
|
{ |
||||||
|
/// <summary>
|
||||||
|
/// Description of ParamCheckForNull.
|
||||||
|
/// </summary>
|
||||||
|
public class ParamCheckForNull : ParamCheck |
||||||
|
{ |
||||||
|
public override string Title { |
||||||
|
get { return "Add check for null"; } |
||||||
|
} |
||||||
|
|
||||||
|
public override bool IsAvailable(IReturnType parameterType) |
||||||
|
{ |
||||||
|
var parameterTypeClass = parameterType.GetUnderlyingClass(); |
||||||
|
return (parameterTypeClass == null || parameterTypeClass.ClassType != ClassType.Enum && parameterTypeClass.ClassType != ClassType.Struct); |
||||||
|
} |
||||||
|
|
||||||
|
public override string GetCodeToInsert(string parameterName) |
||||||
|
{ |
||||||
|
return "if (" + parameterName + " == null)\n" + |
||||||
|
"throw new ArgumentNullException(\"" + parameterName + "\");"; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
@ -0,0 +1,35 @@ |
|||||||
|
// <file>
|
||||||
|
// <copyright see="prj:///doc/copyright.txt"/>
|
||||||
|
// <license see="prj:///doc/license.txt"/>
|
||||||
|
// <owner name="Martin Konicek" email="martin.konicek@gmail.com"/>
|
||||||
|
// <version>$Revision: $</version>
|
||||||
|
// </file>
|
||||||
|
using System; |
||||||
|
using System.Runtime.Remoting.Contexts; |
||||||
|
using ICSharpCode.SharpDevelop.Dom; |
||||||
|
using ICSharpCode.SharpDevelop.Refactoring; |
||||||
|
|
||||||
|
namespace SharpRefactoring.ContextActions |
||||||
|
{ |
||||||
|
/// <summary>
|
||||||
|
/// Description of ParamRangeCheck.
|
||||||
|
/// </summary>
|
||||||
|
public class ParamRangeCheck : ParamCheck |
||||||
|
{ |
||||||
|
public override string Title { |
||||||
|
get { return "Add range check"; } |
||||||
|
} |
||||||
|
|
||||||
|
public override bool IsAvailable(IReturnType parameterType) |
||||||
|
{ |
||||||
|
IClass parameterTypeClass = parameterType.GetUnderlyingClass(); |
||||||
|
return (parameterTypeClass != null && parameterTypeClass.FullyQualifiedName == "System.Int32"); |
||||||
|
} |
||||||
|
|
||||||
|
public override string GetCodeToInsert(string parameterName) |
||||||
|
{ |
||||||
|
return "if (" + parameterName + " < 0 || " + parameterName + " > upper_bound)\n" + |
||||||
|
"throw new ArgumentOutOfRangeException(\"" + parameterName + "\", " + parameterName + ", \"Value must be between 0 and \" + upper_bound);"; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
@ -1,115 +0,0 @@ |
|||||||
// <file>
|
|
||||||
// <copyright see="prj:///doc/copyright.txt"/>
|
|
||||||
// <license see="prj:///doc/license.txt"/>
|
|
||||||
// <author name="Daniel Grunwald"/>
|
|
||||||
// <version>$Revision$</version>
|
|
||||||
// </file>
|
|
||||||
|
|
||||||
using System; |
|
||||||
using System.Collections; |
|
||||||
using System.Collections.Generic; |
|
||||||
using System.Windows.Forms; |
|
||||||
|
|
||||||
using ICSharpCode.Core; |
|
||||||
using ICSharpCode.Core.Presentation; |
|
||||||
using ICSharpCode.Core.WinForms; |
|
||||||
using ICSharpCode.SharpDevelop; |
|
||||||
using ICSharpCode.SharpDevelop.Dom; |
|
||||||
using ICSharpCode.SharpDevelop.Editor; |
|
||||||
using ICSharpCode.SharpDevelop.Refactoring; |
|
||||||
|
|
||||||
namespace SharpRefactoring |
|
||||||
{ |
|
||||||
/// <summary>
|
|
||||||
/// Provides "Add check for null" and "Add range check" commands in
|
|
||||||
/// context menu of parameter declarations.
|
|
||||||
/// </summary>
|
|
||||||
public class ParameterCheckRefactoringMenuBuilder : ISubmenuBuilder, IMenuItemBuilder |
|
||||||
{ |
|
||||||
public ICollection BuildItems(Codon codon, object owner) |
|
||||||
{ |
|
||||||
return BuildSubmenu(codon, owner).TranslateToWpf(); |
|
||||||
} |
|
||||||
|
|
||||||
public ToolStripItem[] BuildSubmenu(Codon codon, object owner) |
|
||||||
{ |
|
||||||
List<ToolStripItem> resultItems = new List<ToolStripItem>(); |
|
||||||
RefactoringMenuContext context = (RefactoringMenuContext)owner; |
|
||||||
LocalResolveResult lrr = context.ResolveResult as LocalResolveResult; |
|
||||||
if (lrr == null || lrr.CallingClass == null || lrr.ResolvedType == null) |
|
||||||
return resultItems.ToArray(); |
|
||||||
LanguageProperties language = lrr.CallingClass.ProjectContent.Language; |
|
||||||
if (language != LanguageProperties.CSharp) |
|
||||||
return resultItems.ToArray(); |
|
||||||
|
|
||||||
IClass parameterTypeClass = lrr.ResolvedType.GetUnderlyingClass(); |
|
||||||
if (parameterTypeClass == null || parameterTypeClass.ClassType != ClassType.Enum && parameterTypeClass.ClassType != ClassType.Struct) { |
|
||||||
// the parameter is a reference type
|
|
||||||
resultItems.Add(MakeItem("Add check for null", delegate { AddCheckForNull(context); })); |
|
||||||
} |
|
||||||
if (parameterTypeClass != null) { |
|
||||||
if (parameterTypeClass.FullyQualifiedName == "System.Int32") { |
|
||||||
resultItems.Add(MakeItem("Add range check", delegate { AddRangeCheck(context); })); |
|
||||||
} |
|
||||||
} |
|
||||||
return resultItems.ToArray(); |
|
||||||
} |
|
||||||
|
|
||||||
ToolStripMenuItem MakeItem(string title, EventHandler onClick) |
|
||||||
{ |
|
||||||
ToolStripMenuItem menuItem = new ToolStripMenuItem(StringParser.Parse(title)); |
|
||||||
menuItem.Click += onClick; |
|
||||||
return menuItem; |
|
||||||
} |
|
||||||
|
|
||||||
void AddCheck(RefactoringMenuContext context, string newCode) |
|
||||||
{ |
|
||||||
var codeGen = context.ResolveResult.CallingClass.ProjectContent.Language.CodeGenerator; |
|
||||||
ITextEditor textArea = context.Editor; |
|
||||||
IMember m = context.ResolveResult.CallingMember; |
|
||||||
int methodStart = FindMethodStartOffset(textArea.Document, m.BodyRegion); |
|
||||||
if (methodStart < 0) |
|
||||||
return; |
|
||||||
textArea.Select(methodStart, 0); |
|
||||||
using (textArea.Document.OpenUndoGroup()) { |
|
||||||
int startLine = textArea.Caret.Line; |
|
||||||
foreach (string newCodeLine in newCode.Split('\n')) { |
|
||||||
textArea.Document.Insert(textArea.Caret.Offset, |
|
||||||
DocumentUtilitites.GetLineTerminator(textArea.Document, textArea.Caret.Line) + newCodeLine); |
|
||||||
} |
|
||||||
int endLine = textArea.Caret.Line; |
|
||||||
textArea.Language.FormattingStrategy.IndentLines(textArea, startLine, endLine); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
void AddCheckForNull(RefactoringMenuContext context) |
|
||||||
{ |
|
||||||
string name = ((LocalResolveResult)context.ResolveResult).VariableName; |
|
||||||
AddCheck(context, |
|
||||||
"if (" + name + " == null)\n" + |
|
||||||
"throw new ArgumentNullException(\"" + name + "\");"); |
|
||||||
} |
|
||||||
|
|
||||||
void AddRangeCheck(RefactoringMenuContext context) |
|
||||||
{ |
|
||||||
string name = ((LocalResolveResult)context.ResolveResult).VariableName; |
|
||||||
AddCheck(context, |
|
||||||
"if (" + name + " < 0 || " + name + " > upper_bound)\n" + |
|
||||||
"throw new ArgumentOutOfRangeException(\"" + name + "\", " + name + ", \"Value must be between 0 and \" + upper_bound);"); |
|
||||||
} |
|
||||||
|
|
||||||
static int FindMethodStartOffset(IDocument document, DomRegion bodyRegion) |
|
||||||
{ |
|
||||||
if (bodyRegion.IsEmpty) |
|
||||||
return -1; |
|
||||||
int offset = document.PositionToOffset(bodyRegion.BeginLine, bodyRegion.BeginColumn); |
|
||||||
while (offset < document.TextLength) { |
|
||||||
if (document.GetCharAt(offset) == '{') { |
|
||||||
return offset + 1; |
|
||||||
} |
|
||||||
offset++; |
|
||||||
} |
|
||||||
return -1; |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
Loading…
Reference in new issue