コード例 #1
0
ファイル: TypeLoader.cs プロジェクト: seanofw/crossdox
        public TypeCollection ReflectOnAssembly(Assembly assembly, IncludeKind includeKind)
        {
            TypeCollection typeCollection = new TypeCollection();

            Type[] types = assembly.GetTypes();
            foreach (Type type in types)
            {
                // Skip any classes they don't want us to include.
                IncludeKind currentIncludeKind = type.IsPublic ? IncludeKind.Public : IncludeKind.Internal;
                if ((currentIncludeKind & includeKind) == 0)
                {
                    continue;
                }

                // Skip compiler-generated classes, which are invisible to both
                // consumers of the assembly and to the assembly's creator.
                if (type.Name.StartsWith("<"))
                {
                    continue;
                }

                TypeDoc typeDoc = ConvertTypeToDocForm(type, includeKind);
                typeCollection = typeCollection.AddType(typeDoc.Name, typeDoc);
            }

            return(typeCollection);
        }
コード例 #2
0
ファイル: TypeLoader.cs プロジェクト: seanofw/crossdox
        private TypeDoc ConvertTypeToDocForm(Type type, IncludeKind includeKind)
        {
            NameInfo typeName = ConvertTypeToNameInfo(type);

            IEnumerable <TypeParameterDoc>            typeParameters = ExtractTypeParameters(type);
            ImmutableDictionary <string, FieldDoc>    fields         = ExtractFields(type, typeName, includeKind);
            ImmutableDictionary <string, PropertyDoc> properties     = ExtractProperties(type, typeName, includeKind);
            ImmutableDictionary <string, EventDoc>    events         = ExtractEvents(type, typeName, includeKind);
            ImmutableDictionary <string, MethodDoc>   methods        = ExtractMethods(type, typeName, includeKind);
            ImmutableDictionary <string, MethodDoc>   constructors   = ExtractConstructors(type, typeName, includeKind);

            methods = methods.AddRange(constructors);

            TypeDoc typeDoc = new TypeDoc(typeName, null,
                                          typeParameters, fields, properties, events, methods);

            return(typeDoc);
        }
コード例 #3
0
ファイル: Options.cs プロジェクト: seanofw/crossdox
 private Options(
     IEnumerable <string> filenames,
     OutputKind outputKind,
     SplitKind splitKind,
     IncludeKind includeKind,
     string templatePath,
     string outputPath,
     bool verbose,
     bool success
     )
 {
     Filenames    = new ReadOnlyCollection <string>(filenames.ToArray());
     OutputKind   = outputKind;
     SplitKind    = splitKind;
     IncludeKind  = includeKind;
     TemplatePath = templatePath;
     OutputPath   = outputPath;
     Verbose      = verbose;
     Success      = success;
 }
