Esempio n. 1
0
        public static SemanticInfoSummary GetSemanticInfoSummary(this SemanticModel semanticModel, SyntaxNode node)
        {
            SemanticInfoSummary summary = new SemanticInfoSummary();

            // The information that is available varies by the type of the syntax node.

            SymbolInfo symbolInfo = SymbolInfo.None;

            if (node is ExpressionSyntax expr)
            {
                symbolInfo            = semanticModel.GetSymbolInfo(expr);
                summary.ConstantValue = semanticModel.GetConstantValue(expr);
                var typeInfo = semanticModel.GetTypeInfo(expr);
                summary.Type               = (TypeSymbol)typeInfo.Type;
                summary.ConvertedType      = (TypeSymbol)typeInfo.ConvertedType;
                summary.ImplicitConversion = semanticModel.GetConversion(expr);
                summary.MemberGroup        = semanticModel.GetMemberGroup(expr);
            }
            else if (node is AttributeSyntax attribute)
            {
                symbolInfo = semanticModel.GetSymbolInfo(attribute);
                var typeInfo = semanticModel.GetTypeInfo(attribute);
                summary.Type               = (TypeSymbol)typeInfo.Type;
                summary.ConvertedType      = (TypeSymbol)typeInfo.ConvertedType;
                summary.ImplicitConversion = semanticModel.GetConversion(attribute);
                summary.MemberGroup        = semanticModel.GetMemberGroup(attribute);
            }
            else if (node is OrderingSyntax ordering)
            {
                symbolInfo = semanticModel.GetSymbolInfo(ordering);
            }
            else if (node is SelectOrGroupClauseSyntax selectOrGroupClause)
            {
                symbolInfo = semanticModel.GetSymbolInfo(selectOrGroupClause);
            }
            else if (node is ConstructorInitializerSyntax initializer)
            {
                symbolInfo = semanticModel.GetSymbolInfo(initializer);
                var typeInfo = semanticModel.GetTypeInfo(initializer);
                summary.Type               = (TypeSymbol)typeInfo.Type;
                summary.ConvertedType      = (TypeSymbol)typeInfo.ConvertedType;
                summary.ImplicitConversion = semanticModel.GetConversion(initializer);
                summary.MemberGroup        = semanticModel.GetMemberGroup(initializer);
            }
            else
            {
                throw ExceptionUtilities.UnexpectedValue(node);
            }

            summary.Symbol           = (Symbol)symbolInfo.Symbol;
            summary.CandidateReason  = symbolInfo.CandidateReason;
            summary.CandidateSymbols = symbolInfo.CandidateSymbols;

            if (node is IdentifierNameSyntax identifier)
            {
                summary.Alias = semanticModel.GetAliasInfo(identifier);
            }

            return(summary);
        }
        private static void ConditionalExpressionCheck(ConditionalExpressionSyntax conditionalExpression, SemanticModel semanticModel, Action <Diagnostic> reportDiagnostic, string filePath, CancellationToken cancellationToken)
        {
            var trueExp  = conditionalExpression.WhenTrue;
            var falseExp = conditionalExpression.WhenFalse;

            if (trueExp != null)
            {
                CheckTypeConversion(semanticModel.GetConversion(trueExp, cancellationToken), reportDiagnostic, trueExp.GetLocation(), filePath);
            }

            if (falseExp != null)
            {
                CheckTypeConversion(semanticModel.GetConversion(falseExp, cancellationToken), reportDiagnostic, falseExp.GetLocation(), filePath);
            }
        }
Esempio n. 3
0
        private static void BinaryExpressionCheck(EnabledRules rules, SyntaxNode node, SemanticModel semanticModel, bool isAssignmentToReadonly, Action <Diagnostic> reportDiagnostic, string filePath, CancellationToken cancellationToken)
        {
            var binaryExpression = node as BinaryExpressionSyntax;

            bool conversionRuleEnabled = rules.TryGet(AllocationRules.ValueTypeToReferenceTypeConversionRule.Id, out DiagnosticDescriptor conversionRule);

            // as expression
            if (conversionRuleEnabled && binaryExpression.IsKind(SyntaxKind.AsExpression) && binaryExpression.Left != null && binaryExpression.Right != null)
            {
                var leftT  = semanticModel.GetTypeInfo(binaryExpression.Left, cancellationToken);
                var rightT = semanticModel.GetTypeInfo(binaryExpression.Right, cancellationToken);

                if (leftT.Type?.IsValueType == true && rightT.Type?.IsReferenceType == true)
                {
                    reportDiagnostic(Diagnostic.Create(conversionRule, binaryExpression.Left.GetLocation(), EmptyMessageArgs));
                }

                return;
            }

            if (binaryExpression.Right != null)
            {
                if (conversionRuleEnabled)
                {
                    var assignmentExprConversionInfo = semanticModel.GetConversion(binaryExpression.Right, cancellationToken);
                    CheckTypeConversion(conversionRule, assignmentExprConversionInfo, reportDiagnostic, binaryExpression.Right.GetLocation(), filePath);
                }

                var assignmentExprTypeInfo = semanticModel.GetTypeInfo(binaryExpression.Right, cancellationToken);
                CheckDelegateCreation(rules, binaryExpression.Right, assignmentExprTypeInfo, semanticModel, isAssignmentToReadonly, reportDiagnostic, binaryExpression.Right.GetLocation(), filePath, cancellationToken);
                return;
            }
        }
