/// <summary> /// Creates a generated expression for a default argument value. /// </summary> public static Expression?CreateGenerated(Context cx, IParameterSymbol parameter, IExpressionParentEntity parent, int childIndex, Extraction.Entities.Location location) { if (!parameter.HasExplicitDefaultValue) { return(null); } var defaultValue = parameter.ExplicitDefaultValue; if (parameter.Type is INamedTypeSymbol nt && nt.EnumUnderlyingType is not null) { // = (MyEnum)1, = MyEnum.Value1, = default(MyEnum), = new MyEnum() // we're generating a (MyEnum)value cast expression: defaultValue ??= 0; Action <Expression, int> createChild = (parent, index) => Literal.CreateGenerated(cx, parent, index, nt.EnumUnderlyingType, defaultValue, location); return(Cast.CreateGenerated(cx, parent, childIndex, parameter.Type, defaultValue, createChild, location)); } if (defaultValue is null) { // = null, = default, = default(T), = new MyStruct() // we're generating a default expression: return(Default.CreateGenerated(cx, parent, childIndex, location, parameter.Type.IsReferenceType ? ValueAsString(null) : null)); } // const literal: return(Literal.CreateGenerated(cx, parent, childIndex, parameter.Type, defaultValue, location)); }
/// <summary> /// Creates a generated expression for a default argument value. /// </summary> public static Expression?CreateGenerated(Context cx, IParameterSymbol parameter, IExpressionParentEntity parent, int childIndex, Extraction.Entities.Location location) { if (!parameter.HasExplicitDefaultValue || parameter.Type is IErrorTypeSymbol) { return(null); } var defaultValue = parameter.ExplicitDefaultValue; var type = parameter.Type; if (type.IsBoundNullable() && type is INamedTypeSymbol named) { type = named.TypeArguments[0]; } if (type is INamedTypeSymbol nt && nt.EnumUnderlyingType is not null) { // = (MyEnum)1, = MyEnum.Value1, = default(MyEnum), = new MyEnum() // we're generating a (MyEnum)value cast expression: defaultValue ??= 0; Action <Expression, int> createChild = (parent, index) => Literal.CreateGenerated(cx, parent, index, nt.EnumUnderlyingType, defaultValue, location); return(Cast.CreateGenerated(cx, parent, childIndex, parameter.Type, defaultValue, createChild, location)); } if (defaultValue is null) { // = null, = default, = default(T), = new MyStruct() // we're generating a default expression: return(Default.CreateGenerated(cx, parent, childIndex, location, parameter.Type.IsReferenceType ? ValueAsString(null) : null)); } if (parameter.Type.SpecialType is SpecialType.System_Object) { // this can happen in VB.NET cx.ExtractionError($"Extracting default argument value 'object {parameter.Name} = default' instead of 'object {parameter.Name} = {defaultValue}'. The latter is not supported in C#.", null, null, severity: Util.Logging.Severity.Warning); // we're generating a default expression: return(Default.CreateGenerated(cx, parent, childIndex, location, ValueAsString(null))); } // const literal: return(Literal.CreateGenerated(cx, parent, childIndex, type, defaultValue, location)); }
/// <summary> /// Creates a generated expression from a typed constant. /// </summary> public static Expression?CreateGenerated(Context cx, TypedConstant constant, IExpressionParentEntity parent, int childIndex, Extraction.Entities.Location location) { if (constant.IsNull || constant.Type is null) { return(Literal.CreateGeneratedNullLiteral(cx, parent, childIndex, location)); } switch (constant.Kind) { case TypedConstantKind.Primitive: return(Literal.CreateGenerated(cx, parent, childIndex, constant.Type, constant.Value, location)); case TypedConstantKind.Enum: // Enum value is generated in the following format: (Enum)value Action <Expression, int> createChild = (parent, index) => Literal.CreateGenerated(cx, parent, index, ((INamedTypeSymbol)constant.Type).EnumUnderlyingType !, constant.Value, location); var cast = Cast.CreateGenerated(cx, parent, childIndex, constant.Type !, constant.Value, createChild, location); return(cast); case TypedConstantKind.Type: var type = ((ITypeSymbol)constant.Value !).OriginalDefinition; return(TypeOf.CreateGenerated(cx, parent, childIndex, type, location)); case TypedConstantKind.Array: // Single dimensional arrays are in the following format: // * new Type[N] { item1, item2, ..., itemN } // * new Type[0] // // itemI is generated recursively. return(NormalArrayCreation.CreateGenerated(cx, parent, childIndex, constant.Type, constant.Values, location)); case TypedConstantKind.Error: default: cx.ExtractionError("Couldn't extract constant in attribute", constant.ToString(), location); return(null); } }