Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Rule S3909: Collections should implement the generic interface #389

Merged
merged 4 commits into from
Jun 6, 2017

Conversation

michalb-sonar
Copy link
Contributor

Fix #361

Copy link
Contributor

@valhristov valhristov left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Generally looks fine, but I have a few things I want to discuss.

}
}

issues.ForEach(i => c.ReportDiagnostic(i));
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You could use issues.ForEach(c.ReportDiagnostic); instead :)

var typeSymbol = c.SemanticModel.GetSymbolInfo(typeSyntax.Type).Symbol?.GetSymbolType();

var originalDefinition = typeSymbol?.OriginalDefinition;
if (originalDefinition.IsAny(genericTypes))
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It took me some time to understand that if we have at least one generic interface the rule does not raise issues (I thought there is a bug and I had to check the tests). Perhaps it will be more obvious if you extract the two lines above into a method IsGenericCollection(typeSymbol), WDYT?

SyntaxKind.ClassDeclaration);
}

private static KnownType ToKnownType(ITypeSymbol typeSymbol, IEnumerable<KnownType> knownTypes)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You could remove the knownTypes argument and perhaps rename the method to something like SuggestGenericCollectionType or better and refactor it to directly return a generic type counterpart or null... WDYT?

public sealed class CollectionsShouldImplementGenericInterface : SonarDiagnosticAnalyzer
{
internal const string DiagnosticId = "S3909";
private const string MessageFormat = "Refactor this collection to implement '{0}'.";
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was thinking about making this rule to report only once per class and put the additional base classes and interfaces as secondary locations. But then I realized that you should probably report only once anyway, because if you implement at least one generic interface/class the rule will not report anymore. What will happen with FxCop if you have a class like this? How many reports are we going to get? What interface do they suggest in this case?

public class Foo : IList, IEnumerable {}

Copy link
Contributor

@valhristov valhristov left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You decided to keep the multiple issues. Ok, the code looks much better now, I have a little comment, you could disregard it if you want.

private static string SuggestGenericCollectionType(ITypeSymbol typeSymbol)
{
KnownType suggestedGenericType;
if (nongenericToGenericMapping.TryGetValue(typeSymbol.ToDisplayString(), out suggestedGenericType))
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If you use ImmutableDictionary you will have the GetValueOrDefault extension method and this could be written as:

return nongenericToGenericMapping.GetValueOrDefault(typeSymbol.ToDisplayString())?.TypeName;

perhaps we should some day add such method for normal IDictionary<K,V>

@michalb-sonar michalb-sonar merged commit e455536 into master Jun 6, 2017
@michalb-sonar michalb-sonar deleted the s3909 branch June 6, 2017 15:20
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants