private bool TypeHasWeakIdentity(ITypeSymbol type, SemanticModel model)
 {
     switch (type.TypeKind)
     {
         case TypeKind.ArrayType:
             var arrayType = type as IArrayTypeSymbol;
             return arrayType != null && arrayType.ElementType.IsPrimitiveType();
         case TypeKind.Class:
         case TypeKind.TypeParameter:
             Compilation compilation = model.Compilation;
             INamedTypeSymbol marshalByRefObjectTypeSymbol = compilation.GetTypeByMetadataName("System.MarshalByRefObject");
             INamedTypeSymbol executionEngineExceptionTypeSymbol = compilation.GetTypeByMetadataName("System.ExecutionEngineException");
             INamedTypeSymbol outOfMemoryExceptionTypeSymbol = compilation.GetTypeByMetadataName("System.OutOfMemoryException");
             INamedTypeSymbol stackOverflowExceptionTypeSymbol = compilation.GetTypeByMetadataName("System.StackOverflowException");
             INamedTypeSymbol memberInfoTypeSymbol = compilation.GetTypeByMetadataName("System.Reflection.MemberInfo");
             INamedTypeSymbol parameterInfoTypeSymbol = compilation.GetTypeByMetadataName("System.Reflection.ParameterInfo");
             INamedTypeSymbol threadTypeSymbol = compilation.GetTypeByMetadataName("System.Threading.Thread");
             return
                 type.SpecialType == SpecialType.System_String ||
                 type.Equals(executionEngineExceptionTypeSymbol) ||
                 type.Equals(outOfMemoryExceptionTypeSymbol) ||
                 type.Equals(stackOverflowExceptionTypeSymbol) ||
                 type.Inherits(marshalByRefObjectTypeSymbol) ||
                 type.Inherits(memberInfoTypeSymbol) ||
                 type.Inherits(parameterInfoTypeSymbol) ||
                 type.Inherits(threadTypeSymbol);
         
         // What about struct types?
         default:
             return false;
     }
 }
        private static bool HasPublicWritableIndexer(
            ExpressionSyntax expression,
            ObjectCreationExpressionSyntax objectCreationExpression,
            SemanticModel semanticModel,
            CancellationToken cancellationToken)
        {
            var typeSymbol = semanticModel.GetSymbol(objectCreationExpression.Type, cancellationToken) as ITypeSymbol;

            if (typeSymbol != null)
            {
                foreach (ISymbol member in typeSymbol.GetMembers("this[]"))
                {
                    if (member.IsPublic() &&
                        !member.IsStatic &&
                        member.IsProperty())
                    {
                        var propertySymbol = (IPropertySymbol)member;

                        if (!propertySymbol.IsReadOnly)
                        {
                            ImmutableArray <IParameterSymbol> parameters = propertySymbol.Parameters;

                            if (parameters.Length == 1)
                            {
                                ITypeSymbol expressionSymbol = semanticModel.GetTypeInfo(expression, cancellationToken).ConvertedType;

                                return(expressionSymbol?.Equals(propertySymbol.Parameters[0].Type) == true);
                            }
                        }
                    }
                }
            }

            return(false);
        }
        private static void AnalyzeObjectCreationExpression(SyntaxNodeAnalysisContext context, INamedTypeSymbol dateTimeSymbol)
        {
            var objectCreationSyntax = (ObjectCreationExpressionSyntax)context.Node;

            ITypeSymbol typeSymbol = context.SemanticModel.GetTypeSymbol(objectCreationSyntax, context.CancellationToken);

            if (typeSymbol?.Equals(dateTimeSymbol) != true)
            {
                return;
            }

            var dateTimeKindArgument = objectCreationSyntax.ArgumentList.Arguments.FirstOrDefault(e =>
                                                                                                  (e is ArgumentSyntax argumentSyntax) &&
                                                                                                  (argumentSyntax.Expression is MemberAccessExpressionSyntax memberSyntax) &&
                                                                                                  (memberSyntax.Expression is IdentifierNameSyntax idSyntax) &&
                                                                                                  idSyntax.Identifier.ValueText == DATETIMEKIND);

            if (dateTimeKindArgument is null)
            {
                context.ReportDiagnostic(Diagnostic.Create(Rule, context.Node.GetLocation()));
            }
            else if (dateTimeKindArgument.Expression.TryGetInferredMemberName() != UTC)
            {
                context.ReportDiagnostic(Diagnostic.Create(Rule, context.Node.GetLocation()));
            }
        }
        private static bool HasPublicAddMethod(
            ExpressionSyntax expression,
            ObjectCreationExpressionSyntax objectCreationExpression,
            SemanticModel semanticModel,
            CancellationToken cancellationToken)
        {
            var typeSymbol = semanticModel.GetSymbol(objectCreationExpression.Type, cancellationToken) as ITypeSymbol;

            if (typeSymbol != null)
            {
                foreach (IMethodSymbol methodSymbol in typeSymbol.GetMethods("Add"))
                {
                    if (methodSymbol.IsPublic() &&
                        !methodSymbol.IsStatic)
                    {
                        ImmutableArray <IParameterSymbol> parameters = methodSymbol.Parameters;

                        if (parameters.Length == 1)
                        {
                            ITypeSymbol expressionSymbol = semanticModel.GetTypeInfo(expression, cancellationToken).ConvertedType;

                            return(expressionSymbol?.Equals(parameters[0].Type) == true);
                        }
                    }
                }
            }

            return(false);
        }
Beispiel #5
0
        private void AnalyzeMethodInvocation(SyntaxNodeAnalysisContext context)
        {
            var invocation = (InvocationExpressionSyntax)context.Node;

            var symbol = context.SemanticModel.GetSymbolInfo(invocation).Symbol as IMethodSymbol;

            if (symbol != null && FormatHelper.IsFormattableCall(symbol, context.SemanticModel))
            {
                var parsedFormat = FormatHelper.ParseFormatMethodInvocation(invocation, symbol, context.SemanticModel);
                if (!parsedFormat.IsValid)
                {
                    context.ReportDiagnostic(Diagnostic.Create(InvalidFormatRule, parsedFormat.FormatArgument.GetLocation()));
                }
                else
                {
                    // Special corner case: if param args is an expression that provides object or object[]
                    // then giving up the analysis!
                    int actualArgumentsLength = parsedFormat.Args.Length;

                    if (parsedFormat.Args.Length == 1)
                    {
                        ITypeSymbol expressionType = GetExpressionType(parsedFormat.Args[0], context.SemanticModel);
                        if (expressionType?.Equals(context.SemanticModel.GetClrType(typeof(object))) == true ||
                            IsArrayOfObjects(expressionType, context.SemanticModel))
                        {
                            // Giving up all the checks! Can't deal with them!
                            return;
                        }
                    }

                    // Checking for non-existed indices in a format string
                    var missedArguments = parsedFormat.UsedIndices.Where(i => i < 0 || i >= actualArgumentsLength).ToList();
                    if (missedArguments.Count != 0)
                    {
                        context.ReportDiagnostic(Diagnostic
                                                 .Create(
                                                     NonExistingIndexRule, parsedFormat.FormatArgument.GetLocation(),
                                                     string.Join(", ", missedArguments)));
                    }

                    // TODO: unused parameters should have warnings on the parameters themselves not on the string format!
                    var excessiveArguments =
                        Enumerable.Range(0, actualArgumentsLength)
                        .Where(i => !parsedFormat.UsedIndices.Contains(i))
                        .Select(i => parsedFormat.Args[i])
                        .ToList();

                    foreach (var excessiveArg in excessiveArguments)
                    {
                        context.ReportDiagnostic(
                            Diagnostic.Create(
                                ExcessiveArgumentRule, excessiveArg.GetLocation(), excessiveArg));
                    }
                }
            }
        }
        protected static bool IsPropertyAccessSomeObviousTypeCase(SyntaxNodeAnalysisContext nodeContext, ExpressionSyntax initializerExpression, ITypeSymbol variableType)
        {
            var simpleMemberAccess = initializerExpression as MemberAccessExpressionSyntax;
            if (simpleMemberAccess != null)
            {
                var propertyType = nodeContext.SemanticModel.GetTypeInfo(simpleMemberAccess, nodeContext.CancellationToken).Type;
                return propertyType != null && variableType.Equals(propertyType);
            }

            return false;
        }
 static bool CheckCuriouslyRecurringTemplatePattern(ITypeSymbol containingType, ITypeSymbol type)
 {
     if (containingType.Equals(type))
         return true;
     var nt = containingType as INamedTypeSymbol;
     if (nt == null)
         return false;
     foreach (var typeArg in nt.TypeArguments)
     {
         if (CheckCuriouslyRecurringTemplatePattern(typeArg, type))
             return true;
     }
     return false;
 }
        internal static bool IsSameType(this ITypeSymbol first, ITypeSymbol other)
        {
            if (ReferenceEquals(first, other) ||
                first?.Equals(other) == true)
            {
                return(true);
            }

            if (first is ITypeParameterSymbol firstParameter &&
                other is ITypeParameterSymbol otherParameter)
            {
                return(firstParameter.MetadataName == otherParameter.MetadataName &&
                       firstParameter.ContainingSymbol.Equals(otherParameter.ContainingSymbol));
            }

            return(first is INamedTypeSymbol firstNamed &&
                   other is INamedTypeSymbol otherNamed &&
                   IsSameType(firstNamed, otherNamed));
        }
        public static void AnalyzeObjectCreationExpression(SyntaxNodeAnalysisContext context, INamedTypeSymbol eventArgsSymbol)
        {
            if (context.Node.SpanContainsDirectives())
            {
                return;
            }

            var objectCreation = (ObjectCreationExpressionSyntax)context.Node;

            if (objectCreation.ArgumentList?.Arguments.Count == 0 &&
                objectCreation.Initializer == null)
            {
                ITypeSymbol typeSymbol = context.SemanticModel.GetTypeSymbol(objectCreation, context.CancellationToken);

                if (typeSymbol?.Equals(eventArgsSymbol) == true)
                {
                    context.ReportDiagnostic(DiagnosticDescriptors.UseEventArgsEmpty, objectCreation);
                }
            }
        }
        public static void AnalyzeCatchClause(SyntaxNodeAnalysisContext context, ITypeSymbol exceptionSymbol)
        {
            if (context.Node.ContainsDiagnostics)
            {
                return;
            }

            var catchClause = (CatchClauseSyntax)context.Node;

            if (catchClause.Filter != null)
            {
                return;
            }

            if (catchClause.Block?.Statements.Any() != false)
            {
                return;
            }

            TypeSyntax type = catchClause.Declaration?.Type;

            if (type == null)
            {
                return;
            }

            ITypeSymbol typeSymbol = context.SemanticModel.GetTypeSymbol(type, context.CancellationToken);

            if (typeSymbol?.Equals(exceptionSymbol) != true)
            {
                return;
            }

            context.ReportDiagnostic(
                DiagnosticDescriptors.AvoidEmptyCatchClauseThatCatchesSystemException,
                catchClause.CatchKeyword);
        }
        protected static bool IsTaskLike(
            ITypeSymbol returnType, ITypeSymbol taskType, INamedTypeSymbol taskOfTType)
        {
            if (returnType.Equals(taskType))
            {
                return true;
            }

            if (returnType.OriginalDefinition.Equals(taskOfTType))
            {
                return true;
            }

            if (returnType.IsErrorType() &&
                returnType.Name.Equals("Task"))
            {
                return true;
            }

            return false;
        }
