Exemple #1
0
 private static bool IsImplicitStylePreferred(
     UseVarPreference stylePreferences, bool isBuiltInTypeContext, bool isTypeApparentContext)
 {
     return(isBuiltInTypeContext
             ? stylePreferences.HasFlag(UseVarPreference.ForBuiltInTypes)
             : isTypeApparentContext
                 ? stylePreferences.HasFlag(UseVarPreference.WhenTypeIsApparent)
                 : stylePreferences.HasFlag(UseVarPreference.Elsewhere));
 }
Exemple #2
0
        /// <summary>
        /// Analyzes if type information is obvious to the reader by simply looking at the assignment expression.
        /// </summary>
        /// <remarks>
        /// <paramref name="typeInDeclaration"/> accepts null, to be able to cater to codegen features
        /// that are about to generate a local declaration and do not have this information to pass in.
        /// Things (like analyzers) that do have a local declaration already, should pass this in.
        /// </remarks>
        public static bool IsTypeApparentInAssignmentExpression(
            UseVarPreference stylePreferences,
            ExpressionSyntax initializerExpression,
            SemanticModel semanticModel,
            ITypeSymbol typeInDeclaration,
            CancellationToken cancellationToken)
        {
            // tuple literals
            if (initializerExpression.IsKind(SyntaxKind.TupleExpression, out TupleExpressionSyntax tuple))
            {
                if (typeInDeclaration == null || !typeInDeclaration.IsTupleType)
                {
                    return(false);
                }

                var tupleType = (INamedTypeSymbol)typeInDeclaration;
                if (tupleType.TupleElements.Length != tuple.Arguments.Count)
                {
                    return(false);
                }

                for (int i = 0, n = tuple.Arguments.Count; i < n; i++)
                {
                    var argument         = tuple.Arguments[i];
                    var tupleElementType = tupleType.TupleElements[i].Type;

                    if (!IsTypeApparentInAssignmentExpression(
                            stylePreferences, argument.Expression, semanticModel, tupleElementType, cancellationToken))
                    {
                        return(false);
                    }
                }

                return(true);
            }

            // default(type)
            if (initializerExpression.IsKind(SyntaxKind.DefaultExpression))
            {
                return(true);
            }

            // literals, use var if options allow usage here.
            if (initializerExpression.IsAnyLiteralExpression())
            {
                return(stylePreferences.HasFlag(UseVarPreference.ForBuiltInTypes));
            }

            // constructor invocations cases:
            //      = new type();
            if (initializerExpression.IsKind(SyntaxKind.ObjectCreationExpression, SyntaxKind.ArrayCreationExpression) &&
                !initializerExpression.IsKind(SyntaxKind.AnonymousObjectCreationExpression))
            {
                return(true);
            }

            // explicit conversion cases:
            //      (type)expr, expr is type, expr as type
            if (initializerExpression.IsKind(SyntaxKind.CastExpression) ||
                initializerExpression.IsKind(SyntaxKind.IsExpression) ||
                initializerExpression.IsKind(SyntaxKind.AsExpression))
            {
                return(true);
            }

            // other Conversion cases:
            //      a. conversion with helpers like: int.Parse methods
            //      b. types that implement IConvertible and then invoking .ToType()
            //      c. System.Convert.ToType()
            var memberName = GetRightmostInvocationExpression(initializerExpression).GetRightmostName();

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

            if (!(semanticModel.GetSymbolInfo(memberName, cancellationToken).Symbol is IMethodSymbol methodSymbol))
            {
                return(false);
            }

            if (memberName.IsRightSideOfDot())
            {
                var containingTypeName = memberName.GetLeftSideOfDot();
                return(IsPossibleCreationOrConversionMethod(methodSymbol, typeInDeclaration, semanticModel, containingTypeName, cancellationToken));
            }

            return(false);
        }