コード例 #1
0
        private static void Analyze(
            SymbolAnalysisContext context
            )
        {
            var symbol = (INamedTypeSymbol)context.Symbol;

            if (!symbol.IsDefinition)
            {
                return;
            }

            foreach (ITypeSymbol argument in symbol.TypeArguments)
            {
                ImmutabilityScope scope = argument.GetImmutabilityScope();
                if (scope == ImmutabilityScope.SelfAndChildren)
                {
                    continue;
                }

                if (ImmutableGenericArgument.BaseClassDemandsImmutability(symbol, argument) ||
                    ImmutableGenericArgument.InterfacesDemandImmutability(symbol, argument) ||
                    ImmutableGenericArgument.ConstraintsDemandImmutabliity(symbol, argument)
                    )
                {
                    context.ReportDiagnostic(Diagnostic.Create(
                                                 Diagnostics.GenericArgumentImmutableMustBeApplied,
                                                 argument.DeclaringSyntaxReferences
                                                 .First()
                                                 .GetSyntax()
                                                 .GetLocation()));
                }
            }
        }
コード例 #2
0
        private static bool SymbolDemandsImmutability(
            ITypeSymbol symbol,
            ITypeSymbol argument
            )
        {
            var symbolType = symbol as INamedTypeSymbol;

            if (symbolType == default)
            {
                return(false);
            }

            int ordinal = symbolType.IndexOfArgument(argument.Name);

            if (ordinal < 0)
            {
                return(false);
            }

            ImmutabilityScope argumentScope =
                symbolType.TypeParameters[ordinal].GetImmutabilityScope();

            if (argumentScope == ImmutabilityScope.SelfAndChildren)
            {
                return(true);
            }

            return(false);
        }
        private static void AnalyzeNode(
            SyntaxNodeAnalysisContext context
            )
        {
            var syntaxNode = context.Node as GenericNameSyntax;

            // Attributes are not allowed on local function parameters so we
            // have to ignore this node, otherwise we'll tell people to
            // annotate a declaration that is forbidden.
            if (syntaxNode.Ancestors().Any(a => a is LocalFunctionStatementSyntax))
            {
                return;
            }

            SymbolInfo hostTypeSymbolInfo = context.SemanticModel.GetSymbolInfo(syntaxNode);
            var        hostTypeSymbol     = hostTypeSymbolInfo.Symbol as INamedTypeSymbol;

            if (hostTypeSymbol == default)
            {
                return;
            }

            TypeArgumentListSyntax typeArgumentNode = syntaxNode.TypeArgumentList;

            for (int index = 0; index < typeArgumentNode.Arguments.Count; index++)
            {
                ITypeParameterSymbol hostParameterSymbol = hostTypeSymbol.TypeParameters[index];

                ImmutabilityScope declarationScope = hostParameterSymbol.GetImmutabilityScope();
                if (declarationScope != ImmutabilityScope.SelfAndChildren)
                {
                    continue;
                }

                SymbolInfo argumentSymbolInfo = context.SemanticModel.GetSymbolInfo(typeArgumentNode.Arguments[index]);
                var        typeSymbol         = argumentSymbolInfo.Symbol as ITypeSymbol;
                if (typeSymbol == default)
                {
                    continue;
                }

                ValidateImmutability(
                    context,
                    typeSymbol
                    );
            }
        }