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); } }
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; } }
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; } }
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); }
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); } }
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); } }
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); }
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()); }
/// <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)); }
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); } } }
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); }
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); }
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; }
protected override bool IsTargetTyped(SemanticModel semanticModel, ConditionalExpressionSyntax conditional, CancellationToken cancellationToken) { var conversion = semanticModel.GetConversion(conditional, cancellationToken); return(conversion.IsConditionalExpression); }
protected override bool ConversionsAreCompatible(SemanticModel originalModel, ExpressionSyntax originalExpression, SemanticModel newModel, ExpressionSyntax newExpression) { return(ConversionsAreCompatible(originalModel.GetConversion(originalExpression), newModel.GetConversion(newExpression))); }
/// <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); } }
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); }