示例#1
0
        static ErrorFacts()
        {
            ImmutableHashSet <string> .Builder builder = ImmutableHashSet.CreateBuilder <string>();
            builder.Add(getId(ErrorCode.WRN_NullReferenceAssignment));
            builder.Add(getId(ErrorCode.WRN_NullReferenceReceiver));
            builder.Add(getId(ErrorCode.WRN_NullReferenceReturn));
            builder.Add(getId(ErrorCode.WRN_NullReferenceArgument));
            builder.Add(getId(ErrorCode.WRN_UninitializedNonNullableField));
            builder.Add(getId(ErrorCode.WRN_NullabilityMismatchInAssignment));
            builder.Add(getId(ErrorCode.WRN_NullabilityMismatchInArgument));
            builder.Add(getId(ErrorCode.WRN_NullabilityMismatchInArgumentForOutput));
            builder.Add(getId(ErrorCode.WRN_NullabilityMismatchInReturnTypeOfTargetDelegate));
            builder.Add(getId(ErrorCode.WRN_NullabilityMismatchInParameterTypeOfTargetDelegate));
            builder.Add(getId(ErrorCode.WRN_NullAsNonNullable));
            builder.Add(getId(ErrorCode.WRN_NullableValueTypeMayBeNull));
            builder.Add(getId(ErrorCode.WRN_NullabilityMismatchInTypeParameterConstraint));
            builder.Add(getId(ErrorCode.WRN_NullabilityMismatchInTypeParameterReferenceTypeConstraint));
            builder.Add(getId(ErrorCode.WRN_PossibleNull));

            NullableFlowAnalysisSafetyWarnings = builder.ToImmutable();

            builder.Clear();
            builder.Add(getId(ErrorCode.WRN_ConvertingNullableToNonNullable));
            builder.Add(getId(ErrorCode.HDN_NullCheckIsProbablyAlwaysFalse));
            builder.Add(getId(ErrorCode.HDN_NullCheckIsProbablyAlwaysTrue));
            builder.Add(getId(ErrorCode.HDN_ExpressionIsProbablyNeverNull));

            NullableFlowAnalysisNonSafetyWarnings = builder.ToImmutable();

            string getId(ErrorCode errorCode)
            {
                return(MessageProvider.Instance.GetIdForErrorCode((int)errorCode));
            }
        }
示例#2
0
        static ErrorFacts()
        {
            ImmutableHashSet <string> .Builder builder = ImmutableHashSet.CreateBuilder <string>();
            builder.Add(getId(ErrorCode.WRN_NullReferenceAssignment));
            builder.Add(getId(ErrorCode.WRN_NullReferenceReceiver));
            builder.Add(getId(ErrorCode.WRN_NullReferenceReturn));
            builder.Add(getId(ErrorCode.WRN_NullReferenceArgument));
            builder.Add(getId(ErrorCode.WRN_UninitializedNonNullableField));
            builder.Add(getId(ErrorCode.WRN_NullabilityMismatchInAssignment));
            builder.Add(getId(ErrorCode.WRN_NullabilityMismatchInArgument));
            builder.Add(getId(ErrorCode.WRN_NullabilityMismatchInArgumentForOutput));
            builder.Add(getId(ErrorCode.WRN_NullabilityMismatchInReturnTypeOfTargetDelegate));
            builder.Add(getId(ErrorCode.WRN_NullabilityMismatchInParameterTypeOfTargetDelegate));
            builder.Add(getId(ErrorCode.WRN_NullAsNonNullable));
            builder.Add(getId(ErrorCode.WRN_NullableValueTypeMayBeNull));
            builder.Add(getId(ErrorCode.WRN_NullabilityMismatchInTypeParameterConstraint));
            builder.Add(getId(ErrorCode.WRN_NullabilityMismatchInTypeParameterReferenceTypeConstraint));
            builder.Add(getId(ErrorCode.WRN_PossibleNull));
            builder.Add(getId(ErrorCode.WRN_DefaultExpressionMayIntroduceNullT));
            builder.Add(getId(ErrorCode.WRN_NullLiteralMayIntroduceNullT));
            builder.Add(getId(ErrorCode.WRN_ConditionalAccessMayReturnNull));
            builder.Add(getId(ErrorCode.WRN_AsOperatorMayReturnNull));

            NullableFlowAnalysisSafetyWarnings = builder.ToImmutable();

            builder.Clear();
            builder.Add(getId(ErrorCode.WRN_ConvertingNullableToNonNullable));

            NullableFlowAnalysisNonSafetyWarnings = builder.ToImmutable();

            string getId(ErrorCode errorCode)
            {
                return(MessageProvider.Instance.GetIdForErrorCode((int)errorCode));
            }
        }
示例#3
0
            public ImageLayers Build()
            {
                if (!_removeDuplicates)
                {
                    return(new ImageLayers(ImmutableArray.CreateRange(layers), layerDigestsBuilder.ToImmutable()));
                }

                // LinkedHashSet maintains the order but keeps the first occurrence. Keep last occurrence by
                // adding elements in reverse, and then reversing the result
                ISet <ILayer>           dedupedButReversed = new LinkedHashSet <ILayer>(layers.Reverse());
                ImmutableArray <ILayer> deduped            = ImmutableArray.CreateRange(dedupedButReversed.Reverse());

                return(new ImageLayers(deduped, layerDigestsBuilder.ToImmutable()));
            }
示例#4
0
 public ImmutableHashSet <string> GetAllTargetImageTags()
 {
     ImmutableHashSet <string> .Builder allTargetImageTags = ImmutableHashSet.CreateBuilder <string>();
     allTargetImageTags.Add(targetImageConfiguration.GetImageTag());
     allTargetImageTags.UnionWith(additionalTargetImageTags);
     return(allTargetImageTags.ToImmutable());
 }
示例#5
0
        static ErrorFacts()
        {
            ImmutableHashSet <string> .Builder builder = ImmutableHashSet.CreateBuilder <string>();
            builder.Add(getId(ErrorCode.WRN_ConvertingNullableToNonNullable));
            builder.Add(getId(ErrorCode.WRN_NullReferenceAssignment));
            builder.Add(getId(ErrorCode.WRN_NullReferenceReceiver));
            builder.Add(getId(ErrorCode.WRN_NullReferenceReturn));
            builder.Add(getId(ErrorCode.WRN_NullReferenceArgument));
            builder.Add(getId(ErrorCode.WRN_UninitializedNonNullableField));
            builder.Add(getId(ErrorCode.WRN_NullabilityMismatchInAssignment));
            builder.Add(getId(ErrorCode.WRN_NullabilityMismatchInArgument));
            builder.Add(getId(ErrorCode.WRN_NullabilityMismatchInReturnTypeOfTargetDelegate));
            builder.Add(getId(ErrorCode.WRN_NullabilityMismatchInParameterTypeOfTargetDelegate));
            builder.Add(getId(ErrorCode.WRN_NullAsNonNullable));
            builder.Add(getId(ErrorCode.WRN_NoBestNullabilityConditionalExpression));
            builder.Add(getId(ErrorCode.WRN_NullabilityMismatchInTypeParameterConstraint));
            builder.Add(getId(ErrorCode.WRN_NullabilityMismatchInTypeParameterReferenceTypeConstraint));
            builder.Add(getId(ErrorCode.WRN_CantInferNullabilityOfMethodTypeArgs));
            builder.Add(getId(ErrorCode.WRN_NoBestNullabilityArrayElements));
            builder.Add(getId(ErrorCode.HDN_NullCheckIsProbablyAlwaysFalse));
            builder.Add(getId(ErrorCode.HDN_NullCheckIsProbablyAlwaysTrue));
            builder.Add(getId(ErrorCode.HDN_ExpressionIsProbablyNeverNull));

            NullableFlowAnalysisWarnings = builder.ToImmutable();

            string getId(ErrorCode errorCode)
            {
                return(MessageProvider.Instance.GetIdForErrorCode((int)errorCode));
            }
        }
