private static Dictionary<ITypeSymbol, string> GetFormattableMembers(SemanticModel model)
 {
     return new Dictionary<ITypeSymbol, string>()
     {
         [model.GetClrType(typeof(string))] = nameof(string.Format),
         [model.GetClrType(typeof(StringBuilder))] = nameof(StringBuilder.AppendFormat),
     };
 }
        public static ITypeSymbol UnwrapFromNullableType(this ITypeSymbol type, SemanticModel semanticModel)
        {
            var namedType = type as INamedTypeSymbol;
            if (namedType == null) return null;
            if (type.UnwrapGenericIfNeeded().Equals(semanticModel.GetClrType(typeof (Nullable<>))))
            {
                return namedType.TypeArguments[0];
            }

            return null;
        }
 private HashSet<INamedTypeSymbol> GetWellKnownFactories(SemanticModel model)
 {
     return new HashSet<INamedTypeSymbol>()
     {
         model.GetClrType(typeof(Enumerable)),
         model.GetClrType(typeof(Queryable)),
         model.GetClrType(typeof(Convert)),
     };
 }
        private HashSet<INamedTypeSymbol> GetWellKnownImmutableSystemTypes(SemanticModel model)
        {
            return new HashSet<INamedTypeSymbol>()
            {
                model.GetClrType(typeof(object)),
                model.GetClrType(typeof(Delegate)),
                model.GetClrType(typeof(string)),
                model.GetClrType(typeof(Enum)),
                model.GetClrType(typeof(Type)),

                model.GetClrType(typeof(IEquatable<>)),
                model.GetClrType(typeof(IComparable<>)),
                model.GetClrType(typeof(IFormattable)),
                model.GetClrType(typeof(IEnumerable<>)),
                model.GetClrType(typeof(IQueryable<>)),
                model.GetClrType(typeof(ICustomFormatter)),
            };
        }
        private bool IsTaskOfT(AwaitExpressionSyntax awaitExpression, SemanticModel semanticModel)
        {
            var type = semanticModel.GetTypeInfo(awaitExpression.Expression);

            return type.Type?.UnwrapGenericIfNeeded()?.Equals(
                semanticModel.GetClrType(typeof(Task<>))) == true;
        }
 private bool IsArrayOfObjects(ITypeSymbol expressionType, SemanticModel semanticModel)
 {
     var arrayType = expressionType as IArrayTypeSymbol;
     return arrayType?.Rank == 1 &&
            arrayType?.ElementType.Equals(semanticModel.GetClrType(typeof (object))) == true;
 }
        private bool DefaultSectionThrows(SwitchStatementSyntax switchStatement, SemanticModel semanticModel)
        {
            var defaultCase = switchStatement.Sections.FirstOrDefault(s => s.Labels.OfType<DefaultSwitchLabelSyntax>().Any());

            if (defaultCase == null)
            {
                return false;
            }

            bool throwsInvalidOperation =
                defaultCase.Statements
                    // Filtering throw
                    .OfType<ThrowStatementSyntax>()
                    .Select(s => s.Expression)
                    // Filtering throw new Exception
                    .OfType<ObjectCreationExpressionSyntax>()
                    // Filtering unknown symbols
                    .Select(s => semanticModel.GetSymbolInfo(s.Type).Symbol)
                    .Where(s => s != null)
                    // True, if throw new InvalidOperationException()
                    .Any(s => s.Equals(semanticModel.GetClrType(typeof(InvalidOperationException))));

            if (throwsInvalidOperation)
            {
                return true;
            }

            bool hasContractAssertOrAssumeWithFalse =
                defaultCase.Statements
                    // Getting only expressions
                    .OfType<ExpressionStatementSyntax>()
                    // that calls functions
                    .Select(s => s.Expression as InvocationExpressionSyntax)
                    .Where(s => s != null)
                    // with first argument equals to false
                    .Where(s =>
                            s.ArgumentList.Arguments.FirstOrDefault()?.Expression?.Kind() == SyntaxKind.FalseLiteralExpression)
                    // with known symbols
                    .Select(s => semanticModel.GetSymbolInfo(s).Symbol as IMethodSymbol)
                    .Where(s => s != null)
                    // Contract.Assert/Assume or Debug.Assert
                    .Any(m => (m.ContainingType.Equals(semanticModel.GetClrType(typeof(Contract))) &&
                               (m.Name == "Assert" || m.Name == "Assume")) ||
                              (m.ContainingType.Name == "Debug" && m.Name == "Assert"));

            if (hasContractAssertOrAssumeWithFalse)
            {
                return true;
            }

            return false;
        }
        private static void GetSize(SemanticModel semanticModel, ITypeSymbol type, ref int capacity, ref int largestFieldSize, ref int actualSize)
        {
            int currentItemSize;

            int newLargestFieldSize = largestFieldSize;
            if (TryGetPrimitiveSize(type, out currentItemSize, ref newLargestFieldSize))
            {
                if (currentItemSize > largestFieldSize)
                {
                    // we're trying to add large item. For instance, in case: byte b; int i;
                    // In this case we need to adjust current size and capacity to larger bucket
                    largestFieldSize = newLargestFieldSize;

                    int padding = (largestFieldSize - capacity % largestFieldSize)%largestFieldSize;
                    var oldCapacity = capacity;

                    capacity += padding;

                    // Removing very first case, when capacity was zero. In that case, no need to change size.
                    if (oldCapacity != 0)
                    {
                        actualSize = capacity;
                    }
                }

                if (actualSize + currentItemSize > capacity)
                {
                    // Need to take max value from it.
                    // Consider case, when the field is of a large struct type. In this case, bucket size would be IntPtr.Size
                    // but actual size would be much larger!
                    // And in this case, large struct size would be computed by this method and would be adjusted by IntPtr.Size.
                    capacity += Math.Max(currentItemSize, largestFieldSize);
                }

                actualSize += currentItemSize;
            }
            else
            {
                bool empty = true;
                foreach (var field in type.GetMembers().OfType<IFieldSymbol>().Where(f => !f.IsStatic))
                {
                    GetSize(semanticModel, field.Type, ref capacity, ref largestFieldSize, ref actualSize);
                    empty = false;
                }

                if (empty)
                {
                    // Empty struct is similar to byte struct. The size is 1.
                    GetSize(semanticModel, semanticModel.GetClrType(typeof(byte)), ref capacity, ref largestFieldSize, ref actualSize);
                }

                // When composite type layed out, need to adjust actual size to current capacity,
                // because CLR will not put new fields into padding left from the composite type.
                // Consider following example:
                // struct NestedWithLongAndByteAndInt2 { struct N { byte b; long l; byte b2; } N n; int i; }
                // In this case, for N field capacity is 24, but actual size is 17.
                // But in this case, int i would not be stored in the same bucket, but new bucket would be created.
                actualSize = capacity;
            }
        }
 private bool IsCollection(ITypeSymbol symbol, SemanticModel semanticModel)
 {
     return symbol.AllInterfaces.Any(i => i.Equals(semanticModel.GetClrType(typeof(IEnumerable))));
 }