示例#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_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));

            NullableFlowAnalysisWarnings = builder.ToImmutable();

            string getId(ErrorCode errorCode)
            {
                return(MessageProvider.Instance.GetIdForErrorCode((int)errorCode));
            }
        }
示例#2
0
            public State(INamedTypeSymbol bindingFlagsConstants, INamedTypeSymbol bindingFlags, ImmutableArray <SourceSpan> bindingFlagsConstantsRoots)
            {
                BindingFlagsConstants      = bindingFlagsConstants;
                BindingFlags               = bindingFlags;
                BindingFlagsConstantsRoots = bindingFlagsConstantsRoots;

                {
                    var bfcns = ImmutableHashSet.CreateBuilder <string>();
                    foreach (var member in bindingFlagsConstants.GetMembers())
                    {
                        bfcns.Add(member.Name);
                    }
                    BindingFlagsConstantsNames = bfcns.ToImmutable();
                }

                {
                    var bfns = ImmutableHashSet.CreateBuilder <string>();
                    foreach (var member in bindingFlags.GetMembers())
                    {
                        bfns.Add(member.Name);
                    }
                    BindingFlagsNames = bfns.ToImmutable();
                }
            }
        private static BlockSyntax RewriteBody(
            IImmutableDictionary <ISymbol, PrivateField> privateFields,
            BlockSyntax body,
            IImmutableDictionary <SyntaxNode, ISymbol> references,
            out ISet <SyntaxNode> rewrittenNodes)
        {
            var symbolsToRewrite = references.Values.ToImmutableHashSet();

            var localDeclaration = SyntaxFactory.LocalDeclarationStatement(
                SyntaxFactory.VariableDeclaration(
                    SyntaxFactory.PredefinedType(
                        SyntaxFactory.Token(SyntaxKind.IntKeyword)).WithTrailingTrivia(SyntaxFactory.Space),
                    SyntaxFactory.SeparatedList(symbolsToRewrite.Select(
                                                    s => SyntaxFactory.VariableDeclarator(privateFields[s].UniqueName)))));

            var rewrittenNodesBuilder = ImmutableHashSet.CreateBuilder <SyntaxNode>();
            var newBody = body.ReplaceSyntax(
                references.Keys,
                (original, partiallyRewritten) =>
            {
                rewrittenNodesBuilder.Add(original);
                return(SyntaxFactory.IdentifierName(privateFields[references[original]].UniqueName));
            },
                null,
                null,
                null,
                null);

            var newStatements = newBody.Statements.Insert(0, localDeclaration);

            newBody = newBody.WithStatements(newStatements);

            rewrittenNodes = rewrittenNodesBuilder.ToImmutable();

            return(newBody);
        }
        public void ToImmutableHashSet()
        {
            ImmutableHashSet <int> .Builder builder = ImmutableHashSet.CreateBuilder <int>();
            builder.Add(1);
            builder.Add(2);
            builder.Add(3);

            var set = builder.ToImmutableSortedSet();

            Assert.True(builder.Contains(1));
            Assert.True(builder.Contains(2));
            Assert.True(builder.Contains(3));

            builder.Remove(3);
            Assert.False(builder.Contains(3));
            Assert.True(set.Contains(3));

            builder.Clear();
            Assert.True(builder.ToImmutableHashSet().IsEmpty);
            Assert.False(set.IsEmpty);

            ImmutableHashSet <int> .Builder nullBuilder = null;
            AssertExtensions.Throws <ArgumentNullException>("builder", () => nullBuilder.ToImmutableHashSet());
        }
示例#5
0
            static GlobalFlowStateAnalysisValueSet GetNegateValueFromParents(ImmutableHashSet <GlobalFlowStateAnalysisValueSet> parents)
            {
                Debug.Assert(parents.Count > 0);
                var analysisValuesBuilder = ImmutableHashSet.CreateBuilder <IAbstractAnalysisValue>();
                var parentsBuilder        = ImmutableHashSet.CreateBuilder <GlobalFlowStateAnalysisValueSet>();

                var height = 0;

                foreach (var parent in parents)
                {
                    if (parent.AnalysisValues.Count == 1 && parent.Height == 0)
                    {
                        analysisValuesBuilder.Add(parent.AnalysisValues.Single().GetNegatedValue());
                    }
                    else
                    {
                        var negatedParent = parent.GetNegatedValue();
                        parentsBuilder.Add(negatedParent);
                        height = Math.Max(height, negatedParent.Height + 1);
                    }
                }

                return(new GlobalFlowStateAnalysisValueSet(analysisValuesBuilder.ToImmutable(), parentsBuilder.ToImmutable(), height, GlobalFlowStateAnalysisValueSetKind.Known));
            }
示例#6
0
        private ImmutableHashSet <string> GetWhitelist(
            ImmutableArray <AdditionalText> additionalFiles
            )
        {
            ImmutableHashSet <string> .Builder whitelistedClasses = ImmutableHashSet.CreateBuilder <string>();

            AdditionalText whitelistFile = additionalFiles.FirstOrDefault(
                file => Path.GetFileName(file.Path) == WhitelistFileName
                );

            if (whitelistFile == null)
            {
                return(whitelistedClasses.ToImmutableHashSet());
            }

            SourceText whitelistText = whitelistFile.GetText();

            foreach (TextLine line in whitelistText.Lines)
            {
                whitelistedClasses.Add(line.ToString().Trim());
            }

            return(whitelistedClasses.ToImmutableHashSet());
        }
        private static async Task<(ImmutableHashSet<string> remoteRootPaths, ImmutableHashSet<string> externalPaths)> GetLocalPathsOfRemoteRootsAsync(CollaborationSession session)
        {
            var roots = await session.ListRootsAsync(CancellationToken.None).ConfigureAwait(false);
            var localPathsOfRemoteRoots = roots.Select(root => session.ConvertSharedUriToLocalPath(root)).ToImmutableArray();

            var remoteRootPaths = ImmutableHashSet.CreateBuilder<string>();
            var externalPaths = ImmutableHashSet.CreateBuilder<string>();

            foreach (var localRoot in localPathsOfRemoteRoots)
            {
                // The local root is something like tmp\\xxx\\<workspace name>
                // The external root should be tmp\\xxx\\~external, so replace the workspace name with ~external.
#pragma warning disable CS8602 // Dereference of a possibly null reference. (Can localRoot be null here?)
                var splitRoot = localRoot.TrimEnd('\\').Split('\\');
#pragma warning restore CS8602 // Dereference of a possibly null reference.
                splitRoot[splitRoot.Length - 1] = "~external";
                var externalPath = string.Join("\\", splitRoot) + "\\";

                remoteRootPaths.Add(localRoot);
                externalPaths.Add(externalPath);
            }

            return (remoteRootPaths.ToImmutable(), externalPaths.ToImmutable());
        }
示例#8
0
        private static bool TryAddMatches(
            ImmutableHashSet <string> values,
            int minRequiredLength,
            int maxRequiredLength,
            ref ImmutableHashSet <string> .Builder matches)
        {
            var success = false;

            foreach (string value2 in values)
            {
                if (value2.Length < minRequiredLength ||
                    value2.Length > maxRequiredLength)
                {
                    continue;
                }

                if ((matches ??= ImmutableHashSet.CreateBuilder(WordList.DefaultComparer)).Add(value2))
                {
                    success = true;
                }
            }

            return(success);
        }
示例#9
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.Add(GetId(ErrorCode.WRN_ParameterNotNullIfNotNull));
            nullableWarnings.Add(GetId(ErrorCode.WRN_ReturnNotNullIfNotNull));

            NullableWarnings = nullableWarnings.ToImmutable();
        }
