private static void ValidateImmutability( SyntaxNodeAnalysisContext context, ITypeSymbol typeSymbol ) { if (ImmutableContainerMethods.IsAnImmutableContainerType(typeSymbol)) { var namedTypeSymbol = typeSymbol as INamedTypeSymbol; if (namedTypeSymbol == default(INamedTypeSymbol)) { context.ReportDiagnostic(Diagnostic.Create( Diagnostics.GenericArgumentTypeMustBeImmutable, context.Node.GetLocation(), messageArgs: new object[] { namedTypeSymbol.Name })); } foreach (var typeArgument in namedTypeSymbol.TypeArguments) { ValidateImmutability(context, typeArgument); } } else { if ((!KnownImmutableTypes.IsTypeKnownImmutable(typeSymbol)) && (typeSymbol.GetImmutabilityScope() != ImmutabilityScope.SelfAndChildren)) { context.ReportDiagnostic(Diagnostic.Create( Diagnostics.GenericArgumentTypeMustBeImmutable, context.Node.GetLocation(), messageArgs: new object[] { typeSymbol.Name })); } } }
internal MutabilityInspector( Compilation compilation, KnownImmutableTypes knownImmutableTypes ) { m_compilation = compilation; m_knownImmutableTypes = knownImmutableTypes; }
public void IsTypeKnownImmutable_NotDeclaredImmutableAndNotDefault_False() { var knownTypes = new KnownImmutableTypes(ImmutableHashSet <string> .Empty); var type = Field("System.IDisposable foo").Symbol.Type; var result = knownTypes.IsTypeKnownImmutable(type); Assert.False(result); }
public void IsTypeKnownImmutable_DefaultlyImmutable_True() { var knownTypes = new KnownImmutableTypes(ImmutableHashSet <string> .Empty); var type = Field("System.Version foo").Symbol.Type; var result = knownTypes.IsTypeKnownImmutable(type); Assert.True(result); }
public void IsTypeKnownImmutable_DeclaredImmutable_True() { var knownTypes = new KnownImmutableTypes(new HashSet <string> { "System.IDisposable" }.ToImmutableHashSet()); var type = Field("System.IDisposable foo").Symbol.Type; var result = knownTypes.IsTypeKnownImmutable(type); Assert.True(result); }
public void IsTypeKnownImmutable_AssemblyDeclaredImmutable_True() { var cs = @" using System; using D2L.CodeStyle.Annotations; [assembly: Types.Audited( typeof( Test.Foo ), ""Random Owner"", ""Random Date"", ""Random rationale"" )] namespace Test { public class Foo { } } namespace D2L.CodeStyle.Annotations { public static partial class Types { [AttributeUsage( validOn: AttributeTargets.Assembly, AllowMultiple = true )] public sealed class Audited : Attribute { public Audited( Type type, string owner, string auditedDate, string rationale ) { Type = type; Owner = owner; AuditedDate = auditedDate; Rationale = rationale; } public Type Type { get; } public string Owner { get; } public string AuditedDate { get; } public string Rationale { get; } } } } "; var compilation = Compile(cs); var knownTypes = new KnownImmutableTypes(compilation.Assembly); var fooType = compilation.GetSymbolsWithName( predicate: n => true, filter: SymbolFilter.Type ).OfType <ITypeSymbol>().FirstOrDefault(); Assert.IsNotNull(fooType); Assert.AreNotEqual(TypeKind.Error, fooType.TypeKind); var result = knownTypes.IsTypeKnownImmutable(fooType); Assert.True(result); }