Browse Source

[CodeIssue,CodeAction] Use the FindReferences class instead of custom visitors to find variable references.

newNRvisualizers
Simon Lindgren 14 years ago
parent
commit
e914c9e0ab
  1. 42
      ICSharpCode.NRefactory.CSharp/Refactoring/CodeActions/RemoveRedundantCatchTypeAction.cs
  2. 45
      ICSharpCode.NRefactory.CSharp/Refactoring/CodeIssues/SetterDoesNotUseValueParameterIssue.cs

42
ICSharpCode.NRefactory.CSharp/Refactoring/CodeActions/RemoveRedundantCatchTypeAction.cs

@ -23,11 +23,13 @@
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE. // THE SOFTWARE.
using ICSharpCode.NRefactory.CSharp.Refactoring; using ICSharpCode.NRefactory.CSharp.Refactoring;
using ICSharpCode.NRefactory.TypeSystem; using ICSharpCode.NRefactory.TypeSystem;
using System; using System;
using ICSharpCode.NRefactory.Semantics; using ICSharpCode.NRefactory.Semantics;
using System.Threading;
using ICSharpCode.NRefactory.CSharp.Resolver;
using System.Linq;
namespace ICSharpCode.NRefactory.CSharp.Refactoring namespace ICSharpCode.NRefactory.CSharp.Refactoring
{ {
@ -46,9 +48,12 @@ namespace ICSharpCode.NRefactory.CSharp.Refactoring
var exceptionType = context.ResolveType(catchClause.Type); var exceptionType = context.ResolveType(catchClause.Type);
if (exceptionType != context.Compilation.FindType(typeof(Exception))) if (exceptionType != context.Compilation.FindType(typeof(Exception)))
yield break; yield break;
var compilationUnit = context.RootNode as CompilationUnit ?? context.GetNode<CompilationUnit>();
if (compilationUnit == null)
yield break;
var exceptionIdentifierRR = context.Resolve(catchClause.VariableNameToken) as LocalResolveResult; var exceptionIdentifierRR = context.Resolve(catchClause.VariableNameToken) as LocalResolveResult;
if (exceptionIdentifierRR != null && if (exceptionIdentifierRR != null &&
IsReferenced(exceptionIdentifierRR.Variable, catchClause.Body, context)) IsReferenced(exceptionIdentifierRR.Variable, catchClause.Body, compilationUnit, context))
yield break; yield break;
yield return new CodeAction(context.TranslateString("Remove type specifier"), script => { yield return new CodeAction(context.TranslateString("Remove type specifier"), script => {
script.Replace(catchClause, new CatchClause() { script.Replace(catchClause, new CatchClause() {
@ -57,33 +62,16 @@ namespace ICSharpCode.NRefactory.CSharp.Refactoring
}); });
} }
bool IsReferenced(IVariable variable, AstNode node, RefactoringContext context) bool IsReferenced(IVariable variable, AstNode node, CompilationUnit unit, RefactoringContext context)
{ {
var visitor = new ReferenceFinderVisitor(context, variable); int referencesFound = 0;
node.AcceptVisitor(visitor); var findRef = new FindReferences();
return visitor.FoundReference; findRef.FindLocalReferences(variable, context.ParsedFile, unit, context.Compilation, (n, entity) => {
} referencesFound++;
}, CancellationToken.None);
class ReferenceFinderVisitor: DepthFirstAstVisitor
{
RefactoringContext context;
IVariable variable;
public ReferenceFinderVisitor(RefactoringContext context, IVariable variable)
{
this.context = context;
this.variable = variable;
}
public bool FoundReference { get; private set; }
public override void VisitIdentifierExpression(IdentifierExpression identifierExpression) // One reference is the declaration, and that does not count
{ return referencesFound > 1;
var resolvedIdentifier = context.Resolve(identifierExpression) as LocalResolveResult;
if (resolvedIdentifier != null)
FoundReference |= resolvedIdentifier.Variable == variable;
base.VisitIdentifierExpression(identifierExpression);
}
} }
#endregion #endregion

45
ICSharpCode.NRefactory.CSharp/Refactoring/CodeIssues/SetterDoesNotUseValueParameterIssue.cs

@ -25,6 +25,10 @@
// THE SOFTWARE. // THE SOFTWARE.
using System.Collections.Generic; using System.Collections.Generic;
using ICSharpCode.NRefactory.Semantics; using ICSharpCode.NRefactory.Semantics;
using System.Linq;
using ICSharpCode.NRefactory.TypeSystem;
using ICSharpCode.NRefactory.CSharp.Resolver;
using System.Threading;
namespace ICSharpCode.NRefactory.CSharp.Refactoring namespace ICSharpCode.NRefactory.CSharp.Refactoring
{ {
@ -48,6 +52,8 @@ namespace ICSharpCode.NRefactory.CSharp.Refactoring
this.context = context; this.context = context;
} }
public override void VisitIndexerDeclaration(IndexerDeclaration indexerDeclaration) public override void VisitIndexerDeclaration(IndexerDeclaration indexerDeclaration)
{ {
FindIssuesInNode(indexerDeclaration.Setter.Body); FindIssuesInNode(indexerDeclaration.Setter.Body);
@ -58,34 +64,29 @@ namespace ICSharpCode.NRefactory.CSharp.Refactoring
FindIssuesInNode(propertyDeclaration.Setter.Body); FindIssuesInNode(propertyDeclaration.Setter.Body);
} }
void FindIssuesInNode(AstNode node) CompilationUnit compilationUnit;
public override void VisitCompilationUnit(CompilationUnit unit)
{ {
var setterVisitor = new ReferenceFinderVisitor(context, "value"); compilationUnit = unit;
node.AcceptVisitor(setterVisitor); base.VisitCompilationUnit(unit);
if (!setterVisitor.FoundReference)
AddIssue(node, context.TranslateString("The setter does not use the 'value' parameter."));
} }
}
class ReferenceFinderVisitor: DepthFirstAstVisitor
{
readonly BaseRefactoringContext context;
readonly string variableName;
public ReferenceFinderVisitor(BaseRefactoringContext context, string variableName) void FindIssuesInNode(AstNode node)
{ {
this.context = context; var variable = context.GetResolverStateBefore(node).LocalVariables
this.variableName = variableName; .Where(v => v.Name == "value").FirstOrDefault();
} if (variable == null)
return;
public bool FoundReference { get; private set; } bool referenceFound = false;
var findRef = new FindReferences();
findRef.FindLocalReferences(variable, context.ParsedFile, compilationUnit, context.Compilation, (n, entity) => {
referenceFound = true;
}, CancellationToken.None);
public override void VisitIdentifierExpression(IdentifierExpression identifierExpression) if(!referenceFound)
{ AddIssue(node, context.TranslateString("The setter does not use the 'value' parameter."));
var resolvedIdentifier = context.Resolve(identifierExpression) as LocalResolveResult;
if (resolvedIdentifier != null)
FoundReference |= resolvedIdentifier.Variable.Name == variableName;
base.VisitIdentifierExpression(identifierExpression);
} }
} }
} }

Loading…
Cancel
Save