示例#10
0
        /// <summary>
        /// Triggered when the file picker button is clicked
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private async void UIButtonFilePick_Click(object sender, RoutedEventArgs e)
        {
            // Pick image file
            var imageFiles = await GetFilesPickedAsync();

            if (imageFiles == null || imageFiles.Count == 0)
            {
                return;
            }
            await UIParameterDialog.ShowAsync();

            UIResultPanel.Items.Clear();
            m_imageToProcessTotal   = imageFiles.Count;
            UIProgressMaxValue.Text = m_imageToProcessTotal.ToString();
            m_hashTags = ImmutableHashSet.CreateBuilder(new TagEqualityComparer());

            // Disable UI
            UIOptionPanel.IsEnabled       = false;
            UIButtonFilePick.IsEnabled    = false;
            UIHashTagBrowser.IsEnabled    = false;
            UIClearFilterButton.IsEnabled = false;
            NotifyUser("", NotifyType.ClearMessage);

            // Start our stopwatch to measure the time it takes to process all of this
            m_perfWatch.Restart();
            m_e2eRunTime                       = (float)m_perfWatch.ElapsedTicks / Stopwatch.Frequency * 1000f;
            m_imageProcessedCount              = 0;
            UIFilterPanel.Visibility           = Visibility.Collapsed;
            UIProgressPanel.Visibility         = Visibility.Visible;
            UIExecutionProgressRing.Visibility = Visibility.Visible;
            UIExecutionProgressRing.IsActive   = true;

            // Process each image selected
            foreach (var file in imageFiles)
            {
                // Take a lock for using a binding if one is available, or wait if not
                await m_bindingLock.WaitAsync();

                // Display a staging content in our UI
                ResultItemUserControl resultItem = new ResultItemUserControl();
                UIResultPanel.Items.Add(resultItem);

                // Start a task that will Load the frame, display it in the UI, binf it and schedule
                // execution of the skill against that binding
                // (fire and forget)
                var bindingTask = Task.Run(async() =>
                {
                    ConceptTaggerBinding binding = null;

                    // Execute concept tag skill
                    try
                    {
                        // Load the VideoFrame from the image file
                        var frame = await LoadVideoFrameFromFileAsync(file);
                        if (frame == null)
                        {
                            throw new Exception($"Error reading image file: {file.Path}");
                        }


                        if (!m_bindingQueue.TryDequeue(out binding))
                        {
                            throw new Exception("Could not access binding");
                        }

                        var baseTime = (float)m_perfWatch.ElapsedTicks / Stopwatch.Frequency * 1000f;

                        // Bind input image
                        await binding.SetInputImageAsync(frame);

                        // Record bind time for display
                        resultItem.BindTime = (float)m_perfWatch.ElapsedTicks / Stopwatch.Frequency * 1000f - baseTime;

                        // Display image and results
                        await Dispatcher.RunAsync(
                            CoreDispatcherPriority.Normal,
                            async() =>
                        {
                            await resultItem.UpdateResultItemImageAsync(frame.SoftwareBitmap);
                        });

                        // Evaluate binding (fire and forget)
                        var evalTask = Task.Run(() => EvaluateBinding(binding, resultItem));
                    }
                    catch (Exception ex)
                    {
                        NotifyUser(ex.Message, NotifyType.ErrorMessage);
                        if (binding != null)
                        {
                            m_bindingQueue.Enqueue(binding);
                        }
                        m_bindingLock.Release();
                        m_imageToProcessTotal--;
                        await UIProgressMaxValue.Dispatcher.RunAsync(CoreDispatcherPriority.Normal,
                                                                     () => UIProgressMaxValue.Text = m_imageToProcessTotal.ToString());
                    }
                });
            }

            // Enable UI
            UIOptionPanel.IsEnabled            = true;
            UIButtonFilePick.IsEnabled         = true;
            UIHashTagBrowser.IsEnabled         = true;
            UIClearFilterButton.IsEnabled      = true;
            UIFilterPanel.Visibility           = Visibility.Visible;
            UIExecutionProgressRing.Visibility = Visibility.Collapsed;
            UIExecutionProgressRing.IsActive   = false;
        }