Esempio n. 4
0
        private static void BinaryExpressionCheck(SyntaxNode node, SemanticModel semanticModel, bool isAssignmentToReadonly, Action <Diagnostic> reportDiagnostic, string filePath, CancellationToken cancellationToken)
        {
            var binaryExpression = node as BinaryExpressionSyntax;

            // as expression
            if (binaryExpression.IsKind(SyntaxKind.AsExpression) && binaryExpression.Left != null && binaryExpression.Right != null)
            {
                var leftT  = semanticModel.GetTypeInfo(binaryExpression.Left, cancellationToken);
                var rightT = semanticModel.GetTypeInfo(binaryExpression.Right, cancellationToken);

                if (leftT.Type?.IsValueType == true && rightT.Type?.IsReferenceType == true)
                {
                    reportDiagnostic(Diagnostic.Create(ValueTypeToReferenceTypeConversionRule, binaryExpression.Left.GetLocation(), EmptyMessageArgs));
                    HeapAllocationAnalyzerEventSource.Logger.BoxingAllocation(filePath);
                }

                return;
            }

            if (binaryExpression.Right != null)
            {
                var assignmentExprTypeInfo       = semanticModel.GetTypeInfo(binaryExpression.Right, cancellationToken);
                var assignmentExprConversionInfo = semanticModel.GetConversion(binaryExpression.Right, cancellationToken);
                CheckTypeConversion(assignmentExprConversionInfo, reportDiagnostic, binaryExpression.Right.GetLocation(), filePath);
                CheckDelegateCreation(binaryExpression.Right, assignmentExprTypeInfo, semanticModel, isAssignmentToReadonly, reportDiagnostic, binaryExpression.Right.GetLocation(), filePath, cancellationToken);
                return;
            }
        }
Esempio n. 5
0
        public static bool TryAnalyzeVariableDeclaration(
            SemanticModel semanticModel,
            VariableDeclarationSyntax variableDeclaration,
            out INamedTypeSymbol tupleType,
            out ImmutableArray <MemberAccessExpressionSyntax> memberAccessExpressions,
            CancellationToken cancellationToken)
        {
            tupleType = null;
            memberAccessExpressions = default;

            // Only support code of the form:
            //
            //      var t = ...;  or
            //      (T1 e1, ..., TN eN) t = ...
            if (!variableDeclaration.IsParentKind(SyntaxKind.LocalDeclarationStatement))
            {
                return(false);
            }

            var declarator = variableDeclaration;

            if (declarator.Initializer == null)
            {
                return(false);
            }

            var local = (ILocalSymbol)semanticModel.GetDeclaredSymbol(declarator, cancellationToken);
            var initializerConversion = semanticModel.GetConversion(declarator.Initializer.Value, cancellationToken);

            return(TryAnalyze(
                       semanticModel, local, variableDeclaration.Type, declarator.Identifier, initializerConversion,
                       variableDeclaration.Parent.Parent, out tupleType, out memberAccessExpressions, cancellationToken));
        }
            private static ITypeSymbol GetRegularExpressionType(SemanticModel semanticModel, SyntaxNode node)
            {
                // regular case. always use ConvertedType to get implicit conversion right.
                var expression = node.GetUnparenthesizedExpression();

                var info = semanticModel.GetTypeInfo(expression);
                var conv = semanticModel.GetConversion(expression);

                if (info.ConvertedType == null || info.ConvertedType.IsErrorType())
                {
                    // there is no implicit conversion involved. no need to go further
                    return(info.Type);
                }

                // always use converted type if method group
                if ((!node.IsKind(SyntaxKind.ObjectCreationExpression) && semanticModel.GetMemberGroup(expression).Length > 0) ||
                    IsCoClassImplicitConversion(info, conv, semanticModel.Compilation.CoClassType()))
                {
                    return(info.ConvertedType);
                }

                // check implicit conversion
                if (conv.IsImplicit && (conv.IsConstantExpression || conv.IsEnumeration))
                {
                    return(info.ConvertedType);
                }

                // always try to use type that is more specific than object type if possible.
                return(!info.Type.IsObjectType() ? info.Type : info.ConvertedType);
            }
