示例#1
0
            public static UseAsyncAwaitRewriter Create(IMethodSymbol methodSymbol)
            {
                ITypeSymbol returnType = methodSymbol.ReturnType.OriginalDefinition;

                var keepReturnStatement = false;

                if (returnType.EqualsOrInheritsFrom(MetadataNames.System_Threading_Tasks_ValueTask_T) ||
                    returnType.EqualsOrInheritsFrom(MetadataNames.System_Threading_Tasks_Task_T))
                {
                    keepReturnStatement = true;
                }

                return(new UseAsyncAwaitRewriter(keepReturnStatement: keepReturnStatement));
            }
示例#2
0
        public static bool IsSyntaxTypeSymbol(ITypeSymbol typeSymbol)
        {
            if (typeSymbol.Equals(SyntaxTokenListSymbol))
            {
                return(true);
            }

            if (typeSymbol.Equals(SyntaxTokenSymbol))
            {
                return(true);
            }

            ITypeSymbol originalDefinition = typeSymbol.OriginalDefinition;

            if (originalDefinition.Equals(SyntaxListSymbol))
            {
                return(true);
            }

            if (originalDefinition.Equals(SeparatedSyntaxListSymbol))
            {
                return(true);
            }

            if (typeSymbol.EqualsOrInheritsFrom(SyntaxNodeSymbol))
            {
                return(true);
            }

            return(false);
        }
        private static bool CanRefactor(
            TypeSyntax type,
            ExpressionSyntax expression,
            ExpressionSyntax accessedExpression,
            SemanticModel semanticModel,
            CancellationToken cancellationToken)
        {
            ITypeSymbol typeSymbol = semanticModel.GetTypeSymbol(type, cancellationToken);

            if (typeSymbol?.IsErrorType() == false)
            {
                ITypeSymbol expressionTypeSymbol = semanticModel.GetTypeSymbol(expression, cancellationToken);

                if (expressionTypeSymbol?.IsErrorType() == false &&
                    !expressionTypeSymbol.IsInterface())
                {
                    bool isInterface = typeSymbol.IsInterface();

                    if (isInterface ||
                        typeSymbol.EqualsOrInheritsFrom(expressionTypeSymbol, includeInterfaces: true))
                    {
                        ISymbol accessedSymbol = semanticModel.GetSymbol(accessedExpression, cancellationToken);

                        INamedTypeSymbol containingType = accessedSymbol?.ContainingType;

                        if (containingType != null)
                        {
                            if (isInterface)
                            {
                                ISymbol implementation = expressionTypeSymbol.FindImplementationForInterfaceMember(accessedSymbol);

                                switch (implementation?.Kind)
                                {
                                case SymbolKind.Property:
                                    return(!((IPropertySymbol)implementation).ExplicitInterfaceImplementations.Any(f => f.Equals(accessedSymbol)));

                                case SymbolKind.Method:
                                    return(!((IMethodSymbol)implementation).ExplicitInterfaceImplementations.Any(f => f.Equals(accessedSymbol)));
                                }
                            }
                            else
                            {
                                return(expressionTypeSymbol.EqualsOrInheritsFrom(containingType, includeInterfaces: true));
                            }
                        }
                    }
                }
            }

            return(false);
        }
示例#4
0
        public static bool IsException(ITypeSymbol typeSymbol, SemanticModel semanticModel)
        {
            if (typeSymbol == null)
            {
                throw new ArgumentNullException(nameof(typeSymbol));
            }

            if (semanticModel == null)
            {
                throw new ArgumentNullException(nameof(semanticModel));
            }

            return(typeSymbol.IsClass() &&
                   typeSymbol.EqualsOrInheritsFrom(semanticModel.GetTypeByMetadataName(MetadataNames.System_Exception)));
        }
        public static bool IsTaskOrDerivedFromTask(this ITypeSymbol typeSymbol, SemanticModel semanticModel)
        {
            if (typeSymbol == null)
            {
                throw new ArgumentNullException(nameof(typeSymbol));
            }

            if (semanticModel == null)
            {
                throw new ArgumentNullException(nameof(semanticModel));
            }

            INamedTypeSymbol taskSymbol = semanticModel.GetTypeByMetadataName(MetadataNames.System_Threading_Tasks_Task);

            return(typeSymbol.EqualsOrInheritsFrom(taskSymbol));
        }