示例#11
0
        private ImmutableHashSet <INamedTypeSymbol> GetUsedNamedTypes(INamedTypeSymbol namedType, Compilation compilation, CancellationToken cancellationToken, ref bool hasAccessToTypeFromWorkspaceAssemblies)
        {
            var builder = ImmutableHashSet.CreateBuilder <INamedTypeSymbol>();

            foreach (var decl in namedType.DeclaringSyntaxReferences)
            {
                var syntax = decl.GetSyntax(cancellationToken);

                // GetSyntax for VB returns the StatementSyntax instead of BlockSyntax node.
                syntax = syntax.FirstAncestorOrSelf <SyntaxNode>(node => IsNamedTypeDeclarationBlock(node), ascendOutOfTrivia: false) ?? syntax;

                var semanticModel  = compilation.GetSemanticModel(syntax.SyntaxTree);
                var nodesToProcess = new Queue <(SyntaxNode node, bool inExecutableCode)>();
                nodesToProcess.Enqueue((node: syntax, inExecutableCode: false));

                do
                {
                    (SyntaxNode node, bool inExecutableCode)nodeToProcess = nodesToProcess.Dequeue();
                    var node             = nodeToProcess.node;
                    var inExecutableCode = nodeToProcess.inExecutableCode;
                    if (!inExecutableCode && !ReferenceEquals(node, syntax) && IsNamedTypeDeclarationBlock(node))
                    {
                        // Skip type member declarations.
                        continue;
                    }

                    if (node is TTypeSyntax typeSyntax)
                    {
                        var typeInfo = semanticModel.GetTypeInfo(typeSyntax, cancellationToken);
                        AddUsedNamedTypeCore(typeInfo.Type, builder, ref hasAccessToTypeFromWorkspaceAssemblies);
                    }

                    if (!inExecutableCode)
                    {
                        var operationBlock = semanticModel.GetOperation(node, cancellationToken);
                        if (operationBlock != null)
                        {
                            // Add used types within executable code in the operation tree.
                            inExecutableCode = true;
                            foreach (var operation in operationBlock.DescendantsAndSelf())
                            {
                                AddUsedNamedTypeCore(operation.Type, builder, ref hasAccessToTypeFromWorkspaceAssemblies);

                                // 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)
                                {
                                    AddUsedNamedTypeCore(memberReference.Member.ContainingType, builder, ref hasAccessToTypeFromWorkspaceAssemblies);
                                }
                                else if (operation is IInvocationOperation invocation &&
                                         (invocation.TargetMethod.IsStatic || invocation.TargetMethod.IsExtensionMethod))
                                {
                                    AddUsedNamedTypeCore(invocation.TargetMethod.ContainingType, builder, ref hasAccessToTypeFromWorkspaceAssemblies);
                                }
                            }
                        }
                    }

                    foreach (var child in node.ChildNodes())
                    {
                        nodesToProcess.Enqueue((child, inExecutableCode));
                    }
                } while (nodesToProcess.Count != 0);
 void countUnaryOperator(IOperation operation, UnaryOperatorKind operatorKind)
 {
     countOperator(operation);
     distinctUnaryOperatorKindsBuilder ??= ImmutableHashSet.CreateBuilder <UnaryOperatorKind>();
     distinctUnaryOperatorKindsBuilder.Add(operatorKind);
 }
 void countOperator(IOperation operation)
 {
     operatorUsageCounts++;
     distinctOperatorKindsBuilder ??= ImmutableHashSet.CreateBuilder <OperationKind>();
     distinctOperatorKindsBuilder.Add(operation.Kind);
 }
            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);
                }
            }
        protected override void InitializeWorker(CompilationStartAnalysisContext context)
        {
            #region "Get All the WellKnown Types and Members"
            var iformatProviderType = context.Compilation.GetOrCreateTypeByMetadataName(WellKnownTypeNames.SystemIFormatProvider);
            var cultureInfoType     = context.Compilation.GetOrCreateTypeByMetadataName(WellKnownTypeNames.SystemGlobalizationCultureInfo);
            if (iformatProviderType == null || cultureInfoType == null)
            {
                return;
            }

            var objectType = context.Compilation.GetSpecialType(SpecialType.System_Object);
            var stringType = context.Compilation.GetSpecialType(SpecialType.System_String);
            if (objectType == null || stringType == null)
            {
                return;
            }

            var charType = context.Compilation.GetSpecialType(SpecialType.System_Char);
            var boolType = context.Compilation.GetSpecialType(SpecialType.System_Boolean);
            var guidType = context.Compilation.GetOrCreateTypeByMetadataName(WellKnownTypeNames.SystemGuid);

            var builder = ImmutableHashSet.CreateBuilder <INamedTypeSymbol>();
            builder.AddIfNotNull(charType);
            builder.AddIfNotNull(boolType);
            builder.AddIfNotNull(stringType);
            builder.AddIfNotNull(guidType);
            var invariantToStringTypes = builder.ToImmutableHashSet();

            var dateTimeType       = context.Compilation.GetOrCreateTypeByMetadataName(WellKnownTypeNames.SystemDateTime);
            var dateTimeOffsetType = context.Compilation.GetOrCreateTypeByMetadataName(WellKnownTypeNames.SystemDateTimeOffset);
            var timeSpanType       = context.Compilation.GetOrCreateTypeByMetadataName(WellKnownTypeNames.SystemTimeSpan);

            var stringFormatMembers = stringType.GetMembers("Format").OfType <IMethodSymbol>();

            var stringFormatMemberWithStringAndObjectParameter = stringFormatMembers.GetFirstOrDefaultMemberWithParameterInfos(
                GetParameterInfo(stringType),
                GetParameterInfo(objectType));
            var stringFormatMemberWithStringObjectAndObjectParameter = stringFormatMembers.GetFirstOrDefaultMemberWithParameterInfos(
                GetParameterInfo(stringType),
                GetParameterInfo(objectType),
                GetParameterInfo(objectType));
            var stringFormatMemberWithStringObjectObjectAndObjectParameter = stringFormatMembers.GetFirstOrDefaultMemberWithParameterInfos(
                GetParameterInfo(stringType),
                GetParameterInfo(objectType),
                GetParameterInfo(objectType),
                GetParameterInfo(objectType));
            var stringFormatMemberWithStringAndParamsObjectParameter = stringFormatMembers.GetFirstOrDefaultMemberWithParameterInfos(
                GetParameterInfo(stringType),
                GetParameterInfo(objectType, isArray: true, arrayRank: 1, isParams: true));
            var stringFormatMemberWithIFormatProviderStringAndParamsObjectParameter = stringFormatMembers.GetFirstOrDefaultMemberWithParameterInfos(
                GetParameterInfo(iformatProviderType),
                GetParameterInfo(stringType),
                GetParameterInfo(objectType, isArray: true, arrayRank: 1, isParams: true));

            var currentCultureProperty     = cultureInfoType.GetMembers("CurrentCulture").OfType <IPropertySymbol>().FirstOrDefault();
            var invariantCultureProperty   = cultureInfoType.GetMembers("InvariantCulture").OfType <IPropertySymbol>().FirstOrDefault();
            var currentUICultureProperty   = cultureInfoType.GetMembers("CurrentUICulture").OfType <IPropertySymbol>().FirstOrDefault();
            var installedUICultureProperty = cultureInfoType.GetMembers("InstalledUICulture").OfType <IPropertySymbol>().FirstOrDefault();

            var threadType = context.Compilation.GetOrCreateTypeByMetadataName(WellKnownTypeNames.SystemThreadingThread);
            var currentThreadCurrentUICultureProperty = threadType?.GetMembers("CurrentUICulture").OfType <IPropertySymbol>().FirstOrDefault();

            var activatorType       = context.Compilation.GetOrCreateTypeByMetadataName(WellKnownTypeNames.SystemActivator);
            var resourceManagerType = context.Compilation.GetOrCreateTypeByMetadataName(WellKnownTypeNames.SystemResourcesResourceManager);

            var computerInfoType = context.Compilation.GetOrCreateTypeByMetadataName(WellKnownTypeNames.MicrosoftVisualBasicDevicesComputerInfo);
            var installedUICulturePropertyOfComputerInfoType = computerInfoType?.GetMembers("InstalledUICulture").OfType <IPropertySymbol>().FirstOrDefault();

            var obsoleteAttributeType = context.Compilation.GetOrCreateTypeByMetadataName(WellKnownTypeNames.SystemObsoleteAttribute);
            #endregion

            context.RegisterOperationAction(oaContext =>
            {
                var invocationExpression = (IInvocationOperation)oaContext.Operation;
                var targetMethod         = invocationExpression.TargetMethod;

                #region "Exceptions"
                if (targetMethod.IsGenericMethod ||
                    targetMethod.ContainingType.IsErrorType() ||
                    (activatorType != null && activatorType.Equals(targetMethod.ContainingType)) ||
                    (resourceManagerType != null && resourceManagerType.Equals(targetMethod.ContainingType)) ||
                    IsValidToStringCall(invocationExpression, invariantToStringTypes, dateTimeType, dateTimeOffsetType, timeSpanType))
                {
                    return;
                }
                #endregion

                #region "IFormatProviderAlternateStringRule Only"
                if (stringFormatMemberWithIFormatProviderStringAndParamsObjectParameter != null &&
                    (targetMethod.Equals(stringFormatMemberWithStringAndObjectParameter) ||
                     targetMethod.Equals(stringFormatMemberWithStringObjectAndObjectParameter) ||
                     targetMethod.Equals(stringFormatMemberWithStringObjectObjectAndObjectParameter) ||
                     targetMethod.Equals(stringFormatMemberWithStringAndParamsObjectParameter)))
                {
                    // Sample message for IFormatProviderAlternateStringRule: Because the behavior of string.Format(string, object) could vary based on the current user's locale settings,
                    // replace this call in IFormatProviderStringTest.M() with a call to string.Format(IFormatProvider, string, params object[]).
                    oaContext.ReportDiagnostic(
                        invocationExpression.Syntax.CreateDiagnostic(
                            IFormatProviderAlternateStringRule,
                            targetMethod.ToDisplayString(SymbolDisplayFormats.ShortSymbolDisplayFormat),
                            oaContext.ContainingSymbol.ToDisplayString(SymbolDisplayFormats.ShortSymbolDisplayFormat),
                            stringFormatMemberWithIFormatProviderStringAndParamsObjectParameter.ToDisplayString(SymbolDisplayFormats.ShortSymbolDisplayFormat)));

                    return;
                }
                #endregion

                #region "IFormatProviderAlternateStringRule & IFormatProviderAlternateRule"

                IEnumerable <IMethodSymbol> methodsWithSameNameAsTargetMethod = targetMethod.ContainingType.GetMembers(targetMethod.Name).OfType <IMethodSymbol>().WhereMethodDoesNotContainAttribute(obsoleteAttributeType).ToList();
                if (methodsWithSameNameAsTargetMethod.HasMoreThan(1))
                {
                    var correctOverloads = methodsWithSameNameAsTargetMethod.GetMethodOverloadsWithDesiredParameterAtLeadingOrTrailing(targetMethod, iformatProviderType).ToList();

                    // If there are two matching overloads, one with CultureInfo as the first parameter and one with CultureInfo as the last parameter,
                    // report the diagnostic on the overload with CultureInfo as the last parameter, to match the behavior of FxCop.
                    var correctOverload = correctOverloads.FirstOrDefault(overload => overload.Parameters.Last().Type.Equals(iformatProviderType)) ?? correctOverloads.FirstOrDefault();

                    // Sample message for IFormatProviderAlternateRule: Because the behavior of Convert.ToInt64(string) could vary based on the current user's locale settings,
                    // replace this call in IFormatProviderStringTest.TestMethod() with a call to Convert.ToInt64(string, IFormatProvider).
                    if (correctOverload != null)
                    {
                        oaContext.ReportDiagnostic(
                            invocationExpression.Syntax.CreateDiagnostic(
                                targetMethod.ReturnType.Equals(stringType) ?
                                IFormatProviderAlternateStringRule :
                                IFormatProviderAlternateRule,
                                targetMethod.ToDisplayString(SymbolDisplayFormats.ShortSymbolDisplayFormat),
                                oaContext.ContainingSymbol.ToDisplayString(SymbolDisplayFormats.ShortSymbolDisplayFormat),
                                correctOverload.ToDisplayString(SymbolDisplayFormats.ShortSymbolDisplayFormat)));
                    }
                }
                #endregion

                #region "UICultureStringRule & UICultureRule"
                IEnumerable <int> IformatProviderParameterIndices = GetIndexesOfParameterType(targetMethod, iformatProviderType);
                foreach (var index in IformatProviderParameterIndices)
                {
                    var argument = invocationExpression.Arguments[index];

                    if (argument != null && currentUICultureProperty != null &&
                        installedUICultureProperty != null && currentThreadCurrentUICultureProperty != null)
                    {
                        var semanticModel = argument.SemanticModel;

                        var symbol = semanticModel.GetSymbolInfo(argument.Value.Syntax, oaContext.CancellationToken).Symbol;

                        if (symbol != null &&
                            (symbol.Equals(currentUICultureProperty) ||
                             symbol.Equals(installedUICultureProperty) ||
                             symbol.Equals(currentThreadCurrentUICultureProperty) ||
                             (installedUICulturePropertyOfComputerInfoType != null && symbol.Equals(installedUICulturePropertyOfComputerInfoType))))
                        {
                            // Sample message
                            // 1. UICultureStringRule - 'TestClass.TestMethod()' passes 'Thread.CurrentUICulture' as the 'IFormatProvider' parameter to 'TestClass.CalleeMethod(string, IFormatProvider)'.
                            // This property returns a culture that is inappropriate for formatting methods.
                            // 2. UICultureRule -'TestClass.TestMethod()' passes 'CultureInfo.CurrentUICulture' as the 'IFormatProvider' parameter to 'TestClass.Callee(IFormatProvider, string)'.
                            // This property returns a culture that is inappropriate for formatting methods.

                            oaContext.ReportDiagnostic(
                                invocationExpression.Syntax.CreateDiagnostic(
                                    targetMethod.ReturnType.Equals(stringType) ?
                                    UICultureStringRule :
                                    UICultureRule,
                                    oaContext.ContainingSymbol.ToDisplayString(SymbolDisplayFormats.ShortSymbolDisplayFormat),
                                    symbol.ToDisplayString(SymbolDisplayFormats.ShortSymbolDisplayFormat),
                                    targetMethod.ToDisplayString(SymbolDisplayFormats.ShortSymbolDisplayFormat)));
                        }
                    }
                }
                #endregion
            }, OperationKind.Invocation);
        }
