public FactoryMethodsWriterVisitor(object o, OneOf <string, Language?> languageArg, bool hasPathSpans = false) : base( o, languageArg.ResolveLanguage() ?? throw new ArgumentException("Invalid language"), insertionPointKeys, hasPathSpans ) => writeUsings();
public ObjectNotationWriterVisitor(object o, OneOf <string, Language?> languageArg, bool hasPathSpans = false) : base(o, languageArg.ResolveLanguage() ?? throw new ArgumentException("Invalid language"), insertionPointKeys, hasPathSpans) { }
public static (bool isLiteral, string repr) TryRenderLiteral(object?o, OneOf <string, Language?> languageArg) { var language = languageArg.ResolveLanguage(); var rendered = true; string?ret = null; if (o is null) { ret = language == CSharp ? "null" : language == VisualBasic ? "Nothing" : "␀"; return(rendered, ret); } var type = o.GetType().UnderlyingIfNullable(); if (o is bool b) { ret = language == CSharp ? b ? "true" : "false" : b ? "True" : "False"; } else if (o is char c) { if (language == CSharp) { ret = $"'{c}'"; } else if (language == VisualBasic) { ret = $"\"{c}\"C"; } } else if ((o is DateTime) && language == VisualBasic) { ret = $"#{o:yyyy-MM-dd HH:mm:ss}#"; } else if (o is string s) { if (language.Inside(CSharp, VisualBasic)) { ret = s.ToVerbatimString(language); } else if (!s.HasSpecialCharacters()) { ret = $"\"{s}\""; } } else if (o is Enum e) { if (type.HasAttribute <FlagsAttribute>()) { var flagValues = e.GetIndividualFlags().ToArray(); var or = language switch { CSharp => " | ", VisualBasic => " Or ", _ => ", " }; ret = flagValues.Joined(or, flagValue => $"{type.Name}.{flagValue}"); } else { // If GetIndividualFlags is used with a non-Flags enum, it returns multiple values. // TODO this could probably be avoided by sorting the values in descending numeric order, then checking for the highest values first. // At the very least, GetIndividualFlags should throw an Exception if used with a non-flags enum ret = $"{type.Name}.{e}"; } } else if (o is Type t && language.Inside(CSharp, VisualBasic)) { var typeOp = language == CSharp ? "typeof" : "GetType"; // I'm not entirely sure a generic type definition type can have IsByRef == true var isByRef = false; if (t.IsByRef) { isByRef = true; t = t.GetElementType() !; } if (t.IsGenericParameter) { ret = $"Type.MakeGenericMethodParameter({t.GenericParameterPosition})"; } else if (!t.ContainsGenericParameters) { ret = t.IsAnonymous() ? $"{typeOp}(<{(language == CSharp ? "a" : "A")}nonymous({t.FriendlyName(language)})>)" : $"{typeOp}({t.FriendlyName(language)})"; } else if (t.IsGenericTypeDefinition) { var(pre, post) = language == CSharp ? ("<", ">") : ("(Of ", ")"); ret = $"{typeOp}({t.NonGenericName()}{pre}{t.GetGenericArguments().Joined(",", _ => "")}{post})"; } else { ret = $"{RenderLiteral(t.GetGenericTypeDefinition(), language)}.MakeGenericType({t.GenericTypeArguments.Joined(", ", x => RenderLiteral(x, language))})"; } if (isByRef) { ret += ".MakeByRefType()"; } }