Esempio n. 1
0
            private static int CalculateMaintainabilityIndex(ComputationalComplexityMetrics computationalComplexityMetrics, int cyclomaticComplexity)
            {
                double computationalComplexityVolume = Math.Max(0.0, Math.Log(computationalComplexityMetrics.Volume));               //avoid Log(0) = -Infinity
                double logEffectiveLinesOfCode       = Math.Max(0.0, Math.Log(computationalComplexityMetrics.EffectiveLinesOfCode)); //avoid Log(0) = -Infinity

                return(MetricsHelper.NormalizeAndRoundMaintainabilityIndex(171 - 5.2 * computationalComplexityVolume - 0.23 * cyclomaticComplexity - 16.2 * logEffectiveLinesOfCode));
            }
        internal CodeAnalysisMetricData(
            ISymbol symbol,
            int maintainabilityIndex,
            ComputationalComplexityMetrics computationalComplexityMetrics,
            ImmutableHashSet <INamedTypeSymbol> coupledNamedTypes,
            long linesOfCode,
            int cyclomaticComplexity,
            int?depthOfInheritance,
            ImmutableArray <CodeAnalysisMetricData> children)
        {
            Debug.Assert(
                symbol.Kind == SymbolKind.Assembly ||
                symbol.Kind == SymbolKind.Namespace ||
                symbol.Kind == SymbolKind.NamedType ||
                symbol.Kind == SymbolKind.Method ||
                symbol.Kind == SymbolKind.Field ||
                symbol.Kind == SymbolKind.Event ||
                symbol.Kind == SymbolKind.Property);
            Debug.Assert(depthOfInheritance.HasValue == (symbol.Kind == SymbolKind.Assembly || symbol.Kind == SymbolKind.Namespace || symbol.Kind == SymbolKind.NamedType));

            var executableLines = !computationalComplexityMetrics.IsDefault ?
                                  computationalComplexityMetrics.ExecutableLines :
                                  children.Sum(c => c.ExecutableLines);

            Symbol = symbol;
            MaintainabilityIndex           = maintainabilityIndex;
            ComputationalComplexityMetrics = computationalComplexityMetrics;
            CoupledNamedTypes    = coupledNamedTypes;
            SourceLines          = linesOfCode;
            ExecutableLines      = executableLines;
            CyclomaticComplexity = cyclomaticComplexity;
            DepthOfInheritance   = depthOfInheritance;
            Children             = children;
        }
