Browse Source

Moved "Add check for null" and "And range check" from context menu to context actions.

git-svn-id: svn://svn.sharpdevelop.net/sharpdevelop/trunk@6389 1ccf3a8d-04fe-1044-b7c0-cef0b8235c61
pull/1/head
Martin Koníček 15 years ago
parent
commit
46060649fb
  1. 6
      src/AddIns/Misc/SharpRefactoring/Project/SharpRefactoring.addin
  2. 4
      src/AddIns/Misc/SharpRefactoring/Project/SharpRefactoring.csproj
  3. 37
      src/AddIns/Misc/SharpRefactoring/Project/Src/ContextActions/Extensions.cs
  4. 49
      src/AddIns/Misc/SharpRefactoring/Project/Src/ContextActions/ParamCheck.cs
  5. 34
      src/AddIns/Misc/SharpRefactoring/Project/Src/ContextActions/ParamCheckForNull.cs
  6. 35
      src/AddIns/Misc/SharpRefactoring/Project/Src/ContextActions/ParamRangeCheck.cs
  7. 115
      src/AddIns/Misc/SharpRefactoring/Project/Src/MenuItemFactories/ParameterCheckRefactoringMenuBuilder.cs

6
src/AddIns/Misc/SharpRefactoring/Project/SharpRefactoring.addin

@ -11,10 +11,6 @@ @@ -11,10 +11,6 @@
<Import assembly = "SharpRefactoring.dll"/>
</Runtime>
<Path name="/SharpDevelop/ViewContent/DefaultTextEditor/Refactoring/ParameterDefinition">
<MenuItem id="parameterCheckRefactorings" type="Builder" class="SharpRefactoring.ParameterCheckRefactoringMenuBuilder"/>
</Path>
<Path name="/SharpDevelop/ViewContent/DefaultTextEditor/ClassBookmarkContextMenu">
<MenuItem id="classCodeGenerators"
type="Builder"
@ -47,6 +43,8 @@ @@ -47,6 +43,8 @@
<Class class="SharpRefactoring.ContextActions.GenerateMemberProvider" />
<Class class="SharpRefactoring.ContextActions.CheckAssignmentNull" />
<Class class="SharpRefactoring.ContextActions.CheckAssignmentNotNull" />
<Class class="SharpRefactoring.ContextActions.ParamCheckForNull" />
<Class class="SharpRefactoring.ContextActions.ParamRangeCheck" />
</Path>
<Path name="/SharpDevelop/ViewContent/TextEditor/OverrideCompletionHandler">

4
src/AddIns/Misc/SharpRefactoring/Project/SharpRefactoring.csproj

@ -80,6 +80,9 @@ @@ -80,6 +80,9 @@
<Compile Include="Src\ContextActions\GenerateMember.cs" />
<Compile Include="Src\ContextActions\ImplementAbstractClass.cs" />
<Compile Include="Src\ContextActions\ImplementInterface.cs" />
<Compile Include="Src\ContextActions\ParamCheck.cs" />
<Compile Include="Src\ContextActions\ParamCheckForNull.cs" />
<Compile Include="Src\ContextActions\ParamRangeCheck.cs" />
<Compile Include="Src\CSharpMethodExtractor.cs" />
<Compile Include="Src\Extensions.cs" />
<Compile Include="Src\ExtractMethodCommand.cs" />
@ -111,7 +114,6 @@ @@ -111,7 +114,6 @@
</Compile>
<Compile Include="Src\Gui\Wrapper.cs" />
<Compile Include="Src\InsertCtorSnippetRefactoring.cs" />
<Compile Include="Src\MenuItemFactories\ParameterCheckRefactoringMenuBuilder.cs" />
<Compile Include="Src\MenuItemFactories\ResolveAttribute.cs" />
<Compile Include="Src\MenuItemFactories\ResolveExtensionMethod.cs" />
<Compile Include="Src\MethodExtractorBase.cs" />

37
src/AddIns/Misc/SharpRefactoring/Project/Src/ContextActions/Extensions.cs

@ -86,5 +86,42 @@ namespace SharpRefactoring.ContextActions @@ -86,5 +86,42 @@ namespace SharpRefactoring.ContextActions
int lineEndOffset = line.Offset + line.Length;
document.Remove(offset, lineEndOffset - offset);
}
/// <summary>
/// C# only.
/// </summary>
public static void AddCodeToMethodStart(IMember m, ITextEditor textArea, string newCode)
{
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);
}
}
/// <summary>
/// C# only.
/// </summary>
public 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;
}
}
}

49
src/AddIns/Misc/SharpRefactoring/Project/Src/ContextActions/ParamCheck.cs

@ -0,0 +1,49 @@ @@ -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);
}
}

34
src/AddIns/Misc/SharpRefactoring/Project/Src/ContextActions/ParamCheckForNull.cs

@ -0,0 +1,34 @@ @@ -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 + "\");";
}
}
}

35
src/AddIns/Misc/SharpRefactoring/Project/Src/ContextActions/ParamRangeCheck.cs

@ -0,0 +1,35 @@ @@ -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);";
}
}
}

115
src/AddIns/Misc/SharpRefactoring/Project/Src/MenuItemFactories/ParameterCheckRefactoringMenuBuilder.cs

@ -1,115 +0,0 @@ @@ -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…
Cancel
Save