private static Dictionary <String, String> AppendMethodMapping(MethodInfo method, IEnumerable <Type> types, String prefix) { var mapping = new Dictionary <String, String>(); mapping.AddElements(GetGenericArgsMapping(method.ReturnType, types, "ret", prefix)); for (var i = 0; i < method.GetParameters().Length; ++i) { var parameterType = method.GetParameters()[i].ParameterType; mapping.AddElements(GetGenericArgsMapping(parameterType, types, "a" + i, prefix)); } return(mapping); }
public static Dictionary <TKey, TValue> ToDictionary <TKey, TValue>(this IEnumerable <KeyValuePair <TKey, TValue> > flattenedDict) { var dict = new Dictionary <TKey, TValue>(); dict.AddElements(flattenedDict); return(dict); }
public static ReadOnlyDictionary <MethodBase, MethodBase> MapInterfacesToImpls(this Type t, IEnumerable <Type> ifaces) { var map = new Dictionary <MethodBase, MethodBase>(); ifaces.ForEach(iface => map.AddElements(t.MapInterfacesToImpls(iface))); return(map.ToReadOnly()); }
// say, we have a type Type<(1) T1, (2) T2> with the method of the following signature: // T3[,][] Meth<(3) T3>(T1 o1, Func<T1, T3> o2) that has the following public type points: // // ReturnValue = T3 (a)[,][] // Args = T1 (b), Func<T1 (c), T3 (d)> // // to be perfectly fine we need the following typelinks to be built: // (3) <-> (a), (1) <-> (b), (1) <-> (c), (3) <-> (d) // // after some analysis we build the following mapping: // (key <- value) // a0 <- t[0] // a1[0] <- t[0] // a1[1] <- m[0] // ret[0][0] <- m[0] public static Dictionary <String, String> GetGenericArgsMapping(this MethodInfo method) { if (method == null) { return(null); } else { var pattern = (MethodInfo)method.Module.ResolveMethod(method.MetadataToken); var methodGenericArgs = pattern.XGetGenericArguments(); var typeGenericArgs = pattern.DeclaringType.XGetGenericArguments(); var mapping = new Dictionary <String, String>(); mapping.AddElements(AppendMethodMapping(pattern, methodGenericArgs, "m")); mapping.AddElements(AppendMethodMapping(pattern, typeGenericArgs, "t")); return(mapping); } }
// say, we have a type Type<(1) T1, (2) T2> with the method of the following signature: // T3[,][] Meth<(3) T3>(T1 o1, Func<T1, T3> o2) that has the following public type points: // // ReturnValue = T3 (a)[,][] // Args = T1 (b), Func<T1 (c), T3 (d)> // // to be perfectly fine we need the following typelinks to be built: // (3) <-> (a), (1) <-> (b), (1) <-> (c), (3) <-> (d) // // after some analysis we build the following mapping: // (key <- value) // a0 <- t[0] // a1[0] <- t[0] // a1[1] <- m[0] // ret[0][0] <- m[0] public static Dictionary<String, String> GetGenericArgsMapping(this MethodInfo method) { if (method == null) { return null; } else { var pattern = (MethodInfo)method.Module.ResolveMethod(method.MetadataToken); var methodGenericArgs = pattern.XGetGenericArguments(); var typeGenericArgs = pattern.DeclaringType.XGetGenericArguments(); var mapping = new Dictionary<String, String>(); mapping.AddElements(AppendMethodMapping(pattern, methodGenericArgs, "m")); mapping.AddElements(AppendMethodMapping(pattern, typeGenericArgs, "t")); return mapping; } }
protected CommandLineConfig(String[] s_args) { Log = Logger.Get(GetType()); Log.MinLevel = Level.Info; if (s_args.Count() == 1 && s_args[0] == "/?") { Banners.About(); throw new ConfigException(String.Empty); } else { if (s_args.LastOrDefault() == "/verbose") { IsVerbose = true; s_args = s_args.SkipLast().ToArray(); Info.WriteLine("Detected the \"/verbose\" switch, entering verbose mode."); Log.MinLevel = Level.Debug; Debug.EnsureBlankLine(); Debug.Write("Command line args are: "); if (s_args.IsEmpty()) { Debug.WriteLine("empty"); } else { Debug.WriteLine("({0} arg{1})", s_args.Count(), s_args.Count() == 1 ? "" : "s"); } s_args.ForEach((arg, i) => Debug.WriteLine("{0}: {1}", i + 1, arg)); } Debug.EnsureBlankLine(); Debug.WriteLine("Pre-parsing arguments..."); var named_args = new Dictionary <String, String>(); var shortcut_args = new List <String>(); foreach (var s_arg in s_args) { var m = s_arg.Parse("^-(?<name>.*?):(?<value>.*)$"); var name = m != null ? m["name"] : null; var value = m != null ? m["value"] : s_arg; if (m != null) { Debug.WriteLine("Parsed \"{0}\" as name/value pair: {1} => \"{2}\".", s_arg, name, value); } else { Debug.WriteLine("Parsed \"{0}\" as raw value.", s_arg); } if (name == null) { if (named_args.IsNotEmpty()) { throw new ConfigException("Fatal error: shortcut arguments must be specified before named arguments."); } else { shortcut_args.Add(value); } } else { if (named_args.ContainsKey(name)) { throw new ConfigException("Fatal error: duplicate argument \"{0}\".", name); } else { named_args.Add(name, value); } } } Debug.WriteLine("Pre-parse completed: found {0} named argument{1} and {2} shortcut argument{3}.", named_args.Count(), named_args.Count() == 1 ? "" : "s", shortcut_args.Count(), shortcut_args.Count() == 1 ? "" : "s"); Debug.EnsureBlankLine(); Debug.WriteLine("Parsing arguments..."); var parsed_args = new Dictionary <PropertyInfo, Object>(); if (named_args.IsNotEmpty()) { Debug.WriteLine("Parsing named arguments..."); parsed_args = ParseArgs(named_args); } if (shortcut_args.IsNotEmpty()) { Debug.WriteLine("Parsing shortcut arguments..."); Dictionary <PropertyInfo, Object> parsed_shortcut_args = null; var shortcuts = GetType().Attrs <ShortcutAttribute>().OrderBy(shortcut => shortcut.Priority); var bind_errors = new Dictionary <String, String>(); foreach (var shortcut in shortcuts) { Debug.WriteLine("Considering shortcut schema \"{0}\"...", shortcut.Schema); var words = shortcut.Schema.SplitWords(); if (words.Count() != shortcut_args.Count()) { var message = String.Format("argument count mismatch."); bind_errors.Add(shortcut.Schema, message); Debug.WriteLine("Schema \"{0}\" won't work: {1}", shortcut.Schema, message); continue; } try { parsed_shortcut_args = ParseArgs(words.Zip(shortcut_args).ToDictionary(t => t.Item1, t => t.Item2)); } catch (ConfigException cex) { bind_errors.Add(shortcut.Schema, cex.Message); Debug.WriteLine(cex.Message); Debug.WriteLine("Schema \"{0}\" won't work: failed to parse arguments.", shortcut.Schema); continue; } var dupes = Set.Intersect(parsed_args.Keys, parsed_shortcut_args.Keys); if (dupes.IsNotEmpty()) { var a = dupes.AssertFirst().Attr <ParamAttribute>(); var name = named_args.Keys.Single(k => a.Aliases.Contains(k)); Debug.WriteLine("Schema \"{0}\" won't work: shortcut argument duplicates parsed argument \"{1}\".", shortcut.Schema, name); parsed_shortcut_args = null; continue; } else { Debug.WriteLine("Schema \"{0}\" works fine, skipping other schemas (if any).", shortcut.Schema); break; } } if (parsed_shortcut_args == null) { var message = "Fatal error: failed to match the shortcuts."; var bind_summary = bind_errors.Select(kvp => String.Format("Failed to match \"{0}\": {1}", kvp.Key, kvp.Value.Replace("Fatal error: ", String.Empty))).StringJoin(Environment.NewLine); if (!IsVerbose) { message = message + Environment.NewLine + bind_summary; } throw new ConfigException(message); } else { parsed_args.AddElements(parsed_shortcut_args); } } Debug.WriteLine("Parse completed."); Debug.EnsureBlankLine(); Debug.WriteLine("Setting configuration parameters..."); var props = this.GetType().GetProperties(BF.AllInstance).Where(p => p.HasAttr <ParamAttribute>()).OrderBy(p => p.Attr <ParamAttribute>().Priority); props.ForEach(p => { if (parsed_args.ContainsKey(p)) { var value = parsed_args[p]; Debug.WriteLine("Resolved %{0} as {1}.", p.Name, value.ToLog()); p.SetValue(this, value, null); } else { var p_default = this.GetType().GetProperty("Default" + p.Name, BF.AllStatic); if (p_default == null) { throw new ConfigException("Fatal error: parameter \"{0}\" must be specified."); } var value = p_default.GetValue(null, null); Debug.WriteLine("Defaulted %{0} to {1}.", p.Name, value.ToLog()); p.SetValue(this, value, null); } }); Debug.WriteLine("Configuration parameters successfully set."); } }
private static Dictionary<String, String> AppendMethodMapping(MethodInfo method, IEnumerable<Type> types, String prefix) { var mapping = new Dictionary<String, String>(); mapping.AddElements(GetGenericArgsMapping(method.ReturnType, types, "ret", prefix)); for (var i = 0; i < method.GetParameters().Length; ++i) { var parameterType = method.GetParameters()[i].ParameterType; mapping.AddElements(GetGenericArgsMapping(parameterType, types, "a" + i, prefix)); } return mapping; }
protected CommandLineConfig(String[] s_args) { Log = Logger.Get(GetType()); Log.MinLevel = Level.Info; if (s_args.Count() == 1 && s_args[0] == "/?") { Banners.About(); throw new ConfigException(String.Empty); } else { if (s_args.LastOrDefault() == "/verbose") { IsVerbose = true; s_args = s_args.SkipLast().ToArray(); Info.WriteLine("Detected the \"/verbose\" switch, entering verbose mode."); Log.MinLevel = Level.Debug; Debug.EnsureBlankLine(); Debug.Write("Command line args are: "); if (s_args.IsEmpty()) Debug.WriteLine("empty"); else Debug.WriteLine("({0} arg{1})", s_args.Count(), s_args.Count() == 1 ? "" : "s"); s_args.ForEach((arg, i) => Debug.WriteLine("{0}: {1}", i + 1, arg)); } Debug.EnsureBlankLine(); Debug.WriteLine("Pre-parsing arguments..."); var named_args = new Dictionary<String, String>(); var shortcut_args = new List<String>(); foreach (var s_arg in s_args) { var m = s_arg.Parse("^-(?<name>.*?):(?<value>.*)$"); var name = m != null ? m["name"] : null; var value = m != null ? m["value"] : s_arg; if (m != null) Debug.WriteLine("Parsed \"{0}\" as name/value pair: {1} => \"{2}\".", s_arg, name, value); else Debug.WriteLine("Parsed \"{0}\" as raw value.", s_arg); if (name == null) { if (named_args.IsNotEmpty()) throw new ConfigException("Fatal error: shortcut arguments must be specified before named arguments."); else shortcut_args.Add(value); } else { if (named_args.ContainsKey(name)) throw new ConfigException("Fatal error: duplicate argument \"{0}\".", name); else named_args.Add(name, value); } } Debug.WriteLine("Pre-parse completed: found {0} named argument{1} and {2} shortcut argument{3}.", named_args.Count(), named_args.Count() == 1 ? "" : "s", shortcut_args.Count(), shortcut_args.Count() == 1 ? "" : "s"); Debug.EnsureBlankLine(); Debug.WriteLine("Parsing arguments..."); var parsed_args = new Dictionary<PropertyInfo, Object>(); if (named_args.IsNotEmpty()) { Debug.WriteLine("Parsing named arguments..."); parsed_args = ParseArgs(named_args); } if (shortcut_args.IsNotEmpty()) { Debug.WriteLine("Parsing shortcut arguments..."); Dictionary<PropertyInfo, Object> parsed_shortcut_args = null; var shortcuts = GetType().Attrs<ShortcutAttribute>().OrderBy(shortcut => shortcut.Priority); var bind_errors = new Dictionary<String, String>(); foreach (var shortcut in shortcuts) { Debug.WriteLine("Considering shortcut schema \"{0}\"...", shortcut.Schema); var words = shortcut.Schema.SplitWords(); if (words.Count() != shortcut_args.Count()) { var message = String.Format("argument count mismatch."); bind_errors.Add(shortcut.Schema, message); Debug.WriteLine("Schema \"{0}\" won't work: {1}", shortcut.Schema, message); continue; } try { parsed_shortcut_args = ParseArgs(words.Zip(shortcut_args).ToDictionary(t => t.Item1, t => t.Item2)); } catch (ConfigException cex) { bind_errors.Add(shortcut.Schema, cex.Message); Debug.WriteLine(cex.Message); Debug.WriteLine("Schema \"{0}\" won't work: failed to parse arguments.", shortcut.Schema); continue; } var dupes = Set.Intersect(parsed_args.Keys, parsed_shortcut_args.Keys); if (dupes.IsNotEmpty()) { var a = dupes.AssertFirst().Attr<ParamAttribute>(); var name = named_args.Keys.Single(k => a.Aliases.Contains(k)); Debug.WriteLine("Schema \"{0}\" won't work: shortcut argument duplicates parsed argument \"{1}\".", shortcut.Schema, name); parsed_shortcut_args = null; continue; } else { Debug.WriteLine("Schema \"{0}\" works fine, skipping other schemas (if any).", shortcut.Schema); break; } } if (parsed_shortcut_args == null) { var message = "Fatal error: failed to match the shortcuts."; var bind_summary = bind_errors.Select(kvp => String.Format("Failed to match \"{0}\": {1}", kvp.Key, kvp.Value.Replace("Fatal error: ", String.Empty))).StringJoin(Environment.NewLine); if (!IsVerbose) message = message + Environment.NewLine + bind_summary; throw new ConfigException(message); } else { parsed_args.AddElements(parsed_shortcut_args); } } Debug.WriteLine("Parse completed."); Debug.EnsureBlankLine(); Debug.WriteLine("Setting configuration parameters..."); var props = this.GetType().GetProperties(BF.AllInstance).Where(p => p.HasAttr<ParamAttribute>()).OrderBy(p => p.Attr<ParamAttribute>().Priority); props.ForEach(p => { if (parsed_args.ContainsKey(p)) { var value = parsed_args[p]; Debug.WriteLine("Resolved %{0} as {1}.", p.Name, value.ToLog()); p.SetValue(this, value, null); } else { var p_default = this.GetType().GetProperty("Default" + p.Name, BF.AllStatic); if (p_default == null) throw new ConfigException("Fatal error: parameter \"{0}\" must be specified."); var value = p_default.GetValue(null, null); Debug.WriteLine("Defaulted %{0} to {1}.", p.Name, value.ToLog()); p.SetValue(this, value, null); } }); Debug.WriteLine("Configuration parameters successfully set."); } }
public static ReadOnlyDictionary<MethodBase, MethodBase> MapInterfacesToImpls(this Type t, IEnumerable<Type> ifaces) { var map = new Dictionary<MethodBase, MethodBase>(); ifaces.ForEach(iface => map.AddElements(t.MapInterfacesToImpls(iface))); return map.ToReadOnly(); }