Repository: go-swagger/go-swagger (go)

Issue:
allOf is always pointer using inheritance
## Problem statement

Can't make allOf object to be not nullable. It's always pointer. `x-nullable:false` doesn't help. 

## Swagger specification
```
BundleAttributesResponse:
    properties:
      type:
        $ref: "#/definitions/BundleType"
      items:
        description: Array of bundle items in the root of the bundle.
        type: array
        items:
          $ref: "#/definitions/BundleItemResponse"
      sections:
        description: Array of bundle section in the root of the bundle.
        type: array
        items:
          $ref: "#/definitions/ItemBundleSectionResponse"
BundleSectionResponse:
    type: object
    x-omitempty: false
    properties:
      id:
        type: string
        x-omitempty: false
        example: 5dfb977429ec145dd6f9c307
     ...
  ItemBundleSectionResponse:
    allOf:
      - $ref: "#/definitions/BundleSectionResponse"
      - type: object
        x-omitempty: false
        properties:
          items:
            description: Array of bundle items inside a section of the bundle
            type: array
            items:
              $ref: "#/definitions/BundleItemResponse"
```
## Go code:
### Actual
```
// BundleAttributesResponse bundle attributes response
//
// swagger:model BundleAttributesResponse
type BundleAttributesResponse struct {

	// Array of bundle items in the root of the bundle.
	Items []BundleItemResponse `json:"items"`

	// Array of bundle section in the root of the bundle.
	Sections []*ItemBundleSectionResponse `json:"sections"`

	// type
	Type BundleType `json:"type,omitempty"`
}
```
### Expected
```
// BundleAttributesResponse bundle attributes response
//
// swagger:model BundleAttributesResponse
type BundleAttributesResponse struct {

	// Array of bundle items in the root of the bundle.
	Items []BundleItemResponse `json:"items"`

	// Array of bundle section in the root of the bundle.
	Sections []ItemBundleSectionResponse `json:"sections"`

	// type
	Type BundleType `json:"type,omitempty"`
}
```
I need `Sections []ItemBundleSectionResponse` to be without pointer. Is it known issue or am i missing smth?
## Steps to reproduce
Run `swagger generate model --spec=swagger.yml`
## Environment
swagger version: v0.25.0  
go version:  go1.13.5 linux/amd64
OS:  linux/amd64


Pull request:
allow x-nullable hint to override allOf nullability status
* fixes #2364

Signed-off-by: Frederic BIDON <fredbi@yahoo.com>