示例#16
0
        protected override ComposablePartDefinition?CreatePart(Type partType, bool typeExplicitlyRequested)
        {
            Requires.NotNull(partType, nameof(partType));

            var partTypeInfo = partType.GetTypeInfo();

            if (!typeExplicitlyRequested)
            {
                bool isPublic = partType.IsNested ? partTypeInfo.IsNestedPublic : partTypeInfo.IsPublic;
                if (!this.IsNonPublicSupported && !isPublic)
                {
                    // Skip non-public types.
                    return(null);
                }
            }

            var declaredProperties  = partTypeInfo.GetProperties(BindingFlags.Instance | this.PublicVsNonPublicFlags);
            var exportingProperties = from member in declaredProperties
                                      from export in member.GetAttributes <ExportAttribute>()
                                      where member.GetMethod != null // MEFv2 quietly omits exporting properties with no getter
                                      select new KeyValuePair <MemberInfo, ExportAttribute>(member, export);
            var exportedTypes = from export in partTypeInfo.GetAttributes <ExportAttribute>()
                                select new KeyValuePair <MemberInfo, ExportAttribute>(partTypeInfo, export);
            var exportsByMember = (from export in exportingProperties.Concat(exportedTypes)
                                   group export.Value by export.Key into exportsByType
                                   select exportsByType).Select(g => new KeyValuePair <MemberInfo, ExportAttribute[]>(g.Key, g.ToArray())).ToArray();

            if (exportsByMember.Length == 0)
            {
                return(null);
            }

            // Check for PartNotDiscoverable only after we've established it's an interesting part.
            // This optimizes for the fact that most types have no exports, in which case it's not a discoverable
            // part anyway. Checking for the PartNotDiscoverableAttribute first, which is rarely defined,
            // doesn't usually pay for itself in terms of short-circuiting. But it does add an extra
            // attribute to look for that we don't need to find for all the types that have no export attributes either.
            if (!typeExplicitlyRequested && partTypeInfo.IsAttributeDefined <PartNotDiscoverableAttribute>())
            {
                return(null);
            }

            foreach (var exportingMember in exportsByMember)
            {
                this.ThrowOnInvalidExportingMember(exportingMember.Key);
            }

            TypeRef partTypeRef = TypeRef.Get(partType, this.Resolver);
            Type?   partTypeAsGenericTypeDefinition = partTypeInfo.IsGenericType ? partType.GetGenericTypeDefinition() : null;

            string?sharingBoundary = null;
            var    sharedAttribute = partTypeInfo.GetFirstAttribute <SharedAttribute>();

            if (sharedAttribute != null)
            {
                sharingBoundary = sharedAttribute.SharingBoundary ?? string.Empty;
            }

            CreationPolicy partCreationPolicy = sharingBoundary != null ? CreationPolicy.Shared : CreationPolicy.NonShared;
            var            allExportsMetadata = ImmutableDictionary.CreateRange(PartCreationPolicyConstraint.GetExportMetadata(partCreationPolicy));

            var exportsOnType    = ImmutableList.CreateBuilder <ExportDefinition>();
            var exportsOnMembers = ImmutableDictionary.CreateBuilder <MemberRef, IReadOnlyCollection <ExportDefinition> >();
            var imports          = ImmutableList.CreateBuilder <ImportDefinitionBinding>();

            foreach (var export in exportsByMember)
            {
                var member = export.Key;
                var memberExportMetadata = allExportsMetadata.AddRange(this.GetExportMetadata(member));

                if (member is TypeInfo)
                {
                    foreach (var exportAttribute in export.Value)
                    {
                        Type             exportedType     = exportAttribute.ContractType ?? partTypeAsGenericTypeDefinition ?? partType;
                        ExportDefinition exportDefinition = CreateExportDefinition(memberExportMetadata, exportAttribute, exportedType);
                        exportsOnType.Add(exportDefinition);
                    }
                }
                else // property
                {
                    var property = (PropertyInfo)member;
                    Verify.Operation(!partTypeInfo.IsGenericTypeDefinition, Strings.ExportsOnMembersNotAllowedWhenDeclaringTypeGeneric);
                    var exportDefinitions = ImmutableList.CreateBuilder <ExportDefinition>();
                    foreach (var exportAttribute in export.Value)
                    {
                        Type             exportedType     = exportAttribute.ContractType ?? property.PropertyType;
                        ExportDefinition exportDefinition = CreateExportDefinition(memberExportMetadata, exportAttribute, exportedType);
                        exportDefinitions.Add(exportDefinition);
                    }

                    exportsOnMembers.Add(MemberRef.Get(member, this.Resolver), exportDefinitions.ToImmutable());
                }
            }

            foreach (var member in declaredProperties)
            {
                var importAttribute     = member.GetFirstAttribute <ImportAttribute>();
                var importManyAttribute = member.GetFirstAttribute <ImportManyAttribute>();
                Requires.Argument(!(importAttribute != null && importManyAttribute != null), "partType", Strings.MemberContainsBothImportAndImportMany, member.Name);

                var importConstraints = GetImportConstraints(member);
                ImportDefinition?importDefinition;
                if (this.TryCreateImportDefinition(ReflectionHelpers.GetMemberType(member), member, importConstraints, out importDefinition))
                {
                    var importDefinitionBinding = new ImportDefinitionBinding(
                        importDefinition,
                        TypeRef.Get(partType, this.Resolver),
                        MemberRef.Get(member, this.Resolver),
                        TypeRef.Get(member.PropertyType, this.Resolver),
                        TypeRef.Get(GetImportingSiteTypeWithoutCollection(importDefinition, member.PropertyType), this.Resolver));
                    imports.Add(importDefinitionBinding);
                }
            }

            MethodInfo?onImportsSatisfied = null;

            foreach (var method in partTypeInfo.GetMethods(this.PublicVsNonPublicFlags | BindingFlags.Instance))
            {
                if (method.IsAttributeDefined <OnImportsSatisfiedAttribute>())
                {
                    Verify.Operation(method.GetParameters().Length == 0, Strings.OnImportsSatisfiedTakeNoParameters);
                    Verify.Operation(onImportsSatisfied == null, Strings.OnlyOneOnImportsSatisfiedMethodIsSupported);
                    onImportsSatisfied = method;
                }
            }

            var importingConstructorParameters = ImmutableList.CreateBuilder <ImportDefinitionBinding>();
            var importingCtor = GetImportingConstructor <ImportingConstructorAttribute>(partType, publicOnly: !this.IsNonPublicSupported);

            Verify.Operation(importingCtor != null, Strings.NoImportingConstructorFound);
            foreach (var parameter in importingCtor.GetParameters())
            {
                var import = this.CreateImport(parameter, GetImportConstraints(parameter));
                if (import.ImportDefinition.Cardinality == ImportCardinality.ZeroOrMore)
                {
                    Verify.Operation(PartDiscovery.IsImportManyCollectionTypeCreateable(import), Strings.CollectionMustBePublicAndPublicCtorWhenUsingImportingCtor);
                }

                importingConstructorParameters.Add(import);
            }

            var partMetadata = ImmutableDictionary.CreateBuilder <string, object?>();

            foreach (var partMetadataAttribute in partTypeInfo.GetAttributes <PartMetadataAttribute>())
            {
                partMetadata[partMetadataAttribute.Name] = partMetadataAttribute.Value;
            }

            var assemblyNamesForMetadataAttributes = ImmutableHashSet.CreateBuilder <AssemblyName>(ByValueEquality.AssemblyName);

            foreach (var export in exportsByMember)
            {
                GetAssemblyNamesFromMetadataAttributes <MetadataAttributeAttribute>(export.Key, assemblyNamesForMetadataAttributes);
            }

            return(new ComposablePartDefinition(
                       TypeRef.Get(partType, this.Resolver),
                       partMetadata.ToImmutable(),
                       exportsOnType.ToImmutable(),
                       exportsOnMembers.ToImmutable(),
                       imports.ToImmutable(),
                       sharingBoundary,
                       MethodRef.Get(onImportsSatisfied, this.Resolver),
                       MethodRef.Get(importingCtor, this.Resolver),
                       importingConstructorParameters.ToImmutable(),
                       partCreationPolicy,
                       assemblyNamesForMetadataAttributes));
        }
