Browse Source

[CodeIssues] Don't warn about static fields in generic types if the field declaration uses all type parameters.

newNRvisualizers
Simon Lindgren 14 years ago
parent
commit
a46f5e9874
  1. 38
      ICSharpCode.NRefactory.CSharp/Refactoring/CodeIssues/StaticFieldInGenericTypeIssue.cs
  2. 44
      ICSharpCode.NRefactory.Tests/CSharp/CodeIssues/StaticFieldInGenericTypeTests.cs

38
ICSharpCode.NRefactory.CSharp/Refactoring/CodeIssues/StaticFieldInGenericTypeIssue.cs

@ -25,6 +25,8 @@ @@ -25,6 +25,8 @@
// THE SOFTWARE.
using System;
using System.Collections.Generic;
using ICSharpCode.NRefactory.TypeSystem;
using System.Linq;
namespace ICSharpCode.NRefactory.CSharp.Refactoring
{
@ -45,21 +47,47 @@ namespace ICSharpCode.NRefactory.CSharp.Refactoring @@ -45,21 +47,47 @@ namespace ICSharpCode.NRefactory.CSharp.Refactoring
{
}
bool isInGenericType = false;
IList<ITypeParameter> availableTypeParameters = new List<ITypeParameter>();
public override void VisitTypeDeclaration(TypeDeclaration typeDeclaration)
{
var oldGenericStatus = isInGenericType;
var typeResolveResult = ctx.Resolve(typeDeclaration);
var newTypeParameters = typeResolveResult.Type.GetDefinition().TypeParameters;
isInGenericType = typeDeclaration.TypeParameters.Count > 0;
var oldTypeParameters = availableTypeParameters;
availableTypeParameters = Concat(availableTypeParameters, newTypeParameters);
base.VisitTypeDeclaration(typeDeclaration);
isInGenericType = oldGenericStatus;
availableTypeParameters = oldTypeParameters;
}
static IList<ITypeParameter> Concat(params IList<ITypeParameter>[] lists)
{
return lists.SelectMany(l => l).ToList();
}
bool UsesAllTypeParameters(FieldDeclaration fieldDeclaration)
{
if (availableTypeParameters.Count == 0)
return true;
var fieldType = ctx.Resolve(fieldDeclaration.ReturnType).Type as ParameterizedType;
if (fieldType == null)
return false;
// Check that all current type parameters are used in the field type
var fieldTypeParameters = fieldType.TypeArguments;
foreach (var typeParameter in availableTypeParameters) {
if (!fieldTypeParameters.Contains(typeParameter))
return false;
}
return true;
}
public override void VisitFieldDeclaration(FieldDeclaration fieldDeclaration)
{
if (isInGenericType && fieldDeclaration.Modifiers.HasFlag(Modifiers.Static)) {
if (fieldDeclaration.Modifiers.HasFlag(Modifiers.Static) && !UsesAllTypeParameters(fieldDeclaration)) {
AddIssue(fieldDeclaration, ctx.TranslateString("Static field in generic type"));
}
}

44
ICSharpCode.NRefactory.Tests/CSharp/CodeIssues/StaticFieldInGenericTypeTests.cs

@ -34,7 +34,7 @@ namespace ICSharpCode.NRefactory.CSharp.CodeIssues @@ -34,7 +34,7 @@ namespace ICSharpCode.NRefactory.CSharp.CodeIssues
[TestFixture]
public class StaticFieldInGenericTypeTests : InspectionActionTestBase
{
[Test]
public void GenericClass()
{
@ -48,6 +48,48 @@ class Foo<T> @@ -48,6 +48,48 @@ class Foo<T>
Assert.AreEqual(1, issues.Count);
}
[Test]
public void GenericClassWithGenericField()
{
var input = @"
class Foo<T>
{
static System.Collections.Generic.IList<T> Cache;
}";
TestRefactoringContext context;
var issues = GetIssues(new StaticFieldInGenericTypeIssue(), input, out context);
Assert.AreEqual(0, issues.Count);
}
[Test]
public void GenericClassWithMultipleGenericFields()
{
var input = @"
class Foo<T1, T2>
{
static System.Collections.Generic.IList<T1> Cache;
}";
TestRefactoringContext context;
var issues = GetIssues(new StaticFieldInGenericTypeIssue(), input, out context);
Assert.AreEqual(1, issues.Count);
}
[Test]
public void NestedGenericClassWithGenericField()
{
var input = @"
class Foo<T1>
{
class Bar<T2>
{
static System.Collections.Generic.IList<T1> Cache;
}
}";
TestRefactoringContext context;
var issues = GetIssues(new StaticFieldInGenericTypeIssue(), input, out context);
Assert.AreEqual(1, issues.Count);
}
[Test]
public void NonGenericClass()
{

Loading…
Cancel
Save