Patch:
diff --git a/README.md b/README.md
index 1081a4ae..d7d16b93 100644
--- a/README.md
+++ b/README.md
@@ -216,7 +216,7 @@ Iron.io
 [ScaleFT](https://github.com/authclub/billforward)  
 [StratoScale](https://github.com/Stratoscale/swagger)  
 [Terraform Provider OpenAPI](https://github.com/dikhan/terraform-provider-openapi)  
-[VMWare](https://github.com/vmware/dispatch)  
+[VMware](https://github.com/vmware/dispatch)  
 ...
 
 ## Note to users migrating from older releases
diff --git a/fixtures/bugs/2364/fixture-2364.yaml b/fixtures/bugs/2364/fixture-2364.yaml
new file mode 100644
index 00000000..83670da4
--- /dev/null
+++ b/fixtures/bugs/2364/fixture-2364.yaml
@@ -0,0 +1,65 @@
+swagger: "2.0"
+info:
+  title: "repro #2364"
+  version: "0.0.1"
+  description: "repro issue 2364"
+  license:
+    name: "Apache 2.0"
+    url: "http://www.apache.org/licenses/LICENSE-2.0.html"
+paths:
+  /getRecords:
+    get:
+      operationId: getRecords
+      responses:
+        200:
+          description: "OK"
+          schema:
+            $ref: '#/definitions/BundleAttributesResponse'
+
+definitions:
+  BundleAttributesResponse:
+      properties:
+        type:
+          $ref: "#/definitions/BundleType"
+        items:
+          description: Array of bundle items in the root of the bundle.
+          type: array
+          items:
+            $ref: "#/definitions/BundleItemResponse"
+        sections:
+          description: Array of bundle section in the root of the bundle.
+          type: array
+          items:
+            $ref: "#/definitions/ItemBundleSectionResponse"
+
+  BundleType:
+    type: string
+
+  BundleItemResponse:
+    type: object
+    properties:
+      id:
+        type: string
+    x-nullable: false
+
+  BundleSectionResponse:
+    type: object
+    x-omitempty: false
+    properties:
+      id:
+        type: string
+        x-omitempty: false
+        example: 5dfb977429ec145dd6f9c307
+
+  ItemBundleSectionResponse:
+    allOf:
+      - $ref: "#/definitions/BundleSectionResponse"
+      - type: object
+        x-omitempty: false
+        properties:
+          items:
+            description: Array of bundle items inside a section of the bundle
+            type: array
+            items:
+              $ref: "#/definitions/BundleItemResponse"
+    x-nullable: false
diff --git a/generator/model.go b/generator/model.go
index c005d028..bfa166e0 100644
--- a/generator/model.go
+++ b/generator/model.go
@@ -1730,7 +1730,7 @@ func (sg *schemaGenContext) shortCircuitNamedRef() (bool, error) {
 	tpe.IsMap = false
 	tpe.IsArray = false
 	tpe.IsAnonymous = false
-	tpe.IsNullable = sg.TypeResolver.IsNullable(&sg.Schema)
+	tpe.IsNullable = sg.TypeResolver.isNullable(&sg.Schema)
 
 	item := sg.NewCompositionBranch(sg.Schema, 0)
 	if err := item.makeGenSchema(); err != nil {
@@ -1765,7 +1765,7 @@ func (sg *schemaGenContext) liftSpecialAllOf() error {
 		if err != nil {
 			return err
 		}
-		if sg.TypeResolver.IsNullable(&sch) {
+		if sg.TypeResolver.isNullable(&sch) {
 			seenNullable = true
 		}
 		if len(sch.Type) > 0 || len(sch.Properties) > 0 || sch.Ref.GetURL() != nil || len(sch.AllOf) > 0 {
diff --git a/generator/types.go b/generator/types.go
index e4d2493a..2b0956e7 100644
--- a/generator/types.go
+++ b/generator/types.go
@@ -236,19 +236,6 @@ func (t *typeResolver) withKeepDefinitionsPackage(definitionsPackage string) *ty
 	return t
 }
 
-// IsNullable hints the generator as to render the type with a pointer or not.
-//
-// A schema is deemed nullable (i.e. rendered by a pointer) when:
-// - a custom extension says it has to be so
-// - it is an object with properties
-// - it is a composed object (allOf)
-//
-// The interpretation of Required as a mean to make a type nullable is carried on elsewhere.
-func (t *typeResolver) IsNullable(schema *spec.Schema) bool {
-	nullable := t.isNullable(schema)
-	return nullable || len(schema.AllOf) > 0
-}
-
 func (t *typeResolver) resolveSchemaRef(schema *spec.Schema, isRequired bool) (returns bool, result resolvedType, err error) {
 	if schema.Ref.String() == "" {
 		return
@@ -281,7 +268,7 @@ func (t *typeResolver) resolveSchemaRef(schema *spec.Schema, isRequired bool) (r
 	}
 	result.HasDiscriminator = res.HasDiscriminator
 	result.IsBaseType = result.HasDiscriminator
-	result.IsNullable = t.IsNullable(ref)
+	result.IsNullable = t.isNullable(ref)
 	result.IsEnumCI = false
 	return
 }
@@ -334,12 +321,20 @@ func (t *typeResolver) resolveFormat(schema *spec.Schema, isAnonymous bool, isRe
 		case number, integer:
 			result.IsNullable = nullableNumber(schema, isRequired)
 		default:
-			result.IsNullable = t.IsNullable(schema)
+			result.IsNullable = t.isNullable(schema)
 		}
 	}
 	return
 }
 
+// isNullable hints the generator as to render the type with a pointer or not.
+//
+// A schema is deemed nullable (i.e. rendered by a pointer) when:
+// - a custom extension says it has to be so
+// - it is an object with properties
+// - it is a composed object (allOf)
+//
+// The interpretation of Required as a mean to make a type nullable is carried on elsewhere.
 func (t *typeResolver) isNullable(schema *spec.Schema) bool {
 	check := func(extension string) (bool, bool) {
 		v, found := schema.Extensions[extension]
@@ -353,7 +348,7 @@ func (t *typeResolver) isNullable(schema *spec.Schema) bool {
 	if nullable, ok := check(xNullable); ok {
 		return nullable
 	}
-	return len(schema.Properties) > 0
+	return len(schema.Properties) > 0 || len(schema.AllOf) > 0
 }
 
 func (t *typeResolver) firstType(schema *spec.Schema) string {
@@ -404,7 +399,7 @@ func (t *typeResolver) resolveArray(schema *spec.Schema, isAnonymous, isRequired
 	}
 	// override the general nullability rule from ResolveSchema():
 	// only complex items are nullable (when not discriminated, not forced by x-nullable)
-	rt.IsNullable = t.IsNullable(schema.Items.Schema) && !rt.HasDiscriminator
+	rt.IsNullable = t.isNullable(schema.Items.Schema) && !rt.HasDiscriminator
 	result.GoType = "[]" + rt.GoType
 	if rt.IsNullable && !strings.HasPrefix(rt.GoType, "*") {
 		result.GoType = "[]*" + rt.GoType
@@ -458,7 +453,7 @@ func (t *typeResolver) resolveObject(schema *spec.Schema, isAnonymous bool) (res
 		result.IsComplexObject = true
 		var isNullable bool
 		for _, p := range schema.AllOf {
-			if t.IsNullable(&p) {
+			if t.isNullable(&p) {
 				isNullable = true
 			}
 		}
@@ -471,7 +466,7 @@ func (t *typeResolver) resolveObject(schema *spec.Schema, isAnonymous bool) (res
 	// resolved type, this should also flag the object as anonymous,
 	// when a ref is found, the anonymous flag will be reset
 	if len(schema.Properties) > 0 {
-		result.IsNullable = t.IsNullable(schema)
+		result.IsNullable = t.isNullable(schema)
 		result.IsComplexObject = true
 		// no return here, still need to check for additional properties
 	}
@@ -664,7 +659,7 @@ func (t *typeResolver) shortCircuitResolveExternal(tpe, pkg, alias string, extTy
 	result.Pkg = pkg
 	result.PkgAlias = alias
 	result.setKind(extType.Hints.Kind)
-	result.IsNullable = t.IsNullable(schema)
+	result.IsNullable = t.isNullable(schema)
 
 	// other extensions
 	if result.IsArray {


Test patch:
diff --git a/generator/moreschemavalidation_fixtures_test.go b/generator/moreschemavalidation_fixtures_test.go
index 6db97416..648290dc 100644
--- a/generator/moreschemavalidation_fixtures_test.go
+++ b/generator/moreschemavalidation_fixtures_test.go
@@ -11082,3 +11082,20 @@ func initFixture1993() {
 		noLines,
 		noLines)
 }
+
+func initFixture2364() {
+	f := newModelFixture("../fixtures/bugs/2364/fixture-2364.yaml", "test non-nullable allOf")
+	thisRun := f.AddRun(false).WithMinimalFlatten(true)
+
+	thisRun.AddExpectations("bundle_attributes_response.go", []string{
+		`type BundleAttributesResponse struct {`,
+		`Items []BundleItemResponse`,
+		`Sections []ItemBundleSectionResponse`,
+		`Type BundleType`,
+	},
+		// not expected
+		todo,
+		// output in log
+		noLines,
+		noLines)
+}
diff --git a/generator/moreschemavalidation_test.go b/generator/moreschemavalidation_test.go
index b012b1f6..7dd73b3e 100644
--- a/generator/moreschemavalidation_test.go
+++ b/generator/moreschemavalidation_test.go
@@ -213,6 +213,9 @@ func initModelFixtures() {
 
 	// additionalProperties in base type (pending fix, non regression assertion only atm)
 	initFixture2220()
+
+	// allOf can be forced to non-nullable
+	initFixture2364()
 }
 
 /* Template initTxxx() to prepare and load a fixture: