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 @@ @@ -23,11 +23,13 @@
// 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
// THE SOFTWARE.
using ICSharpCode.NRefactory.CSharp.Refactoring;
using ICSharpCode.NRefactory.TypeSystem;
using System;
using ICSharpCode.NRefactory.Semantics;
using System.Threading;
using ICSharpCode.NRefactory.CSharp.Resolver;
using System.Linq;
namespace ICSharpCode.NRefactory.CSharp.Refactoring
{
@ -46,9 +48,12 @@ namespace ICSharpCode.NRefactory.CSharp.Refactoring @@ -46,9 +48,12 @@ namespace ICSharpCode.NRefactory.CSharp.Refactoring
var exceptionType = context.ResolveType(catchClause.Type);
if (exceptionType != context.Compilation.FindType(typeof(Exception)))
yield break;
var compilationUnit = context.RootNode as CompilationUnit ?? context.GetNode<CompilationUnit>();
if (compilationUnit == null)
yield break;
var exceptionIdentifierRR = context.Resolve(catchClause.VariableNameToken) as LocalResolveResult;
if (exceptionIdentifierRR != null &&
IsReferenced(exceptionIdentifierRR.Variable, catchClause.Body, context))
IsReferenced(exceptionIdentifierRR.Variable, catchClause.Body, compilationUnit, context))
yield break;
yield return new CodeAction(context.TranslateString("Remove type specifier"), script => {
script.Replace(catchClause, new CatchClause() {
@ -57,33 +62,16 @@ namespace ICSharpCode.NRefactory.CSharp.Refactoring @@ -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);
node.AcceptVisitor(visitor);
return visitor.FoundReference;
}
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; }
int referencesFound = 0;
var findRef = new FindReferences();
findRef.FindLocalReferences(variable, context.ParsedFile, unit, context.Compilation, (n, entity) => {
referencesFound++;
}, CancellationToken.None);
public override void VisitIdentifierExpression(IdentifierExpression identifierExpression)
{
var resolvedIdentifier = context.Resolve(identifierExpression) as LocalResolveResult;
if (resolvedIdentifier != null)
FoundReference |= resolvedIdentifier.Variable == variable;
base.VisitIdentifierExpression(identifierExpression);
}
// One reference is the declaration, and that does not count
return referencesFound > 1;
}
#endregion

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

@ -25,6 +25,10 @@ @@ -25,6 +25,10 @@
// THE SOFTWARE.
using System.Collections.Generic;
using ICSharpCode.NRefactory.Semantics;
using System.Linq;
using ICSharpCode.NRefactory.TypeSystem;
using ICSharpCode.NRefactory.CSharp.Resolver;
using System.Threading;
namespace ICSharpCode.NRefactory.CSharp.Refactoring
{
@ -48,6 +52,8 @@ namespace ICSharpCode.NRefactory.CSharp.Refactoring @@ -48,6 +52,8 @@ namespace ICSharpCode.NRefactory.CSharp.Refactoring
this.context = context;
}
public override void VisitIndexerDeclaration(IndexerDeclaration indexerDeclaration)
{
FindIssuesInNode(indexerDeclaration.Setter.Body);
@ -58,34 +64,29 @@ namespace ICSharpCode.NRefactory.CSharp.Refactoring @@ -58,34 +64,29 @@ namespace ICSharpCode.NRefactory.CSharp.Refactoring
FindIssuesInNode(propertyDeclaration.Setter.Body);
}
void FindIssuesInNode(AstNode node)
CompilationUnit compilationUnit;
public override void VisitCompilationUnit(CompilationUnit unit)
{
var setterVisitor = new ReferenceFinderVisitor(context, "value");
node.AcceptVisitor(setterVisitor);
if (!setterVisitor.FoundReference)
AddIssue(node, context.TranslateString("The setter does not use the 'value' parameter."));
compilationUnit = unit;
base.VisitCompilationUnit(unit);
}
}
class ReferenceFinderVisitor: DepthFirstAstVisitor
{
readonly BaseRefactoringContext context;
readonly string variableName;
public ReferenceFinderVisitor(BaseRefactoringContext context, string variableName)
void FindIssuesInNode(AstNode node)
{
this.context = context;
this.variableName = variableName;
}
var variable = context.GetResolverStateBefore(node).LocalVariables
.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)
{
var resolvedIdentifier = context.Resolve(identifierExpression) as LocalResolveResult;
if (resolvedIdentifier != null)
FoundReference |= resolvedIdentifier.Variable.Name == variableName;
base.VisitIdentifierExpression(identifierExpression);
if(!referenceFound)
AddIssue(node, context.TranslateString("The setter does not use the 'value' parameter."));
}
}
}

Loading…
Cancel
Save