private ITypeSymbol TryGetArgsArgumentType( SemanticModel semanticModel, SeparatedSyntaxList <SyntaxNode> arguments, ImmutableArray <IParameterSymbol> parameters, ISyntaxFactsService syntaxFacts) { var argsArgument = TryGetArgument(semanticModel, NameOfArgsParameter, arguments, parameters); if (argsArgument == null) { return(null); } var expression = syntaxFacts.GetExpressionOfArgument(argsArgument); return(semanticModel.GetTypeInfo(expression).Type); }
private async Task <Document> CreateInterpolatedString( TInvocationExpressionSyntax invocation, Document document, ISyntaxFactsService syntaxFactsService, CancellationToken cancellationToken) { var semanticModel = await document.GetSemanticModelAsync(cancellationToken).ConfigureAwait(false); var arguments = syntaxFactsService.GetArgumentsOfInvocationExpression(invocation); var literalExpression = syntaxFactsService.GetExpressionOfArgument(arguments[0]) as TLiteralExpressionSyntax; var text = literalExpression.GetFirstToken().ToString(); var syntaxGenerator = document.Project.LanguageServices.GetService <SyntaxGenerator>(); var expandedArguments = GetExpandedArguments(semanticModel, arguments, syntaxGenerator, syntaxFactsService); var interpolatedString = GetInterpolatedString(text); var newInterpolatedString = VisitArguments(expandedArguments, interpolatedString, syntaxFactsService); var root = await document.GetSyntaxRootAsync(cancellationToken).ConfigureAwait(false); var newRoot = root.ReplaceNode(invocation, newInterpolatedString.WithTriviaFrom(invocation)); return(document.WithSyntaxRoot(newRoot)); }
static bool IsValidPlaceholderToInterpolatedString( TInvocationExpressionSyntax invocation, ISyntaxFactsService syntaxFactsService, SemanticModel semanticModel, ImmutableArray <IMethodSymbol> formatMethods, AbstractConvertPlaceholderToInterpolatedStringRefactoringProvider < TInvocationExpressionSyntax, TExpressionSyntax, TArgumentSyntax, TLiteralExpressionSyntax, TArgumentListExpressionSyntax > thisInstance, CancellationToken cancellationToken ) { var arguments = syntaxFactsService.GetArgumentsOfInvocationExpression(invocation); if (arguments.Count >= 2) { if ( syntaxFactsService.GetExpressionOfArgument( GetFormatArgument(arguments, syntaxFactsService) ) is TLiteralExpressionSyntax firstArgumentExpression && syntaxFactsService.IsStringLiteral( firstArgumentExpression.GetFirstToken() ) ) { var invocationSymbol = semanticModel.GetSymbolInfo(invocation, cancellationToken).Symbol; if (formatMethods.Contains(invocationSymbol)) { return(true); } } } return(false); }
protected SyntaxNode?TryGetFormatStringLiteralExpressionSyntax( SeparatedSyntaxList <SyntaxNode> arguments, ImmutableArray <IParameterSymbol> parameters, ISyntaxFactsService syntaxFacts) { var formatArgumentSyntax = TryGetArgument( NameOfFormatStringParameter, arguments, parameters); if (formatArgumentSyntax == null) { return(null); } if (!syntaxFacts.IsStringLiteralExpression(syntaxFacts.GetExpressionOfArgument(formatArgumentSyntax))) { return(null); } return(GetArgumentExpression(formatArgumentSyntax)); }
private static TArgumentSyntax DetermineFirstArgumentToAdd( SemanticModel semanticModel, ISyntaxFactsService syntaxFacts, StringComparer comparer, IMethodSymbol method, SeparatedSyntaxList <TArgumentSyntax> arguments) { var compilation = semanticModel.Compilation; var methodParameterNames = new HashSet <string>(comparer); methodParameterNames.AddRange(method.Parameters.Select(p => p.Name)); for (int i = 0, n = arguments.Count; i < n; i++) { var argument = arguments[i]; var argumentName = syntaxFacts.GetNameForArgument(argument); if (!string.IsNullOrWhiteSpace(argumentName)) { // If the user provided an argument-name and we don't have any parameters that // match, then this is the argument we want to add a parameter for. if (!methodParameterNames.Contains(argumentName)) { return(argument); } } else { // Positional argument. If the position is beyond what the method supports, // then this definitely is an argument we could add. if (i >= method.Parameters.Length) { if (method.Parameters.LastOrDefault()?.IsParams == true) { // Last parameter is a params. We can't place any parameters past it. return(null); } return(argument); } // Now check the type of the argument versus the type of the parameter. If they // don't match, then this is the argument we should make the parameter for. var expressionOfArgument = syntaxFacts.GetExpressionOfArgument(argument); if (expressionOfArgument is null) { return(null); } var argumentTypeInfo = semanticModel.GetTypeInfo(expressionOfArgument); var isNullLiteral = syntaxFacts.IsNullLiteralExpression(expressionOfArgument); var isDefaultLiteral = syntaxFacts.IsDefaultLiteralExpression(expressionOfArgument); if (argumentTypeInfo.Type == null && argumentTypeInfo.ConvertedType == null) { // Didn't know the type of the argument. We shouldn't assume it doesn't // match a parameter. However, if the user wrote 'null' and it didn't // match anything, then this is the problem argument. if (!isNullLiteral && !isDefaultLiteral) { continue; } } var parameter = method.Parameters[i]; if (!TypeInfoMatchesType( compilation, argumentTypeInfo, parameter.Type, isNullLiteral, isDefaultLiteral)) { if (TypeInfoMatchesWithParamsExpansion( compilation, argumentTypeInfo, parameter, isNullLiteral, isDefaultLiteral)) { // The argument matched if we expanded out the params-parameter. // As the params-parameter has to be last, there's nothing else to // do here. return(null); } return(argument); } } } return(null); }
private bool MatchesPattern(ISyntaxFactsService syntaxFacts, SyntaxNode node1, SyntaxNode node2) => syntaxFacts.IsNullLiteralExpression(syntaxFacts.GetExpressionOfArgument(node1)) && !syntaxFacts.IsNullLiteralExpression(syntaxFacts.GetExpressionOfArgument(node2));