Esempio n. 7
0
            private void GetAnonymousExprSymbols(ExpressionSyntax expr, SemanticModel model, List <ISymbol> list)
            {
                var kind = expr.Kind();

                if (kind != SyntaxKind.AnonymousObjectCreationExpression &&
                    kind != SyntaxKind.AnonymousMethodExpression &&
                    kind != SyntaxKind.ParenthesizedLambdaExpression &&
                    kind != SyntaxKind.SimpleLambdaExpression)
                {
                    return;
                }

                var tinfo = model.GetTypeInfo(expr);
                var conv  = model.GetConversion(expr);

                if (conv.IsAnonymousFunction)
                {
                    // Lambda has no Type unless in part of case expr (C# specific)
                    // var f = (Func<int>)(() => { return 1; }); Type is delegate
                    // method symbol
                    var sinfo = model.GetSymbolInfo(expr);
                    list.Add((Symbol)sinfo.Symbol);
                }
                else if (tinfo.Type != null && tinfo.Type.TypeKind != TypeKind.Delegate)
                {
                    // bug#12625
                    // GetSymbolInfo -> .ctor (part of members)
                    list.Add((Symbol)tinfo.Type); // NamedType with empty name
                    foreach (var m in tinfo.Type.GetMembers())
                    {
                        list.Add((Symbol)m);
                    }
                }
            }
 private static void YieldReturnStatementExpressionCheck(YieldStatementSyntax yieldExpression, SemanticModel semanticModel, Action <Diagnostic> reportDiagnostic, string filePath, CancellationToken cancellationToken)
 {
     if (yieldExpression.Expression != null)
     {
         var returnConversionInfo = semanticModel.GetConversion(yieldExpression.Expression, cancellationToken);
         CheckTypeConversion(returnConversionInfo, reportDiagnostic, yieldExpression.Expression.GetLocation(), filePath);
     }
 }
        private static ITypeSymbol GetOuterCastType(ExpressionSyntax expression, SemanticModel semanticModel, out bool parentIsOrAsExpression)
        {
            expression             = expression.WalkUpParentheses();
            parentIsOrAsExpression = false;

            var parentNode = expression.Parent;

            if (parentNode == null)
            {
                return(null);
            }

            if (parentNode.IsKind(SyntaxKind.CastExpression))
            {
                var castExpression = (CastExpressionSyntax)parentNode;
                return(semanticModel.GetTypeInfo(castExpression).Type);
            }

            if (parentNode.IsKind(SyntaxKind.IsExpression) ||
                parentNode.IsKind(SyntaxKind.AsExpression))
            {
                parentIsOrAsExpression = true;
                return(null);
            }

            if (parentNode.IsKind(SyntaxKind.ArrayRankSpecifier))
            {
                return(semanticModel.Compilation.GetSpecialType(SpecialType.System_Int32));
            }

            if (parentNode.IsKind(SyntaxKind.SimpleMemberAccessExpression))
            {
                var memberAccess = (MemberAccessExpressionSyntax)parentNode;
                if (memberAccess.Expression == expression)
                {
                    var memberSymbol = semanticModel.GetSymbolInfo(memberAccess).Symbol;
                    if (memberSymbol != null)
                    {
                        return(memberSymbol.ContainingType);
                    }
                }
            }

            if (parentNode.IsKind(SyntaxKind.ConditionalExpression) &&
                ((ConditionalExpressionSyntax)parentNode).Condition == expression)
            {
                return(semanticModel.Compilation.GetSpecialType(SpecialType.System_Boolean));
            }

            if ((parentNode is PrefixUnaryExpressionSyntax || parentNode is PostfixUnaryExpressionSyntax) &&
                !semanticModel.GetConversion(expression).IsUserDefined)
            {
                var parentEpression = (ExpressionSyntax)parentNode;
                return(GetOuterCastType(parentEpression, semanticModel, out parentIsOrAsExpression) ?? semanticModel.GetTypeInfo(parentEpression).ConvertedType);
            }

            return(null);
        }
        private static ITypeSymbol GetOuterCastType(ExpressionSyntax expression, SemanticModel semanticModel, out bool parentIsOrAsExpression)
        {
            expression = expression.WalkUpParentheses();
            parentIsOrAsExpression = false;

            var parentNode = expression.Parent;
            if (parentNode == null)
            {
                return null;
            }

            if (parentNode.IsKind(SyntaxKind.CastExpression))
            {
                var castExpression = (CastExpressionSyntax)parentNode;
                return semanticModel.GetTypeInfo(castExpression).Type;
            }

            if (parentNode.IsKind(SyntaxKind.IsExpression) ||
                parentNode.IsKind(SyntaxKind.AsExpression))
            {
                parentIsOrAsExpression = true;
                return null;
            }

            if (parentNode.IsKind(SyntaxKind.ArrayRankSpecifier))
            {
                return semanticModel.Compilation.GetSpecialType(SpecialType.System_Int32);
            }

            if (parentNode.IsKind(SyntaxKind.SimpleMemberAccessExpression))
            {
                var memberAccess = (MemberAccessExpressionSyntax)parentNode;
                if (memberAccess.Expression == expression)
                {
                    var memberSymbol = semanticModel.GetSymbolInfo(memberAccess).Symbol;
                    if (memberSymbol != null)
                    {
                        return memberSymbol.ContainingType;
                    }
                }
            }

            if (parentNode.IsKind(SyntaxKind.ConditionalExpression) &&
                ((ConditionalExpressionSyntax)parentNode).Condition == expression)
            {
                return semanticModel.Compilation.GetSpecialType(SpecialType.System_Boolean);
            }

            if ((parentNode is PrefixUnaryExpressionSyntax || parentNode is PostfixUnaryExpressionSyntax) &&
                !semanticModel.GetConversion(expression).IsUserDefined)
            {
                var parentEpression = (ExpressionSyntax)parentNode;
                return GetOuterCastType(parentEpression, semanticModel, out parentIsOrAsExpression) ?? semanticModel.GetTypeInfo(parentEpression).ConvertedType;
            }

            return null;
        }
        private static void ArrowExpressionCheck(ArrowExpressionClauseSyntax syntax, SemanticModel semanticModel, bool isAssignmentToReadonly, Action <Diagnostic> reportDiagnostic, string filePath, CancellationToken cancellationToken)
        {
            var typeInfo       = semanticModel.GetTypeInfo(syntax.Expression, cancellationToken);
            var conversionInfo = semanticModel.GetConversion(syntax.Expression, cancellationToken);

            CheckTypeConversion(conversionInfo, reportDiagnostic, syntax.Expression.GetLocation(), filePath);
            CheckDelegateCreation(syntax, typeInfo, semanticModel, false, reportDiagnostic,
                                  syntax.Expression.GetLocation(), filePath, cancellationToken);
        }
        private static void AssertTypeInfo(SemanticModel model, TypeSyntax typeSyntax, ITypeSymbol expectedType)
        {
            TypeInfo typeInfo = model.GetTypeInfo(typeSyntax);

            Assert.Equal(expectedType, typeInfo.Type);
            Assert.Equal(expectedType, typeInfo.ConvertedType);
            Assert.Equal(typeInfo, ((CSharpSemanticModel)model).GetTypeInfo(typeSyntax));
            Assert.True(model.GetConversion(typeSyntax).IsIdentity);
        }
 private static void EqualsValueClauseCheck(EqualsValueClauseSyntax initializer, SemanticModel semanticModel, bool isAssignmentToReadonly, Action <Diagnostic> reportDiagnostic, string filePath, CancellationToken cancellationToken)
 {
     if (initializer.Value != null)
     {
         var typeInfo       = semanticModel.GetTypeInfo(initializer.Value, cancellationToken);
         var conversionInfo = semanticModel.GetConversion(initializer.Value, cancellationToken);
         CheckTypeConversion(conversionInfo, reportDiagnostic, initializer.Value.GetLocation(), filePath);
         CheckDelegateCreation(initializer.Value, typeInfo, semanticModel, isAssignmentToReadonly, reportDiagnostic, initializer.Value.GetLocation(), filePath, cancellationToken);
     }
 }
 private static void ArgumentSyntaxCheck(ArgumentSyntax argument, SemanticModel semanticModel, bool isAssignmentToReadonly, Action <Diagnostic> reportDiagnostic, string filePath, CancellationToken cancellationToken)
 {
     if (argument.Expression != null)
     {
         var argumentTypeInfo       = semanticModel.GetTypeInfo(argument.Expression, cancellationToken);
         var argumentConversionInfo = semanticModel.GetConversion(argument.Expression, cancellationToken);
         CheckTypeConversion(argumentConversionInfo, reportDiagnostic, argument.Expression.GetLocation(), filePath);
         CheckDelegateCreation(argument.Expression, argumentTypeInfo, semanticModel, isAssignmentToReadonly, reportDiagnostic, argument.Expression.GetLocation(), filePath, cancellationToken);
     }
 }
Esempio n. 15
0
        private static void ReturnStatementExpressionCheck(DiagnosticDescriptor typeConversionRule, SyntaxNode node, SemanticModel semanticModel, Action <Diagnostic> reportDiagnostic, string filePath, CancellationToken cancellationToken)
        {
            var returnStatementExpression = node as ReturnStatementSyntax;

            if (returnStatementExpression.Expression != null)
            {
                var returnConversionInfo = semanticModel.GetConversion(returnStatementExpression.Expression, cancellationToken);
                CheckTypeConversion(typeConversionRule, returnConversionInfo, reportDiagnostic, returnStatementExpression.Expression.GetLocation(), filePath);
            }
        }
Esempio n. 16
0
        private static void ArrowExpressionCheck(EnabledRules rules, SyntaxNode node, SemanticModel semanticModel, bool isAssignmentToReadonly, Action <Diagnostic> reportDiagnostic, string filePath, CancellationToken cancellationToken)
        {
            var syntax = node as ArrowExpressionClauseSyntax;

            var typeInfo       = semanticModel.GetTypeInfo(syntax.Expression, cancellationToken);
            var conversionInfo = semanticModel.GetConversion(syntax.Expression, cancellationToken);

            CheckTypeConversion(rules.Get(AllocationRules.ValueTypeToReferenceTypeConversionRule.Id), conversionInfo, reportDiagnostic, syntax.Expression.GetLocation(), filePath);
            CheckDelegateCreation(rules, syntax, typeInfo, semanticModel, false, reportDiagnostic,
                                  syntax.Expression.GetLocation(), filePath, cancellationToken);
        }
Esempio n. 17
0
        private static void EqualsValueClauseCheck(EnabledRules rules, SyntaxNode node, SemanticModel semanticModel, bool isAssignmentToReadonly, Action <Diagnostic> reportDiagnostic, string filePath, CancellationToken cancellationToken)
        {
            var initializer = node as EqualsValueClauseSyntax;

            if (initializer.Value != null)
            {
                var typeInfo       = semanticModel.GetTypeInfo(initializer.Value, cancellationToken);
                var conversionInfo = semanticModel.GetConversion(initializer.Value, cancellationToken);
                CheckTypeConversion(rules.Get(AllocationRules.ValueTypeToReferenceTypeConversionRule.Id), conversionInfo, reportDiagnostic, initializer.Value.GetLocation(), filePath);
                CheckDelegateCreation(rules, initializer.Value, typeInfo, semanticModel, isAssignmentToReadonly, reportDiagnostic, initializer.Value.GetLocation(), filePath, cancellationToken);
            }
        }
            private static ITypeSymbol?GetRegularExpressionType(
                SemanticModel semanticModel,
                ExpressionSyntax node
                )
            {
                // regular case. always use ConvertedType to get implicit conversion right.
                var expression = node.GetUnparenthesizedExpression();

                var info = semanticModel.GetTypeInfo(expression);
                var conv = semanticModel.GetConversion(expression);

                if (info.ConvertedType == null || info.ConvertedType.IsErrorType())
                {
                    // there is no implicit conversion involved. no need to go further
                    return(info.GetTypeWithAnnotatedNullability());
                }

                // always use converted type if method group
                if (
                    (
                        !node.IsKind(SyntaxKind.ObjectCreationExpression) &&
                        semanticModel.GetMemberGroup(expression).Length > 0
                    ) ||
                    IsCoClassImplicitConversion(
                        info,
                        conv,
                        semanticModel.Compilation.CoClassType()
                        )
                    )
                {
                    return(info.GetConvertedTypeWithAnnotatedNullability());
                }

                // check implicit conversion
                if (conv.IsImplicit && (conv.IsConstantExpression || conv.IsEnumeration))
                {
                    return(info.GetConvertedTypeWithAnnotatedNullability());
                }

                // use FormattableString if conversion between String and FormattableString
                if (
                    info.Type?.SpecialType == SpecialType.System_String &&
                    info.ConvertedType?.IsFormattableStringOrIFormattable() == true
                    )
                {
                    return(info.GetConvertedTypeWithAnnotatedNullability());
                }

                // always try to use type that is more specific than object type if possible.
                return(!info.Type.IsObjectType()
                  ? info.GetTypeWithAnnotatedNullability()
                  : info.GetConvertedTypeWithAnnotatedNullability());
            }
