Example #1
0
        public static string GetSimpleClassName(ISerializableTypeDescription serializableType)
        {
#pragma warning disable RS1024 // Compare symbols correctly
            var uniquifier = RuntimeHelpers.GetHashCode(serializableType).ToString("X");
#pragma warning restore RS1024 // Compare symbols correctly
            return($"{CodeGenerator.CodeGeneratorName}_Activator_{serializableType.Name}_{uniquifier}");
        }
Example #2
0
 public SerializableMember(LibraryTypes wellKnownTypes, ISerializableTypeDescription type, IMemberDescription member, int ordinal)
 {
     this.wellKnownTypes = wellKnownTypes;
     this.model          = type.SemanticModel;
     this.Description    = member;
     this.ordinal        = ordinal;
 }
Example #3
0
        public static TypeSyntax GetPartialSerializerTypeName(this ISerializableTypeDescription type)
        {
            var genericArity = type.TypeParameters.Length;
            var name         = SerializerGenerator.GetSimpleClassName(type);

            if (genericArity > 0)
            {
                name += $"<{new string(',', genericArity - 1)}>";
            }

            return(ParseTypeName(name));
        }
Example #4
0
        public static TypeSyntax GetActivatorTypeName(this ISerializableTypeDescription type)
        {
            var genericArity = type.TypeParameters.Count;
            var name         = ActivatorGenerator.GetSimpleClassName(type);

            if (genericArity > 0)
            {
                name += $"<{new string(',', genericArity - 1)}>";
            }

            return(ParseTypeName(type.GeneratedNamespace + "." + name));
        }