コード例 #4
0
ファイル: Options.cs プロジェクト: seanofw/crossdox
        public static Options Parse(string[] args)
        {
            List <string> filenames    = new List <string>();
            bool          lastOption   = false;
            OutputKind    outputKind   = default;
            SplitKind     splitKind    = default;
            IncludeKind   includeKind  = default;
            string        templatePath = null;
            string        outputPath   = null;
            bool          verbose      = false;
            bool          success      = false;

            for (int i = 0; i < args.Length; i++)
            {
                if (args[i][0] == '-' && !lastOption)
                {
                    if (args[i] == "--")
                    {
                        lastOption = true;
                        continue;
                    }
                    switch (args[i].Length > 1 ? args[i][1] : '-')
                    {
                    case '-':
                        switch (args[i].Substring(2))
                        {
                        case "html":
                            outputKind = OutputKind.Html;
                            break;

                        case "internal":
                            includeKind |= IncludeKind.Internal;
                            break;

                        case "md":
                        case "markdown":
                            outputKind = OutputKind.Markdown;
                            break;

                        case "output":
                            if (i >= args.Length)
                            {
                                Console.Error.WriteLine($"Missing pathname after {args[i]}");
                                Environment.Exit(-1);
                                break;
                            }
                            outputPath = args[++i];
                            break;

                        case "private":
                            includeKind |= IncludeKind.Private;
                            break;

                        case "protected":
                            includeKind |= IncludeKind.Protected;
                            break;

                        case "public":
                            includeKind |= IncludeKind.Public;
                            break;

                        case "split":
                        case "split-types":
                            splitKind = SplitKind.SplitByNamespaceAndType;
                            break;

                        case "split-namespace":
                            splitKind = SplitKind.SplitByNamespace;
                            break;

                        case "template":
                            if (i >= args.Length)
                            {
                                Console.Error.WriteLine($"Missing pathname after {args[i]}");
                                Environment.Exit(-1);
                                break;
                            }
                            templatePath = args[++i];
                            break;

                        case "verbose":
                            verbose = true;
                            break;

                        default:
                            Console.Error.WriteLine($"Unknown option: {args[i]}");
                            Environment.Exit(-1);
                            break;
                        }
                        break;

                    case 'm':
                        outputKind = OutputKind.Markdown;
                        break;

                    case 's':
                        splitKind = SplitKind.SplitByNamespaceAndType;
                        break;

                    case 't':
                        if (args[i].Length > 2)
                        {
                            templatePath = args[i].Substring(2);
                        }
                        else
                        {
                            if (i >= args.Length)
                            {
                                Console.Error.WriteLine($"Missing pathname after {args[i]}");
                                Environment.Exit(-1);
                                break;
                            }
                            templatePath = args[++i];
                        }
                        break;

                    case 'o':
                        if (args[i].Length > 2)
                        {
                            outputPath = args[i].Substring(2);
                        }
                        else
                        {
                            if (i >= args.Length)
                            {
                                Console.Error.WriteLine($"Missing pathname after {args[i]}");
                                Environment.Exit(-1);
                                break;
                            }
                            outputPath = args[++i];
                        }
                        break;

                    case 'v':
                        verbose = true;
                        break;

                    case '?':
                    case 'h':
                    case 'H':
                        Console.Error.WriteLine(
                            @"Usage: crossdox [options] assembly.dll assembly2.xml ...

Crossdox reads XML documentation output from the C# compiler and any
given compiled DLLs or EXEs, and generates cross-referenced, pretty
Markdown or HTML documentation websites from them.

Selection options:
  --public            Include public (exclude private/protected)
  --internal          Include internal (exclude private/protected)
  --protected         Include protected (exclude private)
  --private           Include private

Website options:
  --html              Output is HTML website
  -m --md --markdown  Output is Markdown (default)
  --summary           Output a summary of what does & doesn't have docs
  -t path
  --template path     Use custom HTML/Markdown template(s) from here

Output options:
  -s --split
  --split-types       Output separate files by namespace and type
  --split-namespace   Output separate files only by namespace
  -o path
  --output path       Specify output file/folder (default is '.')
  -v --verbose        Emit verbose debugging information to stderr
");
                        success = false;
                        break;

                    default:
                        Console.Error.WriteLine($"Unknown option: {args[i]}");
                        success = false;
                        break;
                    }
                }
                else
                {
                    filenames.Add(args[i]);
                }
            }

            if (includeKind == default)
            {
                includeKind = IncludeKind.All;
            }

            return(new Options(
                       filenames: filenames,
                       outputKind: outputKind,
                       splitKind: splitKind,
                       includeKind: includeKind,
                       templatePath: templatePath,
                       outputPath: outputPath,
                       verbose: verbose,
                       success: success
                       ));
        }
コード例 #5
0
ファイル: TypeLoader.cs プロジェクト: seanofw/crossdox
        private ImmutableDictionary <string, PropertyDoc> ExtractProperties(Type type, NameInfo typeName, IncludeKind includeKind)
        {
            PropertyInfo[] properties = type.GetProperties(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static | BindingFlags.Instance);

            ImmutableDictionary <string, PropertyDoc> dictionary = ImmutableDictionary <string, PropertyDoc> .Empty;

            IEnumerable <ClassInfo> classes = typeName.AsClass;

            foreach (PropertyInfo property in properties)
            {
                // Don't emit properties that were just inherited.
                if (property.DeclaringType != type)
                {
                    continue;
                }

                // Skip compiler-generated properties, which are invisible to both
                // consumers of the assembly and to the assembly's creator.
                if (type.Name.StartsWith("<"))
                {
                    continue;
                }

                NameFlags getterFlags = GetVisibilityNameFlags(property.GetGetMethod());
                NameFlags setterFlags = GetVisibilityNameFlags(property.GetSetMethod());

                NameFlags nameFlags = (getterFlags | setterFlags)
                                      & (NameFlags.Static | NameFlags.Abstract | NameFlags.Virtual | NameFlags.New);
                if (property.Name.StartsWith("#"))
                {
                    nameFlags |= NameFlags.SpecialName;
                }
                else if (property.Name.Contains("#"))
                {
                    nameFlags |= NameFlags.ExplicitInterfaceImplementation;
                }

                if (((getterFlags | setterFlags) & NameFlags.AllVisibilities) >= NameFlags.Public)
                {
                    nameFlags |= NameFlags.Public;
                }
                else if (((getterFlags | setterFlags) & NameFlags.AllVisibilities) >= NameFlags.Internal)
                {
                    nameFlags |= NameFlags.Internal;
                }
                else if (((getterFlags | setterFlags) & NameFlags.AllVisibilities) >= NameFlags.Protected)
                {
                    nameFlags |= NameFlags.Protected;
                }
                else if (((getterFlags | setterFlags) & NameFlags.AllVisibilities) >= NameFlags.Private)
                {
                    nameFlags |= NameFlags.Private;
                }

                NameInfo propertyName = new NameInfo(classes, property.Name, null, null, nameFlags);
                dictionary = dictionary.Add(property.Name, new PropertyDoc(propertyName,
                                                                           getterFlags: getterFlags, setterFlags: setterFlags));
            }

            return(dictionary);
        }
コード例 #6
0
ファイル: TypeLoader.cs プロジェクト: seanofw/crossdox
        private ImmutableDictionary <string, FieldDoc> ExtractFields(Type type, NameInfo typeName, IncludeKind includeKind)
        {
            FieldInfo[] fields = type.GetFields(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static | BindingFlags.Instance);

            ImmutableDictionary <string, FieldDoc> dictionary = ImmutableDictionary <string, FieldDoc> .Empty;

            IEnumerable <ClassInfo> classes = typeName.AsClass;

            foreach (FieldInfo field in fields)
            {
                // Don't emit fields that were just inherited.
                if (field.DeclaringType != type)
                {
                    continue;
                }

                // Skip compiler-generated fields, which are invisible to both
                // consumers of the assembly and to the assembly's creator.
                if (type.Name.StartsWith("<"))
                {
                    continue;
                }

                NameFlags nameFlags = GetVisibilityNameFlags(field);
                NameInfo  fieldName = new NameInfo(classes, field.Name, null, null, nameFlags);
                dictionary = dictionary.Add(field.Name, new FieldDoc(fieldName));
            }

            return(dictionary);
        }
コード例 #7
0
ファイル: TypeLoader.cs プロジェクト: seanofw/crossdox
        private ImmutableDictionary <string, MethodDoc> ExtractConstructors(Type type, NameInfo typeName, IncludeKind includeKind)
        {
            ConstructorInfo[] constructors = type.GetConstructors(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static | BindingFlags.Instance);

            ImmutableDictionary <string, MethodDoc> dictionary = ImmutableDictionary <string, MethodDoc> .Empty;

            IEnumerable <ClassInfo> classes = typeName.AsClass;

            foreach (ConstructorInfo constructor in constructors)
            {
                // Don't emit constructors that were just inherited.
                if (constructor.DeclaringType != type)
                {
                    continue;
                }

                // Skip compiler-generated constructors, which are invisible to both
                // consumers of the assembly and to the assembly's creator.
                if (constructor.Name.StartsWith("<"))
                {
                    continue;
                }

                NameFlags nameFlags = GetVisibilityNameFlags(constructor);

                List <TypeParameterDoc> typeParameters = null;

                string effectiveMethodName = constructor.Name;
                int    backtickIndex       = effectiveMethodName.IndexOf('`');
                if (backtickIndex >= 0)
                {
                    effectiveMethodName = effectiveMethodName.Substring(0, backtickIndex);
                }

                List <Tuple <ParamInfo, ParameterDoc> > parameters = GetParameters(constructor.GetParameters());

                NameInfo methodName = new NameInfo(classes, effectiveMethodName,
                                                   typeParameters?.Select(t => t.Name),
                                                   parameters.Select(p => p.Item1),
                                                   nameFlags);

                List <ParameterDoc> parameterDocs = parameters.Select(p => p.Item2).ToList();

                dictionary = dictionary.Add(methodName.NameWithParameters,
                                            new MethodDoc(methodName, null, typeParameters, parameterDocs, null));
            }

            return(dictionary);
        }
コード例 #8
0
ファイル: TypeLoader.cs プロジェクト: seanofw/crossdox
        private ImmutableDictionary <string, MethodDoc> ExtractMethods(Type type, NameInfo typeName, IncludeKind includeKind)
        {
            MethodInfo[] methods = type.GetMethods(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static | BindingFlags.Instance);

            ImmutableDictionary <string, MethodDoc> dictionary = ImmutableDictionary <string, MethodDoc> .Empty;

            IEnumerable <ClassInfo> classes = typeName.AsClass;

            foreach (MethodInfo method in methods)
            {
                // Don't emit methods that were just inherited.
                if (method.DeclaringType != type)
                {
                    continue;
                }

                // Skip compiler-generated methods, which are invisible to both
                // consumers of the assembly and to the assembly's creator.
                if (method.Name.StartsWith("<"))
                {
                    continue;
                }
                if (method.IsSpecialName)
                {
                    continue;
                }

                NameFlags nameFlags = GetVisibilityNameFlags(method);

                List <TypeParameterDoc> typeParameters = null;
                if (method.IsGenericMethodDefinition)
                {
                    Type[] genericArgs = method.GetGenericArguments();
                    typeParameters = genericArgs.Select(t => new TypeParameterDoc(t.Name, null)).ToList();
                }

                string effectiveMethodName = method.Name;
                List <Tuple <ParamInfo, ParameterDoc> > parameters = GetParameters(method.GetParameters());

                NameInfo methodName = new NameInfo(classes, method.Name,
                                                   typeParameters?.Select(t => t.Name),
                                                   parameters.Select(p => p.Item1),
                                                   nameFlags);

                List <ParameterDoc> parameterDocs = parameters.Select(p => p.Item2).ToList();

                dictionary = dictionary.Add(methodName.NameWithParameters,
                                            new MethodDoc(methodName, null, typeParameters, parameterDocs, null));
            }

            return(dictionary);
        }
コード例 #9
0
ファイル: TypeLoader.cs プロジェクト: seanofw/crossdox
        private ImmutableDictionary <string, EventDoc> ExtractEvents(Type type, NameInfo typeName, IncludeKind includeKind)
        {
            EventInfo[] events = type.GetEvents(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static | BindingFlags.Instance);

            ImmutableDictionary <string, EventDoc> dictionary = ImmutableDictionary <string, EventDoc> .Empty;

            IEnumerable <ClassInfo> classes = typeName.AsClass;

            foreach (EventInfo @event in events)
            {
                // Don't emit events that were just inherited.
                if (@event.DeclaringType != type)
                {
                    continue;
                }

                // Skip compiler-generated events, which are invisible to both
                // consumers of the assembly and to the assembly's creator.
                if (type.Name.StartsWith("<"))
                {
                    continue;
                }

                NameFlags adderFlags   = GetVisibilityNameFlags(@event.GetAddMethod());
                NameFlags removerFlags = GetVisibilityNameFlags(@event.GetRemoveMethod());

                NameFlags nameFlags = (adderFlags | removerFlags)
                                      & (NameFlags.Static | NameFlags.Abstract | NameFlags.Virtual | NameFlags.New);
                if (@event.Name.StartsWith("#"))
                {
                    nameFlags |= NameFlags.SpecialName;
                }
                else if (@event.Name.Contains("#"))
                {
                    nameFlags |= NameFlags.ExplicitInterfaceImplementation;
                }

                if (((adderFlags | removerFlags) & NameFlags.AllVisibilities) >= NameFlags.Public)
                {
                    nameFlags |= NameFlags.Public;
                }
                else if (((adderFlags | removerFlags) & NameFlags.AllVisibilities) >= NameFlags.Internal)
                {
                    nameFlags |= NameFlags.Internal;
                }
                else if (((adderFlags | removerFlags) & NameFlags.AllVisibilities) >= NameFlags.Protected)
                {
                    nameFlags |= NameFlags.Protected;
                }
                else if (((adderFlags | removerFlags) & NameFlags.AllVisibilities) >= NameFlags.Private)
                {
                    nameFlags |= NameFlags.Private;
                }

                NameInfo eventName = new NameInfo(classes, @event.Name, null, null, nameFlags);
                dictionary = dictionary.Add(@event.Name, new EventDoc(eventName,
                                                                      adderFlags: adderFlags, removerFlags: removerFlags));
            }

            return(dictionary);
        }