diff --git a/src/fsharp/FSharp.Compiler.Unittests/FSharp.Compiler.Unittests.fsproj b/src/fsharp/FSharp.Compiler.Unittests/FSharp.Compiler.Unittests.fsproj index 280b96abace23d247e55c40c68dd2d241cc5732c..5a38e3aa85f5ab00e9a713dcbc9d630fc938ed99 100644 --- a/src/fsharp/FSharp.Compiler.Unittests/FSharp.Compiler.Unittests.fsproj +++ b/src/fsharp/FSharp.Compiler.Unittests/FSharp.Compiler.Unittests.fsproj @@ -1,4 +1,4 @@ - + @@ -60,6 +60,7 @@ + diff --git a/src/fsharp/FSharp.Compiler.Unittests/ManglingNameOfProvidedTypes.fs b/src/fsharp/FSharp.Compiler.Unittests/ManglingNameOfProvidedTypes.fs new file mode 100644 index 0000000000000000000000000000000000000000..0180e6abdd284827997884a9daded11e2d8127d5 --- /dev/null +++ b/src/fsharp/FSharp.Compiler.Unittests/ManglingNameOfProvidedTypes.fs @@ -0,0 +1,68 @@ +// Copyright (c) Microsoft Open Technologies, Inc. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. +namespace FSharp.Compiler.Unittests + +open System +open System.Text +open NUnit.Framework +open Microsoft.FSharp.Compiler + +[] +type ManglingNamesOfProvidedTypesWithSingleParameter() = + + [] + member this.MangleWithNonDefaultValue() = + let mangled = + PrettyNaming.computeMangledNameWithoutDefaultArgValues("MyNamespace.Test", [| "xyz" |], [| "Foo", Some "abc" |]) + Assert.AreEqual("MyNamespace.Test,Foo=\"xyz\"", mangled) + + [] + member this.MangleWithDefaultValue() = + let mangled = + PrettyNaming.computeMangledNameWithoutDefaultArgValues("MyNamespace.Test", [| "xyz" |], [| "Foo", Some "xyz" |]) + Assert.AreEqual("MyNamespace.Test", mangled) + + [] + member this.DemangleNonDefaultValue() = + let name, parameters = PrettyNaming.demangleProvidedTypeName "MyNamespace.Test,Foo=\"xyz\"" + Assert.AreEqual("MyNamespace.Test", name) + Assert.AreEqual([| "Foo", "xyz" |], parameters) + + [] + member this.DemangleDefaultValue() = + let name, parameters = PrettyNaming.demangleProvidedTypeName "MyNamespace.Test," + Assert.AreEqual("MyNamespace.Test", name) + Assert.AreEqual([||], parameters) + + [] + member this.DemangleNewDefaultValue() = + let name, parameters = PrettyNaming.demangleProvidedTypeName "MyNamespace.Test" + Assert.AreEqual("MyNamespace.Test", name) + Assert.AreEqual([||], parameters) + +[] +type ManglingNamesOfProvidedTypesWithMultipleParameter() = + + [] + member this.MangleWithNonDefaultValue() = + let mangled = + PrettyNaming.computeMangledNameWithoutDefaultArgValues + ("MyNamespace.Test", [| "xyz"; "abc" |], + [| "Foo", Some "foo" + "Foo2", Some "foo2" |]) + Assert.AreEqual("MyNamespace.Test,Foo=\"xyz\",Foo2=\"abc\"", mangled) + + [] + member this.MangleWithDefaultValue() = + let mangled = + PrettyNaming.computeMangledNameWithoutDefaultArgValues + ("MyNamespace.Test", [| "xyz"; "abc" |], + [| "Foo", Some "xyz" + "Foo2", Some "abc" |]) + Assert.AreEqual("MyNamespace.Test", mangled) + + [] + member this.DemangleMultiParameter() = + let name, parameters = PrettyNaming.demangleProvidedTypeName "TestType,Foo=\"xyz\",Foo2=\"abc\"" + Assert.AreEqual("TestType", name) + Assert.AreEqual([| "Foo", "xyz" + "Foo2", "abc" |], parameters) \ No newline at end of file diff --git a/src/fsharp/PrettyNaming.fs b/src/fsharp/PrettyNaming.fs index 9b74deacf49bd07ff70d6a9046f4f8854bf304f0..84e3848095c43a460a0cc31f86c42572f4564260 100644 --- a/src/fsharp/PrettyNaming.fs +++ b/src/fsharp/PrettyNaming.fs @@ -445,16 +445,15 @@ module internal Microsoft.FSharp.Compiler.PrettyNaming let demangleProvidedTypeName (typeLogicalName:string) = if typeLogicalName.Contains "," then - let pieces = splitAroundQuotation typeLogicalName ',' - if pieces.[1..] |> Array.forall (fun x -> tryDemangleStaticStringArg x |> Option.isSome) then - let argNamesAndValues = - pieces.[1..] |> Array.map (fun piece -> - match tryDemangleStaticStringArg piece with - | None -> raise (InvalidMangledStaticArg piece) - | Some v -> v) - pieces.[0], argNamesAndValues - else - typeLogicalName, [| |] + let pieces = splitAroundQuotation typeLogicalName ',' + match pieces with + | [| x; "" |] -> x, [| |] + | _ -> + let argNamesAndValues = pieces.[1..] |> Array.choose tryDemangleStaticStringArg + if argNamesAndValues.Length = (pieces.Length - 1) then + pieces.[0], argNamesAndValues + else + typeLogicalName, [| |] else typeLogicalName, [| |] @@ -463,8 +462,20 @@ module internal Microsoft.FSharp.Compiler.PrettyNaming nonDefaultArgs |> Array.map mangleStaticStringArg |> String.concat "," - typeLogicalName+","+nonDefaultArgsText - //let testDemangleStaticStringArg() = - // for x in [ ""; "\""; "\"\""; "a"; "\\"; "\\\\"; "\\\""; "_"; "\"\"" ] do - // if demangleStaticStringArg (mangleStaticStringArg x) <> x then printfn "failed for <<%s>>" x + if nonDefaultArgsText = "" then + typeLogicalName + else + typeLogicalName + "," + nonDefaultArgsText + + + let computeMangledNameWithoutDefaultArgValues(nm,staticArgs,defaultArgValues) = + let nonDefaultArgs = + (staticArgs,defaultArgValues) + ||> Array.zip + |> Array.choose (fun (staticArg, (defaultArgName, defaultArgValue)) -> + let actualArgValue = string staticArg + match defaultArgValue with + | Some v when v = actualArgValue -> None + | _ -> Some (defaultArgName, actualArgValue)) + mangleProvidedTypeName (nm, nonDefaultArgs) \ No newline at end of file diff --git a/src/fsharp/est.fs b/src/fsharp/est.fs index 31c2198b727242d890f075ac1990956e5b0be992..59e513ebc0977a5244432cd1cdaec60303d57dc2 100644 --- a/src/fsharp/est.fs +++ b/src/fsharp/est.fs @@ -1262,16 +1262,7 @@ module internal ExtensionTyping = staticParams.PApply((fun ps -> ps |> Array.map (fun sp -> sp.Name, (if sp.IsOptional then Some (string sp.RawDefaultValue) else None ))),range=m) let defaultArgValues = defaultArgValues.PUntaint(id,m) - - let nonDefaultArgs = - (staticArgs,defaultArgValues) - ||> Array.zip - |> Array.choose (fun (staticArg, (defaultArgName, defaultArgValue)) -> - let actualArgValue = string staticArg - match defaultArgValue with - | Some v when v = actualArgValue -> None - | _ -> Some (defaultArgName, actualArgValue)) - PrettyNaming.mangleProvidedTypeName (nm, nonDefaultArgs) + PrettyNaming.computeMangledNameWithoutDefaultArgValues(nm,staticArgs,defaultArgValues) /// Apply the given provided method to the given static arguments (the arguments are assumed to have been sorted into application order) let TryApplyProvidedMethod(methBeforeArgs:Tainted, staticArgs:obj[], m:range) =