public Event Resolve(EventInfo e) { if (e == null) { return(null); } Event ret; if (_eventMap.TryGetValue(e, out ret)) { return(ret); } ret = new Event(); _eventMap[e] = ret; ret.Name = e.Name; ret.Access = AccessOf(e); ret.Nature = NatureOf(e); ret.HandlerType = (Delegate)Resolve(e.EventHandlerType); ret.XmlDoc = XmlDocReader.XMLFromMember(e); var m = e.EventHandlerType.GetMethod("Invoke"); ret.Return = Resolve(m.ReturnParameter); ret.Return.Name = "___ret"; foreach (var arg in m.GetParameters()) { ret.Parameters.Add(Resolve(arg)); } return(ret); }
public Constructor ResolveAsConstructor(MethodInfo method) { if (method == null) { return(null); } Constructor ret; if (_constructorMap.TryGetValue(method, out ret)) { return(ret); } ret = new Constructor(); _constructorMap[method] = ret; ret.Name = method.DeclaringType.Name; ret.Access = AccessOf(method); ret.Nature = MemberNature.Instance; ret.XmlDoc = XmlDocReader.XMLFromMember(method); foreach (var arg in method.GetParameters()) { ret.Parameters.Add(Resolve(arg)); } foreach (var arg in ret.Parameters) { arg.XmlDoc = ret.XmlDoc?.ChildNodes.OfType <XmlElement>().FirstOrDefault(xml => xml.LocalName == "typeparam" && xml.Attributes["name"].InnerText == arg.Name); } return(ret); }
public void It_finds_member_xml() { const string xml = @"<?xml version=""1.0""?> <doc> <assembly> <name>DragonFruit</name> </assembly> <members> <member name=""M:System.CommandLine.DragonFruit.Tests." + nameof(XmlDocReaderTests) + @".Program.Main(System.Boolean,System.String,System.Nullable{System.Int32})""> <summary> Hello </summary> <param name=""verbose"">Show verbose output</param> <param name=""flavor"">Which flavor to use</param> <param name=""count"">How many smoothies?</param> </member> </members> </doc> "; Action <bool, string, int?> action = Program.Main; var reader = new StringReader(xml); XmlDocReader.TryLoad(reader, out var docReader).Should().BeTrue(); docReader.TryGetMethodDescription(action.Method, out var helpMetadata).Should().BeTrue(); helpMetadata.Description.Should().Be("Hello"); helpMetadata.ParameterDescriptions["verbose"].Should().Be("Show verbose output"); helpMetadata.ParameterDescriptions["flavor"].Should().Be("Which flavor to use"); helpMetadata.ParameterDescriptions["count"].Should().Be("How many smoothies?"); }
private XElement GetMethodDocComments(MethodInfo mInfo) { XmlDocReader reader = this.GetDocReader(mInfo.DeclaringType.Assembly); if (reader != null) { return(reader.GetDocComments(mInfo)); } return(null); }
public XmlDocReader TryLoad_Sample1() { // I experienced problems with [IterationSetup]/[IterationCleanup] // https://github.com/dotnet/BenchmarkDotNet/issues/1127 // So I have ended up placing it here for now _xmlDocsStreamReader.BaseStream.Seek(0, SeekOrigin.Begin); // XmlDocReader.TryLoad(_xmlDocsStreamReader, out var docReader); return(docReader); }
public static CommandLineBuilder ConfigureHelpFromXmlComments( this CommandLineBuilder builder, MethodInfo method, string xmlDocsFilePath) { if (builder == null) { throw new ArgumentNullException(nameof(builder)); } if (method == null) { throw new ArgumentNullException(nameof(method)); } if (XmlDocReader.TryLoad(xmlDocsFilePath ?? GetDefaultXmlDocsFileLocation(method.DeclaringType.Assembly), out var xmlDocs)) { if (xmlDocs.TryGetMethodDescription(method, out CommandHelpMetadata metadata) && metadata.Description != null) { builder.Command.Description = metadata.Description; var options = builder.Options.ToArray(); foreach (var parameterDescription in metadata.ParameterDescriptions) { var kebabCasedParameterName = parameterDescription.Key.ToKebabCase(); var option = options.FirstOrDefault(o => o.HasAlias(kebabCasedParameterName)); if (option != null) { option.Description = parameterDescription.Value; } else { foreach (var argument in builder.Command.Arguments) { if (string.Equals( argument.Name, kebabCasedParameterName, StringComparison.OrdinalIgnoreCase)) { argument.Description = parameterDescription.Value; } } } } metadata.Name = method.DeclaringType.Assembly.GetName().Name; } } return(builder); }
public static bool TryLoad(string filePath, out XmlDocReader xmlDocReader) { try { return(TryLoad(File.OpenText(filePath), out xmlDocReader)); } catch { xmlDocReader = null; return(false); } }
public void EnrichTypeParameter(IProcessingContext context, Type type, Type typeParameter) { XmlDocReader reader = this.GetDocReader(type.Assembly); if (reader != null) { XElement element = reader.GetTypeParameterSummary(type, typeParameter); if (element != null) { this.RewriteXmlContent(context, typeParameter.Assembly, "summary", element); } } }
public void EnrichType(IProcessingContext context, Type type) { XmlDocReader reader = this.GetDocReader(type.Assembly); if (reader != null) { XElement element = reader.GetDocComments(type); if (element != null) { this.RewriteXml(context, type.Assembly, element, "typeparam"); } } }
public void EnrichConstructor(IProcessingContext context, ConstructorInfo ctor) { XmlDocReader reader = this.GetDocReader(ctor.DeclaringType.Assembly); if (reader != null) { XElement element = reader.GetDocComments(ctor); if (element != null) { this.RewriteXml(context, ctor.ReflectedType.Assembly, element, "param", "typeparam"); } } }
public void EnrichProperty(IProcessingContext context, PropertyInfo propertyInfo) { XmlDocReader reader = this.GetDocReader(propertyInfo.ReflectedType.Assembly); if (reader != null) { XElement element = reader.GetDocComments(propertyInfo); if (element != null) { this.RewriteXml(context, propertyInfo.ReflectedType.Assembly, element); } } }
public void Merge(Enum ast, System.Type type) { var names = System.Enum.GetNames(type); var values = System.Enum.GetValues(type).Cast <int>().ToArray(); for (int i = 0; i < names.Length; i++) { XmlElement xml = XmlDocReader.XMLFromMember(type.GetMember(names[i]).FirstOrDefault()); ast.Entries.Add(new Enum.Entry(names[i], values[i], xml)); } ast.UnderlyingType = Resolve(System.Enum.GetUnderlyingType(type)); }
public void EnrichEvent(IProcessingContext context, EventInfo eventInfo) { XmlDocReader reader = this.GetDocReader(eventInfo.ReflectedType.Assembly); if (reader != null) { XElement element = reader.GetDocComments(eventInfo); if (element != null) { this.RewriteXml(context, eventInfo.ReflectedType.Assembly, element); } } }
public static bool TryLoad(TextReader reader, out XmlDocReader xmlDocReader) { try { xmlDocReader = new XmlDocReader(XDocument.Load(reader)); return(true); } catch { xmlDocReader = null; return(false); } }
public void EnrichParameter(IProcessingContext context, ParameterInfo parameter) { XmlDocReader reader = this.GetDocReader(parameter.Member.ReflectedType.Assembly); if (reader != null) { XNamespace ns = "urn:doc"; XElement element = reader.GetDocComments(parameter); if (element != null) { this.RewriteXmlContent(context, parameter.Member.ReflectedType.Assembly, "summary", element); } } }
public void EnrichReturnValue(IProcessingContext context, MethodInfo methodInfo) { XmlDocReader reader = this.GetDocReader(methodInfo.ReflectedType.Assembly); if (reader != null) { XNamespace ns = "urn:doc"; XElement element = reader.GetDocCommentsReturnParameter(methodInfo.ReturnParameter); if (element != null) { this.RewriteXmlContent(context, methodInfo.ReflectedType.Assembly, "summary", element); } } }
public Field Resolve(FieldInfo field) { if (field == null) { return(null); } var ret = new Field(); ret.Name = field.Name; ret.Type = Resolve(field.FieldType); ret.IsArray = U.Deref(field.FieldType).IsArray; ret.Access = AccessOf(field); ret.XmlDoc = XmlDocReader.XMLFromMember(field); return(ret); }
public TimeWarpCommandLineBuilder(Command aRootCommand = null) : base(aRootCommand ?? new RootCommand()) { var startup = new Startup(); ServiceCollection = new ServiceCollection(); startup.ConfigureServices(ServiceCollection); startup.Configure(this); ServiceCollection.AddMediatR(typeof(Startup).GetTypeInfo().Assembly); ServiceProvider = ServiceCollection.BuildServiceProvider(); string xmlPath = Assembly.GetEntryAssembly().Location.Replace(".dll", ".xml"); XmlDocReader = new XmlDocReader(xmlPath); UseMediatorCommands(); }
public Method Resolve(MethodInfo method) { if (method == null) { return(null); } Method ret; if (_methodMap.TryGetValue(method, out ret)) { return(ret); } ret = new Method(); _methodMap[method] = ret; ret.Name = method.Name; ret.IsConst = (method.GetCustomAttribute <ConstAttribute>() != null); ret.Access = AccessOf(method); ret.Nature = NatureOf(method); ret.XmlDoc = XmlDocReader.XMLFromMember(method); ret.Return = Resolve(method.ReturnParameter); ret.Return.XmlDoc = ret.XmlDoc?["returns"]; ret.Return.Context = VariableContext.Return; ret.Return.Name = "___ret"; foreach (var arg in method.GetParameters()) { ret.Parameters.Add(Resolve(arg)); } foreach (var arg in ret.Parameters) { arg.XmlDoc = ret.XmlDoc?.ChildNodes.OfType <XmlElement>().FirstOrDefault(xml => xml.LocalName == "typeparam" && xml.Attributes["name"].InnerText == arg.Name); } return(ret); }
private XmlDocReader GetDocReader(Assembly assembly) { XmlDocReader reader; if (!this._docReaders.TryGetValue(assembly, out reader)) { string path = Path.Combine(Path.GetDirectoryName(assembly.Location), Path.GetFileNameWithoutExtension(assembly.Location) + ".xml"); if (!File.Exists(path)) { // check alt paths foreach (string dir in this._paths) { path = Path.Combine(dir, Path.GetFileNameWithoutExtension(assembly.Location) + ".xml"); if (File.Exists(path)) { break; } } } if (File.Exists(path)) { this._docReaders.Add(assembly, reader = new XmlDocReader()); using (XmlReader xreader = XmlReader.Create(path)) reader.Load(xreader); } else { reader = null; } } return(reader); }
public Property Resolve(PropertyInfo prop) { if (prop == null) { return(null); } if (prop.CanWrite && !prop.CanRead) { Errors.WriteOnlyProperty(prop); return(null); } Property ret; if (_propertyMap.TryGetValue(prop, out ret)) { return(ret); } ret = new Property(); _propertyMap[prop] = ret; ret.IsFactory = (prop.GetCustomAttribute <FactoryAttribute>() != null || prop.GetMethod.GetCustomAttribute <FactoryAttribute>() != null); ret.ConstGetter = !ret.IsFactory && (prop.GetMethod.GetCustomAttribute <UnconstAttribute>() == null); ret.IsBacked = (prop.GetCustomAttribute <BackedAttribute>() != null); ret.Name = prop.Name; ret.IsArray = U.Deref(prop.PropertyType).IsArray; ret.XmlDoc = XmlDocReader.XMLFromMember(prop); ret.Type = Resolve(prop.PropertyType); ret.Access = AccessOf(prop); ret.Nature = NatureOf(prop); ret.IsReadOnly = !prop.CanWrite; return(ret); }
public void It_finds_member_without_param() { const string xml = @"<?xml version=""1.0""?> <doc> <assembly> <name>DragonFruit</name> </assembly> <members> <member name=""M:System.CommandLine.DragonFruit.Tests." + nameof(XmlDocReaderTests) + @".Program.MainWithoutParam""> <summary> Hello </summary> </member> </members> </doc> "; Action action = Program.MainWithoutParam; var reader = new StringReader(xml); XmlDocReader.TryLoad(reader, out var docReader).Should().BeTrue(); docReader.TryGetMethodDescription(action.Method, out var helpMetadata).Should().BeTrue(); helpMetadata.Description.Should().Be("Hello"); }
private XmlDocReader GetDocReader(Assembly assembly) { XmlDocReader reader; if (!this._docReaders.TryGetValue(assembly, out reader)) { string path = Path.Combine(Path.GetDirectoryName(assembly.Location), Path.GetFileNameWithoutExtension(assembly.Location) + ".xml"); if (!File.Exists(path)) { // check alt paths foreach (string dir in this._paths) { path = Path.Combine(dir, Path.GetFileNameWithoutExtension(assembly.Location) + ".xml"); if (File.Exists(path)) break; } } if (File.Exists(path)) { this._docReaders.Add(assembly, reader = new XmlDocReader()); using (XmlReader xreader = XmlReader.Create(path)) reader.Load(xreader); } else reader = null; } return reader; }
public Type Resolve(System.Type type) { if (type == null) { return(null); } if (type.IsByRef) { return(Resolve(type.GetElementType())); } if (type.IsArray) { return(Resolve(type.GetElementType())); } Type ret; if (_typeMap.TryGetValue(type, out ret)) { return(ret); } ret = BasicTypes.Of(type); if (ret != null) { _typeMap[type] = ret; return(ret); } switch (ConstructOf(type)) { case Construct.Void: ret = new Void(); break; case Construct.Primitive: ret = new Primitive(); break; case Construct.Enum: ret = new Enum(); break; case Construct.String: ret = new String(); break; case Construct.Delegate: ret = new Delegate(); break; case Construct.Task: ret = new Task(); break; case Construct.Struct: ret = new Struct(); break; case Construct.Object: ret = new Object(); break; default: Debug.Assert(false); return(null); } _typeMap[type] = ret; Product.AllTypes.Add(ret); ret.Name = type.Name; ret.Namespace = Resolve(type.Namespace); ret.Assembly = Resolve(type.Assembly); ret.XmlDoc = XmlDocReader.XMLFromType(type); ret.IsAttribute = typeof(System.Attribute).IsAssignableFrom(type); var nativeAttr = type.GetCustomAttribute <NativeAttribute>(); if (ret.IsDelegate && ((AST.Delegate)ret).IsGeneric || ret.IsTask) { ret.Origin = TypeOrigin.Mapped; } else if (!ret.Assembly.IsGluonDefinition) { if (ret.ConstructType == Construct.Object) { ret.IsPureReference = true; } ret.Origin = TypeOrigin.Managed; } else if (nativeAttr == null) { ret.Origin = TypeOrigin.Gluon; } else { if (ret.ConstructType == Construct.Object) { ret.IsPureReference = true; } ret.Origin = TypeOrigin.Native; ret.CppHeader = nativeAttr.Header; ret.CppLib = nativeAttr.StaticLibrary; } foreach (var attr in type.GetCustomAttributesData()) { ret.Attributes.Add(Resolve(attr)); } int isPublic = (type.GetCustomAttribute <PublicAttribute>() != null ? 1 : 0); int isProtected = (type.GetCustomAttribute <ProtectedAttribute>() != null ? 1 : 0); int isInternal = (type.GetCustomAttribute <InternalAttribute>() != null ? 1 : 0); int isPrivate = (type.GetCustomAttribute <PrivateAttribute>() != null ? 1 : 0); ret.Access = Access.Public; if (isPublic + isProtected + isInternal + isPrivate > 1) { Errors.Generic(type.FullName + " has multiple, conflicting access attributes"); } else if (isPublic == 1) { ret.Access = Access.Public; } else if (isProtected == 1) { ret.Access = Access.Protected; } else if (isInternal == 1) { ret.Access = Access.Internal; } else if (isPrivate == 1) { ret.Access = Access.Private; } if (!ret.IsPureReference) { Merge(ret, type); } return(ret); }
public static void ConfigureFromMethod( this Command command, MethodInfo method, object target = null) { if (command == null) { throw new ArgumentNullException(nameof(command)); } if (method == null) { throw new ArgumentNullException(nameof(method)); } foreach (var option in method.BuildOptions()) { command.AddOption(option); } if (method.GetParameters() .FirstOrDefault(p => _argumentParameterNames.Contains(p.Name)) is ParameterInfo argsParam) { var argument = new Argument { ArgumentType = argsParam.ParameterType, Name = argsParam.Name }; if (argsParam.HasDefaultValue) { if (argsParam.DefaultValue != null) { argument.SetDefaultValue(argsParam.DefaultValue); } else { argument.SetDefaultValueFactory(() => null); } } command.AddArgument(argument); } if (XmlDocReader.TryLoad(GetDefaultXmlDocsFileLocation(method.DeclaringType.Assembly), out var xmlDocs)) { if (xmlDocs.TryGetMethodDescription(method, out CommandHelpMetadata metadata) && metadata.Description != null) { command.Description = metadata.Description; var options = command.Options.ToArray(); foreach (var parameterDescription in metadata.ParameterDescriptions) { var kebabCasedParameterName = parameterDescription.Key.ToKebabCase(); var option = options.FirstOrDefault(o => o.HasAlias(kebabCasedParameterName)); if (option != null) { option.Description = parameterDescription.Value; } else { foreach (var argument in command.Arguments) { if (string.Equals( argument.Name, kebabCasedParameterName, StringComparison.OrdinalIgnoreCase)) { argument.Description = parameterDescription.Value; } } } } metadata.Name = method.DeclaringType.Assembly.GetName().Name; } } command.Handler = CommandHandler.Create(method, target); }
public void SetupTryGetMethodDescription_Sample1() { _xmlDocReaderSample1 = TryLoad_Sample1(); }