예제 #1
0
        public static CodeTypeDeclaration Sort(this CodeTypeDeclaration original)
        {
            if (original.IsEnum)
            {
                return(original);
            }

            var sorted = new CodeTypeDeclaration(original.Name)
            {
                Attributes       = original.Attributes,
                CustomAttributes = original.CustomAttributes,
                IsClass          = original.IsClass,
                IsEnum           = original.IsEnum,
                IsInterface      = original.IsInterface,
                IsPartial        = original.IsPartial,
                IsStruct         = original.IsStruct,
                LinePragma       = original.LinePragma,
                Name             = original.Name,
                TypeAttributes   = original.TypeAttributes,
            };

            sorted.BaseTypes.AddRange(original.BaseTypes);
            sorted.Comments.AddRange(original.Comments);
            sorted.EndDirectives.AddRange(original.EndDirectives);
            sorted.StartDirectives.AddRange(original.StartDirectives);
            sorted.TypeParameters.AddRange(original.TypeParameters);

            foreach (var key in original.UserData.Keys)
            {
                sorted.UserData[key] = original.UserData[key];
            }

            var emptyParamList = new List <CodeParameterDeclarationExpression>();

            var sortedMembers = original.Members.OfType <CodeTypeMember>()
                                .OrderBy(m => m.Attributes.HasFlag(MemberAttributes.Static))
                                .ThenBy(m => m.GetType().Name, StringComparer.Ordinal)
                                .ThenBy(m => CodeNormalizer.NormalizeMethodName(m.Name), StringComparer.Ordinal)
                                .ThenBy(m => m is CodeMemberMethod method
                            ? method.TypeParameters.Count
                            : 0)
                                .ThenBy(m => m is CodeMemberMethod method
                            ? method.Parameters.Count
                            : 0)
                                .ThenBy(m => m is CodeMemberMethod method
                            ? method.Parameters.OfType <CodeParameterDeclarationExpression>().ToList()
                            : emptyParamList,
                                        new ParamListComparer());

            foreach (var member in sortedMembers)
            {
                sorted.Members.Add(member);
            }

            return(sorted);
        }
예제 #2
0
        // TODO: Assembly references?
        // TODO: Better handle namespaces - using statements? - requires non-qualified type names
        static string CreatePublicApiForAssembly(AssemblyDefinition assembly, Func <TypeDefinition, bool> shouldIncludeType, bool shouldIncludeAssemblyAttributes, string[] whitelistedNamespacePrefixes, AttributeFilter attributeFilter)
        {
            using (var provider = new CSharpCodeProvider())
            {
                var compileUnit = new CodeCompileUnit();
                if (shouldIncludeAssemblyAttributes && assembly.HasCustomAttributes)
                {
                    PopulateCustomAttributes(assembly, compileUnit.AssemblyCustomAttributes, attributeFilter);
                }

                var publicTypes = assembly.Modules.SelectMany(m => m.GetTypes())
                                  .Where(t => !t.IsNested && ShouldIncludeType(t) && shouldIncludeType(t))
                                  .OrderBy(t => t.FullName, StringComparer.Ordinal);
                foreach (var publicType in publicTypes)
                {
                    var @namespace = compileUnit.Namespaces.Cast <CodeNamespace>()
                                     .FirstOrDefault(n => n.Name == publicType.Namespace);
                    if (@namespace == null)
                    {
                        @namespace = new CodeNamespace(publicType.Namespace);
                        compileUnit.Namespaces.Add(@namespace);
                    }

                    using (NullableContext.Push(publicType))
                    {
                        var typeDeclaration = CreateTypeDeclaration(publicType, whitelistedNamespacePrefixes, attributeFilter);
                        @namespace.Types.Add(typeDeclaration);
                    }
                }

                using (var writer = new StringWriter())
                {
                    var cgo = new CodeGeneratorOptions
                    {
                        BracingStyle             = "C",
                        BlankLinesBetweenMembers = false,
                        VerbatimOrder            = false,
                        IndentString             = "    "
                    };

                    provider.GenerateCodeFromCompileUnit(compileUnit, writer, cgo);
                    return(CodeNormalizer.NormalizeGeneratedCode(writer));
                }
            }
        }