diff --git a/DynamicObj.sln b/DynamicObj.sln index b60139b..89c4a52 100644 --- a/DynamicObj.sln +++ b/DynamicObj.sln @@ -9,6 +9,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "build", "build", "{39AA72A1 ProjectSection(SolutionItems) = preProject build.cmd = build.cmd build.sh = build.sh + global.json = global.json EndProjectSection EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = ".ci", ".ci", "{F82A6F26-517C-4D5E-BD4F-BFC45B5867FE}" @@ -20,14 +21,7 @@ EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = ".proj", ".proj", "{C3CF2F15-81C7-4C11-889E-5FCA2C8A981D}" ProjectSection(SolutionItems) = preProject .gitignore = .gitignore - build.cmd = build.cmd - build.sh = build.sh - .config\dotnet-tools.json = .config\dotnet-tools.json - global.json = global.json - key.snk = key.snk LICENSE = LICENSE - package.json = package.json - pyproject.toml = pyproject.toml README.md = README.md RELEASE_NOTES.md = RELEASE_NOTES.md EndProjectSection @@ -37,7 +31,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "docs", "docs", "{42AA66FC-8 docs\index.fsx = docs\index.fsx EndProjectSection EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "CSharpTests", "tests\CSharpTests\CSharpTests.csproj", "{D62D0901-DB69-4C64-AC63-FBBBDCF6BC7D}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CSharpTests", "tests\CSharpTests\CSharpTests.csproj", "{D62D0901-DB69-4C64-AC63-FBBBDCF6BC7D}" EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "tests", "tests", "{988D804A-3A42-4E46-B233-B64F5C22524B}" EndProject diff --git a/src/DynamicObj/DynamicObj.fs b/src/DynamicObj/DynamicObj.fs index d66879c..4c168ba 100644 --- a/src/DynamicObj/DynamicObj.fs +++ b/src/DynamicObj/DynamicObj.fs @@ -253,8 +253,21 @@ type DynamicObj() = let overWrite = defaultArg overWrite false let rec tryDeepCopyObj (o:obj) = match o with + | :? int | :? float | :? bool + | :? string | :? char | :? byte + | :? sbyte | :? int16 | :? uint16 + | :? int32 | :? uint32 | :? int64 + | :? uint64 | :? single + -> o + + #if !FABLE_COMPILER_PYTHON + // https://github.com/fable-compiler/Fable/issues/3971 + | :? decimal -> o + #endif + | :? DynamicObj as dyn -> let newDyn = DynamicObj() + // might want to keep instance props as dynamic props on copy for kv in (dyn.GetProperties(false)) do newDyn.SetProperty(kv.Key, tryDeepCopyObj kv.Value) box newDyn @@ -264,7 +277,12 @@ type DynamicObj() = box [for dyn in dyns -> tryDeepCopyObj dyn :?> DynamicObj] | :? ResizeArray as dyns -> box (ResizeArray([for dyn in dyns -> tryDeepCopyObj dyn :?> DynamicObj])) - //| :? System.ICloneable as clonable -> clonable.Clone() + + #if !FABLE_COMPILER_PYTHON + // https://github.com/fable-compiler/Fable/issues/3972 + | :? System.ICloneable as clonable -> clonable.Clone() + #endif + | _ -> o this.GetProperties(false) diff --git a/tests/DynamicObject.Tests/DynamicObjs.fs b/tests/DynamicObject.Tests/DynamicObjs.fs index 221c8d0..c646c43 100644 --- a/tests/DynamicObject.Tests/DynamicObjs.fs +++ b/tests/DynamicObject.Tests/DynamicObjs.fs @@ -486,6 +486,22 @@ let tests_ShallowCopyDynamicProperties = testList "ShallowCopyDynamicProperties" Expect.equal a b "copied value was not mutated via reference" ] +type DerivedClass(stat: string, dyn: string) as this = + inherit DynamicObj() + do + this.SetProperty("dyn", dyn) + member this.Stat = stat + +type DerivedClassCloneable(stat: string, dyn: string) as this = + inherit DynamicObj() + do + this.SetProperty("dyn", dyn) + member this.Stat = stat + interface ICloneable with + member this.Clone() = + let dyn = this.GetPropertyValue("dyn") |> unbox + DerivedClassCloneable(stat, dyn) + let tests_DeepCopyDynamicProperties = testList "DeepCopyDynamicProperties" [ let constructClone (props: seq) = @@ -498,6 +514,7 @@ let tests_DeepCopyDynamicProperties = testList "DeepCopyDynamicProperties" [ let bulkMutate (props: seq) (dyn: DynamicObj) = props |> Seq.iter (fun (propertyName, propertyValue) -> dyn.SetProperty(propertyName, propertyValue)) + testList "DynamicObj" [ testList "Cloneable dynamic properties" [ testCase "primitives" <| fun _ -> @@ -534,7 +551,7 @@ let tests_DeepCopyDynamicProperties = testList "DeepCopyDynamicProperties" [ "int64", box (int64 -2L) "uint64", box (uint64 2UL) "single", box (single 2.0f) - "decimal", box (decimal 2M) + "decimal", box (decimal 2M) ] bulkMutate mutatedProps original Expect.notEqual original clone "Original and clone should not be equal after mutating primitive props on original" @@ -570,7 +587,7 @@ let tests_DeepCopyDynamicProperties = testList "DeepCopyDynamicProperties" [ Expect.notEqual original clone "Original and clone should not be equal after mutating DynamicObj prop on original" Expect.sequenceEqual originalProp [|-1; -1; -1|] "Original should have mutated properties" Expect.equal clonedProp [|1; 2; 3|] "Clone should have original properties" - testCase " + testCase "DynamicObj list" <| fun _ -> () testCase "DynamicObj ResizeArray" <| fun _ -> () @@ -588,7 +605,7 @@ let tests_DeepCopyDynamicProperties = testList "DeepCopyDynamicProperties" [ () testCase "DynamicObj array" <| fun _ -> () - testCase " + testCase "DynamicObj list" <| fun _ -> () testCase "DynamicObj ResizeArray" <| fun _ -> ()