diff --git a/src/AddIns/Misc/SharpRefactoring/Project/Src/ContextActions/CheckAssignmentCache.cs b/src/AddIns/Misc/SharpRefactoring/Project/Src/ContextActions/CheckAssignmentCache.cs index 66b7deafc0..4bc1618be7 100644 --- a/src/AddIns/Misc/SharpRefactoring/Project/Src/ContextActions/CheckAssignmentCache.cs +++ b/src/AddIns/Misc/SharpRefactoring/Project/Src/ContextActions/CheckAssignmentCache.cs @@ -17,16 +17,19 @@ namespace SharpRefactoring.ContextActions { public void Initialize(EditorContext context) { + this.context = context; this.VariableName = GetVariableName(context); this.CodeGenerator = GetCodeGenerator(context); this.Element = GetElement(context); this.ElementRegion = (Element == null) ? DomRegion.Empty : DomRegion.FromLocation(Element.StartLocation, Element.EndLocation); } + EditorContext context; + public bool IsActionAvailable { get { - return !string.IsNullOrEmpty(this.VariableName) && (this.CodeGenerator != null); + return !string.IsNullOrEmpty(this.VariableName) && (this.CodeGenerator != null) && (this.context.CurrentLine.Text.Contains(";")); } } @@ -76,7 +79,7 @@ namespace SharpRefactoring.ContextActions var identifier = assignment.Left as IdentifierExpression; if (identifier == null) return null; - if (!ExpressionCanBeNull(assignment.Right)) + if ((!ExpressionCanBeNull(assignment.Right)) || ExpressionIsValueType(assignment.Right)) // don't offer action where it makes no sense return null; return identifier.Identifier; @@ -89,12 +92,19 @@ namespace SharpRefactoring.ContextActions if (declaration.Variables.Count != 1) return null; VariableDeclaration varDecl = declaration.Variables[0]; - if (!ExpressionCanBeNull(varDecl.Initializer)) + if (!ExpressionCanBeNull(varDecl.Initializer) || ExpressionIsValueType(varDecl.Initializer)) // don't offer action where it makes no sense return null; return varDecl.Name; } + bool ExpressionIsValueType(Expression expr) + { + ResolveResult rr = this.context.ResolveExpression(expr); + if (rr == null) return false; // when cannot resolve the assignment right, still offer the action + return (rr.ResolvedType != null && rr.ResolvedType.IsReferenceType == false); + } + bool ExpressionCanBeNull(Expression expr) { if (expr == null) return false; diff --git a/src/AddIns/Misc/SharpRefactoring/Project/Src/ContextActions/CheckMemberNotNull.cs b/src/AddIns/Misc/SharpRefactoring/Project/Src/ContextActions/CheckMemberNotNull.cs index 7143353d93..a14d2d0014 100644 --- a/src/AddIns/Misc/SharpRefactoring/Project/Src/ContextActions/CheckMemberNotNull.cs +++ b/src/AddIns/Misc/SharpRefactoring/Project/Src/ContextActions/CheckMemberNotNull.cs @@ -46,6 +46,16 @@ namespace SharpRefactoring.ContextActions //this.targetExpr is IdentifierExpression; // "don't offer the action for just a.b, only for a.b.c" } + public override void Execute(EditorContext context) + { + var conditionExpr = BuildCondition(this.targetExpr); + if (conditionExpr == null) + return; + var ifExpr = new IfElseStatement(conditionExpr, new BlockStatement()); + + context.Editor.InsertCodeBefore(this.currentExpr, ifExpr); + } + /// /// Gets "a.b" from "a.b.c" /// @@ -57,16 +67,6 @@ namespace SharpRefactoring.ContextActions return null; } - public override void Execute(EditorContext context) - { - var conditionExpr = BuildCondition(this.targetExpr); - if (conditionExpr == null) - return; - var ifExpr = new IfElseStatement(conditionExpr, new BlockStatement()); - - context.Editor.InsertCodeBefore(this.currentExpr, ifExpr); - } - /// /// Turns "(a.b as T).d.e" into "(a != null) && (a.b is T) && ((a.b as T).d != null)" /// diff --git a/src/Main/Base/Project/Src/Services/RefactoringService/ContextActions/EditorContext.cs b/src/Main/Base/Project/Src/Services/RefactoringService/ContextActions/EditorContext.cs index e5287d8a87..639d676b99 100644 --- a/src/Main/Base/Project/Src/Services/RefactoringService/ContextActions/EditorContext.cs +++ b/src/Main/Base/Project/Src/Services/RefactoringService/ContextActions/EditorContext.cs @@ -104,6 +104,12 @@ namespace ICSharpCode.SharpDevelop.Refactoring // DebugLog(); } + public ResolveResult ResolveExpression(Expression expression) + { + ExpressionResult expr = GetExpressionAt(this.Editor, expression.EndLocation.Line, expression.EndLocation.Column); + return ResolveExpression(expr, this.Editor, expression.EndLocation.Line, expression.EndLocation.Column); + } + /// /// Do not call from your Context actions - used by SharpDevelop. /// Sets contents of editor context to null to prevent memory leaks. Used in case users implementing IContextActionProvider @@ -236,10 +242,15 @@ namespace ICSharpCode.SharpDevelop.Refactoring ExpressionResult GetExpressionAtCaret(ITextEditor editor) { - ExpressionResult expr = ParserService.FindFullExpression(CaretLine, CaretColumn, editor.Document, editor.FileName); + return GetExpressionAt(editor, this.CaretLine, this.CaretColumn); + } + + ExpressionResult GetExpressionAt(ITextEditor editor, int caretLine, int caretColumn) + { + ExpressionResult expr = ParserService.FindFullExpression(caretLine, caretColumn, editor.Document, editor.FileName); // if no expression, look one character back (works better with method calls - Foo()(*caret*)) - if (string.IsNullOrWhiteSpace(expr.Expression) && CaretColumn > 1) - expr = ParserService.FindFullExpression(CaretLine, CaretColumn - 1, editor.Document, editor.FileName); + if (string.IsNullOrWhiteSpace(expr.Expression) && caretColumn > 1) + expr = ParserService.FindFullExpression(caretLine, caretColumn - 1, editor.Document, editor.FileName); return expr; }