示例#6
0
        private static bool ShouldAddAsyncSuffix(this ITypeSymbol type, SemanticModel model)
        {
            // skip some common types
            if (type.IsVoid() ||
                type.IsString() ||
                type.IsArrayType() ||
                type.IsPredefinedValueType() ||
                type.IsTupleType ||
                type.IsEnum() ||
                type.MetadataName.Length <= 0)
            {
                return(false);
            }

            if (type.IsTaskOrInheritsFromTask(model))
            {
                return(true);
            }

            // check if the return type implements Windows.Foundation.IAsyncAction
            INamedTypeSymbol symbol = model.GetTypeByMetadataName("Windows.Foundation.IAsyncAction");

            if (type.EqualsOrInheritsFrom(symbol))
            {
                return(true);
            }

            // then we will check if the type is directly one of the remaining three mentioned interfaces
            // notice that, it is quite rare that we create types which implement those interfaces
            // for effciency, we will not check the derived parent types
            if (type is INamedTypeSymbol namedType &&
                namedType.IsInterface() &&
                namedType.IsGenericType)
            {
                if (namedType.IsConstructedFrom(model.GetTypeByMetadataName("Windows.Foundation.IAsyncOperation`1")) ||
                    namedType.IsConstructedFrom(model.GetTypeByMetadataName("Windows.Foundation.IAsyncActionWithProgress`1")) ||
                    namedType.IsConstructedFrom(model.GetTypeByMetadataName("Windows.Foundation.IAsyncOperationWithProgress`2")))
                {
                    return(true);
                }
            }

            return(false);
        }
示例#7
0
        public static bool IsEventHandlerMethod(IMethodSymbol methodSymbol)
        {
            if (methodSymbol?.ReturnsVoid == true)
            {
                ImmutableArray <IParameterSymbol> parameters = methodSymbol.Parameters;

                if (parameters.Length == 2 &&
                    parameters[0].Type.SpecialType == SpecialType.System_Object)
                {
                    ITypeSymbol type = parameters[1].Type;

                    if (type.Kind == SymbolKind.TypeParameter)
                    {
                        return(type.Name.EndsWith("EventArgs", StringComparison.Ordinal));
                    }

                    return(type.EqualsOrInheritsFrom(MetadataNames.System_EventArgs));
                }
            }

            return(false);
        }
示例#8
0
        public static void AnalyzeCastExpression(SyntaxNodeAnalysisContext context)
        {
            var castExpression = (CastExpressionSyntax)context.Node;

            if (castExpression.ContainsDiagnostics)
            {
                return;
            }

            if (!(castExpression.Parent is ParenthesizedExpressionSyntax parenthesizedExpression))
            {
                return;
            }

            ExpressionSyntax accessedExpression = GetAccessedExpression(parenthesizedExpression.Parent);

            if (accessedExpression == null)
            {
                return;
            }

            TypeSyntax type = castExpression.Type;

            if (type == null)
            {
                return;
            }

            ExpressionSyntax expression = castExpression.Expression;

            if (expression == null)
            {
                return;
            }

            SemanticModel     semanticModel     = context.SemanticModel;
            CancellationToken cancellationToken = context.CancellationToken;

            ITypeSymbol typeSymbol = semanticModel.GetTypeSymbol(type, cancellationToken);

            if (typeSymbol?.IsErrorType() != false)
            {
                return;
            }

            ITypeSymbol expressionTypeSymbol = semanticModel.GetTypeSymbol(expression, cancellationToken);

            if (expressionTypeSymbol?.IsErrorType() != false)
            {
                return;
            }

            if (expressionTypeSymbol.TypeKind == TypeKind.Interface)
            {
                return;
            }

            if (typeSymbol.TypeKind != TypeKind.Interface &&
                !typeSymbol.EqualsOrInheritsFrom(expressionTypeSymbol, includeInterfaces: true))
            {
                return;
            }

            ISymbol accessedSymbol = semanticModel.GetSymbol(accessedExpression, cancellationToken);

            INamedTypeSymbol containingType = accessedSymbol?.ContainingType;

            if (containingType == null)
            {
                return;
            }

            if (typeSymbol.TypeKind == TypeKind.Interface)
            {
                if (!CheckExplicitImplementation(expressionTypeSymbol, accessedSymbol))
                {
                    return;
                }
            }
            else
            {
                if (!CheckAccessibility(expressionTypeSymbol.OriginalDefinition, accessedSymbol, expression.SpanStart, semanticModel, cancellationToken))
                {
                    return;
                }

                if (!expressionTypeSymbol.EqualsOrInheritsFrom(containingType, includeInterfaces: true))
                {
                    return;
                }
            }

            context.ReportDiagnostic(
                DiagnosticDescriptors.RemoveRedundantCast,
                Location.Create(castExpression.SyntaxTree, castExpression.ParenthesesSpan()));
        }
示例#9
0
        protected virtual void CreateVisitStatements(MethodGenerationContext context)
        {
            string      parameterName = context.ParameterName;
            ITypeSymbol propertyType  = context.PropertyType;
            string      propertyName  = context.PropertyName;

            if (propertyType.OriginalDefinition.Equals(SyntaxListSymbol))
            {
                if (UseCustomVisitMethod)
                {
                    CreateVisitListStatements(context, isSeparatedList: false);
                }
                else
                {
                    context.AddStatement(VisitStatement("VisitList", parameterName, propertyName));
                }
            }
            else if (propertyType.OriginalDefinition.Equals(SeparatedSyntaxListSymbol))
            {
                if (UseCustomVisitMethod)
                {
                    CreateVisitListStatements(context, isSeparatedList: true);
                }
                else
                {
                    context.AddStatement(VisitStatement("VisitSeparatedList", parameterName, propertyName));
                }
            }
            else if (propertyType.Equals(SyntaxTokenListSymbol))
            {
                if (Depth >= SyntaxWalkerDepth.Token)
                {
                    context.AddStatement(VisitStatement("VisitTokenList", parameterName, propertyName));
                }
            }
            else if (propertyType.Equals(SyntaxTokenSymbol))
            {
                if (Depth >= SyntaxWalkerDepth.Token)
                {
                    context.AddStatement(VisitStatement("VisitToken", parameterName, propertyName));
                }
            }
            else if (propertyType.EqualsOrInheritsFrom(SyntaxNodeSymbol))
            {
                switch (propertyType.Name)
                {
                case "AccessorListSyntax":
                case "ArgumentListSyntax":
                case "ArrayTypeSyntax":
                case "ArrowExpressionClauseSyntax":
                case "AttributeArgumentListSyntax":
                case "AttributeTargetSpecifierSyntax":
                case "BaseListSyntax":
                case "BlockSyntax":
                case "BracketedArgumentListSyntax":
                case "BracketedParameterListSyntax":
                case "CatchDeclarationSyntax":
                case "CatchFilterClauseSyntax":
                case "ConstructorInitializerSyntax":
                case "CrefBracketedParameterListSyntax":
                case "CrefParameterListSyntax":
                case "CrefSyntax":
                case "ElseClauseSyntax":
                case "EqualsValueClauseSyntax":
                case "ExplicitInterfaceSpecifierSyntax":
                case "ExpressionSyntax":
                case "FinallyClauseSyntax":
                case "FromClauseSyntax":
                case "IdentifierNameSyntax":
                case "InitializerExpressionSyntax":
                case "InterpolationAlignmentClauseSyntax":
                case "InterpolationFormatClauseSyntax":
                case "JoinIntoClauseSyntax":
                case "MemberCrefSyntax":
                case "NameColonSyntax":
                case "NameEqualsSyntax":
                case "NameSyntax":
                case "ParameterListSyntax":
                case "ParameterSyntax":
                case "PatternSyntax":
                case "QueryBodySyntax":
                case "QueryContinuationSyntax":
                case "SelectOrGroupClauseSyntax":
                case "SimpleNameSyntax":
                case "StatementSyntax":
                case "TypeArgumentListSyntax":
                case "TypeParameterListSyntax":
                case "TypeSyntax":
                case "VariableDeclarationSyntax":
                case "VariableDesignationSyntax":
                case "WhenClauseSyntax":
                case "XmlElementEndTagSyntax":
                case "XmlElementStartTagSyntax":
                case "XmlNameSyntax":
                case "XmlPrefixSyntax":
                {
                    if (UseCustomVisitMethod)
                    {
                        CreateTypeVisitStatements(context);
                    }
                    else
                    {
                        context.AddStatement(VisitStatement("Visit", parameterName, propertyName));
                    }

                    break;
                }

                case "CSharpSyntaxNode":
                {
                    if (!UseCustomVisitMethod)
                    {
                        context.AddStatement(VisitStatement("Visit", parameterName, propertyName));
                        break;
                    }

                    if (EliminateDefaultVisit &&
                        propertyName == "Body" &&
                        context.ParameterType.InheritsFrom(Microsoft_CodeAnalysis_CSharp_Syntax_AnonymousFunctionExpressionSyntax))
                    {
                        CreateVisitAnonymousFunctionStatements(context);
                    }
                    else
                    {
                        CreateTypeVisitStatements(context);
                    }

                    break;
                }

                default:
                {
                    throw new InvalidOperationException($"Unrecognized property type '{propertyType.ToDisplayString()}'.");
                }
                }
            }
            else if (!propertyType.SpecialType.Is(SpecialType.System_Int32, SpecialType.System_Boolean))
            {
                throw new InvalidOperationException();
            }
        }
