Ejemplo n.º 1
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(
            TypeStylePreference stylePreferences,
            ExpressionSyntax initializerExpression,
            SemanticModel semanticModel,
            CancellationToken cancellationToken,
            ITypeSymbol typeInDeclaration = null)
        {
            // default(type)
            if (initializerExpression.IsKind(SyntaxKind.DefaultExpression))
            {
                return true;
            }

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

            // constructor invocations cases:
            //      = new type();
            if (initializerExpression.IsKind(SyntaxKind.ObjectCreationExpression) &&
                !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;
            }

            var methodSymbol = semanticModel.GetSymbolInfo(memberName, cancellationToken).Symbol as IMethodSymbol;
            if (methodSymbol == null)
            {
                return false;
            }

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

            return false;
        }
 /// <summary>
 /// Returns true if type information could be gleaned by simply looking at the given statement.
 /// This typically means that the type name occurs in right hand side of an assignment.
 /// </summary>
 private bool IsTypeApparentInDeclaration(VariableDeclarationSyntax variableDeclaration, SemanticModel semanticModel, TypeStylePreference stylePreferences, CancellationToken cancellationToken)
 {
     var initializer = variableDeclaration.Variables.Single().Initializer;
     var initializerExpression = GetInitializerExpression(initializer);
     var declaredTypeSymbol = semanticModel.GetTypeInfo(variableDeclaration.Type, cancellationToken).Type;
     return TypeStyleHelper.IsTypeApparentInAssignmentExpression(stylePreferences, initializerExpression, semanticModel,cancellationToken, declaredTypeSymbol);
 }
Ejemplo n.º 3
0
 private static bool IsImplicitStylePreferred(
     TypeStylePreference stylePreferences, bool isBuiltInTypeContext, bool isTypeApparentContext)
 {
     return(isBuiltInTypeContext
             ? stylePreferences.HasFlag(TypeStylePreference.ImplicitTypeForIntrinsicTypes)
             : isTypeApparentContext
                 ? stylePreferences.HasFlag(TypeStylePreference.ImplicitTypeWhereApparent)
                 : stylePreferences.HasFlag(TypeStylePreference.ImplicitTypeWherePossible));
 }
Ejemplo n.º 4
0
        private static bool IsImplicitStylePreferred(TypeStylePreference stylePreferences,
            bool isBuiltInTypeContext,
            bool isTypeApparentContext)
        {

            return isBuiltInTypeContext
                    ? stylePreferences.HasFlag(TypeStylePreference.ImplicitTypeForIntrinsicTypes)
                    : isTypeApparentContext
                        ? stylePreferences.HasFlag(TypeStylePreference.ImplicitTypeWhereApparent)
                        : stylePreferences.HasFlag(TypeStylePreference.ImplicitTypeWherePossible);
        }
Ejemplo n.º 5
0
            /// <summary>
            /// Returns true if type information could be gleaned by simply looking at the given statement.
            /// This typically means that the type name occurs in right hand side of an assignment.
            /// </summary>
            private bool IsTypeApparentInDeclaration(VariableDeclarationSyntax variableDeclaration, SemanticModel semanticModel, TypeStylePreference stylePreferences, CancellationToken cancellationToken)
            {
                var initializer           = variableDeclaration.Variables.Single().Initializer;
                var initializerExpression = GetInitializerExpression(initializer.Value);
                var declaredTypeSymbol    = semanticModel.GetTypeInfo(variableDeclaration.Type, cancellationToken).Type;

                return(TypeStyleHelper.IsTypeApparentInAssignmentExpression(stylePreferences, initializerExpression, semanticModel, cancellationToken, declaredTypeSymbol));
            }
Ejemplo n.º 6
0
            /// <summary>
            /// Returns true if type information could be gleaned by simply looking at the given statement.
            /// This typically means that the type name occurs in right hand side of an assignment.
            /// </summary>
            private bool IsTypeApparentInDeclaration(VariableDeclarationSyntax variableDeclaration, SemanticModel semanticModel, TypeStylePreference stylePreferences, CancellationToken cancellationToken)
            {
                if (variableDeclaration.Variables.Count != 1)
                {
                    return(false);
                }

                var initializer = variableDeclaration.Variables[0].Initializer;

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

                var initializerExpression = CSharpUseImplicitTypeHelper.GetInitializerExpression(initializer.Value);
                var declaredTypeSymbol    = semanticModel.GetTypeInfo(variableDeclaration.Type, cancellationToken).Type;

                return(TypeStyleHelper.IsTypeApparentInAssignmentExpression(stylePreferences, initializerExpression, semanticModel, cancellationToken, declaredTypeSymbol));
            }
Ejemplo n.º 7
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(
            TypeStylePreference stylePreferences,
            ExpressionSyntax initializerExpression,
            SemanticModel semanticModel,
            CancellationToken cancellationToken,
            ITypeSymbol typeInDeclaration = null)
        {
            // default(type)
            if (initializerExpression.IsKind(SyntaxKind.DefaultExpression))
            {
                return(true);
            }

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

            // constructor invocations cases:
            //      = new type();
            if (initializerExpression.IsKind(SyntaxKind.ObjectCreationExpression) &&
                !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);
            }

            var methodSymbol = semanticModel.GetSymbolInfo(memberName, cancellationToken).Symbol as IMethodSymbol;

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

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

            return(false);
        }