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; }
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; }
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; }
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; }
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; }
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; }