Esempio n. 3
0
 internal FieldMetricData(
     IFieldSymbol symbol,
     int maintainabilityIndex,
     ComputationalComplexityMetrics computationalComplexityMetrics,
     ImmutableHashSet <INamedTypeSymbol> coupledNamedTypes,
     long linesOfCode,
     int cyclomaticComplexity,
     int?depthOfInheritance)
     : base(symbol, maintainabilityIndex, computationalComplexityMetrics, coupledNamedTypes,
            linesOfCode, cyclomaticComplexity, depthOfInheritance, children: ImmutableArray <CodeAnalysisMetricData> .Empty)
 {
 }
            private static int CalculateMaintainabilityIndex(
                ComputationalComplexityMetrics computationalComplexityMetrics,
                int cyclomaticComplexity,
                int effectiveChildrenCount)
            {
                double avgComputationalComplexityVolume = 1.0;
                double avgEffectiveLinesOfCode          = 0.0;
                double avgCyclomaticComplexity          = 0.0;

                if (effectiveChildrenCount > 0)
                {
                    avgComputationalComplexityVolume = computationalComplexityMetrics.Volume / effectiveChildrenCount;
                    avgEffectiveLinesOfCode          = computationalComplexityMetrics.EffectiveLinesOfCode / effectiveChildrenCount;
                    avgCyclomaticComplexity          = cyclomaticComplexity / effectiveChildrenCount;
                }

                double logAvgComputationalComplexityVolume = Math.Max(0.0, Math.Log(avgComputationalComplexityVolume)); //avoid Log(0) = -Infinity
                double logAvgLinesOfCode = Math.Max(0.0, Math.Log(avgEffectiveLinesOfCode));                            //avoid Log(0) = -Infinity

                return(MetricsHelper.NormalizeAndRoundMaintainabilityIndex(171 - 5.2 * logAvgComputationalComplexityVolume - 0.23 * avgCyclomaticComplexity - 16.2 * logAvgLinesOfCode));
            }
        public ComputationalComplexityMetrics Union(ComputationalComplexityMetrics other)
        {
            if (ReferenceEquals(this, Default))
            {
                return(other);
            }
            else if (ReferenceEquals(other, Default))
            {
                return(this);
            }

            return(new ComputationalComplexityMetrics(
                       effectiveLinesOfCode: EffectiveLinesOfCode + other.EffectiveLinesOfCode,
                       operatorUsageCounts: _operatorUsageCounts + other._operatorUsageCounts,
                       symbolUsageCounts: _symbolUsageCounts + other._symbolUsageCounts,
                       constantUsageCounts: _constantUsageCounts + other._constantUsageCounts,
                       distinctOperatorKinds: _distinctOperatorKinds.Union(other._distinctOperatorKinds),
                       distinctBinaryOperatorKinds: _distinctBinaryOperatorKinds.Union(other._distinctBinaryOperatorKinds),
                       distinctUnaryOperatorKinds: _distinctUnaryOperatorKinds.Union(other._distinctUnaryOperatorKinds),
                       distinctCaseKinds: _distinctCaseKinds.Union(other._distinctCaseKinds),
                       distinctReferencedSymbols: _distinctReferencedSymbols.Union(other._distinctReferencedSymbols),
                       distinctReferencedConstants: _distinctReferencedConstants.Union(other._distinctReferencedConstants)));
        }
        internal CodeAnalysisMetricData(
            ISymbol symbol,
            int maintainabilityIndex,
            ComputationalComplexityMetrics computationalComplexityMetrics,
            ImmutableHashSet <INamedTypeSymbol> coupledNamedTypes,
            long linesOfCode,
            int cyclomaticComplexity,
            int?depthOfInheritance,
            ImmutableArray <CodeAnalysisMetricData> children)
        {
            Debug.Assert(symbol != null);
            Debug.Assert(
                symbol.Kind == SymbolKind.Assembly ||
                symbol.Kind == SymbolKind.Namespace ||
                symbol.Kind == SymbolKind.NamedType ||
                symbol.Kind == SymbolKind.Method ||
                symbol.Kind == SymbolKind.Field ||
                symbol.Kind == SymbolKind.Event ||
                symbol.Kind == SymbolKind.Property);
            Debug.Assert(depthOfInheritance.HasValue == (symbol.Kind == SymbolKind.Assembly || symbol.Kind == SymbolKind.Namespace || symbol.Kind == SymbolKind.NamedType));

#if LEGACY_CODE_METRICS_MODE
            linesOfCode = !computationalComplexityMetrics.IsDefault ?
                          computationalComplexityMetrics.EffectiveLinesOfCode :
                          children.Sum(c => c.LinesOfCode);
#endif

            Symbol = symbol;
            MaintainabilityIndex           = maintainabilityIndex;
            ComputationalComplexityMetrics = computationalComplexityMetrics;
            CoupledNamedTypes    = coupledNamedTypes;
            LinesOfCode          = linesOfCode;
            CyclomaticComplexity = cyclomaticComplexity;
            DepthOfInheritance   = depthOfInheritance;
            Children             = children;
        }