Esempio n. 19
0
        /// <summary>
        /// Analyzes the assignment expression and rejects a given declaration if it is unsuitable for implicit typing.
        /// </summary>
        /// <returns>
        /// false, if implicit typing cannot be used.
        /// true, otherwise.
        /// </returns>
        protected override bool AssignmentSupportsStylePreference(
            SyntaxToken identifier,
            TypeSyntax typeName,
            ExpressionSyntax initializer,
            SemanticModel semanticModel,
            OptionSet optionSet,
            CancellationToken cancellationToken)
        {
            var expression = GetInitializerExpression(initializer);

            // var cannot be assigned null
            if (expression.IsKind(SyntaxKind.NullLiteralExpression))
            {
                return(false);
            }

            // cannot use implicit typing on method group, anonymous function or on dynamic
            var declaredType = semanticModel.GetTypeInfo(typeName, cancellationToken).Type;

            if (declaredType != null &&
                (declaredType.TypeKind == TypeKind.Delegate || declaredType.TypeKind == TypeKind.Dynamic))
            {
                return(false);
            }

            // variables declared using var cannot be used further in the same initialization expression.
            if (initializer.DescendantNodesAndSelf()
                .Where(n => (n as IdentifierNameSyntax)?.Identifier.ValueText.Equals(identifier.ValueText) == true)
                .Any(n => semanticModel.GetSymbolInfo(n, cancellationToken).Symbol?.IsKind(SymbolKind.Local) == true))
            {
                return(false);
            }

            // Get the conversion that occurred between the expression's type and type implied by the expression's context
            // and filter out implicit conversions. If an implicit conversion (other than identity) exists
            // and if we're replacing the declaration with 'var' we'd be changing the semantics by inferring type of
            // initializer expression and thereby losing the conversion.
            var conversion = semanticModel.GetConversion(expression, cancellationToken);

            if (conversion.Exists && conversion.IsImplicit && !conversion.IsIdentity)
            {
                return(false);
            }

            // final check to compare type information on both sides of assignment.
            var initializerType = semanticModel.GetTypeInfo(expression, cancellationToken).Type;

            return(declaredType.Equals(initializerType));
        }
Esempio n. 20
0
        private static void ArgumentSyntaxCheck(EnabledRules rules, SyntaxNode node, SemanticModel semanticModel, bool isAssignmentToReadonly, Action <Diagnostic> reportDiagnostic, string filePath, CancellationToken cancellationToken)
        {
            var argument = node as ArgumentSyntax;

            if (argument.Expression != null)
            {
                if (rules.IsEnabled(AllocationRules.ValueTypeToReferenceTypeConversionRule.Id))
                {
                    var argumentTypeInfo       = semanticModel.GetTypeInfo(argument.Expression, cancellationToken);
                    var argumentConversionInfo = semanticModel.GetConversion(argument.Expression, cancellationToken);
                    CheckTypeConversion(rules.Get(AllocationRules.ValueTypeToReferenceTypeConversionRule.Id), argumentConversionInfo, reportDiagnostic, argument.Expression.GetLocation(), filePath);
                    CheckDelegateCreation(rules, argument.Expression, argumentTypeInfo, semanticModel, isAssignmentToReadonly, reportDiagnostic, argument.Expression.GetLocation(), filePath, cancellationToken);
                }
            }
        }
