public NRefactoryCodeAction (string id, string title, ICSharpCode.NRefactory.CSharp.Refactoring.CodeAction act) { this.IdString = id; this.Title = title; this.act = act; this.DocumentRegion = new Mono.TextEditor.DocumentRegion (act.Start, act.End); }
public NRefactoryCodeAction(string id, string title, ICSharpCode.NRefactory.CSharp.Refactoring.CodeAction act) { this.IdString = id; this.Title = title; this.act = act; this.DocumentRegion = new Mono.TextEditor.DocumentRegion(act.Start, act.End); }
public NRefactoryCodeAction (string id, string title, CodeAction act, object siblingKey = null) { this.IdString = id; this.Title = title; this.act = act; this.SiblingKey = siblingKey; this.Severity = act.Severity; this.DocumentRegion = new Mono.TextEditor.DocumentRegion (act.Start, act.End); }
public NRefactoryCodeAction(string id, string title, ICSharpCode.NRefactory.CSharp.Refactoring.CodeAction act, object siblingKey = null) { this.IdString = id; this.Title = title; this.act = act; this.SiblingKey = siblingKey; this.Severity = act.Severity; this.DocumentRegion = new Mono.TextEditor.DocumentRegion(act.Start, act.End); }
public override void VisitConditionalExpression (ConditionalExpression conditionalExpression) { base.VisitConditionalExpression (conditionalExpression); if (!conditionalExpression.TrueExpression.Match (conditionalExpression.FalseExpression).Success) return; var action = new CodeAction (ctx.TranslateString ("Replace '?:' with branch"), script => script.Replace (conditionalExpression, conditionalExpression.TrueExpression.Clone ())); AddIssue (conditionalExpression, ctx.TranslateString ("'?:' expression has identical true and false branches"), new [] { action }); }
public CSharpContextActionWrapper(IContextActionProvider provider, CodeAction codeAction, Func<SDRefactoringContext, CodeAction> getUpdatedCodeAction) { if (provider == null) throw new ArgumentNullException("provider"); if (codeAction == null) throw new ArgumentNullException("codeAction"); if (getUpdatedCodeAction == null) throw new ArgumentNullException("getUpdatedCodeAction"); this.provider = provider; this.description = codeAction.Description; this.getUpdatedCodeAction = getUpdatedCodeAction; // Don't maintain a reference to 'action', it indirectly references the compilation etc. }
public override void VisitIsExpression (IsExpression isExpression) { base.VisitIsExpression (isExpression); var type = ctx.Resolve (isExpression.Expression).Type; var providedType = ctx.ResolveType (isExpression.Type); if (type.GetAllBaseTypes ().All (t => !t.Equals (providedType))) return; var action = new CodeAction (ctx.TranslateString ("Compare with 'null'"), scrpit => scrpit.Replace (isExpression, new BinaryOperatorExpression ( isExpression.Expression.Clone (), BinaryOperatorType.InEquality, new PrimitiveExpression (null)))); AddIssue (isExpression, ctx.TranslateString ("Given expression is always of the provided type. " + "Consider comparing with 'null' instead"), new [] { action }); }
public override void VisitInvocationExpression (InvocationExpression invocationExpression) { base.VisitInvocationExpression (invocationExpression); var resolveResult = ctx.Resolve (invocationExpression) as InvocationResolveResult; if (resolveResult == null || resolveResult.Member.DeclaringTypeDefinition == null || resolveResult.Member.DeclaringTypeDefinition.KnownTypeCode != KnownTypeCode.Object || resolveResult.Member.Name != "ReferenceEquals" || invocationExpression.Arguments.All(arg => ctx.Resolve(arg).Type.IsReferenceType ?? true)) return; var action = new CodeAction (ctx.TranslateString ("Use Equals()"), script => script.Replace (invocationExpression.Target, new MemberReferenceExpression ( new TypeReferenceExpression (new PrimitiveType ("object")), "Equals"))); AddIssue (invocationExpression, ctx.TranslateString ("'Object.ReferenceEquals' is always false because it is called with value type"), new [] { action }); }
public override void VisitCatchClause(CatchClause catchClause) { base.VisitCatchClause(catchClause); var exceptionResolveResult = ctx.Resolve(catchClause.VariableNameToken) as LocalResolveResult; if (exceptionResolveResult == null) return; var catchVisitor = new CatchClauseVisitor(ctx, exceptionResolveResult.Variable); catchClause.Body.AcceptVisitor(catchVisitor); foreach (var throwStatement in catchVisitor.OffendingThrows) { var localThrowStatement = throwStatement; var title = ctx.TranslateString("The exception is rethrown with explicit usage of the variable"); var action = new CodeAction(ctx.TranslateString("Change to 'throw;'"), script => { script.Replace(localThrowStatement, new ThrowStatement()); }); AddIssue(localThrowStatement, title, new [] { action }); } }
void AddIssuesForClauses(List<CatchClause> redundantCatchClauses) { var allCatchClausesMessage = ctx.TranslateString("Remove all '{0}' redundant catches"); var removeAllRedundantClausesAction = new CodeAction(allCatchClausesMessage, script => { foreach (var redundantCatchClause in redundantCatchClauses) { script.Remove(redundantCatchClause); } }); var singleCatchClauseMessage = ctx.TranslateString("Remove redundant catch clause"); var redundantCatchClauseMessage = ctx.TranslateString("A catch clause containing a single empty throw statement is redundant."); foreach (var redundantCatchClause in redundantCatchClauses) { var closureLocalCatchClause = redundantCatchClause; var removeRedundantClauseAction = new CodeAction(singleCatchClauseMessage, script => { script.Remove(closureLocalCatchClause); }); var actions = new List<CodeAction>(); actions.Add(removeRedundantClauseAction); if (redundantCatchClauses.Count > 1) { actions.Add(removeAllRedundantClausesAction); } AddIssue(closureLocalCatchClause, redundantCatchClauseMessage, actions); } }
public override void VisitIsExpression(IsExpression isExpression) { base.VisitIsExpression (isExpression); var type = ctx.Resolve (isExpression.Expression).Type; var providedType = ctx.ResolveType (isExpression.Type); var foundConversion = conversions.ImplicitConversion(type, providedType); if (!IsValidReferenceOrBoxingConversion(type, providedType)) return; var action = new CodeAction (ctx.TranslateString ("Compare with 'null'"), scrpit => scrpit.Replace (isExpression, new BinaryOperatorExpression ( isExpression.Expression.Clone (), BinaryOperatorType.InEquality, new PrimitiveExpression (null)))); AddIssue (isExpression, ctx.TranslateString ("Given expression is always of the provided type. " + "Consider comparing with 'null' instead"), new [] { action }); }
IContextAction Wrap(CodeAction actionToWrap, int index) { // Take care not to capture 'actionToWrap' in the lambda string actionDescription = actionToWrap.Description; return new CSharpContextActionWrapper( manager, actionToWrap, context => { // Look up the new issue position int newStart = InspectedVersion.MoveOffsetTo(context.Version, StartOffset, AnchorMovementType.Default); int newEnd = InspectedVersion.MoveOffsetTo(context.Version, EndOffset, AnchorMovementType.Default); // If the length changed, don't bother looking up the issue again if (newEnd - newStart != EndOffset - StartOffset) return null; // Now rediscover this issue in the new context var issue = this.Provider.GetIssues(context).FirstOrDefault( i => context.GetOffset(i.Start) == newStart && context.GetOffset(i.End) == newEnd && i.Description == this.Description); if (issue == null) return null; // Now look up the action within that issue: if (index < issue.Actions.Count && issue.Actions[index].Description == actionDescription) return issue.Actions[index]; else return null; }); }
public NRefactoryCodeAction(string id, string title, ICSharpCode.NRefactory.CSharp.Refactoring.CodeAction act) { this.IdString = id; this.Title = title; this.act = act; }
public NRefactoryCodeAction (string id, string title, ICSharpCode.NRefactory.CSharp.Refactoring.CodeAction act) { this.IdString = id; this.Title = title; this.act = act; }
/// <summary> /// Initializes a new instance of the <see cref="ICSharpCode.NRefactory.CSharp.Refactoring.CodeIssue"/> class. /// </summary> /// <param name='description'> /// The desription of the issue. /// </param> /// <param name='start'> /// The issue start location. /// </param> /// <param name='end'> /// the issue end location. /// </param> /// <param name='action'> /// A potential solution for the issue. /// </param> public CodeIssue(string description, TextLocation start, TextLocation end, CodeAction action) : this(description, start, end, action != null ? new [] { action } : null) { }
void AddIssueForTryCatchStatement(TryCatchStatement tryCatchStatement) { var lastCatch = tryCatchStatement.CatchClauses.LastOrNullObject(); if (lastCatch.IsNull) return; var removeTryCatchMessage = ctx.TranslateString("Remove try statement"); var removeTryStatementAction = new CodeAction(removeTryCatchMessage, script => { var statements = tryCatchStatement.TryBlock.Statements; if (statements.Count == 1 || tryCatchStatement.Parent is BlockStatement) { foreach (var statement in statements) { script.InsertAfter(tryCatchStatement.PrevSibling, statement.Clone()); } script.Remove(tryCatchStatement); } else { var blockStatement = new BlockStatement(); foreach (var statement in statements) { blockStatement.Statements.Add(statement.Clone()); } script.Replace(tryCatchStatement, blockStatement); } // The replace and insert script functions does not format these things well on their own script.FormatText(tryCatchStatement.Parent); }); var fixes = new [] { removeTryStatementAction }; AddIssue(tryCatchStatement.TryBlock.EndLocation, lastCatch.EndLocation, removeTryCatchMessage, fixes); }
void CheckCondition (Expression condition) { if (condition is PrimitiveExpression) return; var resolveResult = ctx.Resolve (condition); if (!(resolveResult.IsCompileTimeConstant && resolveResult.ConstantValue is bool)) return; var value = (bool)resolveResult.ConstantValue; var conditionalExpr = condition.Parent as ConditionalExpression; var ifElseStatement = condition.Parent as IfElseStatement; var valueStr = value.ToString ().ToLower (); CodeAction action; if (conditionalExpr != null) { var replaceExpr = value ? conditionalExpr.TrueExpression : conditionalExpr.FalseExpression; action = new CodeAction ( string.Format (ctx.TranslateString ("Replace '?:' with '{0}' branch"), valueStr), script => script.Replace (conditionalExpr, replaceExpr.Clone ())); } else if (ifElseStatement != null) { action = new CodeAction ( string.Format (ctx.TranslateString ("Replace 'if' with '{0}' branch"), valueStr), script => { var statement = value ? ifElseStatement.TrueStatement : ifElseStatement.FalseStatement; var blockStatement = statement as BlockStatement; if (statement.IsNull || (blockStatement != null && blockStatement.Statements.Count == 0)) { script.Remove (ifElseStatement); return; } TextLocation start, end; if (blockStatement != null) { start = blockStatement.Statements.FirstOrNullObject ().StartLocation; end = blockStatement.Statements.LastOrNullObject ().EndLocation; } else { start = statement.StartLocation; end = statement.EndLocation; } RemoveText (script, ifElseStatement.StartLocation, start); RemoveText (script, end, ifElseStatement.EndLocation); script.FormatText (ifElseStatement.Parent); }); } else { action = new CodeAction ( string.Format (ctx.TranslateString ("Replace expression with '{0}'"), valueStr), script => script.Replace (condition, new PrimitiveExpression (value))); } AddIssue (condition, string.Format (ctx.TranslateString ("Condition is always '{0}'"), valueStr), new [] { action }); }
IContextAction Wrap(CodeAction actionToWrap, int index) { // Take care not to capture 'actionToWrap' in the lambda string description = actionToWrap.Description; return new CSharpContextActionWrapper( this, actionToWrap, context => { var actions = codeActionProvider.GetActions(context).ToList(); if (index < actions.Count) { var action = actions[index]; if (action.Description == description) return action; } return null; }); }
protected void AddIssue(TextLocation start, TextLocation end, string title, CodeAction fix) { FoundIssues.Add(new CodeIssue (title, start, end, fix)); }
protected void AddIssue(AstNode node, string title, CodeAction fix) { FoundIssues.Add(new CodeIssue(title, node.StartLocation, node.EndLocation, fix)); }
bool AddStatement(Statement statement) { if (reachability.IsReachable (statement)) return false; if (collectedStatements.Contains (statement)) return true; var prevEnd = statement.GetPrevNode ().EndLocation; // group multiple continuous statements into one issue var start = statement.StartLocation; collectedStatements.Add (statement); visitor.unreachableNodes.Add (statement); while (statement.NextSibling is Statement) { statement = (Statement)statement.NextSibling; collectedStatements.Add (statement); visitor.unreachableNodes.Add (statement); } var end = statement.EndLocation; var removeAction = new CodeAction (visitor.ctx.TranslateString ("Remove unreachable code"), script => { var startOffset = script.GetCurrentOffset (prevEnd); var endOffset = script.GetCurrentOffset (end); script.RemoveText (startOffset, endOffset - startOffset); }); var commentAction = new CodeAction (visitor.ctx.TranslateString ("Comment unreachable code"), script => { var startOffset = script.GetCurrentOffset (prevEnd); script.InsertText (startOffset, Environment.NewLine + "/*"); var endOffset = script.GetCurrentOffset (end); script.InsertText (endOffset, Environment.NewLine + "*/"); }); var actions = new [] { removeAction, commentAction }; visitor.AddIssue (start, end, visitor.ctx.TranslateString ("Code is unreachable"), actions); return true; }