Example #5
0
        public static ClassDeclarationSyntax GenerateCopier(
            LibraryTypes libraryTypes,
            ISerializableTypeDescription type)
        {
            var simpleClassName = GetSimpleClassName(type);

            var members = new List <ISerializableMember>();

            foreach (var member in type.Members)
            {
                if (member is ISerializableMember serializable)
                {
                    members.Add(serializable);
                }
                else if (member is IFieldDescription or IPropertyDescription)
                {
                    members.Add(new SerializableMember(libraryTypes, type, member, members.Count));
                }
Example #6
0
        private static ClassDeclarationSyntax AddGenericTypeConstraints(ClassDeclarationSyntax classDeclaration, ISerializableTypeDescription serializableType)
        {
            classDeclaration = classDeclaration.WithTypeParameterList(TypeParameterList(SeparatedList(serializableType.TypeParameters.Select(tp => TypeParameter(tp.Name)))));
            var constraints = new List <TypeParameterConstraintSyntax>();

            foreach (var tp in serializableType.TypeParameters)
            {
                constraints.Clear();
                if (tp.HasReferenceTypeConstraint)
                {
                    constraints.Add(ClassOrStructConstraint(SyntaxKind.ClassConstraint));
                }

                if (tp.HasValueTypeConstraint)
                {
                    constraints.Add(ClassOrStructConstraint(SyntaxKind.StructConstraint));
                }

                foreach (var c in tp.ConstraintTypes)
                {
                    constraints.Add(TypeConstraint(c.ToTypeSyntax()));
                }

                if (tp.HasConstructorConstraint)
                {
                    constraints.Add(ConstructorConstraint());
                }

                if (constraints.Count > 0)
                {
                    classDeclaration = classDeclaration.AddConstraintClauses(TypeParameterConstraintClause(tp.Name).AddConstraints(constraints.ToArray()));
                }
            }

            return(classDeclaration);
        }
Example #7
0
        public static string GetSimpleClassName(ISerializableTypeDescription serializableType)
        {
            var uniquifier = RuntimeHelpers.GetHashCode(serializableType).ToString("X");

            return($"{CodeGenerator.CodeGeneratorName}_Serializer_{serializableType.Name}_{uniquifier}");
        }
Example #8
0
        private static MemberDeclarationSyntax GenerateDeserializeMethod(
            ISerializableTypeDescription type,
            List <FieldDescription> serializerFields,
            List <SerializableMember> members,
            LibraryTypes libraryTypes)
        {
            var returnType = PredefinedType(Token(SyntaxKind.VoidKeyword));

            var readerParam   = "reader".ToIdentifierName();
            var instanceParam = "instance".ToIdentifierName();
            var fieldIdVar    = "fieldId".ToIdentifierName();
            var headerVar     = "header".ToIdentifierName();

            var body = new List <StatementSyntax>
            {
                // C#: uint fieldId = 0;
                LocalDeclarationStatement(
                    VariableDeclaration(
                        PredefinedType(Token(SyntaxKind.UIntKeyword)),
                        SingletonSeparatedList(VariableDeclarator(fieldIdVar.Identifier)
                                               .WithInitializer(EqualsValueClause(LiteralExpression(SyntaxKind.NumericLiteralExpression, Literal(0)))))))
            };

            if (type.HasComplexBaseType)
            {
                // C#: this.baseTypeSerializer.Deserialize(ref reader, instance);
                body.Add(
                    ExpressionStatement(
                        InvocationExpression(
                            ThisExpression().Member(BaseTypeSerializerFieldName.ToIdentifierName()).Member(DeserializeMethodName),
                            ArgumentList(SeparatedList(new[]
                {
                    Argument(readerParam).WithRefOrOutKeyword(Token(SyntaxKind.RefKeyword)),
                    Argument(instanceParam)
                })))));
            }

            body.Add(WhileStatement(LiteralExpression(SyntaxKind.TrueLiteralExpression), Block(GetDeserializerLoopBody())));

            var parameters = new[]
            {
                Parameter(readerParam.Identifier).WithType(libraryTypes.Reader.ToTypeSyntax()).WithModifiers(TokenList(Token(SyntaxKind.RefKeyword))),
                Parameter(instanceParam.Identifier).WithType(type.TypeSyntax)
            };

            if (type.IsValueType)
            {
                parameters[1] = parameters[1].WithModifiers(TokenList(Token(SyntaxKind.RefKeyword)));
            }

            return(MethodDeclaration(returnType, DeserializeMethodName)
                   .AddModifiers(Token(SyntaxKind.PublicKeyword))
                   .AddParameterListParameters(parameters)
                   .AddBodyStatements(body.ToArray()));

            // Create the loop body.
            List <StatementSyntax> GetDeserializerLoopBody()
            {
                return(new List <StatementSyntax>
                {
                    // C#: var header = reader.ReadFieldHeader();
                    LocalDeclarationStatement(
                        VariableDeclaration(
                            IdentifierName("var"),
                            SingletonSeparatedList(
                                VariableDeclarator(headerVar.Identifier)
                                .WithInitializer(EqualsValueClause(InvocationExpression(readerParam.Member("ReadFieldHeader"),
                                                                                        ArgumentList())))))),

                    // C#: if (header.IsEndBaseOrEndObject) break;
                    IfStatement(MemberAccessExpression(SyntaxKind.SimpleMemberAccessExpression, headerVar, IdentifierName("IsEndBaseOrEndObject")), BreakStatement()),

                    // C#: fieldId += header.FieldIdDelta;
                    ExpressionStatement(
                        AssignmentExpression(
                            SyntaxKind.AddAssignmentExpression,
                            fieldIdVar,
                            Token(SyntaxKind.PlusEqualsToken),
                            MemberAccessExpression(SyntaxKind.SimpleMemberAccessExpression, headerVar, IdentifierName("FieldIdDelta")))),

                    // C#: switch (fieldId) { ... }
                    SwitchStatement(ParenthesizedExpression(fieldIdVar), List(GetSwitchSections()))
                });
            }

            // Creates switch sections for each member.
            List <SwitchSectionSyntax> GetSwitchSections()
            {
                var switchSections = new List <SwitchSectionSyntax>();

                foreach (var member in members)
                {
                    var description = member.Description;

                    // C#: case <fieldId>:
                    var label = CaseSwitchLabel(LiteralExpression(SyntaxKind.NumericLiteralExpression, Literal(description.FieldId)));

                    // C#: instance.<member> = this.<codec>.ReadValue(ref reader, header);
                    var codec = serializerFields.OfType <ICodecDescription>()
                                .Concat(libraryTypes.StaticCodecs)
                                .First(f => f.UnderlyingType.Equals(GetExpectedType(description.Type)));

                    // Codecs can either be static classes or injected into the constructor.
                    // Either way, the member signatures are the same.
                    var memberType  = GetExpectedType(description.Type);
                    var staticCodec = libraryTypes.StaticCodecs.FirstOrDefault(c => c.UnderlyingType.Equals(memberType));
                    ExpressionSyntax codecExpression;
                    if (staticCodec != null)
                    {
                        codecExpression = staticCodec.CodecType.ToNameSyntax();
                    }
                    else
                    {
                        var instanceCodec = serializerFields.OfType <CodecFieldDescription>().First(f => f.UnderlyingType.Equals(memberType));
                        codecExpression = ThisExpression().Member(instanceCodec.FieldName);
                    }

                    ExpressionSyntax readValueExpression = InvocationExpression(
                        codecExpression.Member("ReadValue"),
                        ArgumentList(SeparatedList(new[] { Argument(readerParam).WithRefOrOutKeyword(Token(SyntaxKind.RefKeyword)), Argument(headerVar) })));
                    if (!codec.UnderlyingType.Equals(member.Type))
                    {
                        // If the member type type differs from the codec type (eg because the member is an array), cast the result.
                        readValueExpression = CastExpression(description.Type.ToTypeSyntax(), readValueExpression);
                    }

                    var memberAssignment = ExpressionStatement(member.GetSetter(instanceParam, readValueExpression));
                    var caseBody         = List(new StatementSyntax[] { memberAssignment, BreakStatement() });

                    // Create the switch section with a break at the end.
                    // C#: break;
                    switchSections.Add(SwitchSection(SingletonList <SwitchLabelSyntax>(label), caseBody));
                }

                // Add the default switch section.
                var consumeUnknown = ExpressionStatement(InvocationExpression(readerParam.Member("ConsumeUnknownField"),
                                                                              ArgumentList(SeparatedList(new[] { Argument(headerVar) }))));

                switchSections.Add(SwitchSection(SingletonList <SwitchLabelSyntax>(DefaultSwitchLabel()), List(new StatementSyntax[] { consumeUnknown, BreakStatement() })));

                return(switchSections);
            }
        }
Example #9
0
        private static MemberDeclarationSyntax GenerateSerializeMethod(
            ISerializableTypeDescription type,
            List <FieldDescription> serializerFields,
            List <SerializableMember> members,
            LibraryTypes libraryTypes)
        {
            var returnType = PredefinedType(Token(SyntaxKind.VoidKeyword));

            var writerParam   = "writer".ToIdentifierName();
            var instanceParam = "instance".ToIdentifierName();

            var body = new List <StatementSyntax>();

            if (type.HasComplexBaseType)
            {
                body.Add(
                    ExpressionStatement(
                        InvocationExpression(
                            ThisExpression().Member(BaseTypeSerializerFieldName.ToIdentifierName()).Member(SerializeMethodName),
                            ArgumentList(SeparatedList(new[] { Argument(writerParam).WithRefOrOutKeyword(Token(SyntaxKind.RefKeyword)), Argument(instanceParam) })))));
                body.Add(ExpressionStatement(InvocationExpression(writerParam.Member("WriteEndBase"), ArgumentList())));
            }

            // Order members according to their FieldId, since fields must be serialized in order and FieldIds are serialized as deltas.
            uint previousFieldId = 0;

            foreach (var member in members.OrderBy(m => m.Description.FieldId))
            {
                var description  = member.Description;
                var fieldIdDelta = description.FieldId - previousFieldId;
                previousFieldId = description.FieldId;

                // Codecs can either be static classes or injected into the constructor.
                // Either way, the member signatures are the same.
                var memberType  = GetExpectedType(description.Type);
                var staticCodec = libraryTypes.StaticCodecs.FirstOrDefault(c => c.UnderlyingType.Equals(memberType));
                ExpressionSyntax codecExpression;
                if (staticCodec != null)
                {
                    codecExpression = staticCodec.CodecType.ToNameSyntax();
                }
                else
                {
                    var instanceCodec = serializerFields.OfType <CodecFieldDescription>().First(f => f.UnderlyingType.Equals(memberType));
                    codecExpression = ThisExpression().Member(instanceCodec.FieldName);
                }

                var expectedType = serializerFields.OfType <TypeFieldDescription>().First(f => f.UnderlyingType.Equals(memberType));
                body.Add(
                    ExpressionStatement(
                        InvocationExpression(
                            codecExpression.Member("WriteField"),
                            ArgumentList(
                                SeparatedList(
                                    new[]
                {
                    Argument(writerParam).WithRefOrOutKeyword(Token(SyntaxKind.RefKeyword)),
                    Argument(LiteralExpression(SyntaxKind.NumericLiteralExpression, Literal(fieldIdDelta))),
                    Argument(expectedType.FieldName.ToIdentifierName()),
                    Argument(member.GetGetter(instanceParam))
                })))));
            }

            var parameters = new[]
            {
                Parameter("writer".ToIdentifier()).WithType(libraryTypes.Writer.ToTypeSyntax()).WithModifiers(TokenList(Token(SyntaxKind.RefKeyword))),
                Parameter("instance".ToIdentifier()).WithType(type.TypeSyntax)
            };

            if (type.IsValueType)
            {
                parameters[1] = parameters[1].WithModifiers(TokenList(Token(SyntaxKind.InKeyword)));
            }

            return(MethodDeclaration(returnType, SerializeMethodName)
                   .AddModifiers(Token(SyntaxKind.PublicKeyword))
                   .AddParameterListParameters(parameters)
                   .AddTypeParameterListParameters(TypeParameter("TBufferWriter"))
                   .AddConstraintClauses(TypeParameterConstraintClause("TBufferWriter").AddConstraints(TypeConstraint(libraryTypes.IBufferWriter.Construct(libraryTypes.Byte).ToTypeSyntax())))
                   .AddBodyStatements(body.ToArray()));
        }
Example #10
0
        private static List <FieldDescription> GetFieldDescriptions(
            ISerializableTypeDescription serializableTypeDescription,
            List <SerializableMember> members,
            LibraryTypes libraryTypes)
        {
            var fields = new List <FieldDescription>();

            fields.AddRange(serializableTypeDescription.Members.Select(m => GetExpectedType(m.Type)).Distinct().Select(GetTypeDescription));

            if (serializableTypeDescription.HasComplexBaseType)
            {
                fields.Add(new InjectedFieldDescription(libraryTypes.PartialSerializer.Construct(serializableTypeDescription.BaseType).ToTypeSyntax(), BaseTypeSerializerFieldName));
            }

            // Add a codec field for any field in the target which does not have a static codec.
            fields.AddRange(serializableTypeDescription.Members
                            .Select(m => GetExpectedType(m.Type)).Distinct()
                            .Where(t => !libraryTypes.StaticCodecs.Any(c => c.UnderlyingType.Equals(t)))
                            .Select(GetCodecDescription));

            foreach (var member in members)
            {
                if (!member.HasAccessibleGetter)
                {
                    fields.Add(GetGetterDescription(member));
                }

                if (!member.HasAccessibleSetter)
                {
                    fields.Add(GetSetterDescription(member));
                }
            }

            return(fields);

            CodecFieldDescription GetCodecDescription(ITypeSymbol t)
            {
                var codecType = libraryTypes.FieldCodec.Construct(t).ToTypeSyntax();
                var fieldName = '_' + ToLowerCamelCase(t.GetValidIdentifier()) + "Codec";

                return(new CodecFieldDescription(codecType, fieldName, t));
            }

            TypeFieldDescription GetTypeDescription(ITypeSymbol t)
            {
                var fieldName = ToLowerCamelCase(t.GetValidIdentifier()) + "Type";

                return(new TypeFieldDescription(libraryTypes.Type.ToTypeSyntax(), fieldName, t));
            }

            GetterFieldDescription GetGetterDescription(SerializableMember member)
            {
                var containingType = member.Field.ContainingType;
                var getterType     = libraryTypes.Func_2.Construct(containingType, member.SafeType).ToTypeSyntax();

                return(new GetterFieldDescription(getterType, member.GetterFieldName, member.Field.Type, member));
            }

            SetterFieldDescription GetSetterDescription(SerializableMember member)
            {
                var        containingType = member.Field.ContainingType;
                TypeSyntax fieldType;

                if (containingType != null && containingType.IsValueType)
                {
                    fieldType = libraryTypes.ValueTypeSetter_2.Construct(containingType, member.SafeType).ToTypeSyntax();
                }
                else
                {
                    fieldType = libraryTypes.Action_2.Construct(containingType, member.SafeType).ToTypeSyntax();
                }

                return(new SetterFieldDescription(fieldType, member.SetterFieldName, member.Field.Type, member));
            }

            string ToLowerCamelCase(string input) => char.IsLower(input, 0) ? input : char.ToLowerInvariant(input[0]) + input.Substring(1);
        }
Example #11
0
        public static ClassDeclarationSyntax GenerateSerializer(Compilation compilation, LibraryTypes libraryTypes, ISerializableTypeDescription type)
        {
            var simpleClassName = GetSimpleClassName(type);

            var serializerInterface = type.IsValueType ? libraryTypes.ValueSerializer : libraryTypes.PartialSerializer;
            var baseInterface       = serializerInterface.ToTypeSyntax(type.TypeSyntax);

            var members = new List <SerializableMember>();

            foreach (var member in type.Members)
            {
                if (member.Member is IFieldSymbol field)
                {
                    members.Add(new SerializableMember(libraryTypes, type, member, members.Count));
                }
            }

            var fieldDescriptions = GetFieldDescriptions(type, members, libraryTypes);
            var fieldDeclarations = GetFieldDeclarations(fieldDescriptions);
            var ctor = GenerateConstructor(simpleClassName, fieldDescriptions);

            var serializeMethod   = GenerateSerializeMethod(type, fieldDescriptions, members, libraryTypes);
            var deserializeMethod = GenerateDeserializeMethod(type, fieldDescriptions, members, libraryTypes);

            var classDeclaration = ClassDeclaration(simpleClassName)
                                   .AddBaseListTypes(SimpleBaseType(baseInterface))
                                   .AddModifiers(Token(SyntaxKind.InternalKeyword), Token(SyntaxKind.SealedKeyword))
                                   .AddAttributeLists(AttributeList(SingletonSeparatedList(CodeGenerator.GetGeneratedCodeAttributeSyntax())))
                                   .AddMembers(fieldDeclarations)
                                   .AddMembers(ctor, serializeMethod, deserializeMethod);

            if (type.IsGenericType)
            {
                classDeclaration = AddGenericTypeConstraints(classDeclaration, type);
            }

            return(classDeclaration);
        }
Example #12
0
 public static string GetSimpleClassName(ISerializableTypeDescription serializableType) => GetSimpleClassName(serializableType.Name);
Example #13
0
        public static ClassDeclarationSyntax GenerateActivator(Compilation compilation, LibraryTypes libraryTypes, ISerializableTypeDescription type)
        {
            var simpleClassName = GetSimpleClassName(type);

            var baseInterface = libraryTypes.IActivator_1.ToTypeSyntax(type.TypeSyntax);

            var classDeclaration = ClassDeclaration(simpleClassName)
                                   .AddBaseListTypes(SimpleBaseType(baseInterface))
                                   .AddModifiers(Token(SyntaxKind.InternalKeyword), Token(SyntaxKind.SealedKeyword))
                                   .AddAttributeLists(AttributeList(SingletonSeparatedList(CodeGenerator.GetGeneratedCodeAttributeSyntax())))
                                   .AddMembers(GenerateCreateMethod(libraryTypes, type));

            if (type.IsGenericType)
            {
                classDeclaration = AddGenericTypeConstraints(classDeclaration, type);
            }

            return(classDeclaration);
        }
Example #14
0
 public static string GetSimpleClassName(ISerializableTypeDescription serializableType) => $"Activator_{serializableType.Name}";
Example #15
0
        public static ClassDeclarationSyntax GenerateActivator(LibraryTypes libraryTypes, ISerializableTypeDescription type)
        {
            var simpleClassName = GetSimpleClassName(type);

            var baseInterface = libraryTypes.IActivator_1.ToTypeSyntax(type.TypeSyntax);

            var orderedFields = new List <ConstructorArgument>();
            var index         = 0;

            if (type.ActivatorConstructorParameters is { Count : > 0 } parameters)
            {
                foreach (var arg in parameters)
                {
                    orderedFields.Add(new ConstructorArgument {
                        Type = arg, FieldName = $"_arg{index}", ParameterName = $"arg{index}"
                    });
                    index++;
                }
            }

            var members = new List <MemberDeclarationSyntax>();

            foreach (var field in orderedFields)
            {
                members.Add(
                    FieldDeclaration(VariableDeclaration(field.Type, SingletonSeparatedList(VariableDeclarator(field.FieldName))))
                    .AddModifiers(
                        Token(SyntaxKind.PrivateKeyword),
                        Token(SyntaxKind.ReadOnlyKeyword)));
            }

            members.Add(GenerateConstructor(libraryTypes, simpleClassName, orderedFields));
            members.Add(GenerateCreateMethod(libraryTypes, type, orderedFields));

            var classDeclaration = ClassDeclaration(simpleClassName)
                                   .AddBaseListTypes(SimpleBaseType(baseInterface))
                                   .AddModifiers(Token(SyntaxKind.InternalKeyword), Token(SyntaxKind.SealedKeyword))
                                   .AddAttributeLists(AttributeList(SingletonSeparatedList(Attribute(libraryTypes.RegisterActivatorAttribute.ToNameSyntax()))))
                                   .AddAttributeLists(AttributeList(SingletonSeparatedList(CodeGenerator.GetGeneratedCodeAttributeSyntax())))
                                   .AddMembers(members.ToArray());

            if (type.IsGenericType)
            {
                classDeclaration = SyntaxFactoryUtility.AddGenericTypeParameters(classDeclaration, type.TypeParameters);
            }

            return(classDeclaration);
        }
Example #16
0
        private static MemberDeclarationSyntax GenerateCreateMethod(LibraryTypes libraryTypes, ISerializableTypeDescription type)
        {
            var createObject = type.GetObjectCreationExpression(libraryTypes);

            return(MethodDeclaration(type.TypeSyntax, "Create")
                   .WithExpressionBody(ArrowExpressionClause(createObject))
                   .WithSemicolonToken(Token(SyntaxKind.SemicolonToken))
                   .AddModifiers(Token(SyntaxKind.PublicKeyword)));
        }
Example #17
0
        public static ClassDeclarationSyntax GenerateCopier(
            LibraryTypes libraryTypes,
            ISerializableTypeDescription type)
        {
            var simpleClassName = GetSimpleClassName(type);

            var members = new List <ISerializableMember>();

            foreach (var member in type.Members)
            {
                if (member is ISerializableMember serializable)
                {
                    members.Add(serializable);
                }
                else if (member is IFieldDescription field)
                {
                    members.Add(new SerializableMember(libraryTypes, type, field, members.Count));
                }
                else if (member is MethodParameterFieldDescription methodParameter)
                {
                    members.Add(new SerializableMethodMember(methodParameter));
                }
            }

            var accessibility = type.Accessibility switch
            {
                Accessibility.Public => SyntaxKind.PublicKeyword,
                _ => SyntaxKind.InternalKeyword,
            };
            var classDeclaration = ClassDeclaration(simpleClassName)
                                   .AddBaseListTypes(SimpleBaseType(libraryTypes.DeepCopier_1.ToTypeSyntax(type.TypeSyntax)))
                                   .AddModifiers(Token(accessibility), Token(SyntaxKind.SealedKeyword))
                                   .AddAttributeLists(AttributeList(SingletonSeparatedList(CodeGenerator.GetGeneratedCodeAttributeSyntax())));

            if (type.IsImmutable)
            {
                var copyMethod = GenerateImmutableTypeCopyMethod(type, libraryTypes);
                classDeclaration = classDeclaration.AddMembers(copyMethod);
            }
            else
            {
                var fieldDescriptions = GetFieldDescriptions(type, members, libraryTypes);
                var fieldDeclarations = GetFieldDeclarations(fieldDescriptions);
                var ctor = GenerateConstructor(libraryTypes, simpleClassName, fieldDescriptions);

                var copyMethod = GenerateMemberwiseDeepCopyMethod(type, fieldDescriptions, members, libraryTypes);
                classDeclaration = classDeclaration
                                   .AddMembers(copyMethod)
                                   .AddMembers(fieldDeclarations)
                                   .AddMembers(ctor);

                if (!type.IsSealedType)
                {
                    classDeclaration = classDeclaration
                                       .AddMembers(GenerateBaseCopierDeepCopyMethod(type, fieldDescriptions, members, libraryTypes))
                                       .AddBaseListTypes(SimpleBaseType(libraryTypes.BaseCopier_1.ToTypeSyntax(type.TypeSyntax)));
                }
            }

            if (type.IsGenericType)
            {
                classDeclaration = SyntaxFactoryUtility.AddGenericTypeParameters(classDeclaration, type.TypeParameters);
            }

            return(classDeclaration);
        }