Esempio n. 21
0
        protected static void VerifyModelNotSupported(
            SemanticModel model,
            SingleVariableDesignationSyntax designation,
            params IdentifierNameSyntax[] references
            )
        {
            Assert.Null(model.GetDeclaredSymbol(designation));
            var identifierText = designation.Identifier.ValueText;

            Assert.False(model.LookupSymbols(designation.SpanStart, name: identifierText).Any());

            Assert.False(model.LookupNames(designation.SpanStart).Contains(identifierText));
            Assert.Null(model.GetSymbolInfo(designation).Symbol);
            Assert.Null(model.GetTypeInfo(designation).Type);
            Assert.Null(model.GetDeclaredSymbol(designation));

            var symbol = (ISymbol)model.GetDeclaredSymbol(designation);

            if (designation.Parent is DeclarationPatternSyntax decl)
            {
                Assert.Null(model.GetSymbolInfo(decl.Type).Symbol);

                TypeInfo typeInfo = model.GetTypeInfo(decl.Type);

                if ((object)symbol != null)
                {
                    var type = symbol.GetTypeOrReturnType();
                    Assert.Equal(type, typeInfo.Type);
                    Assert.Equal(type, typeInfo.ConvertedType);
                }
                else
                {
                    Assert.Equal(SymbolKind.ErrorType, typeInfo.Type.Kind);
                    Assert.Equal(SymbolKind.ErrorType, typeInfo.ConvertedType.Kind);
                }

                Assert.Equal(typeInfo, ((CSharpSemanticModel)model).GetTypeInfo(decl.Type));
                Assert.True(model.GetConversion(decl.Type).IsIdentity);
            }
            else if (designation.Parent is VarPatternSyntax varp)
            {
                // Do we want to add any tests for the var pattern?
            }

            VerifyModelNotSupported(model, references);
        }
Esempio n. 22
0
        public static MyInfo GetTypeInfo2(this SemanticModel model, ExpressionSyntax expression)
        {
            var typeInfo = ModelExtensions.GetTypeInfo(model, expression);

            if (typeInfo.ConvertedType == null)
            {
                Debug.Write("");
            }
            var g = new MyInfo
            {
                Conversion1 = typeInfo.ConvertedType != null
                ? (Conversion?)model.ClassifyConversion(expression, typeInfo.ConvertedType)
                : null,
                Conversion2 = model.GetConversion(expression),
                TypeInfo    = typeInfo
            };

            return(g);
        }
Esempio n. 23
0
            private void GetAnonymousExprSymbols(ExpressionSyntax expr, SemanticModel model, List<ISymbol> list)
            {
                var kind = expr.Kind();
                if (kind != SyntaxKind.AnonymousObjectCreationExpression &&
                    kind != SyntaxKind.AnonymousMethodExpression &&
                    kind != SyntaxKind.ParenthesizedLambdaExpression &&
                    kind != SyntaxKind.SimpleLambdaExpression)
                {
                    return;
                }

                var tinfo = model.GetTypeInfo(expr);
                var conv = model.GetConversion(expr);
                if (conv.IsAnonymousFunction)
                {
                    // Lambda has no Type unless in part of case expr (C# specific)
                    // var f = (Func<int>)(() => { return 1; }); Type is delegate
                    // method symbol
                    var sinfo = model.GetSymbolInfo(expr);
                    list.Add((Symbol)sinfo.Symbol);
                }
                else if (tinfo.Type != null && tinfo.Type.TypeKind != TypeKind.Delegate)
                {
                    // bug#12625
                    // GetSymbolInfo -> .ctor (part of members)
                    list.Add((Symbol)tinfo.Type); // NamedType with empty name
                    foreach (var m in tinfo.Type.GetMembers())
                    {
                        list.Add((Symbol)m);
                    }
                }
            }
 protected override CommonConversion GetConversion(SemanticModel semanticModel, ExpressionSyntax node, CancellationToken cancellationToken)
 => semanticModel.GetConversion(node, cancellationToken).ToCommonConversion();
            private static ITypeSymbol GetRegularExpressionType(SemanticModel semanticModel, SyntaxNode node)
            {
                // regular case. always use ConvertedType to get implicit conversion right.
                var expression = node.GetUnparenthesizedExpression();

                var info = semanticModel.GetTypeInfo(expression);
                var conv = semanticModel.GetConversion(expression);

                if (info.ConvertedType == null || info.ConvertedType.IsErrorType())
                {
                    // there is no implicit conversion involved. no need to go further
                    return info.Type;
                }

                // always use converted type if method group
                if ((!node.IsKind(SyntaxKind.ObjectCreationExpression) && semanticModel.GetMemberGroup(expression).Length > 0) ||
                    IsCoClassImplicitConversion(info, conv, semanticModel.Compilation.CoClassType()))
                {
                    return info.ConvertedType;
                }

                // check implicit conversion
                if (conv.IsImplicit && (conv.IsConstantExpression || conv.IsEnumeration))
                {
                    return info.ConvertedType;
                }

                // always try to use type that is more specific than object type if possible.
                return !info.Type.IsObjectType() ? info.Type : info.ConvertedType;
            }