示例#17
0
            public override IEnumerable <KeyValuePair <BasicBlockTag, ImmutableHashSet <ValueTag> > > GetOutgoingInputs(
                BasicBlock block,
                ImmutableHashSet <ValueTag> output)
            {
                var domTree = block.Graph.GetAnalysisResult <DominatorTree>();
                var preds   = block.Graph.GetAnalysisResult <BasicBlockPredecessors>();

                // Materialization is always propagated forward.
                var results = new List <KeyValuePair <BasicBlockTag, ImmutableHashSet <ValueTag> > >();

                foreach (var pair in base.GetOutgoingInputs(block, output))
                {
                    // Don't materialize values in blocks that are not dominated by the block
                    // that defines those values---those blocks can't use the value, so
                    // materializing values there doesn't make any sense.
                    var matVals = pair.Value
                                  .Where(val =>
                                         domTree.IsDominatedBy(
                                             pair.Key,
                                             block.Graph.GetValueParent(val)))
                                  .ToImmutableHashSet();
                    results.Add(new KeyValuePair <BasicBlockTag, ImmutableHashSet <ValueTag> >(pair.Key, matVals));

                    // An edge from a block to another block that dominates said block indicates
                    // that we've encountered a loop. We absolutely don't want materialization
                    // to happen *inside* a loop. To avoid it, we'll propagate materialization
                    // information to all predecessors of the block.
                    foreach (var targetPred in preds.GetPredecessorsOf(pair.Key))
                    {
                        results.Add(new KeyValuePair <BasicBlockTag, ImmutableHashSet <ValueTag> >(pair.Key, matVals));
                    }
                }

                // Propagate materialization backward for basic block parameters.
                foreach (var pred in preds.GetPredecessorsOf(block))
                {
                    foreach (var branch in block.Graph.GetBasicBlock(pred).Flow.Branches)
                    {
                        if (branch.Target != block.Tag)
                        {
                            continue;
                        }

                        var imported = ImmutableHashSet.CreateBuilder <ValueTag>();
                        foreach (var pair in branch.ZipArgumentsWithParameters(block.Graph))
                        {
                            if (!output.Contains(pair.Key) || !pair.Value.IsValue)
                            {
                                continue;
                            }

                            imported.Add(pair.Value.ValueOrNull);
                        }
                        if (imported.Count > 0)
                        {
                            results.Add(
                                new KeyValuePair <BasicBlockTag, ImmutableHashSet <ValueTag> >(
                                    pred,
                                    imported.ToImmutable()));
                        }
                    }
                }

                // Propagate materialized basic block parameters all the way back to the
                // parameters' definitions.
                foreach (var value in output)
                {
                    if (block.Graph.ContainsBlockParameter(value))
                    {
                        results.Add(
                            new KeyValuePair <BasicBlockTag, ImmutableHashSet <ValueTag> >(
                                block.Graph.GetValueParent(value),
                                ImmutableHashSet.Create(value)));
                    }
                }

                return(results);
            }
        /// <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());
        }
