Beispiel #1
0
        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);
        }
Beispiel #2
0
        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);
        }
Beispiel #3
0
        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?");
        }
Beispiel #4
0
        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);
     }
 }
Beispiel #8
0
        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);
                }
            }
        }
Beispiel #9
0
        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");
                }
            }
        }
Beispiel #10
0
        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");
                }
            }
        }
Beispiel #11
0
        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);
                }
            }
        }
Beispiel #12
0
        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));
        }
Beispiel #13
0
        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);
     }
 }
Beispiel #15
0
        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);
                }
            }
        }
Beispiel #16
0
        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);
                }
            }
        }
Beispiel #17
0
        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();
        }
Beispiel #19
0
        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);
        }
Beispiel #20
0
        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);
        }
Beispiel #21
0
        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);
        }
Beispiel #22
0
        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");
        }
Beispiel #23
0
        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;
        }
Beispiel #24
0
        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();
 }