Esempio n. 7
0
        internal static async Task <(int cyclomaticComplexity, ComputationalComplexityMetrics computationalComplexityMetrics)> ComputeCoupledTypesAndComplexityExcludingMemberDeclsAsync(
            ImmutableArray <SyntaxReference> declarations,
            ISymbol symbol,
            ImmutableHashSet <INamedTypeSymbol> .Builder builder,
            SemanticModelProvider semanticModelProvider,
            CancellationToken cancellationToken)
        {
            int cyclomaticComplexity = 0;
            ComputationalComplexityMetrics computationalComplexityMetrics = ComputationalComplexityMetrics.Default;

            var nodesToProcess = new Queue <SyntaxNode>();

            foreach (var declaration in declarations)
            {
                SyntaxNode syntax = await GetTopmostSyntaxNodeForDeclarationAsync(declaration, symbol, semanticModelProvider, cancellationToken).ConfigureAwait(false);

                nodesToProcess.Enqueue(syntax);

                // Ensure we process parameter initializers and attributes.
                var parameters = GetParameters(symbol);
                foreach (var parameter in parameters)
                {
                    var parameterSyntaxRef = parameter.DeclaringSyntaxReferences.FirstOrDefault();
                    if (parameterSyntaxRef != null)
                    {
                        var parameterSyntax = await parameterSyntaxRef.GetSyntaxAsync(cancellationToken).ConfigureAwait(false);

                        nodesToProcess.Enqueue(parameterSyntax);
                    }
                }

                var attributes = symbol.GetAttributes();
                if (symbol is IMethodSymbol methodSymbol)
                {
                    attributes = attributes.AddRange(methodSymbol.GetReturnTypeAttributes());
                }

                foreach (var attribute in attributes)
                {
                    if (attribute.ApplicationSyntaxReference != null)
                    {
                        var attributeSyntax = await attribute.ApplicationSyntaxReference.GetSyntaxAsync(cancellationToken).ConfigureAwait(false);

                        nodesToProcess.Enqueue(attributeSyntax);
                    }
                }

                do
                {
                    var node  = nodesToProcess.Dequeue();
                    var model = semanticModelProvider.GetSemanticModel(node);

                    if (!ReferenceEquals(node, syntax))
                    {
                        var declaredSymbol = model.GetDeclaredSymbol(node, cancellationToken);
                        if (declaredSymbol != null && !Equals(symbol, declaredSymbol) && declaredSymbol.Kind != SymbolKind.Parameter)
                        {
                            // Skip member declarations.
                            continue;
                        }
                    }

                    var typeInfo = model.GetTypeInfo(node, cancellationToken);
                    AddCoupledNamedTypesCore(builder, typeInfo.Type);

                    var operationBlock = model.GetOperation(node, cancellationToken);
                    if (operationBlock != null && operationBlock.Parent == null)
                    {
                        switch (operationBlock.Kind)
                        {
                        case OperationKind.Block:
                        case OperationKind.MethodBodyOperation:
                        case OperationKind.ConstructorBodyOperation:
                            cyclomaticComplexity += 1;
                            break;
                        }

                        computationalComplexityMetrics = computationalComplexityMetrics.Union(ComputationalComplexityMetrics.Compute(operationBlock));

                        // Add used types within executable code in the operation tree.
                        foreach (var operation in operationBlock.DescendantsAndSelf())
                        {
#if LEGACY_CODE_METRICS_MODE
                            // Legacy mode does not account for code within lambdas/local functions for code metrics.
                            if (operation.IsWithinLambdaOrLocalFunction())
                            {
                                continue;
                            }
#endif

                            if (!operation.IsImplicit && hasConditionalLogic(operation))
                            {
                                cyclomaticComplexity += 1;
                            }

                            AddCoupledNamedTypesCore(builder, operation.Type);

                            // Handle static member accesses specially as there is no operation for static type off which the member is accessed.
                            if (operation is IMemberReferenceOperation memberReference &&
                                memberReference.Member.IsStatic)
                            {
                                AddCoupledNamedTypesCore(builder, memberReference.Member.ContainingType);
                            }
                            else if (operation is IInvocationOperation invocation &&
                                     (invocation.TargetMethod.IsStatic || invocation.TargetMethod.IsExtensionMethod))
                            {
                                AddCoupledNamedTypesCore(builder, invocation.TargetMethod.ContainingType);
                            }
                        }
                    }