Browse Source

Add "Add check for null" and "Add range check" commands to C# refactoring menu.

git-svn-id: svn://svn.sharpdevelop.net/sharpdevelop/trunk@3279 1ccf3a8d-04fe-1044-b7c0-cef0b8235c61
shortcuts
Daniel Grunwald 17 years ago
parent
commit
f18f9a6817
  1. 4
      src/AddIns/BackendBindings/CSharpBinding/Project/CSharpBinding.addin
  2. 1
      src/AddIns/BackendBindings/CSharpBinding/Project/CSharpBinding.csproj
  3. 113
      src/AddIns/BackendBindings/CSharpBinding/Project/Src/ParameterCheckRefactoringMenuBuilder.cs
  4. 1
      src/AddIns/DisplayBindings/FormsDesigner/Project/Src/DesignerGenerator/CSharpDesignerGenerator.cs
  5. 2
      src/Libraries/ICSharpCode.TextEditor/Project/Src/Gui/Caret.cs
  6. 26
      src/Main/Base/Project/Src/Services/RefactoringService/RefactoringMenuBuilder.cs

4
src/AddIns/BackendBindings/CSharpBinding/Project/CSharpBinding.addin

@ -110,6 +110,10 @@ @@ -110,6 +110,10 @@
projectfileextension = ".csproj"
class = "CSharpBinding.CSharpLanguageBinding" />
</Path>
<Path name="/SharpDevelop/ViewContent/DefaultTextEditor/Refactoring/ParameterDefinition">
<MenuItem id="parameterCheckRefactorings" type="Builder" class="CSharpBinding.ParameterCheckRefactoringMenuBuilder"/>
</Path>
</AddIn>

1
src/AddIns/BackendBindings/CSharpBinding/Project/CSharpBinding.csproj

@ -56,6 +56,7 @@ @@ -56,6 +56,7 @@
<Compile Include="Src\OptionPanels\BuildOptions.cs">
<SubType>Form</SubType>
</Compile>
<Compile Include="Src\ParameterCheckRefactoringMenuBuilder.cs" />
<Compile Include="Src\Parser\Parser.cs" />
<Compile Include="Src\Project\RemoveMembersInRangeVisitor.cs" />
<Compile Include="Src\Project\VBNetToCSharpConvertVisitorWithMyFormsSupport.cs" />

113
src/AddIns/BackendBindings/CSharpBinding/Project/Src/ParameterCheckRefactoringMenuBuilder.cs

@ -0,0 +1,113 @@ @@ -0,0 +1,113 @@
// <file>
// <copyright see="prj:///doc/copyright.txt"/>
// <license see="prj:///doc/license.txt"/>
// <owner name="Daniel Grunwald"/>
// <version>$Revision$</version>
// </file>
using System;
using System.Collections.Generic;
using System.IO;
using System.Windows.Forms;
using ICSharpCode.Core;
using ICSharpCode.NRefactory;
using ICSharpCode.SharpDevelop.Dom;
using ICSharpCode.SharpDevelop.Dom.NRefactoryResolver;
using ICSharpCode.SharpDevelop.Dom.Refactoring;
using ICSharpCode.SharpDevelop.Refactoring;
using ICSharpCode.TextEditor;
using ICSharpCode.TextEditor.Actions;
using ICSharpCode.TextEditor.Document;
namespace CSharpBinding
{
/// <summary>
/// Description of ParameterCheckRefactorings.
/// </summary>
public class ParameterCheckRefactoringMenuBuilder : ISubmenuBuilder
{
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;
TextArea textArea = context.TextArea;
IMember m = context.ResolveResult.CallingMember;
TextLocation methodStart = FindMethodStart(textArea.Document, m.BodyRegion);
if (methodStart.IsEmpty)
return;
textArea.Caret.Position = methodStart;
textArea.SelectionManager.ClearSelection();
textArea.Document.UndoStack.StartUndoGroup();
try {
foreach (string newCodeLine in newCode.Split('\n')) {
new Return().Execute(textArea);
textArea.InsertString(newCodeLine);
}
} finally {
textArea.Document.UndoStack.EndUndoGroup();
}
textArea.Document.RequestUpdate(new TextAreaUpdate(TextAreaUpdateType.WholeTextArea));
textArea.Document.CommitUpdate();
}
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 TextLocation FindMethodStart(ICSharpCode.TextEditor.Document.IDocument document, DomRegion bodyRegion)
{
if (bodyRegion.IsEmpty)
return TextLocation.Empty;
int offset = document.PositionToOffset(new TextLocation(bodyRegion.BeginColumn - 1, bodyRegion.BeginLine - 1));
while (offset < document.TextLength) {
if (document.GetCharAt(offset) == '{') {
return document.OffsetToPosition(offset + 1);
}
offset++;
}
return TextLocation.Empty;
}
}
}

