public PropertyDeclarationSyntax Enrich(PropertyDeclarationSyntax target,
                                                OpenApiEnrichmentContext <OpenApiSchema> context)
        {
            if (target.Parent is ClassDeclarationSyntax classDeclaration &&
                classDeclaration.GetGeneratorAnnotation() == typeof(RequestMediaTypeGenerator))
            {
                // Don't enrich body properties on the request classes
                return(target);
            }

            var attribute = Attribute(NewtonsoftJsonTypes.JsonPropertyAttributeName,
                                      AttributeArgumentList(SingletonSeparatedList(
                                                                AttributeArgument(SyntaxHelpers.StringLiteral(context.LocatedElement.Key)))));

            bool isRequired =
                context.LocatedElement.Parent is LocatedOpenApiElement <OpenApiSchema> parentSchema &&
                parentSchema.Element.Required.Contains(context.LocatedElement.Key);

            bool isNullable = context.LocatedElement.Element.Nullable;

            if (!isRequired && !isNullable)
            {
                // We prefer not to send null values if the property is not required.
                // However, for nullable properties, prefer to send the null explicitly.
                // This is a compromise due to .NET not supporting a concept of null vs missing.

                attribute = attribute.AddArgumentListArguments(AttributeArgument(
                                                                   NameEquals(IdentifierName("NullValueHandling")),
                                                                   null,
                                                                   NewtonsoftJsonTypes.NullValueHandling.Ignore));
            }

            return(target.AddAttributeLists(AttributeList(SingletonSeparatedList(attribute))));
        }
Exemple #2
0
 private PropertyDeclarationSyntax AddRequiredAttribute <T>(PropertyDeclarationSyntax syntax,
                                                            OpenApiEnrichmentContext <T> context)
     where T : IOpenApiElement =>
 syntax
 .MakeNullableOrInitializeIfReferenceType(context.Compilation)
 .AddAttributeLists(AttributeList().AddAttributes(
                        Attribute(WellKnownTypes.System.ComponentModel.DataAnnotations.RequiredAttribute.Name)));
 public EnumDeclarationSyntax Enrich(EnumDeclarationSyntax target,
                                     OpenApiEnrichmentContext <OpenApiSchema> context) =>
 context.Element.Type == "string"
         ? target
 .AddAttributeLists(SyntaxFactory.AttributeList().AddAttributes(
                        SyntaxFactory.Attribute(NewtonsoftJsonTypes.JsonConverterAttributeName).AddArgumentListArguments(
                            SyntaxFactory.AttributeArgument(SyntaxFactory.TypeOfExpression(NewtonsoftJsonTypes.StringEnumConverterName)))))
         : target;
Exemple #4
0
 public EnumDeclarationSyntax Enrich(EnumDeclarationSyntax target,
                                     OpenApiEnrichmentContext <OpenApiSchema> context) =>
 context.Element.Type == "string"
         ? target
 .AddAttributeLists(SyntaxFactory.AttributeList().AddAttributes(
                        SyntaxFactory.Attribute(SystemTextJsonTypes.Serialization.JsonConverterAttributeName).AddArgumentListArguments(
                            SyntaxFactory.AttributeArgument(SyntaxFactory.TypeOfExpression(
                                                                _jsonSerializationNamespace.JsonStringEnumConverter(SyntaxFactory.IdentifierName(target.Identifier)))))))
         : target;
Exemple #5
0
        public PropertyDeclarationSyntax Enrich(PropertyDeclarationSyntax syntax, OpenApiEnrichmentContext <OpenApiSchema> context)
        {
            bool isRequired =
                context.LocatedElement.Parent is LocatedOpenApiElement <OpenApiSchema> parentSchema &&
                parentSchema.Element.Required.Contains(context.LocatedElement.Key);

            return(isRequired
                ? AddRequiredAttribute(syntax, context)
                : syntax.MakeNullable());
        }