示例#6
0
        static ErrorFacts()
        {
            ImmutableHashSet <string> .Builder nullableWarnings = ImmutableHashSet.CreateBuilder <string>();

            nullableWarnings.Add(getId(ErrorCode.WRN_NullReferenceAssignment));
            nullableWarnings.Add(getId(ErrorCode.WRN_NullReferenceReceiver));
            nullableWarnings.Add(getId(ErrorCode.WRN_NullReferenceReturn));
            nullableWarnings.Add(getId(ErrorCode.WRN_NullReferenceArgument));
            nullableWarnings.Add(getId(ErrorCode.WRN_UninitializedNonNullableField));
            nullableWarnings.Add(getId(ErrorCode.WRN_NullabilityMismatchInAssignment));
            nullableWarnings.Add(getId(ErrorCode.WRN_NullabilityMismatchInArgument));
            nullableWarnings.Add(getId(ErrorCode.WRN_NullabilityMismatchInArgumentForOutput));
            nullableWarnings.Add(getId(ErrorCode.WRN_NullabilityMismatchInReturnTypeOfTargetDelegate));
            nullableWarnings.Add(getId(ErrorCode.WRN_NullabilityMismatchInParameterTypeOfTargetDelegate));
            nullableWarnings.Add(getId(ErrorCode.WRN_NullAsNonNullable));
            nullableWarnings.Add(getId(ErrorCode.WRN_NullableValueTypeMayBeNull));
            nullableWarnings.Add(getId(ErrorCode.WRN_NullabilityMismatchInTypeParameterConstraint));
            nullableWarnings.Add(getId(ErrorCode.WRN_NullabilityMismatchInTypeParameterReferenceTypeConstraint));
            nullableWarnings.Add(getId(ErrorCode.WRN_NullabilityMismatchInTypeParameterNotNullConstraint));
            nullableWarnings.Add(getId(ErrorCode.WRN_ThrowPossibleNull));
            nullableWarnings.Add(getId(ErrorCode.WRN_UnboxPossibleNull));
            nullableWarnings.Add(getId(ErrorCode.WRN_SwitchExpressionNotExhaustiveForNull));
            nullableWarnings.Add(getId(ErrorCode.WRN_SwitchExpressionNotExhaustiveForNullWithWhen));

            nullableWarnings.Add(getId(ErrorCode.WRN_ConvertingNullableToNonNullable));
            nullableWarnings.Add(getId(ErrorCode.WRN_DisallowNullAttributeForbidsMaybeNullAssignment));
            nullableWarnings.Add(getId(ErrorCode.WRN_ParameterConditionallyDisallowsNull));
            nullableWarnings.Add(getId(ErrorCode.WRN_ShouldNotReturn));

            nullableWarnings.Add(getId(ErrorCode.WRN_NullabilityMismatchInTypeOnOverride));
            nullableWarnings.Add(getId(ErrorCode.WRN_NullabilityMismatchInReturnTypeOnOverride));
            nullableWarnings.Add(getId(ErrorCode.WRN_NullabilityMismatchInReturnTypeOnPartial));
            nullableWarnings.Add(getId(ErrorCode.WRN_NullabilityMismatchInParameterTypeOnOverride));
            nullableWarnings.Add(getId(ErrorCode.WRN_NullabilityMismatchInParameterTypeOnPartial));
            nullableWarnings.Add(getId(ErrorCode.WRN_NullabilityMismatchInTypeOnImplicitImplementation));
            nullableWarnings.Add(getId(ErrorCode.WRN_NullabilityMismatchInReturnTypeOnImplicitImplementation));
            nullableWarnings.Add(getId(ErrorCode.WRN_NullabilityMismatchInParameterTypeOnImplicitImplementation));
            nullableWarnings.Add(getId(ErrorCode.WRN_NullabilityMismatchInTypeOnExplicitImplementation));
            nullableWarnings.Add(getId(ErrorCode.WRN_NullabilityMismatchInReturnTypeOnExplicitImplementation));
            nullableWarnings.Add(getId(ErrorCode.WRN_NullabilityMismatchInParameterTypeOnExplicitImplementation));
            nullableWarnings.Add(getId(ErrorCode.WRN_NullabilityMismatchInConstraintsOnImplicitImplementation));
            nullableWarnings.Add(getId(ErrorCode.WRN_NullabilityMismatchInExplicitlyImplementedInterface));
            nullableWarnings.Add(getId(ErrorCode.WRN_NullabilityMismatchInInterfaceImplementedByBase));
            nullableWarnings.Add(getId(ErrorCode.WRN_DuplicateInterfaceWithNullabilityMismatchInBaseList));
            nullableWarnings.Add(getId(ErrorCode.WRN_NullabilityMismatchInConstraintsOnPartialImplementation));
            nullableWarnings.Add(getId(ErrorCode.WRN_NullReferenceInitializer));
            nullableWarnings.Add(getId(ErrorCode.WRN_ShouldNotReturn));
            nullableWarnings.Add(getId(ErrorCode.WRN_DoesNotReturnMismatch));
            nullableWarnings.Add(getId(ErrorCode.WRN_TopLevelNullabilityMismatchInParameterTypeOnExplicitImplementation));
            nullableWarnings.Add(getId(ErrorCode.WRN_TopLevelNullabilityMismatchInParameterTypeOnImplicitImplementation));
            nullableWarnings.Add(getId(ErrorCode.WRN_TopLevelNullabilityMismatchInParameterTypeOnOverride));
            nullableWarnings.Add(getId(ErrorCode.WRN_TopLevelNullabilityMismatchInReturnTypeOnExplicitImplementation));
            nullableWarnings.Add(getId(ErrorCode.WRN_TopLevelNullabilityMismatchInReturnTypeOnImplicitImplementation));
            nullableWarnings.Add(getId(ErrorCode.WRN_TopLevelNullabilityMismatchInReturnTypeOnOverride));
            nullableWarnings.Add(getId(ErrorCode.WRN_MemberNotNull));
            nullableWarnings.Add(getId(ErrorCode.WRN_MemberNotNullBadMember));
            nullableWarnings.Add(getId(ErrorCode.WRN_MemberNotNullWhen));
            nullableWarnings.Add(getId(ErrorCode.WRN_ParameterDisallowsNull));

            NullableWarnings = nullableWarnings.ToImmutable();
示例#7
0
        private static ImmutableHashSet <string> ToImmutableAndFree(ImmutableHashSet <string> .Builder builder)
        {
            var result = builder.ToImmutable();

            builder.Clear();
            s_memberNameBuilderPool.Free(builder);
            return(result);
        }
示例#8
0
        static ErrorFacts()
        {
            ImmutableHashSet <string> .Builder builder = ImmutableHashSet.CreateBuilder <string>();

            builder.Add(getId(ErrorCode.WRN_NullReferenceAssignment));
            builder.Add(getId(ErrorCode.WRN_NullReferenceReceiver));
            builder.Add(getId(ErrorCode.WRN_NullReferenceReturn));
            builder.Add(getId(ErrorCode.WRN_NullReferenceArgument));
            builder.Add(getId(ErrorCode.WRN_NullReferenceIterationVariable));
            builder.Add(getId(ErrorCode.WRN_UninitializedNonNullableField));
            builder.Add(getId(ErrorCode.WRN_NullabilityMismatchInAssignment));
            builder.Add(getId(ErrorCode.WRN_NullabilityMismatchInArgument));
            builder.Add(getId(ErrorCode.WRN_NullabilityMismatchInArgumentForOutput));
            builder.Add(getId(ErrorCode.WRN_NullabilityMismatchInReturnTypeOfTargetDelegate));
            builder.Add(getId(ErrorCode.WRN_NullabilityMismatchInParameterTypeOfTargetDelegate));
            builder.Add(getId(ErrorCode.WRN_NullAsNonNullable));
            builder.Add(getId(ErrorCode.WRN_NullableValueTypeMayBeNull));
            builder.Add(getId(ErrorCode.WRN_NullabilityMismatchInTypeParameterConstraint));
            builder.Add(getId(ErrorCode.WRN_NullabilityMismatchInTypeParameterReferenceTypeConstraint));
            builder.Add(getId(ErrorCode.WRN_NullabilityMismatchInTypeParameterNotNullConstraint));
            builder.Add(getId(ErrorCode.WRN_ThrowPossibleNull));
            builder.Add(getId(ErrorCode.WRN_UnboxPossibleNull));
            builder.Add(getId(ErrorCode.WRN_DefaultExpressionMayIntroduceNullT));
            builder.Add(getId(ErrorCode.WRN_NullLiteralMayIntroduceNullT));
            builder.Add(getId(ErrorCode.WRN_ConditionalAccessMayReturnNull));
            builder.Add(getId(ErrorCode.WRN_AsOperatorMayReturnNull));
            builder.Add(getId(ErrorCode.WRN_SwitchExpressionNotExhaustiveForNull));

            builder.Add(getId(ErrorCode.WRN_ConvertingNullableToNonNullable));
            builder.Add(getId(ErrorCode.WRN_DisallowNullAttributeForbidsMaybeNullAssignment));

            builder.Add(getId(ErrorCode.WRN_NullabilityMismatchInTypeOnOverride));
            builder.Add(getId(ErrorCode.WRN_NullabilityMismatchInReturnTypeOnOverride));
            builder.Add(getId(ErrorCode.WRN_NullabilityMismatchInParameterTypeOnOverride));
            builder.Add(getId(ErrorCode.WRN_NullabilityMismatchInParameterTypeOnPartial));
            builder.Add(getId(ErrorCode.WRN_NullabilityMismatchInTypeOnImplicitImplementation));
            builder.Add(getId(ErrorCode.WRN_NullabilityMismatchInReturnTypeOnImplicitImplementation));
            builder.Add(getId(ErrorCode.WRN_NullabilityMismatchInParameterTypeOnImplicitImplementation));
            builder.Add(getId(ErrorCode.WRN_NullabilityMismatchInTypeOnExplicitImplementation));
            builder.Add(getId(ErrorCode.WRN_NullabilityMismatchInReturnTypeOnExplicitImplementation));
            builder.Add(getId(ErrorCode.WRN_NullabilityMismatchInParameterTypeOnExplicitImplementation));
            builder.Add(getId(ErrorCode.WRN_NullabilityMismatchInConstraintsOnImplicitImplementation));
            builder.Add(getId(ErrorCode.WRN_NullabilityMismatchInExplicitlyImplementedInterface));
            builder.Add(getId(ErrorCode.WRN_NullabilityMismatchInInterfaceImplementedByBase));
            builder.Add(getId(ErrorCode.WRN_DuplicateInterfaceWithNullabilityMismatchInBaseList));
            builder.Add(getId(ErrorCode.WRN_NullabilityMismatchInConstraintsOnPartialImplementation));
            builder.Add(getId(ErrorCode.WRN_NullReferenceInitializer));

            builder.Add(getId(ErrorCode.WRN_ExpressionMayIntroduceNullT));

            NullableWarnings = builder.ToImmutable();

            string getId(ErrorCode errorCode)
            {
                return(MessageProvider.Instance.GetIdForErrorCode((int)errorCode));
            }
        }
        public override void Initialize(AnalysisContext context)
        {
            base.Initialize(context);

            context.RegisterCompilationStartAction(startContext =>
            {
                if (_syntaxKindNames == null)
                {
                    Compilation compilation = startContext.Compilation;

                    INamedTypeSymbol csharpSyntaxNodeSymbol = compilation.GetTypeByMetadataName("Microsoft.CodeAnalysis.CSharp.CSharpSyntaxNode");

                    if (csharpSyntaxNodeSymbol == null)
                    {
                        return;
                    }

                    Dictionary <string, string> kindsToNames = compilation
                                                               .GetTypeByMetadataName("Microsoft.CodeAnalysis.CSharp.Syntax.AccessorDeclarationSyntax")
                                                               .ContainingNamespace
                                                               .GetTypeMembers()
                                                               .Where(f => f.TypeKind == TypeKind.Class &&
                                                                      !f.IsAbstract &&
                                                                      f.InheritsFrom(csharpSyntaxNodeSymbol) &&
                                                                      f.Name.EndsWith("Syntax", StringComparison.Ordinal))
                                                               .ToDictionary(f => f.Name.Remove(f.Name.Length - 6), f => f.Name);

                    ImmutableHashSet <string> .Builder syntaxKindNames = ImmutableHashSet.CreateBuilder <string>();
                    ImmutableHashSet <string> .Builder syntaxTypeNames = ImmutableHashSet.CreateBuilder <string>();
                    ImmutableDictionary <ushort, string> .Builder syntaxKindValuesToNames = ImmutableDictionary.CreateBuilder <ushort, string>();

                    foreach (SyntaxKind syntaxKind in Enum.GetValues(typeof(SyntaxKind))
                             .Cast <SyntaxKind>()
                             .Select(f => f))
                    {
                        string name = syntaxKind.ToString();

                        if (kindsToNames.TryGetValue(name, out string symbolName))
                        {
                            syntaxKindNames.Add(name);
                            syntaxTypeNames.Add(symbolName);
                        }

                        syntaxKindValuesToNames.Add((ushort)syntaxKind, name);
                    }

                    Interlocked.CompareExchange(ref _syntaxKindNames, syntaxKindNames.ToImmutable(), null);
                    Interlocked.CompareExchange(ref _syntaxTypeNames, syntaxTypeNames.ToImmutable(), null);
                    Interlocked.CompareExchange(ref _syntaxKindValuesToNames, syntaxKindValuesToNames.ToImmutable(), null);
                }

                startContext.RegisterSyntaxNodeAction(f => AnalyzeSwitchStatement(f), SyntaxKind.SwitchStatement);
                startContext.RegisterSyntaxNodeAction(f => AnalyzeIfStatement(f), SyntaxKind.IfStatement);
            });
        }
        private IImmutableSet <string> GetDimensionNames()
        {
            ImmutableHashSet <string> .Builder builder = ImmutableHashSet.CreateBuilder(StringComparers.ConfigurationDimensionNames);

            foreach (Lazy <IActiveConfiguredProjectsDimensionProvider> dimensionProvider in DimensionProviders)
            {
                builder.Add(dimensionProvider.Value.DimensionName);
            }

            return(builder.ToImmutable());
        }
 internal LambdaAndLocalFunctionAnalysisInfo(
     ImmutableHashSet <IMethodSymbol> .Builder escapedLocalFunctions,
     ImmutableHashSet <IMethodSymbol> .Builder analyzedLocalFunctions,
     ImmutableHashSet <IFlowAnonymousFunctionOperation> .Builder escapedLambdas,
     ImmutableHashSet <IFlowAnonymousFunctionOperation> .Builder analyzedLambdas)
 {
     EscapedLocalFunctions  = escapedLocalFunctions.ToImmutable();
     AnalyzedLocalFunctions = analyzedLocalFunctions.ToImmutable();
     EscapedLambdas         = escapedLambdas.ToImmutable();
     AnalyzedLambdas        = analyzedLambdas.ToImmutable();
 }
        private MutabilityInspectionResult InspectClassOrStruct(
            ITypeSymbol type,
            HashSet <ITypeSymbol> typeStack
            )
        {
            if (typeStack.Contains(type))
            {
                // We have a cycle. If we're here, it means that either some read-only member causes the cycle (via IsMemberMutableRecursive),
                // or a generic parameter to a type causes the cycle (via IsTypeMutableRecursive). This is safe if the checks above have
                // passed and the remaining members are read-only immutable. So we can skip the current check, and allow the type to continue
                // to be evaluated.
                return(MutabilityInspectionResult.NotMutable());
            }

            // We have a type that is not marked immutable, is not an interface, is not an immutable container, etc..
            // If it is defined in a different assembly, we might not have the metadata to correctly analyze it; so we fail.
            if (TypeIsFromOtherAssembly(type))
            {
                return(MutabilityInspectionResult.MutableType(type, MutabilityCause.IsAnExternalUnmarkedType));
            }

            ImmutableHashSet <string> .Builder seenUnauditedReasonsBuilder = ImmutableHashSet.CreateBuilder <string>();

            typeStack.Add(type);
            try {
                foreach (ISymbol member in type.GetExplicitNonStaticMembers())
                {
                    var result = InspectMemberRecursive(member, typeStack);
                    if (result.IsMutable)
                    {
                        return(result);
                    }
                    seenUnauditedReasonsBuilder.UnionWith(result.SeenUnauditedReasons);
                }

                // We descend into the base class last
                if (type.BaseType != null)
                {
                    var baseResult = InspectConcreteType(type.BaseType, typeStack);

                    if (baseResult.IsMutable)
                    {
                        return(baseResult);
                    }
                    seenUnauditedReasonsBuilder.UnionWith(baseResult.SeenUnauditedReasons);
                }
            } finally {
                typeStack.Remove(type);
            }

            return(MutabilityInspectionResult.NotMutable(seenUnauditedReasonsBuilder.ToImmutable()));
        }
示例#13
0
        private void UpdateDependenciesSnapshot(
            ImmutableDictionary <ITargetFramework, IDependenciesChanges> changes,
            IProjectCatalogSnapshot catalogs,
            ITargetFramework activeTargetFramework,
            CancellationToken token)
        {
            IImmutableSet <string> projectItemSpecs = GetProjectItemSpecsFromSnapshot();

            TryUpdateSnapshot(
                snapshot => DependenciesSnapshot.FromChanges(
                    _commonServices.Project.FullPath,
                    snapshot,
                    changes,
                    catalogs,
                    activeTargetFramework,
                    _snapshotFilters.ToImmutableValueArray(),
                    _subTreeProviders.ToValueDictionary(p => p.ProviderType),
                    projectItemSpecs),
                token);

            return;

            // Gets the set of items defined directly the project, and not included by imports.
            IImmutableSet <string> GetProjectItemSpecsFromSnapshot()
            {
                // We don't have catalog snapshot, we're likely updating because one of our project
                // dependencies changed. Just return 'no data'
                if (catalogs == null)
                {
                    return(null);
                }

                ImmutableHashSet <string> .Builder itemSpecs = ImmutableHashSet.CreateBuilder(StringComparer.OrdinalIgnoreCase);

                foreach (ProjectItemInstance item in catalogs.Project.ProjectInstance.Items)
                {
                    if (item.IsImported())
                    {
                        continue;
                    }

                    // Returns unescaped evaluated include
                    string itemSpec = item.EvaluatedInclude;
                    if (itemSpec.Length != 0)
                    {
                        itemSpecs.Add(itemSpec);
                    }
                }

                return(itemSpecs.ToImmutable());
            }
        }
示例#14
0
文件: Port.cs 项目: tiaotiao97/jib
        /**
         * Converts/validates a list of strings representing port ranges to an expanded list of {@link
         * Port}s.
         *
         * <p>For example: ["1000", "2000-2002"] will expand to a list of {@link Port}s with the port
         * numbers [1000, 2000, 2001, 2002]
         *
         * @param ports the list of port numbers/ranges, with an optional protocol separated by a '/'
         *     (defaults to TCP if missing).
         * @return the ports as a list of {@link Port}
         * @throws NumberFormatException if any of the ports are in an invalid format or out of range
         */
        public static ImmutableHashSet <Port> Parse(IEnumerable <string> ports)
        {
            ports = ports ?? throw new ArgumentNullException(nameof(ports));
            ImmutableHashSet <Port> .Builder result = ImmutableHashSet.CreateBuilder <Port>();

            foreach (string port in ports)

            {
                Match matcher = PortPattern.Match(port);

                if (!matcher.Success)
                {
                    throw new FormatException(
                              "Invalid port configuration: '"
                              + port
                              + "'. Make sure the port is a single number or a range of two numbers separated "
                              + "with a '-', with or without protocol specified (e.g. '<portNum>/tcp' or "
                              + "'<portNum>/udp').");
                }

                // Parse protocol
                int min = int.Parse(matcher.Groups[1].Value, CultureInfo.InvariantCulture);
                int max = min;
                if (!string.IsNullOrEmpty(matcher.Groups[2].Value))
                {
                    max = int.Parse(matcher.Groups[2].Value, CultureInfo.InvariantCulture);
                }
                string protocol = matcher.Groups[3].Value;

                // Error if configured as 'max-min' instead of 'min-max'
                if (min > max)
                {
                    throw new FormatException(
                              "Invalid port range '" + port + "'; smaller number must come first.");
                }

                // Warn for possibly invalid port numbers
                if (min < 1 || max > 65535)
                {
                    throw new FormatException(
                              "Port number '" + port + "' is out of usual range (1-65535).");
                }

                for (int portNumber = min; portNumber <= max; portNumber++)
                {
                    result.Add(Port.ParseProtocol(portNumber, protocol));
                }
            }

            return(result.ToImmutable());
        }
示例#15
0
        static void Main(string[] args)
        {
            ImmutableHashSet <int> il = ImmutableHashSet.Create <int>();

            il = il.Add(1);
            il = il.Add(2);
            il = il.Remove(2);
            ImmutableHashSet <int> .Builder issBuilder = il.ToBuilder();
            issBuilder.Add(10); //adds to original Hashset. returns void.

            ImmutableHashSet <int> .Builder builder = ImmutableHashSet.CreateBuilder <int>();
            builder.Add(1);
            il = builder.ToImmutable();
        }
示例#16
0
        // Internal, for test use -- normal code should use the factory methods
        internal TargetedDependenciesSnapshot(
            string projectPath,
            ITargetFramework targetFramework,
            IProjectCatalogSnapshot catalogs,
            ImmutableDictionary <string, IDependency> dependenciesWorld)
        {
            Requires.NotNullOrEmpty(projectPath, nameof(projectPath));
            Requires.NotNull(targetFramework, nameof(targetFramework));
            // catalogs can be null
            Requires.NotNull(dependenciesWorld, nameof(dependenciesWorld));

            ProjectPath       = projectPath;
            TargetFramework   = targetFramework;
            Catalogs          = catalogs;
            DependenciesWorld = dependenciesWorld;

            bool hasUnresolvedDependency = false;

            ImmutableHashSet <IDependency> .Builder topLevelDependencies = ImmutableHashSet.CreateBuilder <IDependency>();

            foreach ((string id, IDependency dependency) in dependenciesWorld)
            {
                System.Diagnostics.Debug.Assert(
                    string.Equals(id, dependency.Id),
                    "dependenciesWorld dictionary entry keys must match their value's ids.");

                if (!dependency.Resolved)
                {
                    hasUnresolvedDependency = true;
                }

                if (dependency.TopLevel)
                {
                    bool added = topLevelDependencies.Add(dependency);
                    System.Diagnostics.Debug.Assert(added, "Duplicate top level dependency found.");

                    if (!string.IsNullOrEmpty(dependency.Path))
                    {
                        _topLevelDependenciesByPathMap.Add(
                            Dependency.GetID(TargetFramework, dependency.ProviderType, dependency.Path),
                            dependency);
                    }
                }
            }

            HasUnresolvedDependency = hasUnresolvedDependency;
            TopLevelDependencies    = topLevelDependencies.ToImmutable();
        }
示例#17
0
        /// <summary>
        /// Initializes a new alternation set.
        /// </summary>
        /// <param name="setElements">The elements of this set.</param>
        public NegatedSet(params SetElement[] setElements)
        {
            if (setElements is null)
            {
                throw new ArgumentNullException(nameof(setElements));
            }
            if (setElements.Length < 1)
            {
                throw new ArgumentException("At least 1 set element is required.", nameof(setElements));
            }

            ImmutableHashSet <Char> .Builder                characters = ImmutableHashSet.CreateBuilder <Char>();
            ImmutableHashSet <Range <Char> > .Builder       ranges     = ImmutableHashSet.CreateBuilder <Range <Char> >();
            ImmutableHashSet <UnicodeCategory> .Builder     categories = ImmutableHashSet.CreateBuilder <UnicodeCategory>();
            ImmutableHashSet <GrammarNode <Char> > .Builder nodes      = ImmutableHashSet.CreateBuilder <GrammarNode <Char> >();
            for (var elementIdx = 0; elementIdx < setElements.Length; elementIdx++)
            {
                SetElement setElement = setElements[elementIdx];
                switch (setElement.Type)
                {
                case SetElementType.Character:
                    characters.Add(setElement.Character);
                    break;

                case SetElementType.Range:
                    ranges.Add(setElement.Range);
                    break;

                case SetElementType.UnicodeCategory:
                    categories.Add(setElement.UnicodeCategory);
                    break;

                case SetElementType.Node:
                    nodes.Add(setElement.Node);
                    break;

                case SetElementType.Invalid:
                default:
                    throw new InvalidOperationException($"Invalid set element provided at index {elementIdx}.");
                }
            }

            this.Characters        = characters.ToImmutable();
            this.Ranges            = ranges.ToImmutable();
            this.UnicodeCategories = categories.ToImmutable();
            this.Nodes             = nodes.ToImmutable();
        }
            public ImmutableHashSet <FindSymbolResult> FindPropertyOrFieldSymbols(SemanticModel model, SyntaxList <StatementSyntax> statements, CancellationToken token)
            {
                if (model == null)
                {
                    throw new ArgumentNullException(nameof(model));
                }
                ImmutableHashSet <FindSymbolResult> symbolResults = ImmutableHashSet <FindSymbolResult> .Empty;

                ImmutableHashSet <FindSymbolResult> .Builder builder = symbolResults.ToBuilder();

                foreach (var syntax in statements)
                {
                    token.ThrowIfCancellationRequested();
                    EnumerateNodes(ref builder, model, syntax.DescendantNodesAndSelf(), token);
                }
                return(builder.ToImmutable());
            }
        private MutabilityInspectionResult InspectImmutableContainerType(
            ITypeSymbol type,
            HashSet <ITypeSymbol> typeStack
            )
        {
            var namedType = type as INamedTypeSymbol;

            ImmutableHashSet <string> .Builder unauditedReasonsBuilder = ImmutableHashSet.CreateBuilder <string>();

            for (int i = 0; i < namedType.TypeArguments.Length; i++)
            {
                var arg = namedType.TypeArguments[i];

                var result = InspectType(
                    arg,
                    MutabilityInspectionFlags.Default,
                    typeStack
                    );

                if (result.IsMutable)
                {
                    if (result.Target == MutabilityTarget.Member)
                    {
                        // modify the result to prefix with container member.
                        var prefix = ImmutableContainerTypes[type.GetFullTypeName()];
                        result = result.WithPrefixedMember(prefix[i]);
                    }
                    else
                    {
                        // modify the result to target the type argument if the
                        // target is not a member
                        result = result.WithTarget(
                            MutabilityTarget.TypeArgument
                            );
                    }
                    return(result);
                }

                unauditedReasonsBuilder.UnionWith(result.SeenUnauditedReasons);
            }

            return(MutabilityInspectionResult.NotMutable(unauditedReasonsBuilder.ToImmutable()));
        }
            public ImmutableHashSet <FindSymbolResult> FindPropertyOrFieldSymbols(SemanticModel model, ExpressionSyntax expression, CancellationToken token)
            {
                if (model == null)
                {
                    throw new ArgumentNullException(nameof(model));
                }
                if (expression == null)
                {
                    throw new ArgumentNullException(nameof(expression));
                }

                ImmutableHashSet <FindSymbolResult> symbolResults = ImmutableHashSet <FindSymbolResult> .Empty;

                ImmutableHashSet <FindSymbolResult> .Builder builder = symbolResults.ToBuilder();

                token.ThrowIfCancellationRequested();
                EnumerateNodes(ref builder, model, expression.DescendantNodesAndSelf(), token);
                return(builder.ToImmutable());
            }
        /// <summary>
        /// Gets the set of assemblies that a generated assembly must be granted the ability to skip visiblity checks for
        /// in order to access the specified type.
        /// </summary>
        /// <param name="typeInfo">The type which may be internal.</param>
        /// <returns>The set of names of assemblies to skip visibility checks for.</returns>
        internal static ImmutableHashSet <AssemblyName> GetSkipVisibilityChecksRequirements(TypeInfo typeInfo)
        {
            Requires.NotNull(typeInfo, nameof(typeInfo));

            var visitedTypes = new HashSet <TypeInfo>();

            ImmutableHashSet <AssemblyName> .Builder assembliesDeclaringInternalTypes = ImmutableHashSet.CreateBuilder <AssemblyName>(AssemblyNameEqualityComparer.Instance);
            CheckForNonPublicTypes(typeInfo, assembliesDeclaringInternalTypes, visitedTypes);

            // Enumerate members on the interface that we're going to need to implement.
            foreach (MethodInfo methodInfo in typeInfo.GetMethods(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.FlattenHierarchy))
            {
                CheckForNonPublicTypes(methodInfo.ReturnType.GetTypeInfo(), assembliesDeclaringInternalTypes, visitedTypes);
                foreach (ParameterInfo parameter in methodInfo.GetParameters())
                {
                    CheckForNonPublicTypes(parameter.ParameterType.GetTypeInfo(), assembliesDeclaringInternalTypes, visitedTypes);
                }
            }

            return(assembliesDeclaringInternalTypes.ToImmutable());
        }
示例#22
0
        /**
         * Converts a map of volumes strings to a set of {@link AbsoluteUnixPath}s (e.g. {@code {@code
         * {"/var/log/my-app-logs":{}}} => AbsoluteUnixPath().get("/var/log/my-app-logs")}).
         *
         * @param volumeMap the map to convert
         * @return a set of {@link AbsoluteUnixPath}s
         */

        public static ImmutableHashSet <AbsoluteUnixPath> VolumeMapToSet(IDictionary <string, IDictionary <object, object> > volumeMap)
        {
            if (volumeMap == null)
            {
                return(ImmutableHashSet.Create <AbsoluteUnixPath>());
            }

            ImmutableHashSet <AbsoluteUnixPath> .Builder volumeList = ImmutableHashSet.CreateBuilder <AbsoluteUnixPath>();
            foreach (string volume in volumeMap.Keys)
            {
                try
                {
                    volumeList.Add(AbsoluteUnixPath.Get(volume));
                }
                catch (ArgumentException)
                {
                    throw new BadContainerConfigurationFormatException("Invalid volume path: " + volume);
                }
            }

            return(volumeList.ToImmutable());
        }
示例#23
0
        /**
         * Converts a map of exposed ports as strings to a set of {@link Port}s (e.g. {@code
         * {"1000/tcp":{}}} => {@code Port(1000, Protocol.TCP)}).
         *
         * @param portMap the map to convert
         * @return a set of {@link Port}s
         */

        public static ImmutableHashSet <Port> PortMapToSet(IDictionary <string, IDictionary <object, object> > portMap)
        {
            if (portMap == null)
            {
                return(ImmutableHashSet.Create <Port>());
            }
            ImmutableHashSet <Port> .Builder ports = ImmutableHashSet.CreateBuilder <Port>();
            foreach (KeyValuePair <string, IDictionary <object, object> > entry in portMap)
            {
                string port    = entry.Key;
                Match  matcher = PORT_PATTERN.Match(port);
                if (!matcher.Success)
                {
                    throw new BadContainerConfigurationFormatException(
                              "Invalid port configuration: '" + port + "'.");
                }

                int    portNumber = int.Parse(matcher.Groups["portNum"].Value, CultureInfo.InvariantCulture);
                string protocol   = matcher.Groups["protocol"].Value;
                ports.Add(Port.ParseProtocol(portNumber, protocol));
            }
            return(ports.ToImmutable());
        }
        private static void OnCompilationStart(CompilationStartAnalysisContext context)
        {
            ImmutableHashSet <IMethodSymbol> .Builder syncMethods  = ImmutableHashSet.CreateBuilder <IMethodSymbol>();
            ImmutableHashSet <IMethodSymbol> .Builder asyncMethods = ImmutableHashSet.CreateBuilder <IMethodSymbol>();

            INamedTypeSymbol?           namedType = context.Compilation.GetOrCreateTypeByMetadataName(WellKnownTypeNames.SystemLinqEnumerable);
            IEnumerable <IMethodSymbol>?methods   = namedType?.GetMembers(Count).OfType <IMethodSymbol>().Where(m => m.Parameters.Length <= 2);

            AddIfNotNull(syncMethods, methods);

            methods = namedType?.GetMembers(LongCount).OfType <IMethodSymbol>().Where(m => m.Parameters.Length <= 2);
            AddIfNotNull(syncMethods, methods);

            namedType = context.Compilation.GetOrCreateTypeByMetadataName(WellKnownTypeNames.SystemLinqQueryable);
            methods   = namedType?.GetMembers(Count).OfType <IMethodSymbol>().Where(m => m.Parameters.Length <= 2);
            AddIfNotNull(syncMethods, methods);

            methods = namedType?.GetMembers(LongCount).OfType <IMethodSymbol>().Where(m => m.Parameters.Length <= 2);
            AddIfNotNull(syncMethods, methods);

            namedType = context.Compilation.GetOrCreateTypeByMetadataName(WellKnownTypeNames.MicrosoftEntityFrameworkCoreEntityFrameworkQueryableExtensions);
            methods   = namedType?.GetMembers(CountAsync).OfType <IMethodSymbol>().Where(m => m.Parameters.Length <= 2);
            AddIfNotNull(asyncMethods, methods);

            methods = namedType?.GetMembers(LongCountAsync).OfType <IMethodSymbol>().Where(m => m.Parameters.Length <= 2);
            AddIfNotNull(asyncMethods, methods);

            namedType = context.Compilation.GetOrCreateTypeByMetadataName(WellKnownTypeNames.SystemDataEntityQueryableExtensions);
            methods   = namedType?.GetMembers(CountAsync).OfType <IMethodSymbol>().Where(m => m.Parameters.Length <= 2);
            AddIfNotNull(asyncMethods, methods);

            methods = namedType?.GetMembers(LongCountAsync).OfType <IMethodSymbol>().Where(m => m.Parameters.Length <= 2);
            AddIfNotNull(asyncMethods, methods);

            // Allowed types that should report a CA1836 diagnosis given that there is proven benefit on doing so.
            ImmutableHashSet <ITypeSymbol> .Builder allowedTypesBuilder = ImmutableHashSet.CreateBuilder <ITypeSymbol>();

            namedType = context.Compilation.GetOrCreateTypeByMetadataName(WellKnownTypeNames.SystemCollectionsConcurrentConcurrentBag1);
            allowedTypesBuilder.AddIfNotNull(namedType);

            namedType = context.Compilation.GetOrCreateTypeByMetadataName(WellKnownTypeNames.SystemCollectionsConcurrentConcurrentDictionary2);
            allowedTypesBuilder.AddIfNotNull(namedType);

            namedType = context.Compilation.GetOrCreateTypeByMetadataName(WellKnownTypeNames.SystemCollectionsConcurrentConcurrentQueue1);
            allowedTypesBuilder.AddIfNotNull(namedType);

            namedType = context.Compilation.GetOrCreateTypeByMetadataName(WellKnownTypeNames.SystemCollectionsConcurrentConcurrentStack1);
            allowedTypesBuilder.AddIfNotNull(namedType);

            ImmutableHashSet <ITypeSymbol> allowedTypesForCA1836 = allowedTypesBuilder.ToImmutable();

            if (syncMethods.Count > 0 || asyncMethods.Count > 0)
            {
                context.RegisterOperationAction(operationContext => AnalyzeInvocationOperation(
                                                    operationContext, syncMethods.ToImmutable(), asyncMethods.ToImmutable(), allowedTypesForCA1836),
                                                OperationKind.Invocation);
            }

            if (!allowedTypesForCA1836.IsEmpty)
            {
                context.RegisterOperationAction(operationContext => AnalyzePropertyReference(
                                                    operationContext, allowedTypesForCA1836),
                                                OperationKind.PropertyReference);
            }
        public static ComputationalComplexityMetrics Compute(IOperation operationBlock)
        {
            bool hasSymbolInitializer  = false;
            long executableLinesOfCode = 0;
            long operatorUsageCounts   = 0;
            long symbolUsageCounts     = 0;
            long constantUsageCounts   = 0;

            ImmutableHashSet <OperationKind> .Builder?     distinctOperatorKindsBuilder       = null;
            ImmutableHashSet <BinaryOperatorKind> .Builder?distinctBinaryOperatorKindsBuilder = null;
            ImmutableHashSet <UnaryOperatorKind> .Builder? distinctUnaryOperatorKindsBuilder  = null;
            ImmutableHashSet <CaseKind> .Builder?          distinctCaseKindsBuilder           = null;
            ImmutableHashSet <ISymbol> .Builder?           distinctReferencedSymbolsBuilder   = null;
            ImmutableHashSet <object> .Builder?            distinctReferencedConstantsBuilder = null;

            // Explicit user applied attribute.
            if (operationBlock.Kind == OperationKind.None &&
                hasAnyExplicitExpression(operationBlock))
            {
                executableLinesOfCode += 1;
            }

            foreach (var operation in operationBlock.Descendants())
            {
                executableLinesOfCode += getExecutableLinesOfCode(operation, ref hasSymbolInitializer);

                if (operation.IsImplicit)
                {
                    continue;
                }

#if LEGACY_CODE_METRICS_MODE
                // Legacy mode does not account for code within lambdas/local functions for code metrics.
                if (operation.IsWithinLambdaOrLocalFunction(out _))
                {
                    continue;
                }
#endif

                if (operation.ConstantValue.HasValue)
                {
                    constantUsageCounts++;
                    distinctReferencedConstantsBuilder ??= ImmutableHashSet.CreateBuilder <object>();
                    distinctReferencedConstantsBuilder.Add(operation.ConstantValue.Value ?? s_nullConstantPlaceholder);
                    continue;
                }

                switch (operation.Kind)
                {
                // Symbol references.
                case OperationKind.LocalReference:
                    countOperand(((ILocalReferenceOperation)operation).Local);
                    continue;

                case OperationKind.ParameterReference:
                    countOperand(((IParameterReferenceOperation)operation).Parameter);
                    continue;

                case OperationKind.FieldReference:
                case OperationKind.MethodReference:
                case OperationKind.PropertyReference:
                case OperationKind.EventReference:
                    countOperator(operation);
                    countOperand(((IMemberReferenceOperation)operation).Member);
                    continue;

                // Symbol initializers.
                case OperationKind.FieldInitializer:
                    foreach (var field in ((IFieldInitializerOperation)operation).InitializedFields)
                    {
                        countOperator(operation);
                        countOperand(field);
                    }
                    continue;

                case OperationKind.PropertyInitializer:
                    foreach (var property in ((IPropertyInitializerOperation)operation).InitializedProperties)
                    {
                        countOperator(operation);
                        countOperand(property);
                    }
                    continue;

                case OperationKind.ParameterInitializer:
                    countOperator(operation);
                    countOperand(((IParameterInitializerOperation)operation).Parameter);
                    continue;

                case OperationKind.VariableInitializer:
                    countOperator(operation);
                    // We count the operand in the variable declarator.
                    continue;

                case OperationKind.VariableDeclarator:
                    var variableDeclarator = (IVariableDeclaratorOperation)operation;
                    if (variableDeclarator.GetVariableInitializer() != null)
                    {
                        countOperand(variableDeclarator.Symbol);
                    }
                    continue;

                // Invocations and Object creations.
                case OperationKind.Invocation:
                    countOperator(operation);
                    var invocation = (IInvocationOperation)operation;
                    if (!invocation.TargetMethod.ReturnsVoid)
                    {
                        countOperand(invocation.TargetMethod);
                    }
                    continue;

                case OperationKind.ObjectCreation:
                    countOperator(operation);
                    countOperand(((IObjectCreationOperation)operation).Constructor);
                    continue;

                case OperationKind.DelegateCreation:
                case OperationKind.AnonymousObjectCreation:
                case OperationKind.TypeParameterObjectCreation:
                case OperationKind.DynamicObjectCreation:
                case OperationKind.DynamicInvocation:
                    countOperator(operation);
                    continue;

                // Operators with special operator kinds.
                case OperationKind.BinaryOperator:
                    countBinaryOperator(operation, ((IBinaryOperation)operation).OperatorKind);
                    continue;

                case OperationKind.CompoundAssignment:
                    countBinaryOperator(operation, ((ICompoundAssignmentOperation)operation).OperatorKind);
                    continue;

                case OperationKind.TupleBinaryOperator:
                    countBinaryOperator(operation, ((ITupleBinaryOperation)operation).OperatorKind);
                    continue;

                case OperationKind.UnaryOperator:
                    countUnaryOperator(operation, ((IUnaryOperation)operation).OperatorKind);
                    continue;

                case OperationKind.CaseClause:
                    var caseClauseOperation = (ICaseClauseOperation)operation;
                    distinctCaseKindsBuilder ??= ImmutableHashSet.CreateBuilder <CaseKind>();
                    distinctCaseKindsBuilder.Add(caseClauseOperation.CaseKind);
                    if (caseClauseOperation.CaseKind == CaseKind.Relational)
                    {
                        countBinaryOperator(operation, ((IRelationalCaseClauseOperation)operation).Relation);
                    }
                    else
                    {
                        countOperator(operation);
                    }
                    continue;

                // Other common operators.
                case OperationKind.Increment:
                case OperationKind.Decrement:
                case OperationKind.SimpleAssignment:
                case OperationKind.DeconstructionAssignment:
                case OperationKind.EventAssignment:
                case OperationKind.Coalesce:
                case OperationKind.ConditionalAccess:
                case OperationKind.Conversion:
                case OperationKind.ArrayElementReference:
                case OperationKind.Await:
                case OperationKind.NameOf:
                case OperationKind.SizeOf:
                case OperationKind.TypeOf:
                case OperationKind.AddressOf:
                case OperationKind.MemberInitializer:
                case OperationKind.IsType:
                case OperationKind.IsPattern:
                case OperationKind.Parenthesized:
                    countOperator(operation);
                    continue;

                // Following are considered operators for now, but we may want to revisit.
                case OperationKind.ArrayCreation:
                case OperationKind.ArrayInitializer:
                case OperationKind.DynamicMemberReference:
                case OperationKind.DynamicIndexerAccess:
                case OperationKind.Tuple:
                case OperationKind.Lock:
                case OperationKind.Using:
                case OperationKind.Throw:
                case OperationKind.RaiseEvent:
                case OperationKind.InterpolatedString:
                    countOperator(operation);
                    continue;

                // Return value.
                case OperationKind.Return:
                case OperationKind.YieldBreak:
                case OperationKind.YieldReturn:
                    if (((IReturnOperation)operation).ReturnedValue != null)
                    {
                        countOperator(operation);
                    }
                    continue;
                }
            }

            return(Create(
                       executableLinesOfCode,
                       operatorUsageCounts,
                       symbolUsageCounts,
                       constantUsageCounts,
                       hasSymbolInitializer,
                       distinctOperatorKindsBuilder != null ? distinctOperatorKindsBuilder.ToImmutable() : ImmutableHashSet <OperationKind> .Empty,
                       distinctBinaryOperatorKindsBuilder != null ? distinctBinaryOperatorKindsBuilder.ToImmutable() : ImmutableHashSet <BinaryOperatorKind> .Empty,
                       distinctUnaryOperatorKindsBuilder != null ? distinctUnaryOperatorKindsBuilder.ToImmutable() : ImmutableHashSet <UnaryOperatorKind> .Empty,
                       distinctCaseKindsBuilder != null ? distinctCaseKindsBuilder.ToImmutable() : ImmutableHashSet <CaseKind> .Empty,
                       distinctReferencedSymbolsBuilder != null ? distinctReferencedSymbolsBuilder.ToImmutable() : ImmutableHashSet <ISymbol> .Empty,
                       distinctReferencedConstantsBuilder != null ? distinctReferencedConstantsBuilder.ToImmutable() : ImmutableHashSet <object> .Empty));
            internal static async Task <NamedTypeMetricData> ComputeAsync(INamedTypeSymbol namedType, SemanticModelProvider semanticModelProvider, CancellationToken cancellationToken)
            {
                var coupledTypesBuilder = ImmutableHashSet.CreateBuilder <INamedTypeSymbol>();
                ImmutableArray <SyntaxReference> declarations = namedType.DeclaringSyntaxReferences;

                (int cyclomaticComplexity, ComputationalComplexityMetrics computationalComplexityMetrics) =
                    await MetricsHelper.ComputeCoupledTypesAndComplexityExcludingMemberDeclsAsync(declarations, namedType, coupledTypesBuilder, semanticModelProvider, cancellationToken).ConfigureAwait(false);

                // Compat: Filter out nested types as they are children of most closest containing namespace.
                var members = namedType.GetMembers().Where(m => m.Kind != SymbolKind.NamedType);

#if LEGACY_CODE_METRICS_MODE
                // Legacy mode skips metrics for field/property/event symbols, and explicitly includes accessors as methods.
                members = members.Where(m => m.Kind != SymbolKind.Field && m.Kind != SymbolKind.Property && m.Kind != SymbolKind.Event);
#else
                // Filter out accessors as they are children of their associated symbols, for which we generate a separate node.
                members = members.Where(m => m.Kind != SymbolKind.Method || ((IMethodSymbol)m).AssociatedSymbol == null);
#endif

                ImmutableArray <CodeAnalysisMetricData> children = await ComputeAsync(members, semanticModelProvider, cancellationToken).ConfigureAwait(false);

                // Heuristic to prevent simple fields (no initializer or simple initializer) from skewing the complexity.
                ImmutableHashSet <IFieldSymbol> filteredFieldsForComplexity = getFilteredFieldsForComplexity();

                int effectiveChildrenCountForComplexity      = 0;
                int singleEffectiveChildMaintainabilityIndex = -1;
                foreach (CodeAnalysisMetricData child in children)
                {
                    MetricsHelper.AddCoupledNamedTypes(coupledTypesBuilder, child.CoupledNamedTypes);

                    if (child.Symbol.Kind != SymbolKind.Field ||
                        filteredFieldsForComplexity.Contains((IFieldSymbol)child.Symbol))
                    {
                        singleEffectiveChildMaintainabilityIndex = effectiveChildrenCountForComplexity == 0 && computationalComplexityMetrics.IsDefault ?
                                                                   child.MaintainabilityIndex :
                                                                   -1;
                        effectiveChildrenCountForComplexity++;
                        cyclomaticComplexity          += child.CyclomaticComplexity;
                        computationalComplexityMetrics = computationalComplexityMetrics.Union(child.ComputationalComplexityMetrics);
                    }
                }

                if (cyclomaticComplexity == 0 && !namedType.IsStatic)
                {
                    // Empty named type, account for implicit constructor.
                    cyclomaticComplexity = 1;
                }

                int  depthOfInheritance = CalculateDepthOfInheritance(namedType);
                long linesOfCode        = await MetricsHelper.GetLinesOfCodeAsync(declarations, namedType, semanticModelProvider, cancellationToken).ConfigureAwait(false);

                int maintainabilityIndex = singleEffectiveChildMaintainabilityIndex != -1 ?
                                           singleEffectiveChildMaintainabilityIndex :
                                           CalculateMaintainabilityIndex(computationalComplexityMetrics, cyclomaticComplexity, effectiveChildrenCountForComplexity);
                MetricsHelper.RemoveContainingTypes(namedType, coupledTypesBuilder);

                return(new NamedTypeMetricData(namedType, maintainabilityIndex, computationalComplexityMetrics,
                                               coupledTypesBuilder.ToImmutable(), linesOfCode, cyclomaticComplexity, depthOfInheritance, children));

                ImmutableHashSet <IFieldSymbol> getFilteredFieldsForComplexity()
                {
                    ImmutableHashSet <IFieldSymbol> .Builder?builderOpt = null;
                    var orderedFieldDatas = children.Where(c => c.Symbol.Kind == SymbolKind.Field).OrderBy(c => c.MaintainabilityIndex);
                    var indexThreshold    = 99;

                    foreach (CodeAnalysisMetricData fieldData in orderedFieldDatas)
                    {
                        if (fieldData.MaintainabilityIndex > indexThreshold)
                        {
                            break;
                        }

                        builderOpt ??= ImmutableHashSet.CreateBuilder <IFieldSymbol>();
                        builderOpt.Add((IFieldSymbol)fieldData.Symbol);
                        indexThreshold -= 4;
                    }

                    return(builderOpt?.ToImmutable() ?? ImmutableHashSet <IFieldSymbol> .Empty);
                }
            }
示例#27
0
 private ImmutableHashSet <ProjectReference> GetProjectReferences()
 => _projectReferences.ToImmutable();
示例#28
0
 protected override IImmutableSet <T> Complete(ImmutableHashSet <T> .Builder intermediateCollection)
 {
     return(intermediateCollection.ToImmutable());
 }
 protected override void Finalize(ImmutableHashSet <TItem> .Builder builder, ref ImmutableHashSet <TItem> collection)
 => collection = builder.ToImmutable();
        public static ComputationalComplexityMetrics Compute(IOperation operationBlock)
        {
            Debug.Assert(operationBlock != null);

            long effectiveLinesOfCode = 0;
            long operatorUsageCounts  = 0;
            long symbolUsageCounts    = 0;
            long constantUsageCounts  = 0;

            ImmutableHashSet <OperationKind> .Builder      distinctOperatorKindsBuilder       = null;
            ImmutableHashSet <BinaryOperatorKind> .Builder distinctBinaryOperatorKindsBuilder = null;
            ImmutableHashSet <UnaryOperatorKind> .Builder  distinctUnaryOperatorKindsBuilder  = null;
            ImmutableHashSet <CaseKind> .Builder           distinctCaseKindsBuilder           = null;
            ImmutableHashSet <ISymbol> .Builder            distinctReferencedSymbolsBuilder   = null;
            ImmutableHashSet <object> .Builder             distinctReferencedConstantsBuilder = null;
            foreach (var operation in operationBlock.Descendants())
            {
                effectiveLinesOfCode += getEffectiveLinesOfCode(operation);

                if (operation.IsImplicit)
                {
                    continue;
                }

#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.ConstantValue.HasValue)
                {
                    constantUsageCounts++;
                    distinctReferencedConstantsBuilder = distinctReferencedConstantsBuilder ?? ImmutableHashSet.CreateBuilder <object>();
                    distinctReferencedConstantsBuilder.Add(operation.ConstantValue.Value ?? s_nullConstantPlaceholder);
                    continue;
                }

                switch (operation.Kind)
                {
                // Symbol references.
                case OperationKind.LocalReference:
                    countOperand(((ILocalReferenceOperation)operation).Local);
                    continue;

                case OperationKind.ParameterReference:
                    countOperand(((IParameterReferenceOperation)operation).Parameter);
                    continue;

                case OperationKind.FieldReference:
                case OperationKind.MethodReference:
                case OperationKind.PropertyReference:
                case OperationKind.EventReference:
                    countOperator(operation);
                    countOperand(((IMemberReferenceOperation)operation).Member);
                    continue;

                // Symbol initializers.
                case OperationKind.FieldInitializer:
                    foreach (var field in ((IFieldInitializerOperation)operation).InitializedFields)
                    {
                        countOperator(operation);
                        countOperand(field);
                    }
                    continue;

                case OperationKind.PropertyInitializer:
                    foreach (var property in ((IPropertyInitializerOperation)operation).InitializedProperties)
                    {
                        countOperator(operation);
                        countOperand(property);
                    }
                    continue;

                case OperationKind.ParameterInitializer:
                    countOperator(operation);
                    countOperand(((IParameterInitializerOperation)operation).Parameter);
                    continue;

                case OperationKind.VariableInitializer:
                    countOperator(operation);
                    // We count the operand in the variable declarator.
                    continue;

                case OperationKind.VariableDeclarator:
                    var variableDeclarator = (IVariableDeclaratorOperation)operation;
                    if (variableDeclarator.GetVariableInitializer() != null)
                    {
                        countOperand(variableDeclarator.Symbol);
                    }
                    continue;

                // Invocations and Object creations.
                case OperationKind.Invocation:
                    countOperator(operation);
                    var invocation = (IInvocationOperation)operation;
                    if (!invocation.TargetMethod.ReturnsVoid)
                    {
                        countOperand(invocation.TargetMethod);
                    }
                    continue;

                case OperationKind.ObjectCreation:
                    countOperator(operation);
                    countOperand(((IObjectCreationOperation)operation).Constructor);
                    continue;

                case OperationKind.DelegateCreation:
                case OperationKind.AnonymousObjectCreation:
                case OperationKind.TypeParameterObjectCreation:
                case OperationKind.DynamicObjectCreation:
                case OperationKind.DynamicInvocation:
                    countOperator(operation);
                    continue;

                // Operators with special operator kinds.
                case OperationKind.BinaryOperator:
                    countBinaryOperator(operation, ((IBinaryOperation)operation).OperatorKind);
                    continue;

                case OperationKind.CompoundAssignment:
                    countBinaryOperator(operation, ((ICompoundAssignmentOperation)operation).OperatorKind);
                    continue;

                // https://github.com/dotnet/roslyn-analyzers/issues/1742
                //case OperationKind.TupleBinaryOperator:
                //    countBinaryOperator(operation, ((ITupleBinaryOperation)operation).OperatorKind);
                //    continue;
                case OperationKind.UnaryOperator:
                    countUnaryOperator(operation, ((IUnaryOperation)operation).OperatorKind);
                    continue;

                case OperationKind.CaseClause:
                    var caseClauseOperation = (ICaseClauseOperation)operation;
                    distinctCaseKindsBuilder = distinctCaseKindsBuilder ?? ImmutableHashSet.CreateBuilder <CaseKind>();
                    distinctCaseKindsBuilder.Add(caseClauseOperation.CaseKind);
                    if (caseClauseOperation.CaseKind == CaseKind.Relational)
                    {
                        countBinaryOperator(operation, ((IRelationalCaseClauseOperation)operation).Relation);
                    }
                    else
                    {
                        countOperator(operation);
                    }
                    continue;

                // Other common operators.
                case OperationKind.Increment:
                case OperationKind.Decrement:
                case OperationKind.SimpleAssignment:
                case OperationKind.DeconstructionAssignment:
                case OperationKind.EventAssignment:
                case OperationKind.Coalesce:
                case OperationKind.ConditionalAccess:
                case OperationKind.Conversion:
                case OperationKind.ArrayElementReference:
                case OperationKind.Await:
                case OperationKind.NameOf:
                case OperationKind.SizeOf:
                case OperationKind.TypeOf:
                case OperationKind.AddressOf:
                case OperationKind.MemberInitializer:
                case OperationKind.IsType:
                case OperationKind.IsPattern:
                case OperationKind.Parenthesized:
                    countOperator(operation);
                    continue;

                // Following are considered operators for now, but we may want to revisit.
                case OperationKind.ArrayCreation:
                case OperationKind.ArrayInitializer:
                case OperationKind.DynamicMemberReference:
                case OperationKind.DynamicIndexerAccess:
                case OperationKind.Tuple:
                case OperationKind.Lock:
                case OperationKind.Using:
                case OperationKind.Throw:
                case OperationKind.RaiseEvent:
                case OperationKind.InterpolatedString:
                    countOperator(operation);
                    continue;

                // Return value.
                case OperationKind.Return:
                case OperationKind.YieldBreak:
                case OperationKind.YieldReturn:
                    if (((IReturnOperation)operation).ReturnedValue != null)
                    {
                        countOperator(operation);
                    }
                    continue;
                }
            }

            return(Create(
                       effectiveLinesOfCode,
                       operatorUsageCounts,
                       symbolUsageCounts,
                       constantUsageCounts,
                       distinctOperatorKindsBuilder != null ? distinctOperatorKindsBuilder.ToImmutable() : ImmutableHashSet <OperationKind> .Empty,
                       distinctBinaryOperatorKindsBuilder != null ? distinctBinaryOperatorKindsBuilder.ToImmutable() : ImmutableHashSet <BinaryOperatorKind> .Empty,
                       distinctUnaryOperatorKindsBuilder != null ? distinctUnaryOperatorKindsBuilder.ToImmutable() : ImmutableHashSet <UnaryOperatorKind> .Empty,
                       distinctCaseKindsBuilder != null ? distinctCaseKindsBuilder.ToImmutable() : ImmutableHashSet <CaseKind> .Empty,
                       distinctReferencedSymbolsBuilder != null ? distinctReferencedSymbolsBuilder.ToImmutable() : ImmutableHashSet <ISymbol> .Empty,
                       distinctReferencedConstantsBuilder != null ? distinctReferencedConstantsBuilder.ToImmutable() : ImmutableHashSet <object> .Empty));

            int getEffectiveLinesOfCode(IOperation operation)
            {
                if (operation.Parent != null)
                {
                    switch (operation.Parent.Kind)
                    {
                    case OperationKind.Block:
                        return(hasAnyExplicitExpression(operation) ? 1 : 0);

                    case OperationKind.FieldInitializer:
                    case OperationKind.PropertyInitializer:
                    case OperationKind.ParameterInitializer:
                        // Count declaration and initialization.
                        return(hasAnyExplicitExpression(operation) ? 2 : 0);
                    }
                }

                return(0);
            }

            bool hasAnyExplicitExpression(IOperation operation)
            {
                // Check if all descendants are either implicit or are explicit with no constant value or type, indicating it is not user written code.
                return(!operation.DescendantsAndSelf().All(o => o.IsImplicit || (!o.ConstantValue.HasValue && o.Type == null)));
            }

            void countOperator(IOperation operation)
            {
                operatorUsageCounts++;
                distinctOperatorKindsBuilder = distinctOperatorKindsBuilder ?? ImmutableHashSet.CreateBuilder <OperationKind>();
                distinctOperatorKindsBuilder.Add(operation.Kind);
            }

            void countOperand(ISymbol symbol)
            {
                symbolUsageCounts++;
                distinctReferencedSymbolsBuilder = distinctReferencedSymbolsBuilder ?? ImmutableHashSet.CreateBuilder <ISymbol>();
                distinctReferencedSymbolsBuilder.Add(symbol);
            }

            void countBinaryOperator(IOperation operation, BinaryOperatorKind operatorKind)
            {
                countOperator(operation);
                distinctBinaryOperatorKindsBuilder = distinctBinaryOperatorKindsBuilder ?? ImmutableHashSet.CreateBuilder <BinaryOperatorKind>();
                distinctBinaryOperatorKindsBuilder.Add(operatorKind);
            }

            void countUnaryOperator(IOperation operation, UnaryOperatorKind operatorKind)
            {
                countOperator(operation);
                distinctUnaryOperatorKindsBuilder = distinctUnaryOperatorKindsBuilder ?? ImmutableHashSet.CreateBuilder <UnaryOperatorKind>();
                distinctUnaryOperatorKindsBuilder.Add(operatorKind);
            }
        }