Beispiel #12
0
        public static TypeAnalysisFlags AnalyzeType(
            VariableDeclarationSyntax variableDeclaration,
            SemanticModel semanticModel,
            CancellationToken cancellationToken = default(CancellationToken))
        {
            if (variableDeclaration == null)
            {
                throw new ArgumentNullException(nameof(variableDeclaration));
            }

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

            TypeSyntax type = variableDeclaration.Type;

            if (type != null)
            {
                SeparatedSyntaxList <VariableDeclaratorSyntax> variables = variableDeclaration.Variables;

                if (variables.Count > 0 &&
                    !variableDeclaration.IsParentKind(SyntaxKind.FieldDeclaration, SyntaxKind.EventFieldDeclaration))
                {
                    ExpressionSyntax expression = variables[0].Initializer?.Value;

                    if (expression != null)
                    {
                        ITypeSymbol typeSymbol = semanticModel.GetTypeSymbol(type, cancellationToken);

                        if (typeSymbol?.IsErrorType() == false)
                        {
                            var flags = TypeAnalysisFlags.None;

                            if (typeSymbol.IsDynamicType())
                            {
                                flags = TypeAnalysisFlags.Dynamic;
                            }
                            else
                            {
                                flags = TypeAnalysisFlags.ValidSymbol;

                                if (type.IsVar)
                                {
                                    flags |= TypeAnalysisFlags.Implicit;

                                    if (typeSymbol.SupportsExplicitDeclaration())
                                    {
                                        flags |= TypeAnalysisFlags.SupportsExplicit;
                                    }
                                }
                                else
                                {
                                    flags |= TypeAnalysisFlags.Explicit;

                                    if (variables.Count == 1 &&
                                        !IsLocalConstDeclaration(variableDeclaration) &&
                                        !expression.IsKind(SyntaxKind.NullLiteralExpression) &&
                                        typeSymbol.Equals(semanticModel.GetTypeSymbol(expression, cancellationToken)))
                                    {
                                        flags |= TypeAnalysisFlags.SupportsImplicit;
                                    }
                                }

                                if (IsTypeObvious(expression, semanticModel, cancellationToken))
                                {
                                    flags |= TypeAnalysisFlags.TypeObvious;
                                }
                            }

                            return(flags);
                        }
                    }
                }
            }

            return(TypeAnalysisFlags.None);
        }
 private static bool Inherits(ITypeSymbol symbol, ITypeSymbol baseType)
 {
     Debug.Assert(baseType.Equals(baseType.OriginalDefinition));
     return(symbol?.OriginalDefinition.Inherits(baseType) ?? false);
 }
Beispiel #14
0
        public static async Task ComputeRefactoringAsync(RefactoringContext context, EventFieldDeclarationSyntax eventFieldDeclaration)
        {
            if (eventFieldDeclaration.IsParentKind(SyntaxKind.InterfaceDeclaration))
            {
                return;
            }

            VariableDeclarationSyntax variableDeclaration = eventFieldDeclaration.Declaration;

            if (variableDeclaration == null)
            {
                return;
            }

            SemanticModel semanticModel = null;

            foreach (VariableDeclaratorSyntax variableDeclarator in variableDeclaration.Variables)
            {
                if (!context.Span.IsContainedInSpanOrBetweenSpans(variableDeclarator.Identifier))
                {
                    continue;
                }

                semanticModel = semanticModel ?? await context.GetSemanticModelAsync().ConfigureAwait(false);

                var eventSymbol = semanticModel.GetDeclaredSymbol(variableDeclarator, context.CancellationToken) as IEventSymbol;

                if (eventSymbol?.IsStatic != false)
                {
                    continue;
                }

                INamedTypeSymbol containingType = eventSymbol.ContainingType;

                if (containingType == null)
                {
                    return;
                }

                if (!(eventSymbol.Type is INamedTypeSymbol eventHandlerType))
                {
                    continue;
                }

                ITypeSymbol eventArgsSymbol = GetEventArgsSymbol(eventHandlerType, semanticModel);

                if (eventArgsSymbol == null)
                {
                    continue;
                }

                string methodName = "On" + eventSymbol.Name;

                if (containingType.ContainsMember <IMethodSymbol>(
                        $"On{eventSymbol.Name}",
                        methodSymbol => eventArgsSymbol.Equals(methodSymbol.Parameters.SingleOrDefault(shouldThrow: false)?.Type)))
                {
                    continue;
                }

                methodName = NameGenerator.Default.EnsureUniqueName(methodName, containingType.GetMembers());

                context.RegisterRefactoring(
                    $"Generate '{methodName}' method",
                    cancellationToken =>
                {
                    return(RefactorAsync(
                               context.Document,
                               eventFieldDeclaration,
                               eventSymbol,
                               eventArgsSymbol,
                               context.SupportsCSharp6,
                               cancellationToken));
                },
                    RefactoringIdentifiers.GenerateEventInvokingMethod);
            }
        }
		/// <summary>
		///   Classifies the type of the <paramref name="expressionType" />.
		/// </summary>
		private bool IsFormulaType(ITypeSymbol expressionType)
		{
			return expressionType.Equals(_formulaType);
		}
Beispiel #16
0
        public override void Initialize(AnalysisContext context)
        {
            context.EnableConcurrentExecution();
            context.ConfigureGeneratedCodeAnalysis(GeneratedCodeAnalysisFlags.None);

            context.RegisterCompilationStartAction(compilationContext =>
            {
                INamedTypeSymbol cancellationTokenType = compilationContext.Compilation.GetTypeByMetadataName("System.Threading.CancellationToken");
                if (cancellationTokenType != null)
                {
                    compilationContext.RegisterSymbolAction(symbolContext =>
                    {
                        var methodSymbol = (IMethodSymbol)symbolContext.Symbol;
                        if (methodSymbol.IsOverride ||
                            methodSymbol.IsImplementationOfAnyInterfaceMember())
                        {
                            return;
                        }

                        int last = methodSymbol.Parameters.Length - 1;
                        if (last >= 0 && methodSymbol.Parameters[last].IsParams)
                        {
                            last--;
                        }

                        // Skip optional parameters, UNLESS one of them is a CancellationToken
                        // AND it's not the last one.
                        if (last >= 0 && methodSymbol.Parameters[last].IsOptional &&
                            !methodSymbol.Parameters[last].Type.Equals(cancellationTokenType))
                        {
                            last--;

                            while (last >= 0 && methodSymbol.Parameters[last].IsOptional)
                            {
                                if (methodSymbol.Parameters[last].Type.Equals(cancellationTokenType))
                                {
                                    symbolContext.ReportDiagnostic(Diagnostic.Create(
                                                                       Rule, methodSymbol.Locations.First(), methodSymbol.ToDisplayString()));
                                }

                                last--;
                            }
                        }

                        while (last >= 0 && methodSymbol.Parameters[last].RefKind != RefKind.None)
                        {
                            last--;
                        }

                        for (int i = last; i >= 0; i--)
                        {
                            ITypeSymbol parameterType = methodSymbol.Parameters[i].Type;
                            if (parameterType.Equals(cancellationTokenType) &&
                                i != last)
                            {
                                symbolContext.ReportDiagnostic(Diagnostic.Create(
                                                                   Rule, methodSymbol.Locations.First(), methodSymbol.ToDisplayString()));
                                break;
                            }
                        }
                    },
                                                            SymbolKind.Method);
                }
            });
        }
 public static bool IsSubtypeOf(this ITypeSymbol symbol, ITypeSymbol type)
 {
     return(symbol.Equals(type) || symbol.Implements(type) || symbol.InheritsFrom(type));
 }
		static bool ContainsType (ITypeSymbol testType, ITypeSymbol searchType)
		{
			if (testType == null)
				return false;
			Console.WriteLine (testType +" == " + searchType + " ? " + (testType == searchType) + "/" + testType.Equals (searchType));
			if (testType == searchType)
				return true;
			var namedTypeSymbol = testType as INamedTypeSymbol;
			if (namedTypeSymbol != null) {
				foreach (var arg in namedTypeSymbol.TypeArguments)
					if (ContainsType (arg, searchType))
						return true;
			}
			return false;
		}
