internal static bool CanAssignTo(this AttributeArgumentSyntax @this, ITypeSymbol target, SemanticModel model) { //See https://github.com/nunit/nunit/blob/f16d12d6fa9e5c879601ad57b4b24ec805c66054/src/NUnitFramework/framework/Attributes/TestCaseAttribute.cs#L396 //for the reasoning behind this implementation. Optional <object> possibleConstantValue = model.GetConstantValue(@this.Expression); object argumentValue = null; if (possibleConstantValue.HasValue) { argumentValue = possibleConstantValue.Value; } TypeInfo sourceTypeInfo = model.GetTypeInfo(@this.Expression); ITypeSymbol argumentType = sourceTypeInfo.Type; if (argumentType == null) { return(target.IsReferenceType || target.OriginalDefinition.SpecialType == SpecialType.System_Nullable_T); } else { var targetType = GetTargetType(target); if (targetType.IsAssignableFrom(argumentType)) { return(true); } else { var canConvert = false; if (targetType.SpecialType == SpecialType.System_Int16 || targetType.SpecialType == SpecialType.System_Byte || targetType.SpecialType == SpecialType.System_Int64 || targetType.SpecialType == SpecialType.System_SByte || targetType.SpecialType == SpecialType.System_Double) { canConvert = argumentType.SpecialType == SpecialType.System_Int32; } else if (targetType.SpecialType == SpecialType.System_Decimal) { canConvert = argumentType.SpecialType == SpecialType.System_Double || argumentType.SpecialType == SpecialType.System_String || argumentType.SpecialType == SpecialType.System_Int32; } else if (targetType.SpecialType == SpecialType.System_DateTime) { canConvert = argumentType.SpecialType == SpecialType.System_String; } if (canConvert) { return(AttributeArgumentSyntaxExtensions.TryChangeType(targetType, argumentValue)); } else if (argumentType.SpecialType == SpecialType.System_String && model.Compilation.GetTypeByMetadataName(typeof(TimeSpan).FullName).IsAssignableFrom(targetType)) { canConvert = TimeSpan.TryParse(argumentValue as string, out _); } return(canConvert); } } }
internal static bool CanAssignTo(this AttributeArgumentSyntax @this, ITypeSymbol target, SemanticModel model) { //See https://github.com/nunit/nunit/blob/master/src/NUnitFramework/framework/Attributes/TestCaseAttribute.cs#L363 //for the reasoning behind this implementation. object argumentValue = null; if (@this.Expression is LiteralExpressionSyntax) { argumentValue = (@this.Expression as LiteralExpressionSyntax).Token.Value; } TypeInfo sourceTypeInfo = model.GetTypeInfo(@this.Expression); ITypeSymbol argumentType = sourceTypeInfo.Type; if (sourceTypeInfo.Type == null) { return(target.IsReferenceType || target.OriginalDefinition.SpecialType == SpecialType.System_Nullable_T); } else { var targetType = GetTargetType(target); if (targetType.IsAssignableFrom(argumentType)) { return(true); } else { var canConvert = false; if (targetType.SpecialType == SpecialType.System_Int16 || targetType.SpecialType == SpecialType.System_Byte || targetType.SpecialType == SpecialType.System_SByte || targetType.SpecialType == SpecialType.System_Double) { canConvert = argumentType.SpecialType == SpecialType.System_Int32; } else if (targetType.SpecialType == SpecialType.System_Decimal) { canConvert = argumentType.SpecialType == SpecialType.System_Double || argumentType.SpecialType == SpecialType.System_String || argumentType.SpecialType == SpecialType.System_Int32; } else if (targetType.SpecialType == SpecialType.System_DateTime) { canConvert = argumentType.SpecialType == SpecialType.System_String; } if (canConvert) { return(AttributeArgumentSyntaxExtensions.TryChangeType(targetType, argumentValue)); } else if (argumentType.SpecialType == SpecialType.System_String && model.Compilation.GetTypeByMetadataName(typeof(TimeSpan).FullName).IsAssignableFrom(targetType)) { var outValue = default(TimeSpan); canConvert = TimeSpan.TryParse(argumentValue as string, out outValue); } return(canConvert); } } }