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())); } } }
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 ); } }