internal static bool TryGetStringValue(this ArgumentSyntax argument, SemanticModel semanticModel, CancellationToken cancellationToken, out string result) { result = null; if (argument?.Expression == null || semanticModel == null) { return(false); } if (argument.Expression.IsKind(SyntaxKind.NullLiteralExpression)) { return(true); } if (argument.Expression.IsKind(SyntaxKind.StringLiteralExpression) || argument.Expression.IsNameOf()) { var cv = semanticModel.GetConstantValueSafe(argument.Expression, cancellationToken); if (cv.HasValue && cv.Value is string) { result = (string)cv.Value; return(true); } } var symbolInfo = semanticModel.GetSymbolSafe(argument.Expression, cancellationToken); if (symbolInfo?.ContainingType?.Name == "String" && symbolInfo.Name == "Empty") { result = string.Empty; return(true); } return(false); }
/// <summary> /// Try getting the GetConstantValue for the node. /// Gets the semantic model for the tree if the node is not in the tree corresponding to <paramref name="semanticModel"/>. /// </summary> /// <typeparam name="T">The symbol.</typeparam> /// <param name="semanticModel">The <see cref="SemanticModel"/>.</param> /// <param name="node">The <see cref="SyntaxNode"/>.</param> /// <param name="cancellationToken">The <see cref="CancellationToken"/>.</param> /// <param name="value">The symbol if found.</param> /// <returns>True if a symbol was found.</returns> public static bool TryGetConstantValue <T>(this SemanticModel semanticModel, SyntaxNode node, CancellationToken cancellationToken, out T value) { if (semanticModel.GetConstantValueSafe(node, cancellationToken) is Optional <object> optional && optional.HasValue) { if (optional.Value is T temp) { value = temp; return(true); } if (optional.Value == null) { value = default(T); return(default(T) == null); } // We can't use GetTypeInfo() here as it brings in System.Reflection.Extensions that does not work in VS. if (default(T) is Enum && Enum.GetUnderlyingType(typeof(T)) == optional.Value.GetType()) { // ReSharper disable once PossibleInvalidCastException value = (T)optional.Value; return(true); } } value = default(T); return(false); }
internal static bool TryGetStringValue(this ArgumentSyntax argument, SemanticModel semanticModel, CancellationToken cancellationToken, out string result) { return(TryGetStringValue(argument?.Expression, out result)); bool TryGetStringValue(ExpressionSyntax expression, out string text) { text = null; if (expression == null) { return(false); } if (expression is LiteralExpressionSyntax literal) { switch (literal.Kind()) { case SyntaxKind.NullLiteralExpression: return(true); case SyntaxKind.StringLiteralExpression: text = literal.Token.ValueText; return(true); } } if (expression.IsNameOf()) { var cv = semanticModel.GetConstantValueSafe(expression, cancellationToken); if (cv.HasValue && cv.Value is string) { text = (string)cv.Value; return(true); } } if (expression is MemberAccessExpressionSyntax memberAccess && memberAccess.Name.Identifier.ValueText == "Empty" && ((memberAccess.Expression is PredefinedTypeSyntax predefinedType && predefinedType.Keyword.Text == "string") || (memberAccess.Expression is IdentifierNameSyntax identifierName && identifierName.Identifier.ValueText == "String"))) { if (semanticModel.GetSymbolSafe(expression, cancellationToken) is IFieldSymbol field && field == KnownSymbol.String.Empty) { text = string.Empty; return(true); } } if (expression is CastExpressionSyntax castExpression) { return(TryGetStringValue(castExpression.Expression, out text)); } return(false); } }
/// <summary> /// Try getting the GetConstantValue for the node. /// Gets the semantic model for the tree if the node is not in the tree corresponding to <paramref name="semanticModel"/>. /// </summary> /// <typeparam name="T">The symbol.</typeparam> /// <param name="semanticModel">The <see cref="SemanticModel"/>.</param> /// <param name="node">The <see cref="SyntaxNode"/>.</param> /// <param name="cancellationToken">The <see cref="CancellationToken"/>.</param> /// <param name="value">The symbol if found.</param> /// <returns>True if a symbol was found.</returns> public static bool TryGetConstantValue <T>(this SemanticModel semanticModel, SyntaxNode node, CancellationToken cancellationToken, [MaybeNullWhen(false)] out T value) { if (semanticModel is null) { throw new ArgumentNullException(nameof(semanticModel)); } if (node is null) { throw new ArgumentNullException(nameof(node)); } if (semanticModel.GetConstantValueSafe(node, cancellationToken) is Optional <object> optional && optional.HasValue) { if (optional.Value is T temp) { value = temp; return(true); } if (optional.Value is null) { value = default !;
/// <summary> /// Try getting the GetConstantValue for the node. /// Gets the semantic model for the tree if the node is not in the tree corresponding to <paramref name="semanticModel"/>. /// </summary> /// <typeparam name="T">The symbol.</typeparam> /// <param name="semanticModel">The <see cref="SemanticModel"/>.</param> /// <param name="node">The <see cref="SyntaxNode"/>.</param> /// <param name="cancellationToken">The <see cref="CancellationToken"/>.</param> /// <param name="value">The symbol if found.</param> /// <returns>True if a symbol was found.</returns> public static bool TryGetConstantValue <T>(this SemanticModel semanticModel, SyntaxNode node, CancellationToken cancellationToken, [MaybeNullWhen(false)] out T value) { if (semanticModel is null) { throw new ArgumentNullException(nameof(semanticModel)); } if (node is null) { throw new ArgumentNullException(nameof(node)); } if (semanticModel.GetConstantValueSafe(node, cancellationToken) is { HasValue : true } optional) { if (optional.Value is T temp) { value = temp; return(true); } // ReSharper disable ConditionIsAlwaysTrueOrFalse if (optional.Value is null) { value = default !;
internal static bool TryGetArgumentStringValue(AttributeSyntax attribute, int argumentIndex, SemanticModel semanticModel, CancellationToken cancellationToken, out AttributeArgumentSyntax arg, out string result) { arg = null; result = null; if (attribute?.ArgumentList?.Arguments.TryGetAtIndex(argumentIndex, out arg) != true) { return(false); } if (!arg.Expression.IsKind(SyntaxKind.StringLiteralExpression)) { return(false); } var constantValue = semanticModel.GetConstantValueSafe(arg.Expression, cancellationToken); if (!constantValue.HasValue) { return(false); } result = (string)constantValue.Value; return(true); }