static bool IsDeclarationConstFriendly(LocalDeclarationStatementSyntax declaration, SemanticModel semanticModel)
        {
            // all variables could be const?
            foreach (var variable in declaration.Declaration.Variables)
            {
                if (variable.Initializer == null) return false;
                if (variable.Initializer.Value is InterpolatedStringExpressionSyntax) return false;

                // is constant
                var constantValue = semanticModel.GetConstantValue(variable.Initializer.Value);
                var valueIsConstant = constantValue.HasValue;
                if (!valueIsConstant) return false;

                // if reference type, value is null?
                var variableTypeName = declaration.Declaration.Type;
                var variableType = semanticModel.GetTypeInfo(variableTypeName).ConvertedType;
                if (variableType.IsReferenceType && variableType.SpecialType != SpecialType.System_String && constantValue.Value != null) return false;

                // nullable?
                if (variableType.OriginalDefinition?.SpecialType == SpecialType.System_Nullable_T) return false;

                // value can be converted to variable type?
                var conversion = semanticModel.ClassifyConversion(variable.Initializer.Value, variableType);
                if (!conversion.Exists || conversion.IsUserDefined) return false;
            }
            return true;
        }
        static void RegisterFix(CodeFixContext context, SemanticModel model, SyntaxNode root, Diagnostic diagnostic, InvocationExpressionSyntax invocationExpression, string stringComparison, string message, CancellationToken cancellationToken = default(CancellationToken))
        {
            bool? ignoreCase = null;
            ExpressionSyntax caseArg = null;

            if (invocationExpression.ArgumentList.Arguments.Count == 3)
            {
                var arg = model.GetConstantValue(invocationExpression.ArgumentList.Arguments[2].Expression, cancellationToken);
                if (arg.HasValue)
                {
                    ignoreCase = (bool)arg.Value;
                }
                else
                {
                    caseArg = invocationExpression.ArgumentList.Arguments[2].Expression;
                }
            }

            if (invocationExpression.ArgumentList.Arguments.Count == 6)
            {
                var arg = model.GetConstantValue(invocationExpression.ArgumentList.Arguments[5].Expression, cancellationToken);
                if (arg.HasValue)
                {
                    ignoreCase = (bool)arg.Value;
                }
                else
                {
                    caseArg = invocationExpression.ArgumentList.Arguments[5].Expression;
                }
            }
            var argumentList = new List<ArgumentSyntax>();
            if (invocationExpression.ArgumentList.Arguments.Count <= 3)
            {
                argumentList.AddRange(invocationExpression.ArgumentList.Arguments.Take(2));
            }
            else
            {
                argumentList.AddRange(invocationExpression.ArgumentList.Arguments.Take(5));
            }

            argumentList.Add(SyntaxFactory.Argument(CreateCompareArgument(invocationExpression, ignoreCase, caseArg, stringComparison)));
            var newArguments = SyntaxFactory.ArgumentList(SyntaxFactory.SeparatedList(argumentList));
            var newInvocation = SyntaxFactory.InvocationExpression(invocationExpression.Expression, newArguments);
            var newRoot = root.ReplaceNode(invocationExpression, newInvocation.WithAdditionalAnnotations(Formatter.Annotation));

            context.RegisterCodeFix(CodeActionFactory.Create(invocationExpression.Span, diagnostic.Severity, message, context.Document.WithSyntaxRoot(newRoot)), diagnostic);
        }
 internal static SyntaxNode ComputeExpression(SyntaxNode nodeToReplace, BinaryExpressionSyntax expression, SyntaxNode root, SemanticModel semanticModel)
 {
     var result = semanticModel.GetConstantValue(expression);
     if (!result.HasValue) return null;
     var newExpression = SyntaxFactory.ParseExpression(System.Convert.ToString(result.Value, System.Globalization.CultureInfo.InvariantCulture));
     var newRoot = root.ReplaceNode(nodeToReplace, newExpression);
     return newRoot;
 }
        private static bool IsLiteral(ExpressionSyntax expression, SemanticModel semanticModel)
        {
            // Default expressions are most of the time constants, but not for default(MyStruct).
            if (expression.IsKind(SyntaxKind.DefaultExpression))
            {
                return true;
            }

            var constantValue = semanticModel.GetConstantValue(expression);
            if (constantValue.HasValue)
            {
                return true;
            }

            IFieldSymbol fieldSymbol = semanticModel.GetSymbolInfo(expression).Symbol as IFieldSymbol;

            if (fieldSymbol != null)
            {
                return fieldSymbol.IsStatic && fieldSymbol.IsReadOnly;
            }

            return false;
        }
        private string GetStatus(INamedTypeSymbol classSymbol, SyntaxNode root, SemanticModel model, DiagnosticDescriptor descriptor)
        {
            // Some analyzers use multiple descriptors. We analyze the first one and hope that
            // thats enough.
            var members = GetDescriptors(classSymbol);

            foreach (var member in members)
            {
                ObjectCreationExpressionSyntax initializer = GetObjectCreationExpression(root, member);

                if (initializer == null)
                {
                    continue;
                }

                var firstArgument = initializer.ArgumentList.Arguments[0];

                string constantValue = (string)model.GetConstantValue(firstArgument.Expression).Value;

                if (constantValue != descriptor.Id)
                {
                    continue;
                }

                // We use the fact that the only parameter that returns a boolean is the one we are interested in
                var enabledByDefaultParameter = from argument in initializer.ArgumentList.Arguments
                                                where model.GetTypeInfo(argument.Expression).Type == this.booleanType
                                                select argument.Expression;
                var parameter = enabledByDefaultParameter.FirstOrDefault();
                string parameterString = parameter.ToString();
                var analyzerConstantLength = "AnalyzerConstants.".Length;

                if (parameterString.Length < analyzerConstantLength)
                {
                    return parameterString;
                }

                return parameter.ToString().Substring(analyzerConstantLength);
            }

            return "Unknown";
        }
        private string GetStatus(INamedTypeSymbol classSymbol, SyntaxNode root, SemanticModel model, DiagnosticDescriptor descriptor)
        {
            // Some analyzers use multiple descriptors. We analyze the first one and hope that
            // thats enough.
            var members = classSymbol.GetMembers().Where(x => x.Name.Contains("Descriptor")).ToArray();

            foreach (var member in members)
            {
                ObjectCreationExpressionSyntax initializer;
                SyntaxNode node = root.FindNode(member.Locations.FirstOrDefault().SourceSpan);

                if (node != null)
                {
                    initializer = (node as PropertyDeclarationSyntax)?.Initializer?.Value as ObjectCreationExpressionSyntax;
                    if (initializer == null)
                    {
                        initializer = (node as VariableDeclaratorSyntax)?.Initializer?.Value as ObjectCreationExpressionSyntax;

                        if (initializer == null)
                        {
                            continue;
                        }
                    }
                }
                else
                {
                    continue;
                }

                var firstArgument = initializer.ArgumentList.Arguments[0];

                string constantValue = (string)model.GetConstantValue(firstArgument.Expression).Value;

                if (constantValue != descriptor.Id)
                {
                    continue;
                }

                // We use the fact that the only parameter that returns a boolean is the one we are interested in
                var enabledByDefaultParameter = from argument in initializer.ArgumentList.Arguments
                                                where model.GetTypeInfo(argument.Expression).Type == this.booleanType
                                                select argument.Expression;
                var parameter = enabledByDefaultParameter.FirstOrDefault();
                string parameterString = parameter.ToString();
                var analyzerConstantLength = "AnalyzerConstants.".Length;

                if (parameterString.Length < analyzerConstantLength)
                {
                    return parameterString;
                }

                return parameter.ToString().Substring(analyzerConstantLength);
            }

            return "Unknown";
        }
        internal static bool IsPositiveInfinity(SemanticModel semanticModel, SyntaxNode node)
        {
            var rr = semanticModel.GetConstantValue(node);
            if (!rr.HasValue)
                return false;

            return rr.Value is double && double.IsPositiveInfinity((double)rr.Value) || rr.Value is float && float.IsPositiveInfinity((float)rr.Value);
        }
 static bool IsConstantExpression(SemanticModel context, ExpressionSyntax expr)
 {
     if (expr is LiteralExpressionSyntax)
         return true;
     if (expr is DefaultExpressionSyntax)
         return true;
     return context.GetConstantValue(expr).HasValue;
 }
