private static void GenerateAttributesFile(
            IProjectFileSystem fileSystem,
            string fileName,
            ImmutableArray <AttributeData> attributes,
            string target,
            ImmutableArray <string> initialLines = default)
        {
            if (attributes.IsEmpty && initialLines.IsDefaultOrEmpty)
            {
                return;
            }

            using var textWriter = fileSystem.CreateText(fileName);
            using var writer     = new IndentedTextWriter(textWriter);

            if (!initialLines.IsDefaultOrEmpty)
            {
                foreach (var line in initialLines)
                {
                    writer.WriteLine(line);
                }

                if (!attributes.IsEmpty)
                {
                    writer.WriteLine();
                }
            }

            WriteAttributes(attributes, target, new GenerationContext(writer, currentNamespace: null));
        }
예제 #2
0
        private void GenerateType(INamedTypeSymbol type, TypeDeclarationReason reason, TypeDeclarationAnalysis typeDeclarationAnalysis, IProjectFileSystem fileSystem)
        {
            using var textWriter = fileSystem.CreateText(GetPathForType(type));
            using var writer     = new IndentedTextWriter(textWriter);

            var context = new GenerationContext(writer, type.ContainingNamespace);

            if (!type.ContainingNamespace.IsGlobalNamespace)
            {
                writer.Write("namespace ");
                context.WriteNamespace(type.ContainingNamespace);
                writer.WriteLine();
                writer.WriteLine('{');
                writer.Indent++;
            }

            var containingTypes = MetadataFacts.GetContainingTypes(type);

            foreach (var containingType in containingTypes)
            {
                WriteContainerTypeHeader(containingType, declareAsPartial: true, context);
                writer.WriteLine();
                writer.WriteLine('{');
                writer.Indent++;
            }

            var filteredAttributes = type.GetAttributes()
                                     .AddRange(PseudoCustomAttributeFacts.GenerateApiAttributes(type))
                                     .Where(a => a.AttributeClass?.HasFullName("System", "Reflection", "DefaultMemberAttribute") != true);

            if ((reason & (TypeDeclarationReason.ExternallyVisible | TypeDeclarationReason.DeclaresUsedAttribute)) != 0)
            {
                WriteAttributes(
                    filteredAttributes,
                    target: null,
                    context,
                    onlyWriteAttributeUsageAttribute: (reason & TypeDeclarationReason.ExternallyVisible) == 0);
            }

            WriteAccessibility(type.DeclaredAccessibility, reason, writer);

            var declareAsPartial = type.GetTypeMembers().Any(typeDeclarationAnalysis.ReasonsByType.ContainsKey);

            if (type.TypeKind == TypeKind.Delegate)
            {
                GenerateDelegate(type, context);
            }
            else if (type.TypeKind == TypeKind.Enum)
            {
                if (declareAsPartial)
                {
                    writer.Write("partial ");
                }
                GenerateEnum(type, context);
            }
            else
            {
                if (type.TypeKind == TypeKind.Class)
                {
                    if (type.IsAbstract && type.IsSealed)
                    {
                        writer.Write("static ");
                    }

                    if (MetadataFacts.HidesBaseMember(type, typeDeclarationAnalysis))
                    {
                        writer.Write("new ");
                    }

                    if (type.IsSealed)
                    {
                        writer.Write("sealed ");
                    }
                    else if (type.IsAbstract)
                    {
                        writer.Write("abstract ");
                    }
                }

                WriteContainerTypeHeader(type, declareAsPartial, context);

                var generatedBaseType = type.BaseType;

                if (reason.HasFlag(TypeDeclarationReason.ExternallyVisible))
                {
                    var baseTypes = new List <INamedTypeSymbol>();

                    if (type.BaseType is { SpecialType : not(SpecialType.System_Object or SpecialType.System_ValueType) })