Beispiel #19
0
        public static bool HasAccessibleIndexer(
            ITypeSymbol typeSymbol,
            SemanticModel semanticModel,
            int position)
        {
            if (typeSymbol == null)
            {
                return(false);
            }

            SymbolKind symbolKind = typeSymbol.Kind;

            if (symbolKind == SymbolKind.ErrorType)
            {
                return(false);
            }

            if (symbolKind == SymbolKind.ArrayType)
            {
                return(true);
            }

            bool?hasIndexer = HasIndexer(typeSymbol.SpecialType);

            if (hasIndexer != null)
            {
                return(hasIndexer.Value);
            }

            ITypeSymbol originalDefinition = typeSymbol.OriginalDefinition;

            if (!typeSymbol.Equals(originalDefinition))
            {
                hasIndexer = HasIndexer(originalDefinition.SpecialType);

                if (hasIndexer != null)
                {
                    return(hasIndexer.Value);
                }
            }

            if (originalDefinition.ImplementsAny(
                    SpecialType.System_Collections_Generic_IList_T,
                    SpecialType.System_Collections_Generic_IReadOnlyList_T,
                    allInterfaces: true))
            {
                if (originalDefinition.TypeKind == TypeKind.Interface)
                {
                    return(true);
                }

                foreach (ISymbol symbol in typeSymbol.GetMembers("this[]"))
                {
                    if (semanticModel.IsAccessible(position, symbol))
                    {
                        return(true);
                    }
                }
            }

            return(false);

            bool?HasIndexer(SpecialType specialType)
            {
                switch (specialType)
                {
                case SpecialType.System_String:
                case SpecialType.System_Array:
                case SpecialType.System_Collections_Generic_IList_T:
                case SpecialType.System_Collections_Generic_IReadOnlyList_T:
                    return(true);

                case SpecialType.None:
                    return(null);
                }

                return(false);
            }
        }
        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();
            }
        }
Beispiel #21
0
        public static void AnalyzeAsExpression(SyntaxNodeAnalysisContext context)
        {
            var asExpression = (BinaryExpressionSyntax)context.Node;

            AsExpressionInfo asExpressionInfo = SyntaxInfo.AsExpressionInfo(asExpression);

            if (!asExpressionInfo.Success)
            {
                return;
            }

            SingleLocalDeclarationStatementInfo localInfo = SyntaxInfo.SingleLocalDeclarationStatementInfo(asExpression);

            if (!localInfo.Success)
            {
                return;
            }

            if (localInfo.Statement.SpanOrTrailingTriviaContainsDirectives())
            {
                return;
            }

            if (!(localInfo.Statement.NextStatement() is IfStatementSyntax ifStatement))
            {
                return;
            }

            if (!ifStatement.IsSimpleIf())
            {
                return;
            }

            if (ifStatement.SpanOrLeadingTriviaContainsDirectives())
            {
                return;
            }

            StatementSyntax statement = ifStatement.SingleNonBlockStatementOrDefault();

            if (statement == null)
            {
                return;
            }

            if (!CSharpFacts.IsJumpStatement(statement.Kind()))
            {
                return;
            }

            NullCheckExpressionInfo nullCheck = SyntaxInfo.NullCheckExpressionInfo(ifStatement.Condition, NullCheckStyles.EqualsToNull | NullCheckStyles.IsNull);

            if (!nullCheck.Success)
            {
                return;
            }

            if (!string.Equals(localInfo.IdentifierText, (nullCheck.Expression as IdentifierNameSyntax)?.Identifier.ValueText, StringComparison.Ordinal))
            {
                return;
            }

            if (!localInfo.Type.IsVar)
            {
                SemanticModel     semanticModel     = context.SemanticModel;
                CancellationToken cancellationToken = context.CancellationToken;

                ITypeSymbol typeSymbol  = semanticModel.GetTypeSymbol(localInfo.Type, cancellationToken);
                ITypeSymbol typeSymbol2 = semanticModel.GetTypeSymbol(asExpressionInfo.Type, cancellationToken);

                if (!typeSymbol.Equals(typeSymbol2))
                {
                    return;
                }
            }

            context.ReportDiagnostic(DiagnosticDescriptors.UsePatternMatchingInsteadOfAsAndNullCheck, localInfo.Statement);
        }
		/// <summary>
		///     Classifies the type of the <paramref name="expressionType" />.
		/// </summary>
		private ExpressionType DetermineType(ITypeSymbol expressionType)
		{
			if (expressionType.Equals(_ctlFormulaType))
				return ExpressionType.Ctl;

			if (expressionType.Equals(_ltlFormulaType))
				return ExpressionType.Ltl;

			return ExpressionType.Other;
		}
Beispiel #23
0
        public override void Initialize(AnalysisContext context)
        {
            context.EnableConcurrentExecution();
            context.ConfigureGeneratedCodeAnalysis(GeneratedCodeAnalysisFlags.None);

            context.RegisterCompilationStartAction(compilationContext =>
            {
                var wellKnownTypeProvider = WellKnownTypeProvider.GetOrCreate(compilationContext.Compilation);
                INamedTypeSymbol?cancellationTokenType = wellKnownTypeProvider.GetOrCreateTypeByMetadataName(WellKnownTypeNames.SystemThreadingCancellationToken);
                INamedTypeSymbol?iprogressType         = wellKnownTypeProvider.GetOrCreateTypeByMetadataName(WellKnownTypeNames.SystemIProgress1);
                if (cancellationTokenType == null)
                {
                    return;
                }

                compilationContext.RegisterSymbolAction(symbolContext =>
                {
                    var methodSymbol = (IMethodSymbol)symbolContext.Symbol;
                    if (methodSymbol.IsOverride ||
                        methodSymbol.IsImplementationOfAnyInterfaceMember())
                    {
                        return;
                    }

                    int last = methodSymbol.Parameters.Length - 1;
                    if (last >= 0 && methodSymbol.Parameters[last].IsParams)
                    {
                        last--;
                    }

                    // Skip optional parameters, UNLESS one of them is a CancellationToken
                    // AND it's not the last one.
                    if (last >= 0 && methodSymbol.Parameters[last].IsOptional &&
                        !methodSymbol.Parameters[last].Type.Equals(cancellationTokenType))
                    {
                        last--;

                        while (last >= 0 && methodSymbol.Parameters[last].IsOptional)
                        {
                            if (methodSymbol.Parameters[last].Type.Equals(cancellationTokenType))
                            {
                                symbolContext.ReportDiagnostic(Diagnostic.Create(
                                                                   Rule, methodSymbol.Locations.First(), methodSymbol.ToDisplayString()));
                            }

                            last--;
                        }
                    }

                    // Ignore multiple cancellation token parameters at the end of the parameter list.
                    while (last >= 0 && methodSymbol.Parameters[last].Type.Equals(cancellationTokenType))
                    {
                        last--;
                    }

                    // Ignore parameters passed by reference when they appear at the end of the parameter list.
                    while (last >= 0 && methodSymbol.Parameters[last].RefKind != RefKind.None)
                    {
                        last--;
                    }

                    // Ignore IProgress<T> when last
                    if (last >= 0 &&
                        iprogressType != null &&
                        methodSymbol.Parameters[last].Type.OriginalDefinition.Equals(iprogressType))
                    {
                        last--;
                    }

                    for (int i = last - 1; i >= 0; i--)
                    {
                        ITypeSymbol parameterType = methodSymbol.Parameters[i].Type;
                        if (!parameterType.Equals(cancellationTokenType))
                        {
                            continue;
                        }

                        // Bail if the CancellationToken is the first parameter of an extension method.
                        if (i == 0 && methodSymbol.IsExtensionMethod)
                        {
                            continue;
                        }

                        symbolContext.ReportDiagnostic(Diagnostic.Create(
                                                           Rule, methodSymbol.Locations.First(), methodSymbol.ToDisplayString()));
                        break;
                    }
                },
                                                        SymbolKind.Method);
            });
        }
