Browse Source
Fixed minor bug in CtrlSpaceResolveHelper.GetResultFromDeclarationLine which showed up e.g. when right clicking keyword "as" in the editor. git-svn-id: svn://svn.sharpdevelop.net/sharpdevelop/trunk@6369 1ccf3a8d-04fe-1044-b7c0-cef0b8235c61pull/1/head
15 changed files with 332 additions and 36 deletions
@ -0,0 +1,107 @@ |
|||||||
|
// <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.NRefactory.Ast; |
||||||
|
using ICSharpCode.SharpDevelop; |
||||||
|
using ICSharpCode.SharpDevelop.Dom; |
||||||
|
using ICSharpCode.SharpDevelop.Dom.Refactoring; |
||||||
|
using ICSharpCode.SharpDevelop.Refactoring; |
||||||
|
|
||||||
|
namespace SharpRefactoring.ContextActions |
||||||
|
{ |
||||||
|
/// <summary>
|
||||||
|
/// Description of CheckAssignmentAction.
|
||||||
|
/// </summary>
|
||||||
|
public abstract class CheckAssignmentAction : ContextAction |
||||||
|
{ |
||||||
|
protected string VariableName { get; private set; } |
||||||
|
|
||||||
|
protected CodeGenerator CodeGenerator { get; private set; } |
||||||
|
|
||||||
|
protected DomRegion ElementRegion { get; private set; } |
||||||
|
|
||||||
|
protected string GetVariableName(EditorContext context) |
||||||
|
{ |
||||||
|
// a = Foo() : AssignmentExpression.Left == IdentifierExpression(*identifier*)
|
||||||
|
// var a = Foo() : VariableDeclaration(*name*).Initializer != empty
|
||||||
|
|
||||||
|
var variableName = GetVariableNameFromAssignment(context.GetContainingElement<AssignmentExpression>()); |
||||||
|
if (variableName != null) |
||||||
|
return variableName; |
||||||
|
variableName = GetVariableNameFromVariableDeclaration(context.GetContainingElement<LocalVariableDeclaration>()); |
||||||
|
if (variableName != null) |
||||||
|
return variableName; |
||||||
|
|
||||||
|
return null; |
||||||
|
} |
||||||
|
|
||||||
|
protected DomRegion GetStatementRegion(EditorContext context) |
||||||
|
{ |
||||||
|
// a = Foo() : AssignmentExpression.Left == IdentifierExpression(*identifier*)
|
||||||
|
// var a = Foo() : VariableDeclaration(*name*).Initializer != empty
|
||||||
|
|
||||||
|
var assignment = context.GetContainingElement<AssignmentExpression>(); |
||||||
|
if (assignment != null) |
||||||
|
return DomRegion.FromLocation(assignment.StartLocation, assignment.EndLocation); |
||||||
|
var declaration = context.GetContainingElement<LocalVariableDeclaration>(); |
||||||
|
if (declaration != null) |
||||||
|
return DomRegion.FromLocation(declaration.StartLocation, declaration.EndLocation); |
||||||
|
|
||||||
|
return DomRegion.Empty; |
||||||
|
} |
||||||
|
|
||||||
|
string GetVariableNameFromAssignment(AssignmentExpression assignment) |
||||||
|
{ |
||||||
|
if (assignment == null) |
||||||
|
return null; |
||||||
|
var identifier = assignment.Left as IdentifierExpression; |
||||||
|
if (identifier == null) |
||||||
|
return null; |
||||||
|
if (assignment.Right is ObjectCreateExpression) |
||||||
|
// // don't offer action for "a = new Foo()"
|
||||||
|
return null; |
||||||
|
return identifier.Identifier; |
||||||
|
} |
||||||
|
|
||||||
|
string GetVariableNameFromVariableDeclaration(LocalVariableDeclaration declaration) |
||||||
|
{ |
||||||
|
if (declaration == null) |
||||||
|
return null; |
||||||
|
if (declaration.Variables.Count != 1) |
||||||
|
return null; |
||||||
|
VariableDeclaration varDecl = declaration.Variables[0]; |
||||||
|
if (!varDecl.Initializer.IsNull && |
||||||
|
// don't offer action for "var a = new Foo()"
|
||||||
|
!(varDecl.Initializer is ObjectCreateExpression)) |
||||||
|
return varDecl.Name; |
||||||
|
return null; |
||||||
|
} |
||||||
|
|
||||||
|
CodeGenerator GetCodeGenerator(EditorContext context) |
||||||
|
{ |
||||||
|
var parseInfo = ParserService.GetParseInformation(context.Editor.FileName); |
||||||
|
if (parseInfo == null) |
||||||
|
return null; |
||||||
|
return parseInfo.CompilationUnit.Language.CodeGenerator; |
||||||
|
} |
||||||
|
|
||||||
|
public IReturnType GetResolvedType(ResolveResult symbol) |
||||||
|
{ |
||||||
|
if (symbol != null) |
||||||
|
return symbol.ResolvedType; |
||||||
|
return null; |
||||||
|
} |
||||||
|
|
||||||
|
public override bool IsEnabled(EditorContext context) |
||||||
|
{ |
||||||
|
this.VariableName = GetVariableName(context); |
||||||
|
this.CodeGenerator = GetCodeGenerator(context); |
||||||
|
this.ElementRegion = GetStatementRegion(context); |
||||||
|
return !string.IsNullOrEmpty(this.VariableName) && (this.CodeGenerator != null); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
@ -0,0 +1,50 @@ |
|||||||
|
// <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.NRefactory.Ast; |
||||||
|
using ICSharpCode.SharpDevelop.Editor; |
||||||
|
using ICSharpCode.SharpDevelop.Refactoring; |
||||||
|
|
||||||
|
namespace SharpRefactoring.ContextActions |
||||||
|
{ |
||||||
|
/// <summary>
|
||||||
|
/// Description of CheckAssignmentNotNull.
|
||||||
|
/// </summary>
|
||||||
|
public class CheckAssignmentNotNull : CheckAssignmentAction |
||||||
|
{ |
||||||
|
public override string Title { |
||||||
|
get { return "Check for not null"; } |
||||||
|
} |
||||||
|
|
||||||
|
string caretMarker = "<<>>"; |
||||||
|
|
||||||
|
public override void Execute(EditorContext context) |
||||||
|
{ |
||||||
|
var ifStatement = GenerateAstToInsert(this.VariableName); |
||||||
|
|
||||||
|
var editor = context.Editor; |
||||||
|
string indent = DocumentUtilitites.GetWhitespaceAfter(editor.Document, editor.Document.GetLineStartOffset(this.ElementRegion.GetStart())); |
||||||
|
string code = this.CodeGenerator.GenerateCode(ifStatement, indent); |
||||||
|
int insertOffset = editor.Document.GetLineEndOffset(this.ElementRegion.GetEnd()); |
||||||
|
using (var undoGroup = editor.Document.OpenUndoGroup()) { |
||||||
|
editor.Document.Insert(insertOffset, code); |
||||||
|
var caretPos = editor.Document.Text.IndexOf(caretMarker, insertOffset); |
||||||
|
editor.Caret.Offset = caretPos; |
||||||
|
editor.Document.RemoveRestOfLine(caretPos); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
AbstractNode GenerateAstToInsert(string variableName) |
||||||
|
{ |
||||||
|
var block = new BlockStatement(); |
||||||
|
block.AddChild(new ExpressionStatement(new IdentifierExpression(caretMarker))); |
||||||
|
return new IfElseStatement( |
||||||
|
new BinaryOperatorExpression(new IdentifierExpression(variableName), BinaryOperatorType.InEquality, new PrimitiveExpression(null)), |
||||||
|
block); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
@ -0,0 +1,43 @@ |
|||||||
|
// <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.Collections.Generic; |
||||||
|
using ICSharpCode.NRefactory.Ast; |
||||||
|
using ICSharpCode.SharpDevelop.Editor; |
||||||
|
using ICSharpCode.SharpDevelop.Refactoring; |
||||||
|
|
||||||
|
namespace SharpRefactoring.ContextActions |
||||||
|
{ |
||||||
|
/// <summary>
|
||||||
|
/// Offers inserting "if (a == null) return;" after "var a = *expr*"
|
||||||
|
/// </summary>
|
||||||
|
public class CheckAssignmentNull : CheckAssignmentAction |
||||||
|
{ |
||||||
|
public override string Title { |
||||||
|
get { return "Check for null"; } |
||||||
|
} |
||||||
|
|
||||||
|
public override void Execute(EditorContext context) |
||||||
|
{ |
||||||
|
var ifStatement = GenerateAstToInsert(this.VariableName); |
||||||
|
|
||||||
|
var editor = context.Editor; |
||||||
|
string indent = DocumentUtilitites.GetWhitespaceAfter(editor.Document, editor.Document.GetLineStartOffset(this.ElementRegion.GetStart())); |
||||||
|
string code = this.CodeGenerator.GenerateCode(ifStatement, indent); |
||||||
|
int insertOffset = editor.Document.GetLineEndOffset(this.ElementRegion.GetEnd()); |
||||||
|
editor.Document.Insert(insertOffset, code); |
||||||
|
editor.Caret.Offset = insertOffset + code.Length - 1; |
||||||
|
} |
||||||
|
|
||||||
|
AbstractNode GenerateAstToInsert(string variableName) |
||||||
|
{ |
||||||
|
return new IfElseStatement( |
||||||
|
new BinaryOperatorExpression(new IdentifierExpression(variableName), BinaryOperatorType.Equality, new PrimitiveExpression(null)), |
||||||
|
new ReturnStatement(Expression.Null)); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
@ -0,0 +1,40 @@ |
|||||||
|
// <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.Collections.Generic; |
||||||
|
|
||||||
|
namespace ICSharpCode.SharpDevelop.Refactoring |
||||||
|
{ |
||||||
|
/// <summary>
|
||||||
|
/// Base class for implementing custom context actions.
|
||||||
|
/// </summary>
|
||||||
|
public abstract class ContextAction : IContextActionsProvider, IContextAction |
||||||
|
{ |
||||||
|
public abstract string Title { get; } |
||||||
|
|
||||||
|
public abstract bool IsEnabled(EditorContext context); |
||||||
|
|
||||||
|
public abstract void Execute(EditorContext context); |
||||||
|
|
||||||
|
public IEnumerable<IContextAction> GetAvailableActions(EditorContext context) |
||||||
|
{ |
||||||
|
this.context = context; |
||||||
|
if (this.IsEnabled(context)) |
||||||
|
yield return this; |
||||||
|
} |
||||||
|
|
||||||
|
EditorContext context; |
||||||
|
public void Execute() |
||||||
|
{ |
||||||
|
Execute(this.context); |
||||||
|
} |
||||||
|
|
||||||
|
public virtual string Id { |
||||||
|
get { return this.GetType().FullName; } |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
Loading…
Reference in new issue