Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add JsonCloneSettings to disable copy annotations #2747

Closed
Closed
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
15 changes: 15 additions & 0 deletions Src/Newtonsoft.Json.Tests/Linq/AnnotationsTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -308,6 +308,21 @@ public void MultipleAnnotationsAreCopied()
Assert.AreEqual(annotation, t.DeepClone().Annotation<T>());
}

[Test]
public void MultipleAnnotationsAreNotCopiedWithSetting()
snshivakumar marked this conversation as resolved.
Show resolved Hide resolved
{
Version version = new Version(1, 2, 3, 4);

JObject o = new JObject();
o.AddAnnotation("string!");
o.AddAnnotation(version);

JsonCloneSettings settings = new JsonCloneSettings() { CopyAnnotations = false };
JObject o2 = (JObject)o.DeepClone(settings);
Assert.IsNull(o2.Annotation<string>());
Assert.AreEqual(0, o2.Annotations<Version>().Count());
}

#if !NET20
[Test]
public void Example()
Expand Down
11 changes: 6 additions & 5 deletions Src/Newtonsoft.Json/Linq/JArray.cs
Original file line number Diff line number Diff line change
Expand Up @@ -65,8 +65,9 @@ public JArray()
/// Initializes a new instance of the <see cref="JArray"/> class from another <see cref="JArray"/> object.
/// </summary>
/// <param name="other">A <see cref="JArray"/> object to copy from.</param>
public JArray(JArray other)
: base(other)
/// <param name="settings">A <see cref="JsonCloneSettings"/> object to configure cloning settings.</param>
public JArray(JArray other, JsonCloneSettings? settings = null)
: base(other, settings)
{
}

Expand All @@ -78,7 +79,7 @@ public JArray(params object[] content)
: this((object)content)
{
}

/// <summary>
/// Initializes a new instance of the <see cref="JArray"/> class with the specified content.
/// </summary>
Expand All @@ -93,9 +94,9 @@ internal override bool DeepEquals(JToken node)
return (node is JArray t && ContentsEqual(t));
}

internal override JToken CloneToken()
internal override JToken CloneToken(JsonCloneSettings? settings = null)
{
return new JArray(this);
return new JArray(this, settings);
}
snshivakumar marked this conversation as resolved.
Show resolved Hide resolved

/// <summary>
Expand Down
7 changes: 4 additions & 3 deletions Src/Newtonsoft.Json/Linq/JConstructor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -96,8 +96,9 @@ public JConstructor()
/// Initializes a new instance of the <see cref="JConstructor"/> class from another <see cref="JConstructor"/> object.
/// </summary>
/// <param name="other">A <see cref="JConstructor"/> object to copy from.</param>
public JConstructor(JConstructor other)
: base(other)
/// <param name="settings">A <see cref="JsonCloneSettings"/> object to configure cloning settings.</param>
public JConstructor(JConstructor other, JsonCloneSettings? settings = null)
: base(other, settings)
{
_name = other.Name;
}
Expand Down Expand Up @@ -147,7 +148,7 @@ internal override bool DeepEquals(JToken node)
return (node is JConstructor c && _name == c.Name && ContentsEqual(c));
}

internal override JToken CloneToken()
internal override JToken CloneToken(JsonCloneSettings? settings = null)
{
return new JConstructor(this);
}
Expand Down
7 changes: 5 additions & 2 deletions Src/Newtonsoft.Json/Linq/JContainer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@ internal JContainer()
{
}

internal JContainer(JContainer other)
internal JContainer(JContainer other, JsonCloneSettings? settings = null)
: this()
{
ValidationUtils.ArgumentNotNull(other, nameof(other));
Expand All @@ -118,7 +118,10 @@ internal JContainer(JContainer other)
i++;
}

CopyAnnotations(this, other);
if (settings?.CopyAnnotations ?? true)
{
CopyAnnotations(this, other);
}
}

internal void CheckReentrancy()
Expand Down
9 changes: 5 additions & 4 deletions Src/Newtonsoft.Json/Linq/JObject.cs
Original file line number Diff line number Diff line change
Expand Up @@ -92,8 +92,9 @@ public JObject()
/// Initializes a new instance of the <see cref="JObject"/> class from another <see cref="JObject"/> object.
/// </summary>
/// <param name="other">A <see cref="JObject"/> object to copy from.</param>
public JObject(JObject other)
: base(other)
/// <param name="settings">A <see cref="JsonCloneSettings"/> object to configure cloning settings.</param>
public JObject(JObject other, JsonCloneSettings? settings = null)
: base(other, settings)
{
}

Expand Down Expand Up @@ -244,9 +245,9 @@ internal void InternalPropertyChanging(JProperty childProperty)
#endif
}

internal override JToken CloneToken()
internal override JToken CloneToken(JsonCloneSettings? settings = null)
{
return new JObject(this);
return new JObject(this, settings);
}