示例#19
0
        public static CompositionConfiguration Create(ComposableCatalog catalog)
        {
            Requires.NotNull(catalog, nameof(catalog));

            // We consider all the parts in the catalog, plus the specially synthesized ones
            // that should always be applied.
            var customizedCatalog = catalog.AddParts(AlwaysBundledParts);

            // Construct our part builders, initialized with all their imports satisfied.
            // We explicitly use reference equality because ComposablePartDefinition.Equals is too slow, and unnecessary for this.
            var partBuilders = new Dictionary <ComposablePartDefinition, PartBuilder>(ReferenceEquality <ComposablePartDefinition> .Default);

            foreach (ComposablePartDefinition partDefinition in customizedCatalog.Parts)
            {
                var satisfyingImports = partDefinition.Imports.ToImmutableDictionary(i => i, i => customizedCatalog.GetExports(i.ImportDefinition));
                partBuilders.Add(partDefinition, new PartBuilder(partDefinition, satisfyingImports));
            }

            // Create a lookup table that gets all immediate importers for each part.
            foreach (PartBuilder partBuilder in partBuilders.Values)
            {
                // We want to understand who imports each part so we can properly propagate sharing boundaries
                // for MEFv1 attributed parts. ExportFactory's that create sharing boundaries are an exception
                // because if a part has a factory that creates new sharing boundaries, the requirement for
                // that sharing boundary of the child scope shouldn't be interpreted as a requirement for that
                // same boundary by the parent part.
                // However, if the ExportFactory does not create sharing boundaries, it does in fact need all
                // the same sharing boundaries as the parts it constructs.
                var importedPartsExcludingFactoriesWithSharingBoundaries =
                    (from entry in partBuilder.SatisfyingExports
                     where !entry.Key.IsExportFactory || entry.Key.ImportDefinition.ExportFactorySharingBoundaries.Count == 0
                     from export in entry.Value
                     select export.PartDefinition).Distinct(ReferenceEquality <ComposablePartDefinition> .Default);
                foreach (var importedPartDefinition in importedPartsExcludingFactoriesWithSharingBoundaries)
                {
                    var importedPartBuilder = partBuilders[importedPartDefinition];
                    importedPartBuilder.ReportImportingPart(partBuilder);
                }
            }

            // Propagate sharing boundaries defined on parts to all importers (transitive closure).
            foreach (PartBuilder partBuilder in partBuilders.Values)
            {
                partBuilder.ApplySharingBoundary();
            }

            var sharingBoundaryOverrides = ComputeInferredSharingBoundaries(partBuilders.Values);

            // Build up our set of composed parts.
            var partsBuilder = ImmutableHashSet.CreateBuilder <ComposedPart>();

            foreach (var partBuilder in partBuilders.Values)
            {
                var composedPart = new ComposedPart(partBuilder.PartDefinition, partBuilder.SatisfyingExports, partBuilder.RequiredSharingBoundaries.ToImmutableHashSet());
                partsBuilder.Add(composedPart);
            }

            var parts = partsBuilder.ToImmutable();

            // Determine which metadata views to use for each applicable import.
            var metadataViewsAndProviders = GetMetadataViewProvidersMap(customizedCatalog);

            // Validate configuration.
            var errors = new List <ComposedPartDiagnostic>();

            foreach (var part in parts)
            {
                errors.AddRange(part.Validate(metadataViewsAndProviders));
            }

            // Detect loops of all non-shared parts.
            errors.AddRange(FindLoops(parts));

            // If errors are found, re-validate the salvaged parts in case there are parts whose dependencies are affected by the initial errors
            if (errors.Count > 0)
            {
                // Set salvaged parts to current catalog in case there are no errors
                var salvagedParts           = parts;
                var salvagedPartDefinitions = catalog.Parts;

                List <ComposedPartDiagnostic> previousErrors = errors;
                Stack <IReadOnlyCollection <ComposedPartDiagnostic> > stackedErrors = new Stack <IReadOnlyCollection <ComposedPartDiagnostic> >();

                // While we still find errors we validate the exports so that we remove all dependency failures
                while (previousErrors.Count > 0)
                {
                    stackedErrors.Push(previousErrors);

                    // Get the salvaged parts
                    var invalidParts = previousErrors.SelectMany(error => error.Parts).ToList();

                    if (invalidParts.Count == 0)
                    {
                        // If we can't identify the faulty parts but we still have errors, we have to just throw.
                        throw new CompositionFailedException(Strings.FailStableComposition, ImmutableStack.Create <IReadOnlyCollection <ComposedPartDiagnostic> >(errors));
                    }

                    salvagedParts = salvagedParts.Except(invalidParts);
                    var invalidPartDefinitionsSet = new HashSet <ComposablePartDefinition>(invalidParts.Select(p => p.Definition));
                    salvagedPartDefinitions = salvagedPartDefinitions.Except(invalidPartDefinitionsSet);

                    // Empty the list so that we create a new one only with the new set of errors
                    previousErrors = new List <ComposedPartDiagnostic>();

                    foreach (var part in salvagedParts)
                    {
                        previousErrors.AddRange(part.RemoveSatisfyingExports(invalidPartDefinitionsSet));
                    }
                }

                var finalCatalog = ComposableCatalog.Create(catalog.Resolver).AddParts(salvagedPartDefinitions);

                // We want the first found errors to come out of the stack first, so we need to invert the current stack.
                var compositionErrors = ImmutableStack.CreateRange(stackedErrors);

                var configuration = new CompositionConfiguration(
                    finalCatalog,
                    salvagedParts,
                    metadataViewsAndProviders,
                    compositionErrors,
                    sharingBoundaryOverrides);

                return(configuration);
            }

            return(new CompositionConfiguration(
                       catalog,
                       parts,
                       metadataViewsAndProviders,
                       ImmutableStack <IReadOnlyCollection <ComposedPartDiagnostic> > .Empty,
                       sharingBoundaryOverrides));
        }
 public TrackedPropertiesBuilder()
 {
     this.trackedPropertiesBuilder = ImmutableHashSet.CreateBuilder <string>();
 }
 void countOperand(ISymbol symbol)
 {
     symbolUsageCounts++;
     distinctReferencedSymbolsBuilder ??= ImmutableHashSet.CreateBuilder <ISymbol>();
     distinctReferencedSymbolsBuilder.Add(symbol);
 }
示例#22
0
        private static async Task <RenameLocations> FindLocationsInCurrentProcessAsync(
            ISymbol symbol,
            Solution solution,
            RenameOptionSet optionSet,
            CancellationToken cancellationToken
            )
        {
            Contract.ThrowIfNull(symbol);
            using (Logger.LogBlock(FunctionId.Rename_AllRenameLocations, cancellationToken))
            {
                symbol = await ReferenceProcessing
                         .FindDefinitionSymbolAsync(symbol, solution, cancellationToken)
                         .ConfigureAwait(false);

                // First, find the direct references just to the symbol being renamed.
                var originalSymbolResult = await AddLocationsReferenceSymbolsAsync(
                    symbol,
                    solution,
                    cancellationToken
                    )
                                           .ConfigureAwait(false);

                // Next, find references to overloads, if the user has asked to rename those as well.
                var overloadsResult = await GetOverloadsAsync(
                    symbol,
                    solution,
                    optionSet,
                    cancellationToken
                    )
                                      .ConfigureAwait(false);

                // Finally, include strings/comments if that's what the user wants.
                var(strings, comments) = await ReferenceProcessing
                                         .GetRenamableLocationsInStringsAndCommentsAsync(
                    symbol,
                    solution,
                    originalSymbolResult.Locations,
                    optionSet.RenameInStrings,
                    optionSet.RenameInComments,
                    cancellationToken
                    )
                                         .ConfigureAwait(false);

                var mergedLocations = ImmutableHashSet.CreateBuilder <RenameLocation>();

                using var _1 = ArrayBuilder <ISymbol> .GetInstance(out var mergedReferencedSymbols);

                using var _2 = ArrayBuilder <ReferenceLocation> .GetInstance(
                          out var mergedImplicitLocations
                          );

                mergedLocations.AddRange(strings.NullToEmpty());
                mergedLocations.AddRange(comments.NullToEmpty());

                var renameMethodGroupReferences =
                    optionSet.RenameOverloads || !GetOverloadedSymbols(symbol).Any();
                foreach (var result in overloadsResult.Concat(originalSymbolResult))
                {
                    mergedLocations.AddRange(
                        renameMethodGroupReferences
                          ? result.Locations
                          : result.Locations.Where(
                            x => x.CandidateReason != CandidateReason.MemberGroup
                            )
                        );

                    mergedImplicitLocations.AddRange(result.ImplicitLocations);
                    mergedReferencedSymbols.AddRange(result.ReferencedSymbols);
                }

                return(new RenameLocations(
                           symbol,
                           solution,
                           optionSet,
                           new SearchResult(
                               mergedLocations.ToImmutable(),
                               mergedImplicitLocations.ToImmutable(),
                               mergedReferencedSymbols.ToImmutable()
                               )
                           ));
            }
        }
        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));