Beispiel #24
0
        public static async Task ComputeRefactoringsAsync(RefactoringContext context, ExpressionSyntax expression)
        {
            if (expression != null)
            {
                SemanticModel semanticModel = await context.GetSemanticModelAsync().ConfigureAwait(false);

                ISymbol memberSymbol = GetContainingMethodOrPropertySymbol(expression, semanticModel, context.CancellationToken);

                if (memberSymbol != null)
                {
                    SyntaxNode node = await memberSymbol
                                      .DeclaringSyntaxReferences[0]
                                      .GetSyntaxAsync(context.CancellationToken)
                                      .ConfigureAwait(false);

                    var declaration = node as MemberDeclarationSyntax;

                    if (declaration != null)
                    {
                        TypeSyntax memberType = GetMemberType(declaration);

                        if (memberType != null)
                        {
                            ITypeSymbol memberTypeSymbol = semanticModel.GetTypeSymbol(memberType, context.CancellationToken);

                            if (memberTypeSymbol != null)
                            {
                                ITypeSymbol expressionSymbol = semanticModel.GetTypeSymbol(expression, context.CancellationToken);

                                if (expressionSymbol?.IsErrorType() == false)
                                {
                                    if (context.IsRefactoringEnabled(RefactoringIdentifiers.ChangeMemberTypeAccordingToReturnExpression))
                                    {
                                        ITypeSymbol newType = GetMemberNewType(memberSymbol, memberTypeSymbol, expression, expressionSymbol, semanticModel, context.CancellationToken);

                                        if (newType?.IsErrorType() == false &&
                                            !memberTypeSymbol.Equals(newType) &&
                                            !memberSymbol.IsOverride &&
                                            !memberSymbol.ImplementsInterfaceMember())
                                        {
                                            if (newType.IsNamedType() && memberTypeSymbol.IsNamedType())
                                            {
                                                var newNamedType = (INamedTypeSymbol)newType;

                                                INamedTypeSymbol orderedEnumerableSymbol = semanticModel.GetTypeByMetadataName(MetadataNames.System_Linq_IOrderedEnumerable_T);

                                                if (newNamedType.ConstructedFrom == orderedEnumerableSymbol)
                                                {
                                                    INamedTypeSymbol enumerableSymbol = semanticModel.GetTypeByMetadataName(MetadataNames.System_Collections_Generic_IEnumerable_T);

                                                    if (enumerableSymbol != null &&
                                                        ((INamedTypeSymbol)memberTypeSymbol).ConstructedFrom != enumerableSymbol)
                                                    {
                                                        RegisterChangeType(context, declaration, memberType, enumerableSymbol.Construct(newNamedType.TypeArguments.ToArray()), semanticModel);
                                                    }
                                                }
                                            }

                                            RegisterChangeType(context, declaration, memberType, newType, semanticModel);
                                        }
                                    }

                                    if (context.IsAnyRefactoringEnabled(RefactoringIdentifiers.AddCastExpression, RefactoringIdentifiers.CallToMethod) &&
                                        !memberTypeSymbol.IsErrorType())
                                    {
                                        ITypeSymbol castTypeSymbol = GetCastTypeSymbol(memberSymbol, memberTypeSymbol, expressionSymbol, semanticModel);

                                        if (castTypeSymbol != null)
                                        {
                                            ModifyExpressionRefactoring.ComputeRefactoring(
                                                context,
                                                expression,
                                                castTypeSymbol,
                                                semanticModel);
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
 private bool IsConversionToSimpleTypeNeeded(ITypeSymbol targetType, ITypeSymbol sourceType)
 {
     return(targetType.Equals(sourceType) == false && (ObjectHelper.IsSimpleType(targetType) || SymbolHelper.IsNullable(targetType, out _)));
 }
Beispiel #26
0
        public override void Initialize(AnalysisContext context)
        {
            context.EnableConcurrentExecution();
            context.ConfigureGeneratedCodeAnalysis(GeneratedCodeAnalysisFlags.None);

            context.RegisterCompilationStartAction(compilationContext =>
            {
                var wellKnownTypeProvider = WellKnownTypeProvider.GetOrCreate(compilationContext.Compilation);
                INamedTypeSymbol?cancellationTokenType = wellKnownTypeProvider.GetOrCreateTypeByMetadataName(WellKnownTypeNames.SystemThreadingCancellationToken);
                INamedTypeSymbol?iprogressType         = wellKnownTypeProvider.GetOrCreateTypeByMetadataName(WellKnownTypeNames.SystemIProgress1);

                var builder = ImmutableHashSet.CreateBuilder <INamedTypeSymbol>();
                builder.AddIfNotNull(compilationContext.Compilation.GetOrCreateTypeByMetadataName(WellKnownTypeNames.SystemRuntimeCompilerServicesCallerFilePathAttribute));
                builder.AddIfNotNull(compilationContext.Compilation.GetOrCreateTypeByMetadataName(WellKnownTypeNames.SystemRuntimeCompilerServicesCallerLineNumberAttribute));
                builder.AddIfNotNull(compilationContext.Compilation.GetOrCreateTypeByMetadataName(WellKnownTypeNames.SystemRuntimeCompilerServicesCallerMemberNameAttribute));
                var callerInformationAttributes = builder.ToImmutable();

                if (cancellationTokenType == null)
                {
                    return;
                }

                compilationContext.RegisterSymbolAction(symbolContext =>
                {
                    var methodSymbol = (IMethodSymbol)symbolContext.Symbol;
                    if (methodSymbol.IsOverride ||
                        methodSymbol.IsImplementationOfAnyInterfaceMember())
                    {
                        return;
                    }

                    int last = methodSymbol.Parameters.Length - 1;
                    if (last >= 0 && methodSymbol.Parameters[last].IsParams)
                    {
                        last--;
                    }

                    // Ignore parameters that have any of these attributes.
                    // C# reserved attributes: https://docs.microsoft.com/dotnet/csharp/language-reference/attributes/caller-information
                    while (last >= 0 &&
                           HasCallerInformationAttribute(methodSymbol.Parameters[last], callerInformationAttributes))
                    {
                        last--;
                    }

                    // Skip optional parameters, UNLESS one of them is a CancellationToken
                    // AND it's not the last one.
                    if (last >= 0 && methodSymbol.Parameters[last].IsOptional &&
                        !methodSymbol.Parameters[last].Type.Equals(cancellationTokenType))
                    {
                        last--;

                        while (last >= 0 && methodSymbol.Parameters[last].IsOptional)
                        {
                            if (methodSymbol.Parameters[last].Type.Equals(cancellationTokenType))
                            {
                                symbolContext.ReportDiagnostic(methodSymbol.CreateDiagnostic(Rule, methodSymbol.ToDisplayString()));
                            }

                            last--;
                        }
                    }

                    // Ignore multiple cancellation token parameters at the end of the parameter list.
                    while (last >= 0 && methodSymbol.Parameters[last].Type.Equals(cancellationTokenType))
                    {
                        last--;
                    }

                    // Ignore parameters passed by reference when they appear at the end of the parameter list.
                    while (last >= 0 && methodSymbol.Parameters[last].RefKind != RefKind.None)
                    {
                        last--;
                    }

                    // Ignore IProgress<T> when last
                    if (last >= 0 &&
                        iprogressType != null &&
                        methodSymbol.Parameters[last].Type.OriginalDefinition.Equals(iprogressType))
                    {
                        last--;
                    }

                    for (int i = last - 1; i >= 0; i--)
                    {
                        ITypeSymbol parameterType = methodSymbol.Parameters[i].Type;
                        if (!parameterType.Equals(cancellationTokenType))
                        {
                            continue;
                        }

                        // Bail if the CancellationToken is the first parameter of an extension method.
                        if (i == 0 && methodSymbol.IsExtensionMethod)
                        {
                            continue;
                        }

                        symbolContext.ReportDiagnostic(methodSymbol.CreateDiagnostic(Rule, methodSymbol.ToDisplayString()));
                        break;
                    }
                },
                                                        SymbolKind.Method);
            });
        }
Beispiel #27
0
        public static void Analyze(SyntaxNodeAnalysisContext context, SimpleMemberInvocationExpressionInfo invocationInfo)
        {
            SimpleMemberInvocationExpressionInfo invocationInfo2 = SyntaxInfo.SimpleMemberInvocationExpressionInfo(invocationInfo.Expression);

            if (!invocationInfo2.Success)
            {
                return;
            }

            ArgumentSyntax argument = invocationInfo2.Arguments.SingleOrDefault(shouldThrow: false);

            if (argument == null)
            {
                return;
            }

            if (!string.Equals(invocationInfo2.NameText, "Where", StringComparison.Ordinal))
            {
                return;
            }

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

            IMethodSymbol methodSymbol = semanticModel.GetReducedExtensionMethodInfo(invocationInfo.InvocationExpression, cancellationToken).Symbol;

            if (methodSymbol == null)
            {
                return;
            }

            if (!SymbolUtility.IsLinqCast(methodSymbol, semanticModel))
            {
                return;
            }

            IMethodSymbol methodSymbol2 = semanticModel.GetReducedExtensionMethodInfo(invocationInfo2.InvocationExpression, cancellationToken).Symbol;

            if (methodSymbol2 == null)
            {
                return;
            }

            if (!SymbolUtility.IsLinqWhere(methodSymbol2, semanticModel))
            {
                return;
            }

            IsExpressionInfo isExpressionInfo = SyntaxInfo.IsExpressionInfo(GetLambdaExpression(argument.Expression));

            if (!isExpressionInfo.Success)
            {
                return;
            }

            TypeSyntax type2 = (invocationInfo.Name as GenericNameSyntax)?.TypeArgumentList?.Arguments.SingleOrDefault(shouldThrow: false);

            if (type2 == null)
            {
                return;
            }

            ITypeSymbol typeSymbol = semanticModel.GetTypeSymbol(isExpressionInfo.Type, cancellationToken);

            if (typeSymbol == null)
            {
                return;
            }

            ITypeSymbol typeSymbol2 = semanticModel.GetTypeSymbol(type2, cancellationToken);

            if (!typeSymbol.Equals(typeSymbol2))
            {
                return;
            }

            TextSpan span = TextSpan.FromBounds(invocationInfo2.Name.SpanStart, invocationInfo.InvocationExpression.Span.End);

            if (invocationInfo.InvocationExpression.ContainsDirectives(span))
            {
                return;
            }

            context.ReportDiagnostic(
                DiagnosticDescriptors.SimplifyLinqMethodChain,
                Location.Create(invocationInfo.InvocationExpression.SyntaxTree, span));
        }
Beispiel #28
0
        public sealed override async Task RegisterCodeFixesAsync(CodeFixContext context)
        {
            if (!Settings.IsCodeFixEnabled(CodeFixIdentifiers.AddComparisonWithBooleanLiteral) &&
                !Settings.IsCodeFixEnabled(CodeFixIdentifiers.CreateSingletonArray) &&
                !Settings.IsCodeFixEnabled(CodeFixIdentifiers.UseUncheckedExpression) &&
                !Settings.IsCodeFixEnabled(CodeFixIdentifiers.RemoveConstModifier) &&
                !Settings.IsCodeFixEnabled(CodeFixIdentifiers.ReplaceNullLiteralExpressionWithDefaultValue) &&
                !Settings.IsCodeFixEnabled(CodeFixIdentifiers.UseCoalesceExpression) &&
                !Settings.IsCodeFixEnabled(CodeFixIdentifiers.RemoveConditionThatIsAlwaysEqualToTrueOrFalse))
            {
                return;
            }

            SyntaxNode root = await context.GetSyntaxRootAsync().ConfigureAwait(false);

            if (!TryFindNode(root, context.Span, out ExpressionSyntax expression))
            {
                return;
            }

            foreach (Diagnostic diagnostic in context.Diagnostics)
            {
                switch (diagnostic.Id)
                {
                case CompilerDiagnosticIdentifiers.CannotImplicitlyConvertTypeExplicitConversionExists:
                {
                    SemanticModel semanticModel = await context.GetSemanticModelAsync().ConfigureAwait(false);

                    TypeInfo typeInfo = semanticModel.GetTypeInfo(expression, context.CancellationToken);

                    ITypeSymbol type          = typeInfo.Type;
                    ITypeSymbol convertedType = typeInfo.ConvertedType;

                    if (type?.IsNamedType() == true)
                    {
                        var namedType = (INamedTypeSymbol)type;

                        if (namedType.ConstructedFrom.SpecialType == SpecialType.System_Nullable_T)
                        {
                            if (convertedType?.IsBoolean() == true ||
                                AddComparisonWithBooleanLiteralRefactoring.IsCondition(expression))
                            {
                                if (Settings.IsCodeFixEnabled(CodeFixIdentifiers.AddComparisonWithBooleanLiteral))
                                {
                                    CodeAction codeAction = CodeAction.Create(
                                        AddComparisonWithBooleanLiteralRefactoring.GetTitle(expression),
                                        cancellationToken => AddComparisonWithBooleanLiteralRefactoring.RefactorAsync(context.Document, expression, cancellationToken),
                                        GetEquivalenceKey(diagnostic, CodeFixIdentifiers.AddComparisonWithBooleanLiteral));

                                    context.RegisterCodeFix(codeAction, diagnostic);
                                }
                            }
                            else if (namedType.TypeArguments[0].Equals(convertedType))
                            {
                                if (Settings.IsCodeFixEnabled(CodeFixIdentifiers.UseCoalesceExpression))
                                {
                                    CodeAction codeAction = CodeAction.Create(
                                        "Use coalesce expression",
                                        cancellationToken =>
                                        {
                                            ExpressionSyntax defaultValue = convertedType.ToDefaultValueSyntax(semanticModel, expression.SpanStart);

                                            ExpressionSyntax newNode = CoalesceExpression(expression.WithoutTrivia(), defaultValue)
                                                                       .WithTriviaFrom(expression)
                                                                       .Parenthesize()
                                                                       .WithFormatterAnnotation();

                                            return(context.Document.ReplaceNodeAsync(expression, newNode, cancellationToken));
                                        },
                                        GetEquivalenceKey(diagnostic, CodeFixIdentifiers.UseCoalesceExpression));

                                    context.RegisterCodeFix(codeAction, diagnostic);
                                }
                            }
                        }
                    }

                    if (Settings.IsCodeFixEnabled(CodeFixIdentifiers.CreateSingletonArray) &&
                        type?.IsErrorType() == false &&
                        !type.Equals(convertedType) &&
                        convertedType.IsArrayType())
                    {
                        var arrayType = (IArrayTypeSymbol)convertedType;

                        if (semanticModel.IsImplicitConversion(expression, arrayType.ElementType))
                        {
                            CodeAction codeAction = CodeAction.Create(
                                "Create singleton array",
                                cancellationToken => CreateSingletonArrayRefactoring.RefactorAsync(context.Document, expression, arrayType.ElementType, semanticModel, cancellationToken),
                                GetEquivalenceKey(diagnostic, CodeFixIdentifiers.CreateSingletonArray));

                            context.RegisterCodeFix(codeAction, diagnostic);
                        }
                    }

                    break;
                }

                case CompilerDiagnosticIdentifiers.ConstantValueCannotBeConverted:
                {
                    if (!Settings.IsCodeFixEnabled(CodeFixIdentifiers.UseUncheckedExpression))
                    {
                        break;
                    }

                    CodeAction codeAction = CodeAction.Create(
                        "Use 'unchecked'",
                        cancellationToken =>
                        {
                            CheckedExpressionSyntax newNode = CSharpFactory.UncheckedExpression(expression.WithoutTrivia());

                            newNode = newNode.WithTriviaFrom(expression);

                            return(context.Document.ReplaceNodeAsync(expression, newNode, cancellationToken));
                        },
                        GetEquivalenceKey(diagnostic));

                    context.RegisterCodeFix(codeAction, diagnostic);
                    break;
                }

                case CompilerDiagnosticIdentifiers.ExpressionBeingAssignedMustBeConstant:
                {
                    if (!Settings.IsCodeFixEnabled(CodeFixIdentifiers.RemoveConstModifier))
                    {
                        break;
                    }

                    LocalDeclarationStatementSyntax localDeclarationStatement = GetLocalDeclarationStatement(expression);

                    if (localDeclarationStatement == null)
                    {
                        break;
                    }

                    SyntaxTokenList modifiers = localDeclarationStatement.Modifiers;

                    if (!modifiers.Contains(SyntaxKind.ConstKeyword))
                    {
                        break;
                    }

                    CodeAction codeAction = CodeAction.Create(
                        "Remove 'const' modifier",
                        cancellationToken =>
                        {
                            LocalDeclarationStatementSyntax newNode = localDeclarationStatement.RemoveModifier(SyntaxKind.ConstKeyword);

                            return(context.Document.ReplaceNodeAsync(localDeclarationStatement, newNode, cancellationToken));
                        },
                        GetEquivalenceKey(diagnostic));

                    context.RegisterCodeFix(codeAction, diagnostic);
                    break;
                }

                case CompilerDiagnosticIdentifiers.CannotConvertNullToTypeBecauseItIsNonNullableValueType:
                {
                    if (!Settings.IsCodeFixEnabled(CodeFixIdentifiers.ReplaceNullLiteralExpressionWithDefaultValue))
                    {
                        break;
                    }

                    SemanticModel semanticModel = await context.GetSemanticModelAsync().ConfigureAwait(false);

                    ITypeSymbol typeSymbol = semanticModel.GetTypeInfo(expression, context.CancellationToken).ConvertedType;

                    if (typeSymbol?.SupportsExplicitDeclaration() == true)
                    {
                        CodeAction codeAction = CodeAction.Create(
                            "Replace 'null' with default value",
                            cancellationToken =>
                            {
                                ExpressionSyntax newNode = typeSymbol.ToDefaultValueSyntax(semanticModel, expression.SpanStart);

                                return(context.Document.ReplaceNodeAsync(expression, newNode, cancellationToken));
                            },
                            GetEquivalenceKey(diagnostic));

                        context.RegisterCodeFix(codeAction, diagnostic);
                    }

                    break;
                }

                case CompilerDiagnosticIdentifiers.ResultOfExpressionIsAlwaysConstantSinceValueIsNeverEqualToNull:
                {
                    if (!Settings.IsCodeFixEnabled(CodeFixIdentifiers.RemoveConditionThatIsAlwaysEqualToTrueOrFalse))
                    {
                        break;
                    }

                    SemanticModel semanticModel = await context.GetSemanticModelAsync().ConfigureAwait(false);

                    if (!NullCheckExpression.TryCreate(expression, semanticModel, out NullCheckExpression nullCheck, context.CancellationToken))
                    {
                        break;
                    }

                    if (nullCheck.Kind != NullCheckKind.EqualsToNull &&
                        nullCheck.Kind != NullCheckKind.NotEqualsToNull)
                    {
                        break;
                    }

                    CodeAction codeAction = CodeAction.Create(
                        "Remove condition",
                        cancellationToken =>
                        {
                            SyntaxNode newRoot = RemoveHelper.RemoveCondition(root, expression, nullCheck.Kind == NullCheckKind.NotEqualsToNull);

                            return(Task.FromResult(context.Document.WithSyntaxRoot(newRoot)));
                        },
                        GetEquivalenceKey(diagnostic));

                    context.RegisterCodeFix(codeAction, diagnostic);

                    break;
                }
                }
            }
        }
        static bool IsArrayTypeSomeObviousTypeCase(SyntaxNodeAnalysisContext nodeContext, ExpressionSyntax initializerExpression, ITypeSymbol variableType, LocalDeclarationStatementSyntax localVariable)
        {
            var arrayCreationExpressionSyntax = initializerExpression as ArrayCreationExpressionSyntax;
            if (arrayCreationExpressionSyntax != null)
            {
                if (arrayCreationExpressionSyntax.Type.IsMissing)
                    return false;

                var arrayType = nodeContext.SemanticModel.GetTypeInfo(arrayCreationExpressionSyntax).ConvertedType;
                return arrayType != null && arrayCreationExpressionSyntax.Initializer != null && variableType.Equals(arrayType);
            }

            return false;
        }
 protected override bool IsSyntaxKind(ITypeSymbol type)
 {
     return((_csharpSyntaxKind != null && type.Equals(_csharpSyntaxKind)) ||
            (_basicSyntaxKind != null && type.Equals(_basicSyntaxKind)));
 }
        private bool IsCorrectTypeForYieldReturn(ITypeSymbol returnExpressionType, ITypeSymbol methodReturnType, SemanticModel model)
        {
            var ienumerableSymbol = model.Compilation.GetTypeByMetadataName("System.Collections.IEnumerable");
            var ienumeratorSymbol = model.Compilation.GetTypeByMetadataName("System.Collections.IEnumerator");

            if (ienumerableSymbol == null ||
                    ienumeratorSymbol == null)
            {
                return false;
            }

            if (!(methodReturnType.Equals(ienumerableSymbol) ||
                  methodReturnType.Equals(ienumeratorSymbol)))
            {
                return false;
            }

            return true;
        }
        public static bool Analyze(SyntaxNodeAnalysisContext context, InvocationExpressionSyntax invocation)
        {
            var memberAccess = (MemberAccessExpressionSyntax)invocation.Expression;

            ExpressionSyntax expression = memberAccess?.Expression;

            if (expression?.IsKind(SyntaxKind.InvocationExpression) == true)
            {
                var invocation2 = (InvocationExpressionSyntax)expression;

                ArgumentListSyntax argumentList = invocation2.ArgumentList;

                if (argumentList?.IsMissing == false)
                {
                    SeparatedSyntaxList <ArgumentSyntax> arguments = argumentList.Arguments;

                    if (arguments.Count == 1 &&
                        invocation2.Expression?.IsKind(SyntaxKind.SimpleMemberAccessExpression) == true)
                    {
                        var memberAccess2 = (MemberAccessExpressionSyntax)invocation2.Expression;

                        if (string.Equals(memberAccess2.Name?.Identifier.ValueText, "Where", StringComparison.Ordinal))
                        {
                            SemanticModel     semanticModel     = context.SemanticModel;
                            CancellationToken cancellationToken = context.CancellationToken;

                            IMethodSymbol invocationSymbol = semanticModel.GetMethodSymbol(invocation, cancellationToken);

                            if (invocationSymbol != null &&
                                IsEnumerableCastMethod(invocationSymbol, semanticModel))
                            {
                                IMethodSymbol invocation2Symbol = semanticModel.GetMethodSymbol(invocation2, cancellationToken);

                                if (invocation2Symbol != null &&
                                    (Symbol.IsEnumerableMethodWithPredicate(invocation2Symbol, "Where", semanticModel)))
                                {
                                    BinaryExpressionSyntax isExpression = GetIsExpression(arguments.First().Expression);

                                    if (isExpression != null)
                                    {
                                        var type = isExpression.Right as TypeSyntax;

                                        if (type != null)
                                        {
                                            TypeSyntax type2 = GetTypeArgument(memberAccess.Name);

                                            if (type2 != null)
                                            {
                                                ITypeSymbol typeSymbol = semanticModel.GetTypeSymbol(type);

                                                if (typeSymbol != null)
                                                {
                                                    ITypeSymbol typeSymbol2 = semanticModel.GetTypeSymbol(type2);

                                                    if (typeSymbol.Equals(typeSymbol2))
                                                    {
                                                        TextSpan span = TextSpan.FromBounds(memberAccess2.Name.Span.Start, invocation.Span.End);

                                                        if (!invocation.ContainsDirectives(span))
                                                        {
                                                            context.ReportDiagnostic(
                                                                DiagnosticDescriptors.SimplifyLinqMethodChain,
                                                                Location.Create(invocation.SyntaxTree, span));
                                                        }

                                                        return(true);
                                                    }
                                                }
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }

            return(false);
        }
Beispiel #33
0
    public bool ShouldPreferExplicitType(VBSyntax.ExpressionSyntax exp,
                                         ITypeSymbol expConvertedType,
                                         out bool isNothingLiteral)
    {
        var op = SemanticModel.GetExpressionOperation(exp);

        exp = op.Syntax as VBSyntax.ExpressionSyntax;
        var vbInitConstantValue = SemanticModel.GetConstantValue(exp);

        isNothingLiteral = vbInitConstantValue.HasValue && vbInitConstantValue.Value == null || exp is VBSyntax.LiteralExpressionSyntax les && les.IsKind(SyntaxKind.NothingLiteralExpression);
        bool shouldPreferExplicitType = expConvertedType != null && (expConvertedType.HasCsKeyword() || !expConvertedType.Equals(op.Type, SymbolEqualityComparer.IncludeNullability));

        return(shouldPreferExplicitType);
    }
Beispiel #34
0
        public static string GetCountOrLengthPropertyName(
            ITypeSymbol typeSymbol,
            SemanticModel semanticModel,
            int position)
        {
            SymbolKind kind = typeSymbol.Kind;

            if (kind == SymbolKind.ErrorType)
            {
                return(null);
            }

            if (kind == SymbolKind.ArrayType)
            {
                return("Length");
            }

            string propertyName = GetCountOrLengthPropertyName(typeSymbol.SpecialType);

            if (propertyName != null)
            {
                return((propertyName.Length > 0) ? propertyName : null);
            }

            ITypeSymbol originalDefinition = typeSymbol.OriginalDefinition;

            if (!typeSymbol.Equals(originalDefinition))
            {
                propertyName = GetCountOrLengthPropertyName(originalDefinition.SpecialType);

                if (propertyName != null)
                {
                    return((propertyName.Length > 0) ? propertyName : null);
                }
            }

            if (originalDefinition.ImplementsAny(
                    SpecialType.System_Collections_Generic_ICollection_T,
                    SpecialType.System_Collections_Generic_IReadOnlyCollection_T,
                    allInterfaces: true))
            {
                if (originalDefinition.TypeKind == TypeKind.Interface)
                {
                    return("Count");
                }

                foreach (ISymbol symbol in typeSymbol.GetMembers())
                {
                    if (symbol.Kind == SymbolKind.Property &&
                        StringUtility.Equals(symbol.Name, "Count", "Length") &&
                        semanticModel.IsAccessible(position, symbol))
                    {
                        return(symbol.Name);
                    }
                }
            }

            return(null);

            string GetCountOrLengthPropertyName(SpecialType specialType)
            {
                switch (specialType)
                {
                case SpecialType.System_String:
                case SpecialType.System_Array:
                    return("Length");

                case SpecialType.System_Collections_Generic_IList_T:
                case SpecialType.System_Collections_Generic_ICollection_T:
                case SpecialType.System_Collections_Generic_IReadOnlyList_T:
                case SpecialType.System_Collections_Generic_IReadOnlyCollection_T:
                    return("Count");

                case SpecialType.None:
                    return(null);
                }

                return("");
            }
        }
Beispiel #35
0
        /// <remarks>
        /// If there are type arguments on either side of assignment, we match type names instead of type equality 
        /// to account for inferred generic type arguments.
        /// e.g: Tuple.Create(0, true) returns Tuple&lt;X,y&gt; which isn't the same as type Tuple.
        /// otherwise, we match for type equivalence
        /// </remarks>
        private static bool IsContainerTypeEqualToReturnType(IMethodSymbol methodSymbol, 
            ITypeSymbol typeInDeclaration, 
            ITypeSymbol containingType)
        {
            var returnType = methodSymbol.ReturnType;

            if (typeInDeclaration?.GetTypeArguments().Length > 0 ||
                containingType.GetTypeArguments().Length > 0)
            {
                return containingType.Name.Equals(returnType.Name);
            }
            else
            {
                return containingType.Equals(returnType);
            }
        }
        public static bool IsDefaultValue(
            this SemanticModel semanticModel,
            ITypeSymbol typeSymbol,
            ExpressionSyntax expression,
            CancellationToken cancellationToken = default(CancellationToken))
        {
            if (semanticModel == null)
            {
                throw new ArgumentNullException(nameof(semanticModel));
            }

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

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

            if (typeSymbol.IsErrorType())
            {
                return(false);
            }

            SyntaxKind kind = expression.Kind();

            switch (typeSymbol.SpecialType)
            {
            case SpecialType.System_Void:
                return(false);

            case SpecialType.System_Boolean:
                return(semanticModel.IsConstantValue(expression, false, cancellationToken));

            case SpecialType.System_Char:
                return(semanticModel.IsConstantValue(expression, '\0', cancellationToken));

            case SpecialType.System_SByte:
                return(semanticModel.IsConstantValue(expression, cancellationToken));

            case SpecialType.System_Byte:
                return(semanticModel.IsConstantValue(expression, cancellationToken));

            case SpecialType.System_Int16:
                return(semanticModel.IsConstantValue(expression, cancellationToken));

            case SpecialType.System_UInt16:
                return(semanticModel.IsConstantValue(expression, cancellationToken));

            case SpecialType.System_Int32:
                return(semanticModel.IsConstantValue(expression, cancellationToken));

            case SpecialType.System_UInt32:
                return(semanticModel.IsConstantValue(expression, cancellationToken));

            case SpecialType.System_Int64:
                return(semanticModel.IsConstantValue(expression, cancellationToken));

            case SpecialType.System_UInt64:
                return(semanticModel.IsConstantValue(expression, cancellationToken));

            case SpecialType.System_Decimal:
                return(semanticModel.IsConstantValue(expression, cancellationToken));

            case SpecialType.System_Single:
                return(semanticModel.IsConstantValue(expression, cancellationToken));

            case SpecialType.System_Double:
                return(semanticModel.IsConstantValue(expression, cancellationToken));
            }

            if (typeSymbol.IsEnum())
            {
                INamedTypeSymbol underlyingType = ((INamedTypeSymbol)typeSymbol).EnumUnderlyingType;

                switch (underlyingType.SpecialType)
                {
                case SpecialType.System_SByte:
                    return(semanticModel.IsConstantValue(expression, cancellationToken));

                case SpecialType.System_Byte:
                    return(semanticModel.IsConstantValue(expression, cancellationToken));

                case SpecialType.System_Int16:
                    return(semanticModel.IsConstantValue(expression, cancellationToken));

                case SpecialType.System_UInt16:
                    return(semanticModel.IsConstantValue(expression, cancellationToken));

                case SpecialType.System_Int32:
                    return(semanticModel.IsConstantValue(expression, cancellationToken));

                case SpecialType.System_UInt32:
                    return(semanticModel.IsConstantValue(expression, cancellationToken));

                case SpecialType.System_Int64:
                    return(semanticModel.IsConstantValue(expression, cancellationToken));

                case SpecialType.System_UInt64:
                    return(semanticModel.IsConstantValue(expression, cancellationToken));
                }

                Debug.Assert(false, underlyingType.SpecialType.ToString());

                return(false);
            }

            if (typeSymbol.IsReferenceType)
            {
                if (kind == SyntaxKind.NullLiteralExpression)
                {
                    return(true);
                }
                else
                {
                    Optional <object> optional = semanticModel.GetConstantValue(expression, cancellationToken);

                    if (optional.HasValue)
                    {
                        return(optional.Value == null);
                    }
                }
            }

            if (typeSymbol.IsConstructedFrom(SpecialType.System_Nullable_T) &&
                kind == SyntaxKind.NullLiteralExpression)
            {
                return(true);
            }

            if (kind == SyntaxKind.DefaultExpression)
            {
                var defaultExpression = (DefaultExpressionSyntax)expression;

                TypeSyntax type = defaultExpression.Type;

                return(type != null &&
                       typeSymbol.Equals(semanticModel.GetTypeSymbol(type, cancellationToken)));
            }

            return(false);
        }
        static bool IsObjectCreationSomeObviousTypeCase(SyntaxNodeAnalysisContext nodeContext, ExpressionSyntax initializerExpression, ITypeSymbol variableType)
        {
            var objectCreationExpressionSyntax = initializerExpression as ObjectCreationExpressionSyntax;
            if (objectCreationExpressionSyntax != null)
            {
                var objectType = nodeContext.SemanticModel.GetTypeInfo(objectCreationExpressionSyntax, nodeContext.CancellationToken).ConvertedType;
                return objectType != null && variableType.Equals(objectType);
            }

            return false;
        }
        public sealed override async Task RegisterCodeFixesAsync(CodeFixContext context)
        {
            if (!Settings.IsAnyCodeFixEnabled(
                    CodeFixIdentifiers.AddComparisonWithBooleanLiteral,
                    CodeFixIdentifiers.CreateSingletonArray,
                    CodeFixIdentifiers.UseUncheckedExpression,
                    CodeFixIdentifiers.RemoveConstModifier,
                    CodeFixIdentifiers.ReplaceNullLiteralExpressionWithDefaultValue))
            {
                return;
            }

            SyntaxNode root = await context.GetSyntaxRootAsync().ConfigureAwait(false);

            var expression = root.FindNode(context.Span, getInnermostNodeForTie: true) as ExpressionSyntax;

            Debug.Assert(expression != null, $"{nameof(expression)} is null");

            if (expression == null)
            {
                return;
            }

            foreach (Diagnostic diagnostic in context.Diagnostics)
            {
                switch (diagnostic.Id)
                {
                case CompilerDiagnosticIdentifiers.CannotImplicitlyConvertTypeExplicitConversionExists:
                {
                    SemanticModel semanticModel = await context.GetSemanticModelAsync().ConfigureAwait(false);

                    TypeInfo typeInfo = semanticModel.GetTypeInfo(expression, context.CancellationToken);

                    ITypeSymbol type          = typeInfo.Type;
                    ITypeSymbol convertedType = typeInfo.ConvertedType;

                    if (Settings.IsCodeFixEnabled(CodeFixIdentifiers.AddComparisonWithBooleanLiteral) &&
                        type?.IsNullableOf(SpecialType.System_Boolean) == true)
                    {
                        if (convertedType?.IsBoolean() == true ||
                            AddComparisonWithBooleanLiteralRefactoring.IsCondition(expression))
                        {
                            CodeAction codeAction = CodeAction.Create(
                                AddComparisonWithBooleanLiteralRefactoring.GetTitle(expression),
                                cancellationToken => AddComparisonWithBooleanLiteralRefactoring.RefactorAsync(context.Document, expression, cancellationToken),
                                GetEquivalenceKey(diagnostic));

                            context.RegisterCodeFix(codeAction, diagnostic);
                        }
                    }

                    if (Settings.IsCodeFixEnabled(CodeFixIdentifiers.CreateSingletonArray) &&
                        type?.IsErrorType() == false &&
                        !type.Equals(convertedType) &&
                        convertedType.IsArrayType())
                    {
                        var arrayType = (IArrayTypeSymbol)convertedType;

                        if (semanticModel.IsImplicitConversion(expression, arrayType.ElementType))
                        {
                            CodeAction codeAction = CodeAction.Create(
                                "Create singleton array",
                                cancellationToken => CreateSingletonArrayRefactoring.RefactorAsync(context.Document, expression, arrayType.ElementType, semanticModel, cancellationToken),
                                GetEquivalenceKey(diagnostic));

                            context.RegisterCodeFix(codeAction, diagnostic);
                        }
                    }

                    break;
                }

                case CompilerDiagnosticIdentifiers.ConstantValueCannotBeConverted:
                {
                    if (!Settings.IsCodeFixEnabled(CodeFixIdentifiers.UseUncheckedExpression))
                    {
                        break;
                    }

                    CodeAction codeAction = CodeAction.Create(
                        "Use 'unchecked'",
                        cancellationToken =>
                        {
                            CheckedExpressionSyntax newNode = CSharpFactory.UncheckedExpression(expression.WithoutTrivia());

                            newNode = newNode.WithTriviaFrom(expression);

                            return(context.Document.ReplaceNodeAsync(expression, newNode, cancellationToken));
                        },
                        GetEquivalenceKey(diagnostic));

                    context.RegisterCodeFix(codeAction, diagnostic);
                    break;
                }

                case CompilerDiagnosticIdentifiers.ExpressionBeingAssignedMustBeConstant:
                {
                    if (!Settings.IsCodeFixEnabled(CodeFixIdentifiers.RemoveConstModifier))
                    {
                        break;
                    }

                    LocalDeclarationStatementSyntax localDeclarationStatement = GetLocalDeclarationStatement(expression);

                    if (localDeclarationStatement == null)
                    {
                        break;
                    }

                    SyntaxTokenList modifiers = localDeclarationStatement.Modifiers;

                    if (!modifiers.Contains(SyntaxKind.ConstKeyword))
                    {
                        break;
                    }

                    CodeAction codeAction = CodeAction.Create(
                        "Remove 'const' modifier",
                        cancellationToken =>
                        {
                            LocalDeclarationStatementSyntax newNode = localDeclarationStatement.RemoveModifier(SyntaxKind.ConstKeyword);

                            return(context.Document.ReplaceNodeAsync(localDeclarationStatement, newNode, cancellationToken));
                        },
                        GetEquivalenceKey(diagnostic));

                    context.RegisterCodeFix(codeAction, diagnostic);
                    break;
                }

                case CompilerDiagnosticIdentifiers.CannotConvertNullToTypeBecauseItIsNonNullableValueType:
                {
                    if (!Settings.IsCodeFixEnabled(CodeFixIdentifiers.ReplaceNullLiteralExpressionWithDefaultValue))
                    {
                        break;
                    }

                    SemanticModel semanticModel = await context.GetSemanticModelAsync().ConfigureAwait(false);

                    ITypeSymbol typeSymbol = semanticModel.GetTypeInfo(expression, context.CancellationToken).ConvertedType;

                    if (typeSymbol?.SupportsExplicitDeclaration() == true)
                    {
                        CodeAction codeAction = CodeAction.Create(
                            "Replace 'null' with default value",
                            cancellationToken =>
                            {
                                ExpressionSyntax newNode = typeSymbol.ToDefaultValueSyntax(semanticModel, expression.SpanStart);

                                return(context.Document.ReplaceNodeAsync(expression, newNode, cancellationToken));
                            },
                            GetEquivalenceKey(diagnostic));

                        context.RegisterCodeFix(codeAction, diagnostic);
                    }

                    break;
                }
                }
            }
        }
        /// <summary>
        /// Adds to <paramref name="targetType"/> if it does not contain an anonymous
        /// type and binds to the same type at the given <paramref name="position"/>.
        /// </summary>
        public static ExpressionSyntax CastIfPossible(
            this ExpressionSyntax expression,
            ITypeSymbol targetType,
            int position,
            SemanticModel semanticModel,
            out bool wasCastAdded)
        {
            wasCastAdded = false;

            if (targetType.ContainsAnonymousType())
            {
                return expression;
            }

            if (targetType.Kind == SymbolKind.DynamicType)
            {
                targetType = semanticModel.Compilation.GetSpecialType(SpecialType.System_Object);
            }

            var typeSyntax = targetType.GenerateTypeSyntax();
            var type = semanticModel.GetSpeculativeTypeInfo(
                position,
                typeSyntax,
                SpeculativeBindingOption.BindAsTypeOrNamespace).Type;

            if (!targetType.Equals(type))
            {
                return expression;
            }

            var castExpression = expression.Cast(targetType);

            // Ensure that inserting the cast doesn't change the semantics.
            var specAnalyzer = new SpeculationAnalyzer(expression, castExpression, semanticModel, CancellationToken.None);
            var speculativeSemanticModel = specAnalyzer.SpeculativeSemanticModel;
            if (speculativeSemanticModel == null)
            {
                return expression;
            }

            var speculatedCastExpression = (CastExpressionSyntax)specAnalyzer.ReplacedExpression;
            if (!speculatedCastExpression.IsUnnecessaryCast(speculativeSemanticModel, CancellationToken.None))
            {
                return expression;
            }

            wasCastAdded = true;
            return castExpression;
        }
Beispiel #40
0
        public override SyntaxNode VisitArgument(ArgumentSyntax node)
        {
            var ti = this.semanticModel.GetTypeInfo(node.Expression);

            ITypeSymbol      type      = null;
            IMethodSymbol    method    = null;
            IParameterSymbol parameter = null;

            if (ti.Type != null && ti.Type.TypeKind == TypeKind.Delegate)
            {
                type = ti.Type;
            }
            else if (ti.ConvertedType != null && ti.ConvertedType.TypeKind == TypeKind.Delegate)
            {
                type = ti.ConvertedType;
            }

            if (type != null)
            {
                var list       = node.Parent as ArgumentListSyntax;
                var invocation = node.Parent.Parent as InvocationExpressionSyntax;

                if (list != null && invocation != null)
                {
                    method = this.semanticModel.GetSymbolInfo(invocation).Symbol as IMethodSymbol;

                    if (method != null)
                    {
                        if (node.NameColon != null)
                        {
                            if (node.NameColon.Name != null)
                            {
                                var nameText = node.NameColon.Name.Identifier.ValueText;
                                if (nameText != null)
                                {
                                    foreach (var p in method.Parameters)
                                    {
                                        if (string.Equals(p.Name, nameText, StringComparison.Ordinal))
                                        {
                                            parameter = p;
                                            break;
                                        }
                                    }
                                }
                            }
                        }
                        else
                        {
                            var index = list.Arguments.IndexOf(node);
                            if (index >= 0)
                            {
                                if (index < method.Parameters.Length)
                                {
                                    parameter = method.Parameters[index];
                                }
                                else if (index >= method.Parameters.Length && method.Parameters[method.Parameters.Length - 1].IsParams)
                                {
                                    parameter = method.Parameters[method.Parameters.Length - 1];
                                }
                            }
                        }
                    }
                }
            }
            var isParam = parameter != null && !SyntaxHelper.IsAnonymous(parameter.Type);
            var parent  = isParam && parameter.IsParams ? (InvocationExpressionSyntax)node.Parent.Parent : null;

            node = (ArgumentSyntax)base.VisitArgument(node);

            if (isParam)
            {
                var pType = parameter.Type;
                if (parameter.IsParams && SharpSixRewriter.IsExpandedForm(this.semanticModel, parent, method))
                {
                    pType = ((IArrayTypeSymbol)parameter.Type).ElementType;
                }

                if (node.Expression is CastExpressionSyntax && type.Equals(pType) || parameter.RefKind != RefKind.None)
                {
                    return(node);
                }

                if (pType.TypeKind == TypeKind.Delegate || parameter.IsParams && ((IArrayTypeSymbol)parameter.Type).ElementType.TypeKind == TypeKind.Delegate)
                {
                    var name = SyntaxFactory.IdentifierName(pType.ToDisplayString(SymbolDisplayFormat.FullyQualifiedFormat)).WithoutTrivia();
                    var expr = node.Expression;

                    if (expr is LambdaExpressionSyntax || expr is AnonymousMethodExpressionSyntax)
                    {
                        expr = SyntaxFactory.ParenthesizedExpression(expr);
                    }

                    var cast = SyntaxFactory.CastExpression(name, expr);
                    node = node.WithExpression(cast);
                }
            }

            return(node);
        }
        private bool IsCorrectTypeForYieldReturn(ITypeSymbol typeArgument, ITypeSymbol returnExpressionType, ITypeSymbol methodReturnType, SemanticModel model)
        {
            var ienumerableSymbol = model.Compilation.GetTypeByMetadataName("System.Collections.IEnumerable");
            var ienumeratorSymbol = model.Compilation.GetTypeByMetadataName("System.Collections.IEnumerator");
            var ienumerableGenericSymbol = model.Compilation.GetTypeByMetadataName("System.Collections.Generic.IEnumerable`1");
            var ienumeratorGenericSymbol = model.Compilation.GetTypeByMetadataName("System.Collections.Generic.IEnumerator`1");

            if (ienumerableGenericSymbol == null ||
                ienumerableSymbol == null ||
                ienumeratorGenericSymbol == null ||
                ienumeratorSymbol == null)
            {
                return false;
            }

            ienumerableGenericSymbol = ienumerableGenericSymbol.Construct(typeArgument);
            ienumeratorGenericSymbol = ienumeratorGenericSymbol.Construct(typeArgument);

            if (!CanConvertTypes(typeArgument, returnExpressionType, model))
            {
                return false;
            }

            if (!(methodReturnType.Equals(ienumerableGenericSymbol) ||
                  methodReturnType.Equals(ienumerableSymbol) ||
                  methodReturnType.Equals(ienumeratorGenericSymbol) ||
                  methodReturnType.Equals(ienumeratorSymbol)))
            {
                return false;
            }

            return true;
        }
Beispiel #42
0
        public override SyntaxNode VisitIdentifierName(IdentifierNameSyntax node)
        {
            var symbol = semanticModel.GetSymbolInfo(node).Symbol;

            var parent = node.Parent;

            while (parent != null && !(parent is TypeDeclarationSyntax))
            {
                parent = parent.Parent;
            }

            ITypeSymbol thisType = null;

            if (parent is TypeDeclarationSyntax)
            {
                thisType = this.semanticModel.GetDeclaredSymbol(parent) as ITypeSymbol;
            }

            bool needHandle = !node.IsVar &&
                              symbol is ITypeSymbol &&
                              symbol.ContainingType != null &&
                              thisType != null &&
                              !thisType.InheritsFromOrEquals(symbol.ContainingType) &&
                              !thisType.Equals(symbol);

            var qns = node.Parent as QualifiedNameSyntax;

            if (qns != null && needHandle)
            {
                SyntaxNode n = node;
                do
                {
                    if (!qns.Left.Equals(n))
                    {
                        needHandle = false;
                    }

                    n   = qns;
                    qns = qns.Parent as QualifiedNameSyntax;
                } while (qns != null && needHandle);
            }

            node = (IdentifierNameSyntax)base.VisitIdentifierName(node);

            if (needHandle && !(node.Parent is MemberAccessExpressionSyntax))
            {
                INamedTypeSymbol namedType = symbol as INamedTypeSymbol;
                if (namedType != null && namedType.IsGenericType && namedType.TypeArguments.Length > 0 && !namedType.TypeArguments.Any(SyntaxHelper.IsAnonymous))
                {
                    var genericName = SyntaxHelper.GenerateGenericName(node.Identifier, namedType.TypeArguments);
                    return(genericName.WithLeadingTrivia(node.GetLeadingTrivia()).WithTrailingTrivia(node.GetTrailingTrivia()));
                }

                return(SyntaxFactory.IdentifierName(SyntaxFactory.Identifier(node.GetLeadingTrivia(), symbol.FullyQualifiedName(), node.GetTrailingTrivia())));
            }

            IMethodSymbol methodSymbol = null;

            if (symbol != null && symbol.IsStatic && symbol.ContainingType != null &&
                thisType != null && !thisType.InheritsFromOrEquals(symbol.ContainingType) &&
                !(node.Parent is MemberAccessExpressionSyntax) &&
                (
                    (methodSymbol = symbol as IMethodSymbol) != null ||
                    symbol is IPropertySymbol ||
                    symbol is IFieldSymbol ||
                    symbol is IEventSymbol)
                )
            {
                if (methodSymbol != null && methodSymbol.IsGenericMethod && methodSymbol.TypeArguments.Length > 0 && !methodSymbol.TypeArguments.Any(SyntaxHelper.IsAnonymous))
                {
                    var genericName = SyntaxHelper.GenerateGenericName(node.Identifier, methodSymbol.TypeArguments);
                    return(genericName.WithLeadingTrivia(node.GetLeadingTrivia()).WithTrailingTrivia(node.GetTrailingTrivia()));
                }

                return(SyntaxFactory.IdentifierName(SyntaxFactory.Identifier(node.GetLeadingTrivia(), symbol.FullyQualifiedName(), node.GetTrailingTrivia())));
            }

            return(node);
        }
Beispiel #43
0
        public sealed override async Task RegisterCodeFixesAsync(CodeFixContext context)
        {
            if (!Settings.IsAnyCodeFixEnabled(
                    CodeFixIdentifiers.AddOutModifierToArgument,
                    CodeFixIdentifiers.RemoveRefModifier,
                    CodeFixIdentifiers.CreateSingletonArray))
            {
                return;
            }

            SyntaxNode root = await context.GetSyntaxRootAsync().ConfigureAwait(false);

            if (!TryFindFirstAncestorOrSelf(root, context.Span, out ArgumentSyntax argument))
            {
                return;
            }

            foreach (Diagnostic diagnostic in context.Diagnostics)
            {
                switch (diagnostic.Id)
                {
                case CompilerDiagnosticIdentifiers.ArgumentMustBePassedWithOutKeyword:
                {
                    if (!Settings.IsCodeFixEnabled(CodeFixIdentifiers.AddOutModifierToArgument))
                    {
                        return;
                    }

                    CodeAction codeAction = CodeAction.Create(
                        "Add 'out' modifier",
                        cancellationToken =>
                        {
                            ArgumentSyntax newArgument = argument
                                                         .WithRefOrOutKeyword(CSharpFactory.OutKeyword())
                                                         .WithFormatterAnnotation();

                            return(context.Document.ReplaceNodeAsync(argument, newArgument, cancellationToken));
                        },
                        GetEquivalenceKey(diagnostic));

                    context.RegisterCodeFix(codeAction, diagnostic);

                    break;
                }

                case CompilerDiagnosticIdentifiers.ArgumentMayNotBePassedWithRefKeyword:
                {
                    if (!Settings.IsCodeFixEnabled(CodeFixIdentifiers.RemoveRefModifier))
                    {
                        return;
                    }

                    CodeAction codeAction = CodeAction.Create(
                        "Remove 'ref' modifier",
                        cancellationToken =>
                        {
                            ArgumentSyntax newArgument = argument
                                                         .WithRefOrOutKeyword(default(SyntaxToken))
                                                         .PrependToLeadingTrivia(argument.RefOrOutKeyword.GetLeadingAndTrailingTrivia())
                                                         .WithFormatterAnnotation();

                            return(context.Document.ReplaceNodeAsync(argument, newArgument, cancellationToken));
                        },
                        GetEquivalenceKey(diagnostic));

                    context.RegisterCodeFix(codeAction, diagnostic);
                    break;
                }

                case CompilerDiagnosticIdentifiers.CannotConvertArgumentType:
                {
                    if (!Settings.IsCodeFixEnabled(CodeFixIdentifiers.AddOutModifierToArgument))
                    {
                        return;
                    }

                    ExpressionSyntax expression = argument.Expression;

                    if (expression?.IsMissing == false)
                    {
                        SemanticModel semanticModel = await context.GetSemanticModelAsync().ConfigureAwait(false);

                        ITypeSymbol typeSymbol = semanticModel.GetTypeSymbol(expression);

                        if (typeSymbol?.IsErrorType() == false)
                        {
                            foreach (ITypeSymbol typeSymbol2 in DetermineParameterTypeHelper.DetermineParameterTypes(argument, semanticModel, context.CancellationToken))
                            {
                                if (!typeSymbol.Equals(typeSymbol2) &&
                                    typeSymbol2.IsArrayType())
                                {
                                    var arrayType = (IArrayTypeSymbol)typeSymbol2;

                                    if (semanticModel.IsImplicitConversion(expression, arrayType.ElementType))
                                    {
                                        CodeAction codeAction = CodeAction.Create(
                                            "Create singleton array",
                                            cancellationToken => CreateSingletonArrayRefactoring.RefactorAsync(context.Document, expression, arrayType.ElementType, semanticModel, cancellationToken),
                                            GetEquivalenceKey(diagnostic));

                                        context.RegisterCodeFix(codeAction, diagnostic);
                                        break;
                                    }
                                }
                            }
                        }
                    }

                    break;
                }
                }
            }
        }
        protected static bool IsInvocationSomeObviousTypeCase(SyntaxNodeAnalysisContext nodeContext, ExpressionSyntax initializerExpression, ITypeSymbol variableType)
        {
            var invocationExpression = initializerExpression as InvocationExpressionSyntax;
            if (invocationExpression != null)
            {
                var invokedMethod = nodeContext.SemanticModel.GetSymbolInfo(invocationExpression, nodeContext.CancellationToken).Symbol as IMethodSymbol;
                return invokedMethod != null && variableType.Equals(invokedMethod.ReturnType);
            }

            return false;
        }