/// <summary>
Expand Down
9 changes: 5 additions & 4 deletions Src/Newtonsoft.Json/Linq/JProperty.cs
Original file line number Diff line number Diff line change
Expand Up @@ -186,8 +186,9 @@ public JToken Value
/// Initializes a new instance of the <see cref="JProperty"/> class from another <see cref="JProperty"/> object.
/// </summary>
/// <param name="other">A <see cref="JProperty"/> object to copy from.</param>
public JProperty(JProperty other)
: base(other)
/// <param name="settings">A <see cref="JsonCloneSettings"/> object to configure cloning settings.</param>
public JProperty(JProperty other, JsonCloneSettings? settings = null)
: base(other, settings)
{
_name = other.Name;
}
Expand Down Expand Up @@ -282,9 +283,9 @@ internal override bool DeepEquals(JToken node)
return (node is JProperty t && _name == t.Name && ContentsEqual(t));
}

internal override JToken CloneToken()
internal override JToken CloneToken(JsonCloneSettings? settings = null)
{
return new JProperty(this);
return new JProperty(this, settings);
}

/// <summary>
Expand Down
9 changes: 5 additions & 4 deletions Src/Newtonsoft.Json/Linq/JRaw.cs
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,9 @@ public partial class JRaw : JValue
/// Initializes a new instance of the <see cref="JRaw"/> class from another <see cref="JRaw"/> object.
/// </summary>
/// <param name="other">A <see cref="JRaw"/> object to copy from.</param>
public JRaw(JRaw other)
: base(other)
/// <param name="settings">A <see cref="JsonCloneSettings"/> object to configure cloning settings.</param>
public JRaw(JRaw other, JsonCloneSettings? settings = null)
: base(other, settings)
{
}

Expand Down Expand Up @@ -67,9 +68,9 @@ public static JRaw Create(JsonReader reader)
}
}

internal override JToken CloneToken()
internal override JToken CloneToken(JsonCloneSettings? settings = null)
{
return new JRaw(this);
return new JRaw(this, settings);
}
}
}
12 changes: 11 additions & 1 deletion Src/Newtonsoft.Json/Linq/JToken.cs
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,7 @@ public JToken Root
}
}

internal abstract JToken CloneToken();
internal abstract JToken CloneToken(JsonCloneSettings? settings = null);
internal abstract bool DeepEquals(JToken node);

/// <summary>
Expand Down Expand Up @@ -2446,6 +2446,16 @@ public JToken DeepClone()
return CloneToken();
}

/// <summary>
/// Creates a new instance of the <see cref="JToken"/>. All child tokens are recursively cloned.
/// </summary>
/// <param name="settings">A <see cref="JsonCloneSettings"/> object to configure cloning settings.</param>
/// <returns>A new instance of the <see cref="JToken"/>.</returns>
public JToken DeepClone(JsonCloneSettings settings)
{
return CloneToken(settings);
}

/// <summary>
/// Adds an object to the annotation list of this <see cref="JToken"/>.
/// </summary>
Expand Down
12 changes: 8 additions & 4 deletions Src/Newtonsoft.Json/Linq/JValue.cs
Original file line number Diff line number Diff line change
Expand Up @@ -61,10 +61,14 @@ internal JValue(object? value, JTokenType type)
/// Initializes a new instance of the <see cref="JValue"/> class from another <see cref="JValue"/> object.
/// </summary>
/// <param name="other">A <see cref="JValue"/> object to copy from.</param>
public JValue(JValue other)
/// <param name="settings">A <see cref="JsonCloneSettings"/> object to configure cloning settings.</param>
public JValue(JValue other, JsonCloneSettings? settings = null)
: this(other.Value, other.Type)
{
CopyAnnotations(this, other);
if (settings?.CopyAnnotations ?? true)
{
CopyAnnotations(this, other);
}
}

/// <summary>
Expand Down Expand Up @@ -557,9 +561,9 @@ private static bool Operation(ExpressionType operation, object? objA, object? ob
}
#endif

internal override JToken CloneToken()
internal override JToken CloneToken(JsonCloneSettings? settings = null)
{
return new JValue(this);
return new JValue(this, settings);
}

/// <summary>
Expand Down
18 changes: 18 additions & 0 deletions Src/Newtonsoft.Json/Linq/JsonCloneSettings.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
using System;

namespace Newtonsoft.Json.Linq
{
/// <summary>
/// Specifies the settings used when selecting JSON.
/// </summary>
public class JsonCloneSettings
{
/// <summary>
/// Gets or sets a flag that indicates whether to copy annotations when cloning a JToken.
/// </summary>
/// <value>
/// A flag that indicates whether to copy annotations when cloning a JToken.
/// </value>
public bool CopyAnnotations { get; set; }
}
}