예제 #9
0
 public static bool NodeHasConstantValueBoolFalse(SyntaxNode node, SemanticModel model)
 {
     if (node == null || model == null)
     {
         return false;
     }
     Optional<object> value = model.GetConstantValue(node);
     return value.HasValue &&
            value.Value is bool &&
            (bool)value.Value == false;
 }
예제 #10
0
        private static bool CanBeMadeConst(LocalDeclarationStatementSyntax localDeclaration, SemanticModel semanticModel)
        {
            // already const?
            if (localDeclaration.Modifiers.Any(SyntaxKind.ConstKeyword))
            {
                return false;
            }

            // Ensure that all variables in the local declaration have initializers that
            // are assigned with constant values.
            foreach (var variable in localDeclaration.Declaration.Variables)
            {
                var initializer = variable.Initializer;
                if (initializer == null)
                {
                    return false;
                }

                var constantValue = semanticModel.GetConstantValue(initializer.Value);
                if (!constantValue.HasValue)
                {
                    return false;
                }

                var variableTypeName = localDeclaration.Declaration.Type;
                var variableType = semanticModel.GetTypeInfo(variableTypeName).ConvertedType;

                // Ensure that the initializer value can be converted to the type of the
                // local declaration without a user-defined conversion.
                var conversion = semanticModel.ClassifyConversion(initializer.Value, variableType);
                if (!conversion.Exists || conversion.IsUserDefined)
                {
                    return false;
                }

                // Special cases:
                //   * If the constant value is a string, the type of the local declaration
                //     must be System.String.
                //   * If the constant value is null, the type of the local declaration must
                //     be a reference type.
                if (constantValue.Value is string)
                {
                    if (variableType.SpecialType != SpecialType.System_String)
                    {
                        return false;
                    }
                }
                else if (variableType.IsReferenceType && constantValue.Value != null)
                {
                    return false;
                }
            }

            // Perform data flow analysis on the local declaration.
            var dataFlowAnalysis = semanticModel.AnalyzeDataFlow(localDeclaration);

            // Retrieve the local symbol for each variable in the local declaration
            // and ensure that it is not written outside of the data flow analysis region.
            foreach (var variable in localDeclaration.Declaration.Variables)
            {
                var variableSymbol = semanticModel.GetDeclaredSymbol(variable);
                if (dataFlowAnalysis.WrittenOutside.Contains(variableSymbol))
                {
                    return false;
                }
            }

            return true;
        }