示例#10
0
        public static string CreateName(ITypeSymbol typeSymbol)
        {
            if (typeSymbol == null)
            {
                throw new ArgumentNullException(nameof(typeSymbol));
            }

            if (typeSymbol.IsKind(SymbolKind.ErrorType, SymbolKind.DynamicType))
            {
                return(null);
            }

            ITypeSymbol typeSymbol2 = ExtractFromNullableType(typeSymbol);

            ITypeSymbol typeSymbol3 = ExtractFromArrayOrGenericCollection(typeSymbol2);

            string name = GetName(typeSymbol3);

            if (string.IsNullOrEmpty(name))
            {
                return(null);
            }

            if (typeSymbol3.TypeKind == TypeKind.Interface &&
                name.Length > 1 &&
                name[0] == 'I')
            {
                name = name.Substring(1);
            }

            if (name.Length >= 8 &&
                name.EndsWith("Syntax", StringComparison.Ordinal) &&
                typeSymbol.EqualsOrInheritsFrom(MetadataNames.Microsoft_CodeAnalysis_SyntaxNode))
            {
                name = name.Remove(name.Length - 6);
            }

            if (name.Length > 1 &&
                UsePlural(typeSymbol2))
            {
                if (!StringUtility.TryRemoveSuffix(name, "Collection", out name))
                {
                    StringUtility.TryRemoveSuffix(name, "List", out name);
                }

                if (name.EndsWith("s", StringComparison.Ordinal) || name.EndsWith("x", StringComparison.Ordinal))
                {
                    name += "es";
                }
                else if (name.EndsWith("y", StringComparison.Ordinal))
                {
                    name = name.Remove(name.Length - 1) + "ies";
                }
                else
                {
                    name += "s";
                }
            }

            return(name);
        }