示例#24
0
        private Tuple <ITargetBlock <Type>, Task <DiscoveredParts> > CreateDiscoveryBlockChain(bool typeExplicitlyRequested, IProgress <DiscoveryProgress>?progress, CancellationToken cancellationToken)
        {
            string status         = Strings.ScanningMEFAssemblies;
            int    typesScanned   = 0;
            var    transformBlock = new TransformBlock <Type, object?>(
                type =>
            {
                try
                {
                    return(this.CreatePart(type, typeExplicitlyRequested));
                }
                catch (Exception ex)
                {
                    return(new PartDiscoveryException(string.Format(CultureInfo.CurrentCulture, Strings.FailureWhileScanningType, type.FullName), ex)
                    {
                        AssemblyPath = type.GetTypeInfo().Assembly.Location, ScannedType = type
                    });
                }
            },
                new ExecutionDataflowBlockOptions
            {
                MaxDegreeOfParallelism = Debugger.IsAttached ? 1 : Environment.ProcessorCount,
                CancellationToken      = cancellationToken,
                MaxMessagesPerTask     = 10,
                BoundedCapacity        = 100,
            });
            var parts            = ImmutableHashSet.CreateBuilder <ComposablePartDefinition>();
            var errors           = ImmutableList.CreateBuilder <PartDiscoveryException>();
            var aggregatingBlock = new ActionBlock <object?>(partOrException =>
            {
                var part  = partOrException as ComposablePartDefinition;
                var error = partOrException as PartDiscoveryException;
                Debug.Assert(partOrException is Exception == partOrException is PartDiscoveryException, "Wrong exception type returned.");
                if (part != null)
                {
                    parts.Add(part);
                }
                else if (error != null)
                {
                    errors.Add(error);
                }

                progress.ReportNullSafe(new DiscoveryProgress(++typesScanned, 0, status));
            });

            transformBlock.LinkTo(aggregatingBlock, new DataflowLinkOptions {
                PropagateCompletion = true
            });

            var tcs = new TaskCompletionSource <DiscoveredParts>();

            Task.Run(async delegate
            {
                try
                {
                    await aggregatingBlock.Completion.ConfigureAwait(false);
                    tcs.SetResult(new DiscoveredParts(parts.ToImmutable(), errors.ToImmutable()));
                }
                catch (Exception ex)
                {
                    tcs.SetException(ex);
                }
            });

            return(Tuple.Create <ITargetBlock <Type>, Task <DiscoveredParts> >(transformBlock, tcs.Task));
        }
        private static TaintedDataConfig Create(Compilation compilation)
        {
            WellKnownTypeProvider wellKnownTypeProvider = WellKnownTypeProvider.GetOrCreate(compilation);

            using PooledDictionary <SinkKind, Lazy <TaintedDataSymbolMap <SourceInfo> > > sourceSymbolMapBuilder =
                      PooledDictionary <SinkKind, Lazy <TaintedDataSymbolMap <SourceInfo> > > .GetInstance();

            using PooledDictionary <SinkKind, Lazy <TaintedDataSymbolMap <SanitizerInfo> > > sanitizerSymbolMapBuilder =
                      PooledDictionary <SinkKind, Lazy <TaintedDataSymbolMap <SanitizerInfo> > > .GetInstance();

            using PooledDictionary <SinkKind, Lazy <TaintedDataSymbolMap <SinkInfo> > > sinkSymbolMapBuilder =
                      PooledDictionary <SinkKind, Lazy <TaintedDataSymbolMap <SinkInfo> > > .GetInstance();

            // For tainted data rules with the same set of sources, we'll reuse the same TaintedDataSymbolMap<SourceInfo> instance.
            // Same for sanitizers.
            using PooledDictionary <ImmutableHashSet <SourceInfo>, Lazy <TaintedDataSymbolMap <SourceInfo> > > sourcesToSymbolMap =
                      PooledDictionary <ImmutableHashSet <SourceInfo>, Lazy <TaintedDataSymbolMap <SourceInfo> > > .GetInstance();

            using PooledDictionary <ImmutableHashSet <SanitizerInfo>, Lazy <TaintedDataSymbolMap <SanitizerInfo> > > sanitizersToSymbolMap =
                      PooledDictionary <ImmutableHashSet <SanitizerInfo>, Lazy <TaintedDataSymbolMap <SanitizerInfo> > > .GetInstance();

            // Build a mapping of (sourceSet, sanitizerSet) -> (sinkKinds, sinkSet), so we'll reuse the same TaintedDataSymbolMap<SinkInfo> instance.
            using PooledDictionary <(ImmutableHashSet <SourceInfo> SourceInfos, ImmutableHashSet <SanitizerInfo> SanitizerInfos), (ImmutableHashSet <SinkKind> .Builder SinkKinds, ImmutableHashSet <SinkInfo> .Builder SinkInfos)> sourceSanitizersToSinks =
                      PooledDictionary <(ImmutableHashSet <SourceInfo> SourceInfos, ImmutableHashSet <SanitizerInfo> SanitizerInfos), (ImmutableHashSet <SinkKind> .Builder SinkKinds, ImmutableHashSet <SinkInfo> .Builder SinkInfos)> .GetInstance();

            // Using LazyThreadSafetyMode.ExecutionAndPublication to avoid instantiating multiple times.
            foreach (SinkKind sinkKind in Enum.GetValues(typeof(SinkKind)))
            {
                ImmutableHashSet <SourceInfo> sources = GetSourceInfos(sinkKind);
                if (!sourcesToSymbolMap.TryGetValue(sources, out Lazy <TaintedDataSymbolMap <SourceInfo> > lazySourceSymbolMap))
                {
                    lazySourceSymbolMap = new Lazy <TaintedDataSymbolMap <SourceInfo> >(
                        () => { return(new TaintedDataSymbolMap <SourceInfo>(wellKnownTypeProvider, sources)); },
                        LazyThreadSafetyMode.ExecutionAndPublication);
                    sourcesToSymbolMap.Add(sources, lazySourceSymbolMap);
                }

                sourceSymbolMapBuilder.Add(sinkKind, lazySourceSymbolMap);

                ImmutableHashSet <SanitizerInfo> sanitizers = GetSanitizerInfos(sinkKind);
                if (!sanitizersToSymbolMap.TryGetValue(sanitizers, out Lazy <TaintedDataSymbolMap <SanitizerInfo> > lazySanitizerSymbolMap))
                {
                    lazySanitizerSymbolMap = new Lazy <TaintedDataSymbolMap <SanitizerInfo> >(
                        () => { return(new TaintedDataSymbolMap <SanitizerInfo>(wellKnownTypeProvider, sanitizers)); },
                        LazyThreadSafetyMode.ExecutionAndPublication);
                    sanitizersToSymbolMap.Add(sanitizers, lazySanitizerSymbolMap);
                }

                sanitizerSymbolMapBuilder.Add(sinkKind, lazySanitizerSymbolMap);

                ImmutableHashSet <SinkInfo> sinks = GetSinkInfos(sinkKind);
                if (!sourceSanitizersToSinks.TryGetValue((sources, sanitizers), out (ImmutableHashSet <SinkKind> .Builder SinkKinds, ImmutableHashSet <SinkInfo> .Builder SinkInfos)sinksPair))
                {
                    sinksPair = (ImmutableHashSet.CreateBuilder <SinkKind>(), ImmutableHashSet.CreateBuilder <SinkInfo>());
                    sourceSanitizersToSinks.Add((sources, sanitizers), sinksPair);
                }

                sinksPair.SinkKinds.Add(sinkKind);
                sinksPair.SinkInfos.UnionWith(sinks);
            }

            foreach (KeyValuePair <(ImmutableHashSet <SourceInfo> SourceInfos, ImmutableHashSet <SanitizerInfo> SanitizerInfos), (ImmutableHashSet <SinkKind> .Builder SinkKinds, ImmutableHashSet <SinkInfo> .Builder SinkInfos)> kvp in sourceSanitizersToSinks)
            {
                ImmutableHashSet <SinkInfo>             sinks             = kvp.Value.SinkInfos.ToImmutable();
                Lazy <TaintedDataSymbolMap <SinkInfo> > lazySinkSymbolMap = new Lazy <TaintedDataSymbolMap <SinkInfo> >(
                    () => { return(new TaintedDataSymbolMap <SinkInfo>(wellKnownTypeProvider, sinks)); },
                    LazyThreadSafetyMode.ExecutionAndPublication);
                foreach (SinkKind sinkKind in kvp.Value.SinkKinds)
                {
                    sinkSymbolMapBuilder.Add(sinkKind, lazySinkSymbolMap);
                }
            }

            return(new TaintedDataConfig(
                       wellKnownTypeProvider,
                       sourceSymbolMapBuilder.ToImmutableDictionary(),
                       sanitizerSymbolMapBuilder.ToImmutableDictionary(),
                       sinkSymbolMapBuilder.ToImmutableDictionary()));
        }