Exemple #6
0
        protected virtual InterfaceDeclarationSyntax AddJsonConverter(InterfaceDeclarationSyntax target,
                                                                      OpenApiEnrichmentContext <OpenApiSchema> context)
        {
            var converter = TypeGeneratorRegistry.Get(context.LocatedElement);

            var attribute = Attribute(SystemTextJsonTypes.Serialization.JsonConverterAttributeName,
                                      AttributeArgumentList(SingletonSeparatedList(AttributeArgument(TypeOfExpression(converter.TypeInfo.Name)))));

            return(target.AddAttributeLists(AttributeList(SingletonSeparatedList(attribute))));
        }
        public ClassDeclarationSyntax Enrich(ClassDeclarationSyntax target,
                                             OpenApiEnrichmentContext <OpenApiResponse> context)
        {
            BaseTypeSyntax[] additionalBaseTypes = _responseBaseTypeRegistry
                                                   .GetBaseTypes(context.LocatedElement).ToArray();

            return(additionalBaseTypes.Length > 0
                ? target.AddBaseListTypes(additionalBaseTypes)
                : target);
        }
        public CompilationUnitSyntax Enrich(CompilationUnitSyntax target,
                                            OpenApiEnrichmentContext <OpenApiSchema> context)
        {
            var members = target.GetSpecialMembers(SpecialMembers.AdditionalProperties)
                          .OfType <PropertyDeclarationSyntax>().ToArray();

            target = target.TrackNodes((IEnumerable <PropertyDeclarationSyntax>)members);

            return(members.Aggregate(target,
                                     (current, member) => current.ReplaceNode(current.GetCurrentNode(member), GenerateNewNodes(member))));
        }
        public CompilationUnitSyntax Enrich(CompilationUnitSyntax target,
                                            OpenApiEnrichmentContext <OpenApiResponses> context)
        {
            NamespaceDeclarationSyntax?ns = target.ChildNodes().OfType <NamespaceDeclarationSyntax>().FirstOrDefault();

            if (ns == null)
            {
                return(target);
            }

            return(target.ReplaceNode(ns, ns.AddMembers(GenerateExtensionClass(context.LocatedElement))));
        }
Exemple #10
0
        private PropertyDeclarationSyntax AddRequiredAttribute(PropertyDeclarationSyntax syntax,
                                                               OpenApiEnrichmentContext <OpenApiSchema> context)
        {
            var newSyntax = context.Element.Nullable
                            // If the schema is nullable the property should be nullable
                ? syntax.MakeNullable()
                            // If the schema is not nullable we should try to initialize it, fallback to making it nullable if we can't
                : syntax.MakeNullableOrInitializeIfReferenceType(context.Compilation);

            return(newSyntax
                   .AddAttributeLists(AttributeList(SingletonSeparatedList(
                                                        Attribute(WellKnownTypes.System.ComponentModel.DataAnnotations.RequiredAttribute.Name)))));
        }
Exemple #11
0
        public PropertyDeclarationSyntax Enrich(PropertyDeclarationSyntax target,
                                                OpenApiEnrichmentContext <OpenApiSchema> context)
        {
            if (target.Parent is ClassDeclarationSyntax classDeclaration &&
                classDeclaration.GetGeneratorAnnotation() == typeof(RequestMediaTypeGenerator))
            {
                // Don't enrich body properties on the request classes
                return(target);
            }

            return(target.AddAttributeLists(SyntaxFactory.AttributeList().AddAttributes(
                                                SyntaxFactory.Attribute(SystemTextJsonTypes.Serialization.JsonPropertyNameAttributeName).AddArgumentListArguments(
                                                    SyntaxFactory.AttributeArgument(SyntaxHelpers.StringLiteral(context.LocatedElement.Key))))));
        }
Exemple #12
0
        protected virtual InterfaceDeclarationSyntax AddJsonConverter(InterfaceDeclarationSyntax target,
                                                                      OpenApiEnrichmentContext <OpenApiSchema> context)
        {
            OpenApiSchema schema = context.Element;

            var attribute = SyntaxFactory.Attribute(NewtonsoftJsonTypes.JsonConverterAttributeName).AddArgumentListArguments(
                SyntaxFactory.AttributeArgument(
                    SyntaxFactory.TypeOfExpression(JsonSerializationNamespace.DiscriminatorConverter)),
                SyntaxFactory.AttributeArgument(
                    SyntaxHelpers.StringLiteral(schema.Discriminator.PropertyName)),
                SyntaxFactory.AttributeArgument(
                    SyntaxFactory.TypeOfExpression(Context.TypeGeneratorRegistry.Get(context.LocatedElement).TypeInfo.Name)));

            if (schema.Discriminator.Mapping != null)
            {
                var paramArray = SyntaxFactory.ArrayCreationExpression(
                    SyntaxFactory
                    .ArrayType(SyntaxFactory.PredefinedType(SyntaxFactory.Token(SyntaxKind.ObjectKeyword)))
                    .WithRankSpecifiers(
                        SyntaxFactory.SingletonList(SyntaxFactory.ArrayRankSpecifier(
                                                        SyntaxFactory.SingletonSeparatedList <ExpressionSyntax>(
                                                            SyntaxFactory.OmittedArraySizeExpression())))))
                                 .WithInitializer(SyntaxFactory.InitializerExpression(SyntaxKind.ArrayInitializerExpression,
                                                                                      SyntaxFactory.SeparatedList <ExpressionSyntax>(
                                                                                          schema.Discriminator.Mapping
                                                                                          .SelectMany(mapping =>
                {
                    // Add two parameters to the object array for each mapping
                    // First is the string key of the mapping, second is the Type to deserialize

                    OpenApiSchema referencedSchema = schema.OneOf
                                                     .FirstOrDefault(p => p.Reference?.ReferenceV3 == mapping.Value);

                    return(referencedSchema != null
                                        ? new ExpressionSyntax[]
                    {
                        SyntaxHelpers.StringLiteral(mapping.Key), SyntaxFactory.TypeOfExpression(
                            Context.TypeGeneratorRegistry.Get(
                                referencedSchema.CreateRoot(referencedSchema.Reference.Id)).TypeInfo.Name)
                    }
                                        : Enumerable.Empty <ExpressionSyntax>());
                }))));

                attribute = attribute.AddArgumentListArguments(SyntaxFactory.AttributeArgument(paramArray));
            }

            return(target.AddAttributeLists(SyntaxFactory.AttributeList().AddAttributes(attribute)));
        }
        public ClassDeclarationSyntax Enrich(ClassDeclarationSyntax target,
                                             OpenApiEnrichmentContext <OpenApiSchema> context)
        {
            var feature = _context.GenerationServices.GetRequiredService <ISchemaBaseTypeRegistry>();

            if (feature == null)
            {
                return(target);
            }

            BaseTypeSyntax[] additionalBaseTypes = feature.GetBaseTypes(context.LocatedElement).ToArray();

            return(additionalBaseTypes.Length > 0
                ? target.AddBaseListTypes(additionalBaseTypes)
                : target);
        }
