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