Skip to content

Commit

Permalink
Fix #57, fix #58: Emit initializers and attributes for default values (
Browse files Browse the repository at this point in the history
…#60)

#57: When a schema property declares a default value, assign that value to the property in the default constructor. This ensures that the property has the correct default even if you construct the object by hand rather than by deserializing it from JSON.

#58: When a schema property declares a default value, decorate the property with a `System.ComponentModel.DefaultValue` attribute. This avoids your having to specify those attributes in the CodeGenHints.json file, which is error-prone.

Also:
- Fix a bug where the generated doc comments for properties had an extra space: `cref="P: propName`" → `cref="P:propName`".
- Address some hygiene-related IDE messages by marking some properties `readonly`, and by inlining the declarations of some `out` parameters.
  • Loading branch information
Larry Golding authored Dec 28, 2018
1 parent c871791 commit 7358e25
Show file tree
Hide file tree
Showing 15 changed files with 394 additions and 64 deletions.
152 changes: 133 additions & 19 deletions src/Json.Schema.ToDotNet.UnitTests/DataModelGeneratorTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -871,10 +871,43 @@ public void GeneratesCloningCode()
""type"": ""integer"",
""description"": ""An integer property.""
},
""intPropWithDefault"": {
""type"": ""integer"",
""description"": ""An integer property with a default value."",
""default"": 42
},
""numberProp"": {
""type"": ""number"",
""description"": ""A number property.""
},
""numberPropWithDefault"": {
""type"": ""number"",
""description"": ""A number property with a default value."",
""default"": 42.1
},
""stringProp"": {
""type"": ""string"",
""description"": ""A string property.""
},
""stringPropWithDefault"": {
""type"": ""string"",
""description"": ""A string property with a default value."",
""default"": ""42""
},
""boolProp"": {
""type"": ""boolean"",
""description"": ""A Boolean property.""
},
""boolPropWithTrueDefault"": {
""type"": ""boolean"",
""description"": ""A Boolean property with a true default value."",
""default"": true
},
""boolPropWithFalseDefault"": {
""type"": ""boolean"",
""description"": ""A Boolean property with a false default value."",
""default"": false
},
""arrayProp"": {
""type"": ""array"",
""description"": ""An array property."",
Expand Down Expand Up @@ -1006,6 +1039,7 @@ public void GeneratesCloningCode()
@"using System;
using System.CodeDom.Compiler;
using System.Collections.Generic;
using System.ComponentModel;
using System.Runtime.Serialization;
namespace N
Expand All @@ -1031,12 +1065,59 @@ public SNodeKind SNodeKind
[DataMember(Name = ""intProp"", IsRequired = false, EmitDefaultValue = false)]
public int IntProp { get; set; }
/// <summary>
/// An integer property with a default value.
/// </summary>
[DataMember(Name = ""intPropWithDefault"", IsRequired = false, EmitDefaultValue = false)]
[DefaultValue(42)]
public int IntPropWithDefault { get; set; }
/// <summary>
/// A number property.
/// </summary>
[DataMember(Name = ""numberProp"", IsRequired = false, EmitDefaultValue = false)]
public double NumberProp { get; set; }
/// <summary>
/// A number property with a default value.
/// </summary>
[DataMember(Name = ""numberPropWithDefault"", IsRequired = false, EmitDefaultValue = false)]
[DefaultValue(42.1)]
public double NumberPropWithDefault { get; set; }
/// <summary>
/// A string property.
/// </summary>
[DataMember(Name = ""stringProp"", IsRequired = false, EmitDefaultValue = false)]
public string StringProp { get; set; }
/// <summary>
/// A string property with a default value.
/// </summary>
[DataMember(Name = ""stringPropWithDefault"", IsRequired = false, EmitDefaultValue = false)]
[DefaultValue(""42"")]
public string StringPropWithDefault { get; set; }
/// <summary>
/// A Boolean property.
/// </summary>
[DataMember(Name = ""boolProp"", IsRequired = false, EmitDefaultValue = false)]
public bool BoolProp { get; set; }
/// <summary>
/// A Boolean property with a true default value.
/// </summary>
[DataMember(Name = ""boolPropWithTrueDefault"", IsRequired = false, EmitDefaultValue = false)]
[DefaultValue(true)]
public bool BoolPropWithTrueDefault { get; set; }
/// <summary>
/// A Boolean property with a false default value.
/// </summary>
[DataMember(Name = ""boolPropWithFalseDefault"", IsRequired = false, EmitDefaultValue = false)]
[DefaultValue(false)]
public bool BoolPropWithFalseDefault { get; set; }
/// <summary>
/// An array property.
/// </summary>
Expand Down Expand Up @@ -1110,56 +1191,82 @@ public SNodeKind SNodeKind
/// </summary>
public C()
{
IntPropWithDefault = 42;
NumberPropWithDefault = 42.1;
StringPropWithDefault = ""42"";
BoolPropWithTrueDefault = true;
BoolPropWithFalseDefault = false;
}
/// <summary>
/// Initializes a new instance of the <see cref=""C"" /> class from the supplied values.
/// </summary>
/// <param name=""intProp"">
/// An initialization value for the <see cref=""P: IntProp"" /> property.
/// An initialization value for the <see cref=""P:IntProp"" /> property.
/// </param>
/// <param name=""intPropWithDefault"">
/// An initialization value for the <see cref=""P:IntPropWithDefault"" /> property.
/// </param>
/// <param name=""numberProp"">
/// An initialization value for the <see cref=""P:NumberProp"" /> property.
/// </param>
/// <param name=""numberPropWithDefault"">
/// An initialization value for the <see cref=""P:NumberPropWithDefault"" /> property.
/// </param>
/// <param name=""stringProp"">
/// An initialization value for the <see cref=""P: StringProp"" /> property.
/// An initialization value for the <see cref=""P:StringProp"" /> property.
/// </param>
/// <param name=""stringPropWithDefault"">
/// An initialization value for the <see cref=""P:StringPropWithDefault"" /> property.
/// </param>
/// <param name=""boolProp"">
/// An initialization value for the <see cref=""P:BoolProp"" /> property.
/// </param>
/// <param name=""boolPropWithTrueDefault"">
/// An initialization value for the <see cref=""P:BoolPropWithTrueDefault"" /> property.
/// </param>
/// <param name=""boolPropWithFalseDefault"">
/// An initialization value for the <see cref=""P:BoolPropWithFalseDefault"" /> property.
/// </param>
/// <param name=""arrayProp"">
/// An initialization value for the <see cref=""P: ArrayProp"" /> property.
/// An initialization value for the <see cref=""P:ArrayProp"" /> property.
/// </param>
/// <param name=""uriProp"">
/// An initialization value for the <see cref=""P: UriProp"" /> property.
/// An initialization value for the <see cref=""P:UriProp"" /> property.
/// </param>
/// <param name=""dateTimeProp"">
/// An initialization value for the <see cref=""P: DateTimeProp"" /> property.
/// An initialization value for the <see cref=""P:DateTimeProp"" /> property.
/// </param>
/// <param name=""referencedTypeProp"">
/// An initialization value for the <see cref=""P: ReferencedTypeProp"" /> property.
/// An initialization value for the <see cref=""P:ReferencedTypeProp"" /> property.
/// </param>
/// <param name=""arrayOfRefProp"">
/// An initialization value for the <see cref=""P: ArrayOfRefProp"" /> property.
/// An initialization value for the <see cref=""P:ArrayOfRefProp"" /> property.
/// </param>
/// <param name=""arrayOfArrayProp"">
/// An initialization value for the <see cref=""P: ArrayOfArrayProp"" /> property.
/// An initialization value for the <see cref=""P:ArrayOfArrayProp"" /> property.
/// </param>
/// <param name=""dictionaryProp"">
/// An initialization value for the <see cref=""P: DictionaryProp"" /> property.
/// An initialization value for the <see cref=""P:DictionaryProp"" /> property.
/// </param>
/// <param name=""dictionaryWithPrimitiveSchemaProp"">
/// An initialization value for the <see cref=""P: DictionaryWithPrimitiveSchemaProp"" /> property.
/// An initialization value for the <see cref=""P:DictionaryWithPrimitiveSchemaProp"" /> property.
/// </param>
/// <param name=""dictionaryWithObjectSchemaProp"">
/// An initialization value for the <see cref=""P: DictionaryWithObjectSchemaProp"" /> property.
/// An initialization value for the <see cref=""P:DictionaryWithObjectSchemaProp"" /> property.
/// </param>
/// <param name=""dictionaryWithObjectArraySchemaProp"">
/// An initialization value for the <see cref=""P: DictionaryWithObjectArraySchemaProp"" /> property.
/// An initialization value for the <see cref=""P:DictionaryWithObjectArraySchemaProp"" /> property.
/// </param>
/// <param name=""dictionaryWithUriKeyProp"">
/// An initialization value for the <see cref=""P: DictionaryWithUriKeyProp"" /> property.
/// An initialization value for the <see cref=""P:DictionaryWithUriKeyProp"" /> property.
/// </param>
/// <param name=""dictionaryWithHintedValueProp"">
/// An initialization value for the <see cref=""P: DictionaryWithHintedValueProp"" /> property.
/// An initialization value for the <see cref=""P:DictionaryWithHintedValueProp"" /> property.
/// </param>
public C(int intProp, string stringProp, IEnumerable<double> arrayProp, Uri uriProp, DateTime dateTimeProp, D referencedTypeProp, IEnumerable<D> arrayOfRefProp, IEnumerable<IEnumerable<D>> arrayOfArrayProp, IDictionary<string, string> dictionaryProp, IDictionary<string, double> dictionaryWithPrimitiveSchemaProp, IDictionary<string, D> dictionaryWithObjectSchemaProp, IDictionary<string, IList<D>> dictionaryWithObjectArraySchemaProp, IDictionary<Uri, D> dictionaryWithUriKeyProp, IDictionary<string, V> dictionaryWithHintedValueProp)
public C(int intProp, int intPropWithDefault, double numberProp, double numberPropWithDefault, string stringProp, string stringPropWithDefault, bool boolProp, bool boolPropWithTrueDefault, bool boolPropWithFalseDefault, IEnumerable<double> arrayProp, Uri uriProp, DateTime dateTimeProp, D referencedTypeProp, IEnumerable<D> arrayOfRefProp, IEnumerable<IEnumerable<D>> arrayOfArrayProp, IDictionary<string, string> dictionaryProp, IDictionary<string, double> dictionaryWithPrimitiveSchemaProp, IDictionary<string, D> dictionaryWithObjectSchemaProp, IDictionary<string, IList<D>> dictionaryWithObjectArraySchemaProp, IDictionary<Uri, D> dictionaryWithUriKeyProp, IDictionary<string, V> dictionaryWithHintedValueProp)
{
Init(intProp, stringProp, arrayProp, uriProp, dateTimeProp, referencedTypeProp, arrayOfRefProp, arrayOfArrayProp, dictionaryProp, dictionaryWithPrimitiveSchemaProp, dictionaryWithObjectSchemaProp, dictionaryWithObjectArraySchemaProp, dictionaryWithUriKeyProp, dictionaryWithHintedValueProp);
Init(intProp, intPropWithDefault, numberProp, numberPropWithDefault, stringProp, stringPropWithDefault, boolProp, boolPropWithTrueDefault, boolPropWithFalseDefault, arrayProp, uriProp, dateTimeProp, referencedTypeProp, arrayOfRefProp, arrayOfArrayProp, dictionaryProp, dictionaryWithPrimitiveSchemaProp, dictionaryWithObjectSchemaProp, dictionaryWithObjectArraySchemaProp, dictionaryWithUriKeyProp, dictionaryWithHintedValueProp);
}
/// <summary>
Expand All @@ -1178,7 +1285,7 @@ public C(C other)
throw new ArgumentNullException(nameof(other));
}
Init(other.IntProp, other.StringProp, other.ArrayProp, other.UriProp, other.DateTimeProp, other.ReferencedTypeProp, other.ArrayOfRefProp, other.ArrayOfArrayProp, other.DictionaryProp, other.DictionaryWithPrimitiveSchemaProp, other.DictionaryWithObjectSchemaProp, other.DictionaryWithObjectArraySchemaProp, other.DictionaryWithUriKeyProp, other.DictionaryWithHintedValueProp);
Init(other.IntProp, other.IntPropWithDefault, other.NumberProp, other.NumberPropWithDefault, other.StringProp, other.StringPropWithDefault, other.BoolProp, other.BoolPropWithTrueDefault, other.BoolPropWithFalseDefault, other.ArrayProp, other.UriProp, other.DateTimeProp, other.ReferencedTypeProp, other.ArrayOfRefProp, other.ArrayOfArrayProp, other.DictionaryProp, other.DictionaryWithPrimitiveSchemaProp, other.DictionaryWithObjectSchemaProp, other.DictionaryWithObjectArraySchemaProp, other.DictionaryWithUriKeyProp, other.DictionaryWithHintedValueProp);
}
ISNode ISNode.DeepClone()
Expand All @@ -1199,10 +1306,17 @@ private ISNode DeepCloneCore()
return new C(this);
}
private void Init(int intProp, string stringProp, IEnumerable<double> arrayProp, Uri uriProp, DateTime dateTimeProp, D referencedTypeProp, IEnumerable<D> arrayOfRefProp, IEnumerable<IEnumerable<D>> arrayOfArrayProp, IDictionary<string, string> dictionaryProp, IDictionary<string, double> dictionaryWithPrimitiveSchemaProp, IDictionary<string, D> dictionaryWithObjectSchemaProp, IDictionary<string, IList<D>> dictionaryWithObjectArraySchemaProp, IDictionary<Uri, D> dictionaryWithUriKeyProp, IDictionary<string, V> dictionaryWithHintedValueProp)
private void Init(int intProp, int intPropWithDefault, double numberProp, double numberPropWithDefault, string stringProp, string stringPropWithDefault, bool boolProp, bool boolPropWithTrueDefault, bool boolPropWithFalseDefault, IEnumerable<double> arrayProp, Uri uriProp, DateTime dateTimeProp, D referencedTypeProp, IEnumerable<D> arrayOfRefProp, IEnumerable<IEnumerable<D>> arrayOfArrayProp, IDictionary<string, string> dictionaryProp, IDictionary<string, double> dictionaryWithPrimitiveSchemaProp, IDictionary<string, D> dictionaryWithObjectSchemaProp, IDictionary<string, IList<D>> dictionaryWithObjectArraySchemaProp, IDictionary<Uri, D> dictionaryWithUriKeyProp, IDictionary<string, V> dictionaryWithHintedValueProp)
{
IntProp = intProp;
IntPropWithDefault = intPropWithDefault;
NumberProp = numberProp;
NumberPropWithDefault = numberPropWithDefault;
StringProp = stringProp;
StringPropWithDefault = stringPropWithDefault;
BoolProp = boolProp;
BoolPropWithTrueDefault = boolPropWithTrueDefault;
BoolPropWithFalseDefault = boolPropWithFalseDefault;
if (arrayProp != null)
{
var destination_0 = new List<double>();
Expand Down Expand Up @@ -2450,7 +2564,7 @@ public C()
/// Initializes a new instance of the <see cref=""C"" /> class from the supplied values.
/// </summary>
/// <param name=""uriFormattedStrings"">
/// An initialization value for the <see cref=""P: UriFormattedStrings"" /> property.
/// An initialization value for the <see cref=""P:UriFormattedStrings"" /> property.
/// </param>
public C(IEnumerable<Uri> uriFormattedStrings)
{
Expand Down
Loading

0 comments on commit 7358e25

Please sign in to comment.