Exemple #14
0
        private PropertyDeclarationSyntax AddRequiredAttribute <T>(PropertyDeclarationSyntax syntax,
                                                                   OpenApiEnrichmentContext <T> context)
            where T : IOpenApiElement
        {
            bool forInterface = syntax.Parent is InterfaceDeclarationSyntax;

            if (!forInterface)
            {
                syntax = syntax.MakeNullableOrInitializeIfReferenceType(context.Compilation);
            }

            syntax = syntax
                     .AddAttributeLists(AttributeList().AddAttributes(
                                            Attribute(WellKnownTypes.System.ComponentModel.DataAnnotations.RequiredAttribute.Name)));

            return(syntax);
        }
Exemple #15
0
        public ClassDeclarationSyntax Enrich(ClassDeclarationSyntax target,
                                             OpenApiEnrichmentContext <OpenApiSchema> context)
        {
            if (!context.Element.AdditionalPropertiesAllowed)
            {
                return(target);
            }

            (TypeSyntax dictionaryType, TypeSyntax interfaceType, TypeSyntax valueType) = GetDictionaryType(context);

            string propertyName = _context.NameFormatterSelector.GetFormatter(NameKind.Property)
                                  .Format("AdditionalProperties");
            bool isShadowing = false;

            var originalNode = context.OriginalNode as ClassDeclarationSyntax;

            // Check to see if we're inheriting from a type that already implements AdditionalProperties
            if (originalNode?.BaseList is { Types.Count : > 0 })
Exemple #16
0
        public ClassDeclarationSyntax Enrich(ClassDeclarationSyntax target,
                                             OpenApiEnrichmentContext <OpenApiSchema> context)
        {
            var feature = _context.GenerationServices.GetRequiredService <ISchemaBaseTypeRegistry>();

            if (feature == null)
            {
                return(target);
            }

            var additionalBaseTypes = feature.GetBaseTypes(context.LocatedElement);

            if (target.BaseList != null)
            {
                additionalBaseTypes = additionalBaseTypes.Where(additionalBaseType =>
                                                                target.BaseList.Types.Any(currentType => !currentType.IsEquivalentTo(additionalBaseType)));
            }

            return(target.AddBaseListTypes(additionalBaseTypes.ToArray()));
        }
        public PropertyDeclarationSyntax Enrich(PropertyDeclarationSyntax syntax, OpenApiEnrichmentContext <OpenApiSchema> context)
        {
            if (syntax.Parent?.GetElementAnnotation <OpenApiSchema>(_elementRegistry) is null)
            {
                // We don't need to apply this to properties of request classes, only schemas
                return(syntax);
            }

            bool isRequired =
                context.LocatedElement.Parent is LocatedOpenApiElement <OpenApiSchema> parentSchema &&
                parentSchema.Element.Required.Contains(context.LocatedElement.Key);

            bool isNullable = context.LocatedElement.Element.Nullable;

            // We prefer not to send null values if the property is not required.
            // However, for nullable properties, prefer to send the null explicitly.
            // This is a compromise due to .NET not supporting a concept of null vs missing.
            return(!isRequired && !isNullable
                ? AddJsonIgnoreAttribute(syntax)
                : syntax);
        }
Exemple #18
0
        public CompilationUnitSyntax Enrich(CompilationUnitSyntax target,
                                            OpenApiEnrichmentContext <OpenApiSchema> context)
        {
            var dynamicTypes = target
                               .DescendantNodes(p =>
                                                p is not BlockSyntax && // Don't look inside methods
                                                p is not ArrowExpressionClauseSyntax)
                               .OfType <IdentifierNameSyntax>()
                               .Where(p => p.Parent is not QualifiedNameSyntax && p.Identifier.ValueText == "dynamic")
                               .Select(p => p.Parent is NullableTypeSyntax nullableTypeSyntax ? nullableTypeSyntax : (TypeSyntax)p)
                               .ToArray();

            if (dynamicTypes.Length == 0)
            {
                return(target);
            }

            var nullableJsonNode = NullableType(SystemTextJsonTypes.Nodes.JsonNodeName);

            return(target.ReplaceNodes(
                       dynamicTypes,
                       (_, _) => nullableJsonNode));
        }
 public MethodDeclarationSyntax Enrich(MethodDeclarationSyntax target,
                                       OpenApiEnrichmentContext <OpenApiOperation> context) =>
 target.Parent.IsKind(SyntaxKind.ClassDeclaration) && !string.IsNullOrWhiteSpace(context.Element.Summary)
         ? AddDocumentation(target)
         : target;
Exemple #20
0
 public PropertyDeclarationSyntax Enrich(PropertyDeclarationSyntax syntax, OpenApiEnrichmentContext <OpenApiRequestBody> context)
 {
     return(context.Element.Required
         ? AddRequiredAttribute(syntax, context)
         : syntax.MakeNullable());
 }
Exemple #21
0
 public ClassDeclarationSyntax Enrich(ClassDeclarationSyntax target,
                                      OpenApiEnrichmentContext <OpenApiOperation> context) =>
 context.Element.Security.Count > 0 && target.GetGeneratorAnnotation() == typeof(RequestTypeGenerator)
         ? AddSecuritySchemes(target, context.LocatedElement)
         : target;
 public ClassDeclarationSyntax Enrich(ClassDeclarationSyntax target,
                                      OpenApiEnrichmentContext <OpenApiOperation> context) =>
 context.Element.RequestBody?.Required ?? false
         ? target.AddModifiers(Token(SyntaxKind.AbstractKeyword))
         : target;
Exemple #23
0
 public InterfaceDeclarationSyntax Enrich(InterfaceDeclarationSyntax target,
                                          OpenApiEnrichmentContext <OpenApiSchema> context) =>
 context.Element.Discriminator?.PropertyName != null
         ? AddJsonConverter(target, context)
         : target;
 public ClassDeclarationSyntax Enrich(ClassDeclarationSyntax target,
                                      OpenApiEnrichmentContext <OpenApiSecurityScheme> context) =>
 !string.IsNullOrWhiteSpace(context.Element.Description)
         ? AddDocumentation(target, context.Element)
         : target;
Exemple #25
0
 public InterfaceDeclarationSyntax Enrich(InterfaceDeclarationSyntax target,
                                          OpenApiEnrichmentContext <OpenApiSchema> context) =>
 target.GetGeneratorAnnotation() == typeof(OneOfSchemaGenerator)
         ? AddJsonConverter(target, context)
         : target;
 public MethodDeclarationSyntax Enrich(MethodDeclarationSyntax target,
                                       OpenApiEnrichmentContext <OpenApiOperation> context) =>
 context.Element.Deprecated
         ? MarkObsolete(target, context.Element.OperationId)
         : target;
 public ClassDeclarationSyntax Enrich(ClassDeclarationSyntax target,
                                      OpenApiEnrichmentContext <OpenApiResponse> context) =>
 IsBaseResponseClass(context.LocatedElement) && context.Element.Headers.Count > 0
         ? target.AddMembers(GenerateMethod(context.LocatedElement))
         : target;
 public PropertyDeclarationSyntax Enrich(PropertyDeclarationSyntax target,
                                         OpenApiEnrichmentContext <OpenApiParameter> context) =>
 string.IsNullOrWhiteSpace(context.Element.Description)
         ? target
         : AddDocumentation(target, context.Element);
 public PropertyDeclarationSyntax Enrich(PropertyDeclarationSyntax target,
                                         OpenApiEnrichmentContext <OpenApiSchema> context) =>
 target
 .AddAttributeLists(SyntaxFactory.AttributeList().AddAttributes(
                        SyntaxFactory.Attribute(NewtonsoftJsonTypes.JsonPropertyAttributeName).AddArgumentListArguments(
                            SyntaxFactory.AttributeArgument(SyntaxHelpers.StringLiteral(context.LocatedElement.Key)))));
Exemple #30
0
 public ClassDeclarationSyntax Enrich(ClassDeclarationSyntax target,
                                      OpenApiEnrichmentContext <OpenApiOperation> context) =>
 context.Element.Security.Count > 0
         ? AddSecuritySchemes(target, context.LocatedElement)
         : target;