ArchiMetrics icon indicating copy to clipboard operation
ArchiMetrics copied to clipboard

Depth of Inheritance doesn't work

Open payelh opened this issue 8 years ago • 7 comments

Depth of Inheritance doesn't work,

payelh avatar Jan 13 '17 10:01 payelh

Neither does this kind of bug report.

jjrdk avatar Jan 13 '17 14:01 jjrdk

Analyzer Code:

var codeMetricResult = new CodeMetricsCalculator().Calculate(new[] { context.Tree }).Result;
//For each namespace          
foreach (var nsResult in codeMetricResult)
{
          foreach (var typeResult in nsResult.TypeMetrics)
          {
                var diagnostic = Diagnostic.Create(DemoDiagnostic, Location.None, "=> Type Name: " + typeResult.Name + ", Depth Of Inheritance :  " + typeResult.DepthOfInheritance);
                context.ReportDiagnostic(diagnostic);                        
           }
}

payelh avatar Jan 17 '17 11:01 payelh

Code to analyze:

namespace SampleApp
{
    class A
    {
    }

    class B : A
    {
    }

    class C : B
    {
    }

    class D : C
    {
    }
    class MainClass:D
    {
        public static void Main()
        {
            Console.WriteLine("Hello world");
        }
    }
}

Outputs: Depth of inheritance 1 for each class, even for MainClass

payelh avatar Jan 17 '17 11:01 payelh

In DepthOfInheritanceAnalyzer.cs , I debugged and found when type is D, (in fact for all type which has base), symbolInfo.Symbol is null inside

foreach (var symbolInfo in type.BaseList.Types.Select(syntax => ModelExtensions.GetSymbolInfo(_semanticModel, syntax)))

For that reason variable num inside the loop doesn't increase.

This is what I have anlysed, hope this helps.

public int Calculate(TypeDeclarationSyntax type)
		{
			var num = type.IsKind(SyntaxKind.ClassDeclaration) || type.IsKind(SyntaxKind.StructDeclaration) ? 1 : 0;
			if (type.BaseList != null)
			{
                               // For any type which has base it gets symbolinfo.Symbol as null, so the variable num doesn't increase
				foreach (var symbolInfo in type.BaseList.Types.Select(syntax => ModelExtensions.GetSymbolInfo(_semanticModel, syntax)))
				{
					for (var symbol = symbolInfo.Symbol as INamedTypeSymbol; symbol != null; symbol = symbol.BaseType)
					{
						if (_inheritableTypes.Any(x => x == symbol.TypeKind))
						{
							num++;
						}
					}
				}
			}

			return num == 0 && (type.IsKind(SyntaxKind.ClassDeclaration) || type.IsKind(SyntaxKind.StructDeclaration))
				? 1
				: num;
		}

payelh avatar Jan 17 '17 12:01 payelh

@jjrdk : Could you please check this ?

Thanks Enamul

payelh avatar Jan 19 '17 16:01 payelh

If we change below line

foreach (var symbolInfo in type.BaseList.Types.Select(syntax => ModelExtensions.GetSymbolInfo(_semanticModel, syntax)))

as

foreach (var symbolInfo in type.BaseList.Types.Select(syntax => ModelExtensions.GetSymbolInfo(_semanticModel, syntax.Type)))

then the issue gets fixed

payelh avatar Jan 27 '17 15:01 payelh

Thanks for finding the fix. Can I ask you to submit a pull request?

jjrdk avatar Jan 27 '17 20:01 jjrdk