示例#26
0
        internal static Options Create(string[] args)
        {
            string analyzerPath                = null;
            string solutionPath                = null;
            var    builder                     = ImmutableHashSet.CreateBuilder <string>();
            var    refactoringBuilder          = ImmutableHashSet.CreateBuilder <string>();
            bool   runConcurrent               = false;
            bool   reportSuppressedDiagnostics = false;
            bool   applyChanges                = false;
            bool   showStats                   = false;
            bool   showCompilerDiagnostics     = false;
            bool   useAll        = false;
            int    iterations    = 1;
            bool   testDocuments = false;
            Func <string, bool> testDocumentMatch = _ => true;
            int    testDocumentIterations         = 10;
            string logFileName              = null;
            string profileRoot              = null;
            var    usePersistentStorage     = false;
            var    analysisScope            = BackgroundAnalysisScope.Default;
            var    incrementalAnalyzerNames = ImmutableList.CreateBuilder <string>();

            int i = 0;

            while (i < args.Length)
            {
                var arg = args[i++];
                string ReadValue() => (i < args.Length) ? args[i++] : throw new InvalidDataException($"Missing value for option {arg}");

                switch (arg)
                {
                case "/all":
                    useAll = true;
                    break;

                case "/stats":
                    showStats = true;
                    break;

                case "/compilerStats":
                    showCompilerDiagnostics = true;
                    break;

                case "/concurrent":
                    runConcurrent = true;
                    break;

                case "/editperf":
                    testDocuments = true;
                    break;

                case var _ when arg.StartsWith("/editperf:"):
                    testDocuments = true;

                    var expression = new Regex(arg.Substring("/editperf:".Length), RegexOptions.Compiled | RegexOptions.IgnoreCase);
                    testDocumentMatch = documentPath => expression.IsMatch(documentPath);
                    break;

                case var _ when arg.StartsWith("/edititer:"):
                    testDocumentIterations = int.Parse(arg.Substring("/edititer:".Length));

                    break;

                case var _ when arg.StartsWith("/iter:"):
                    iterations = int.Parse(arg.Substring("/iter:".Length));

                    break;

                case "/suppressed":
                    reportSuppressedDiagnostics = true;
                    break;

                case "/apply":
                    applyChanges = true;
                    break;

                case "/a":
                    builder.Add(ReadValue());
                    break;

                case "/refactor":
                    refactoringBuilder.Add(ReadValue());
                    break;

                case "/log":
                    logFileName = ReadValue();
                    break;

                case "/profileroot":
                    profileRoot = ReadValue();
                    break;

                case "/persist":
                    usePersistentStorage = true;
                    break;

                case "/fsa":
                    analysisScope = BackgroundAnalysisScope.FullSolution;
                    break;

                case "/ia":
                    incrementalAnalyzerNames.Add(ReadValue());
                    break;

                default:
                    if (analyzerPath == null)
                    {
                        analyzerPath = arg;
                    }
                    else if (solutionPath == null)
                    {
                        solutionPath = arg;
                    }
                    else
                    {
                        throw new InvalidDataException((arg.StartsWith("/", StringComparison.Ordinal) ?
                                                        "Unrecognized option " + arg :
                                                        "Unrecognized parameter " + arg));
                    }
                    break;
                }
            }

            if (analyzerPath == null)
            {
                throw new InvalidDataException("Missing analyzer path");
            }

            if (solutionPath == null)
            {
                throw new InvalidDataException("Missing solution path");
            }

            return(new Options(
                       analyzerPath: analyzerPath,
                       solutionPath: solutionPath,
                       analyzerIds: builder.ToImmutableHashSet(),
                       refactoringNodes: refactoringBuilder.ToImmutableHashSet(),
                       runConcurrent: runConcurrent,
                       reportSuppressedDiagnostics: reportSuppressedDiagnostics,
                       applyChanges: applyChanges,
                       showStats: showStats,
                       showCompilerDiagnostics: showCompilerDiagnostics,
                       useAll: useAll,
                       iterations: iterations,
                       testDocuments: testDocuments,
                       testDocumentMatch: testDocumentMatch,
                       testDocumentIterations: testDocumentIterations,
                       logFileName: logFileName,
                       profileRoot: profileRoot,
                       usePersistentStorage: usePersistentStorage,
                       analysisScope: analysisScope,
                       incrementalAnalyzerNames: incrementalAnalyzerNames.ToImmutable()));
        }
示例#27
0
 public void DebuggerAttributesValid()
 {
     DebuggerAttributes.ValidateDebuggerDisplayReferences(ImmutableHashSet.CreateBuilder <int>());
 }
示例#28
0
            protected override async Task <Solution> GetChangedSolutionAsync(CancellationToken cancellationToken)
            {
                var updatedPublicSurfaceAreaText = new List <KeyValuePair <DocumentId, SourceText> >();

                foreach (KeyValuePair <Project, ImmutableArray <Diagnostic> > pair in _diagnosticsToFix)
                {
                    Project project = pair.Key;
                    ImmutableArray <Diagnostic> diagnostics = pair.Value;

                    TextDocument publicSurfaceAreaAdditionalDocument = GetPublicSurfaceAreaDocument(project);

                    if (publicSurfaceAreaAdditionalDocument == null)
                    {
                        continue;
                    }

                    SourceText sourceText = await publicSurfaceAreaAdditionalDocument.GetTextAsync(cancellationToken).ConfigureAwait(false);

                    IEnumerable <IGrouping <SyntaxTree, Diagnostic> > groupedDiagnostics =
                        diagnostics
                        .Where(d => d.Location.IsInSource)
                        .GroupBy(d => d.Location.SourceTree);

                    var newSymbolNames             = new List <string>();
                    var symbolNamesToRemoveBuilder = ImmutableHashSet.CreateBuilder <string>();

                    foreach (IGrouping <SyntaxTree, Diagnostic> grouping in groupedDiagnostics)
                    {
                        Document document = project.GetDocument(grouping.Key);

                        if (document == null)
                        {
                            continue;
                        }

                        SyntaxNode root = await document.GetSyntaxRootAsync(cancellationToken).ConfigureAwait(false);

                        SemanticModel semanticModel = await document.GetSemanticModelAsync(cancellationToken).ConfigureAwait(false);

                        foreach (Diagnostic diagnostic in grouping)
                        {
                            string publicSurfaceAreaSymbolName = diagnostic.Properties[DeclarePublicAPIAnalyzer.PublicApiNamePropertyBagKey];

                            newSymbolNames.Add(publicSurfaceAreaSymbolName);

                            string siblingNamesToRemove = diagnostic.Properties[DeclarePublicAPIAnalyzer.PublicApiNamesOfSiblingsToRemovePropertyBagKey];
                            if (siblingNamesToRemove.Length > 0)
                            {
                                var namesToRemove = siblingNamesToRemove.Split(DeclarePublicAPIAnalyzer.PublicApiNamesOfSiblingsToRemovePropertyBagValueSeparator.ToCharArray());
                                foreach (var nameToRemove in namesToRemove)
                                {
                                    symbolNamesToRemoveBuilder.Add(nameToRemove);
                                }
                            }
                        }
                    }

                    var symbolNamesToRemove = symbolNamesToRemoveBuilder.ToImmutable();

                    // We shouldn't be attempting to remove any symbol name, while also adding it.
                    Debug.Assert(newSymbolNames.All(newSymbolName => !symbolNamesToRemove.Contains(newSymbolName)));

                    SourceText newSourceText = AddSymbolNamesToSourceText(sourceText, newSymbolNames);
                    newSourceText = RemoveSymbolNamesFromSourceText(newSourceText, symbolNamesToRemove);

                    updatedPublicSurfaceAreaText.Add(new KeyValuePair <DocumentId, SourceText>(publicSurfaceAreaAdditionalDocument.Id, newSourceText));
                }

                Solution newSolution = _solution;

                foreach (KeyValuePair <DocumentId, SourceText> pair in updatedPublicSurfaceAreaText)
                {
                    newSolution = newSolution.WithAdditionalDocumentText(pair.Key, pair.Value);
                }

                return(newSolution);
            }
        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);
            }
示例#30
0
 protected override ImmutableHashSet <T> .Builder Create(int count, MessagePackSerializerOptions options)
 {
     return(ImmutableHashSet.CreateBuilder <T>(options.Security.GetEqualityComparer <T>()));
 }