1
src/AddIns/DisplayBindings/FormsDesigner/Project/Src/DesignerGenerator/CSharpDesignerGenerator.cs

@ -64,7 +64,6 @@ namespace ICSharpCode.FormsDesigner @@ -64,7 +64,6 @@ namespace ICSharpCode.FormsDesigner
DomRegion r = method.BodyRegion;
int offset = document.PositionToOffset(new TextLocation(r.BeginColumn - 1, r.BeginLine - 1));
string tmp = document.GetText(offset, 10);
while (offset < document.TextLength) {
char c = document.GetCharAt(offset++);
if (c == '{') {

2
src/Libraries/ICSharpCode.TextEditor/Project/Src/Gui/Caret.cs

@ -294,7 +294,7 @@ namespace ICSharpCode.TextEditor @@ -294,7 +294,7 @@ namespace ICSharpCode.TextEditor
}
#region Caret implementation
public void PaintCaret(Graphics g)
internal void PaintCaret(Graphics g)
{
caretImplementation.PaintCaret(g);
}

26
src/Main/Base/Project/Src/Services/RefactoringService/RefactoringMenuBuilder.cs

@ -7,6 +7,7 @@ @@ -7,6 +7,7 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Windows.Forms;
@ -21,6 +22,14 @@ using ICSharpCode.TextEditor.Document; @@ -21,6 +22,14 @@ using ICSharpCode.TextEditor.Document;
namespace ICSharpCode.SharpDevelop.Refactoring
{
public class RefactoringMenuContext
{
public TextArea TextArea;
public ExpressionResult ExpressionResult;
public ResolveResult ResolveResult;
public bool IsDefinition;
}
/// <summary>
/// Build a menu with refactoring commands for the item that has been clicked on in the text editor.
/// </summary>
@ -80,6 +89,11 @@ namespace ICSharpCode.SharpDevelop.Refactoring @@ -80,6 +89,11 @@ namespace ICSharpCode.SharpDevelop.Refactoring
expressionResult = FindFullExpressionAtCaret(textArea, expressionFinder);
repeatResolve:
rr = ResolveExpressionAtCaret(textArea, expressionResult);
RefactoringMenuContext context = new RefactoringMenuContext {
TextArea = textArea,
ResolveResult = rr,
ExpressionResult = expressionResult
};
item = null;
if (rr is MethodGroupResolveResult) {
item = MakeItem(definitions, ((MethodGroupResolveResult)rr).GetMethodIfSingleOverload());
@ -97,7 +111,8 @@ namespace ICSharpCode.SharpDevelop.Refactoring @@ -97,7 +111,8 @@ namespace ICSharpCode.SharpDevelop.Refactoring
} else if (rr is TypeResolveResult) {
item = MakeItem(definitions, ((TypeResolveResult)rr).ResolvedClass);
} else if (rr is LocalResolveResult) {
item = MakeItem((LocalResolveResult)rr, caretLine + 1 == ((LocalResolveResult)rr).VariableDefinitionRegion.BeginLine);
context.IsDefinition = caretLine + 1 == ((LocalResolveResult)rr).VariableDefinitionRegion.BeginLine;
item = MakeItem((LocalResolveResult)rr, context);
insertIndex = 0; // Insert local variable menu item at the topmost position.
} else if (rr is UnknownIdentifierResolveResult) {
item = MakeItemForResolveError((UnknownIdentifierResolveResult)rr, expressionResult.Context, textArea);
@ -205,16 +220,17 @@ namespace ICSharpCode.SharpDevelop.Refactoring @@ -205,16 +220,17 @@ namespace ICSharpCode.SharpDevelop.Refactoring
return null;
}
ToolStripMenuItem MakeItem(LocalResolveResult local, bool isDefinition)
ToolStripMenuItem MakeItem(LocalResolveResult local, RefactoringMenuContext context)
{
Debug.Assert(local == context.ResolveResult);
ToolStripMenuItem item = MakeItemInternal(local.VariableName,
local.IsParameter ? ClassBrowserIconService.ParameterIndex : ClassBrowserIconService.LocalVariableIndex,
local.CallingClass.CompilationUnit,
isDefinition ? DomRegion.Empty : local.VariableDefinitionRegion);
context.IsDefinition ? DomRegion.Empty : local.VariableDefinitionRegion);
string treePath = "/SharpDevelop/ViewContent/DefaultTextEditor/Refactoring/";
treePath += local.IsParameter ? "Parameter" : "LocalVariable";
if (isDefinition) treePath += "Definition";
MenuService.AddItemsToMenu(item.DropDown.Items, local, treePath);
if (context.IsDefinition) treePath += "Definition";
MenuService.AddItemsToMenu(item.DropDown.Items, context, treePath);
return item;
}

Loading…
Cancel
Save