예제 #11
0
 public static bool NodeHasConstantValueIntZero(SyntaxNode node, SemanticModel model)
 {
     if (node == null || model == null)
     {
         return false;
     }
     Optional<object> value = model.GetConstantValue(node);
     return value.HasValue &&
            value.Value is int &&
            (int)value.Value == 0;
 }
        private static bool InsideNameOfExpression(ExpressionSyntax expr, SemanticModel semanticModel)
        {
            var nameOfInvocationExpr = expr.FirstAncestorOrSelf<InvocationExpressionSyntax>(
                invocationExpr =>
                {
                    var expression = invocationExpr.Expression as IdentifierNameSyntax;
                    return (expression != null) && (expression.Identifier.Text == "nameof") &&
                        semanticModel.GetConstantValue(invocationExpr).HasValue &&
                        (semanticModel.GetTypeInfo(invocationExpr).Type.SpecialType == SpecialType.System_String);
                });

            return nameOfInvocationExpr != null;
        }
        protected static bool CheckResxGeneratedFile(SemanticModel model, SyntaxNode attribute, SyntaxNode argument, CancellationToken cancellationToken)
        {
            if (!CheckDesignerFile(model.SyntaxTree))
            {
                return false;
            }

            var generatedCode = WellKnownTypes.GeneratedCodeAttribute(model.Compilation);
            if (model.GetSymbolInfo(attribute, cancellationToken).Symbol?.ContainingType?.Equals(generatedCode) != true)
            {
                return false;
            }

            var constValue = model.GetConstantValue(argument);
            if (!constValue.HasValue)
            {
                return false;
            }

            var stringValue = constValue.Value as string;
            if (stringValue == null)
            {
                return false;
            }

            if (stringValue.IndexOf(StronglyTypedResourceBuilder, StringComparison.OrdinalIgnoreCase) < 0)
            {
                return false;
            }

            return true;
        }
예제 #14
0
        internal static bool ArgumentHasDefaultValue(
            KeyValuePair<ArgumentSyntax, IParameterSymbol> argumentMapping,
            SemanticModel semanticModel)
        {
            var argument = argumentMapping.Key;
            var parameter = argumentMapping.Value;

            if (!parameter.HasExplicitDefaultValue)
            {
                return false;
            }

            var defaultValue = parameter.ExplicitDefaultValue;
            var argumentValue = semanticModel.GetConstantValue(argument.Expression);
            return argumentValue.HasValue &&
                   object.Equals(argumentValue.Value, defaultValue);
        }
        private static int? GetConstantArgumentValue(ArgumentSyntax argument, SemanticModel semanticModel)
        {
            var bound = semanticModel.GetConstantValue(argument.GetExpression());
            if (!bound.HasValue)
            {
                return null;
            }

            var boundValue = bound.Value as int?;
            return boundValue;
        }
예제 #16
0
        internal static bool ArgumentHasDefaultValue(
            ArgumentParameterMapping argumentMapping,
            SemanticModel semanticModel)
        {
            var argument = argumentMapping.Argument;
            var parameter = argumentMapping.Parameter;

            if (!parameter.HasExplicitDefaultValue)
            {
                return false;
            }

            var defaultValue = parameter.ExplicitDefaultValue;
            var argumentValue = semanticModel.GetConstantValue(argument.Expression);
            return argumentValue.HasValue &&
                   object.Equals(argumentValue.Value, defaultValue);
        }
 public static bool NodeHasConstantValueNull(SyntaxNode node, SemanticModel model)
 {
     if (node == null || model == null)
     {
         return false;
     }
     var value = model.GetConstantValue(node);
     return value.HasValue && value.Value == null;
 }