示例#1
0
            /// <summary>
            /// Collect all the available cast pairs, format is (target argument expression, potential conversion type)
            /// </summary>
            /// <param name="targetArgument"> The argument that need to be cast</param>
            /// <param name="argumentList"> The argument list that contains the target argument to be cast </param>
            /// <param name="invocationNode"> The invocation node that is the parent of "argumentList"</param>
            /// <returns>
            /// Return all the available cast pairs, format is (target argument expression, potential conversion type)
            /// </returns>
            public ImmutableArray <(TExpressionSyntax, ITypeSymbol)> GetPotentialConversionTypes(
                SemanticModel semanticModel,
                SyntaxNode root,
                TArgumentSyntax targetArgument,
                TArgumentListSyntax argumentList,
                TInvocationSyntax invocationNode,
                CancellationToken cancellationToken
                )
            {
                // Implicit downcast appears on the argument of invocation node,
                // get all candidate functions and extract potential conversion types
                var symbolInfo = semanticModel.GetSymbolInfo(invocationNode, cancellationToken);

                using var _ = ArrayBuilder <ISymbol> .GetInstance(out var candidateSymbols);

                if (symbolInfo.Symbol != null) // BC42016: the only candidate symbol is symbolInfo.Symbol
                {
                    candidateSymbols.Add(symbolInfo.Symbol);
                }
                else
                {
                    candidateSymbols.AddRange(symbolInfo.CandidateSymbols);
                }

                using var __ = ArrayBuilder <(TExpressionSyntax, ITypeSymbol)> .GetInstance(
                          out var mutablePotentialConversionTypes
                          );

                foreach (var candidateSymbol in candidateSymbols.OfType <IMethodSymbol>())
                {
                    if (
                        CanArgumentTypesBeConvertedToParameterTypes(
                            semanticModel,
                            root,
                            argumentList,
                            candidateSymbol.Parameters,
                            targetArgument,
                            cancellationToken,
                            out var targetArgumentConversionType
                            ) &&
                        GetExpressionOfArgument(targetArgument)
                        is TExpressionSyntax argumentExpression
                        )
                    {
                        mutablePotentialConversionTypes.Add(
                            (argumentExpression, targetArgumentConversionType)
                            );
                    }
                }

                // Sort the potential conversion types by inheritance distance, so that
                // operations are in order and user can choose least specific types(more accurate)
                mutablePotentialConversionTypes.Sort(
                    new InheritanceDistanceComparer <TExpressionSyntax>(semanticModel)
                    );

                return(mutablePotentialConversionTypes.ToImmutable());
            }
示例#2
0
            public bool CanArgumentTypesBeConvertedToParameterTypes(
                SemanticModel semanticModel,
                SyntaxNode root,
                TArgumentListSyntax argumentList,
                ImmutableArray <IParameterSymbol> parameters,
                TArgumentSyntax targetArgument,
                CancellationToken cancellationToken,
                [NotNullWhen(true)] out ITypeSymbol?targetArgumentConversionType)
            {
                targetArgumentConversionType = null;

                // No conversion happens under this case
                if (parameters.Length == 0)
                {
                    return(false);
                }

                var syntaxFacts = _provider.SyntaxFacts;

                var arguments = GetArgumentsOfArgumentList(argumentList);

                using var _ = ArrayBuilder <TArgumentSyntax> .GetInstance(out var newArguments);

                for (var i = 0; i < arguments.Count; i++)
                {
                    // Parameter index cannot out of its range, #arguments is larger than #parameter only if
                    // the last parameter with keyword params
                    var parameterIndex = Math.Min(i, parameters.Length - 1);

                    // If the argument has a name, get the corresponding parameter index
                    if (syntaxFacts.GetNameForArgument(arguments[i]) is string name &&
                        name != string.Empty &&
                        !FindCorrespondingParameterByName(name, parameters, ref parameterIndex))
                    {
                        return(false);
                    }

                    // The argument is either in order with parameters, or have a matched name with parameters.
                    var argumentExpression = GetExpressionOfArgument(arguments[i]);
                    if (argumentExpression == null)
                    {
                        // argumentExpression is null when it is an omitted argument in VB .NET
                        newArguments.Add(arguments[i]);
                        continue;
                    }

                    var parameterType = parameters[parameterIndex].Type;
                    if (parameters[parameterIndex].IsParams &&
                        parameterType is IArrayTypeSymbol paramsType &&
                        _provider.ClassifyConversion(semanticModel, argumentExpression, paramsType.ElementType).Exists)
                    {
                        newArguments.Add(GenerateNewArgument(arguments[i], paramsType.ElementType));
                        if (arguments[i].Equals(targetArgument))
                        {
                            targetArgumentConversionType = paramsType.ElementType;
                        }
                    }
示例#3
0
 protected abstract SymbolInfo GetSpeculativeSymbolInfo(
     SemanticModel semanticModel,
     TArgumentListSyntax newArgumentList
     );
示例#4
0
 protected abstract SeparatedSyntaxList <TArgumentSyntax> GetArgumentsOfArgumentList(
     TArgumentListSyntax argumentList
     );
示例#5
0
 protected abstract TArgumentListSyntax GenerateNewArgumentList(
     TArgumentListSyntax oldArgumentList,
     ArrayBuilder <TArgumentSyntax> newArguments
     );