Esempio n. 26
0
        protected override bool IsTargetTyped(SemanticModel semanticModel, ConditionalExpressionSyntax conditional, CancellationToken cancellationToken)
        {
            var conversion = semanticModel.GetConversion(conditional, cancellationToken);

            return(conversion.IsConditionalExpression);
        }
Esempio n. 27
0
 protected override bool ConversionsAreCompatible(SemanticModel originalModel, ExpressionSyntax originalExpression, SemanticModel newModel, ExpressionSyntax newExpression)
 {
     return(ConversionsAreCompatible(originalModel.GetConversion(originalExpression), newModel.GetConversion(newExpression)));
 }
Esempio n. 28
0
        /// <summary>
        /// 
        /// </summary>
        /// <param name="binding"></param>
        /// <param name="expr"></param>
        /// <param name="ept1">expr -> TypeInParent</param>
        /// <param name="ept2">Type(expr) -> TypeInParent</param>
        private void ConversionTestHelper(SemanticModel semanticModel, ExpressionSyntax expr, ConversionKind ept1, ConversionKind ept2)
        {
            var info = semanticModel.GetTypeInfo(expr);
            Assert.NotNull(info);
            Assert.NotNull(info.ConvertedType);
            var conv = semanticModel.GetConversion(expr);

            // NOT expect NoConversion
            Conversion act1 = semanticModel.ClassifyConversion(expr, (TypeSymbol)info.ConvertedType);
            Assert.Equal(ept1, act1.Kind);
            ValidateConversion(act1, ept1);
            ValidateConversion(act1, conv.Kind);

            if (ept2 == ConversionKind.NoConversion)
            {
                Assert.Null(info.Type);
            }
            else
            {
                Assert.NotNull(info.Type);
                var act2 = semanticModel.Compilation.ClassifyConversion(info.Type, info.ConvertedType);
                Assert.Equal(ept2, act2.Kind);
                ValidateConversion(act2, ept2);
            }
        }
Esempio n. 29
0
        public override SyntaxNode VisitInterpolatedStringExpression(InterpolatedStringExpressionSyntax node)
        {
            var isInterpolatedString = semanticModel.GetConversion(node).IsInterpolatedString;

            node = (InterpolatedStringExpressionSyntax)base.VisitInterpolatedStringExpression(node);
            string methodNameToCall;
            string classNameToCall;

            if (isInterpolatedString)
            {
                classNameToCall  = "System.Runtime.CompilerServices.FormattableStringFactory";
                methodNameToCall = "Create";
            }
            else
            {
                classNameToCall  = "string";
                methodNameToCall = "Format";
            }

            string str         = "";
            int    placeholder = 0;
            var    expressions = new List <ExpressionSyntax>();

            foreach (var content in node.Contents)
            {
                var interpolatedStringTextSyntax = content as InterpolatedStringTextSyntax;
                if (interpolatedStringTextSyntax != null)
                {
                    str += interpolatedStringTextSyntax.TextToken.Text;
                }
                else if (content is InterpolationSyntax)
                {
                    var interpolation = (InterpolationSyntax)content;

                    str += "{" + placeholder.ToString(CultureInfo.InvariantCulture);

                    if (interpolation.AlignmentClause != null)
                    {
                        var value = semanticModel.GetConstantValue(interpolation.AlignmentClause.Value).Value;

                        if (value == null)
                        {
                            logger.Error("Non-constant alignment");
                            return(null);
                        }

                        str += "," + Convert.ToInt32(value).ToString(CultureInfo.InvariantCulture);
                    }

                    if (interpolation.FormatClause != null)
                    {
                        str += ":" + interpolation.FormatClause.FormatStringToken.Text;
                    }

                    str += "}";
                    placeholder++;
                    expressions.Add(interpolation.Expression);
                }
                else
                {
                    logger.Error("Unknown content in interpolated string: " + content);
                    return(null);
                }
            }

            expressions.Insert(0, SyntaxFactory.LiteralExpression(SyntaxKind.StringLiteralExpression, SyntaxFactory.Literal(str)));

            var methodIdentifier = SyntaxFactory.IdentifierName(classNameToCall + "." + methodNameToCall);
            var invocation       = SyntaxFactory.InvocationExpression(methodIdentifier, SyntaxFactory.ArgumentList(SyntaxFactory.SeparatedList(expressions.Select(SyntaxFactory.Argument))));

            return(invocation);
        }