From 58055db145ea07dd7e0be8ee3d2b3e6a14051a03 Mon Sep 17 00:00:00 2001 From: TIHan Date: Thu, 28 Mar 2019 12:59:14 -0700 Subject: [PATCH 1/2] Making ILVersionInfo a struct --- src/absil/il.fs | 37 +++++++++++++++++++++++-------------- src/absil/il.fsi | 10 +++++++++- src/absil/ilprint.fs | 10 +++++----- src/absil/ilread.fs | 14 +++++++------- src/absil/ilreflect.fs | 4 ++-- src/absil/ilwrite.fs | 23 +++++++++++------------ src/fsharp/TastOps.fs | 12 ++++++------ src/fsharp/TastPickle.fs | 6 ++++-- src/fsharp/fsc.fs | 14 +++++++------- 9 files changed, 74 insertions(+), 56 deletions(-) diff --git a/src/absil/il.fs b/src/absil/il.fs index 012a2385925..6a5714125bb 100644 --- a/src/absil/il.fs +++ b/src/absil/il.fs @@ -320,7 +320,16 @@ let sha1HashInt64 s = SHA1.sha1HashInt64 s // // -------------------------------------------------------------------- -type ILVersionInfo = uint16 * uint16 * uint16 * uint16 +[] +type ILVersionInfo = + + val Major: uint16 + val Minor: uint16 + val Build: uint16 + val Revision: uint16 + + new(major, minor, build, revision) = + { Major = major; Minor = minor; Build = build; Revision = revision } type Locale = string @@ -411,7 +420,7 @@ type ILAssemblyRef(data) = let version = match aname.Version with | null -> None - | v -> Some (uint16 v.Major, uint16 v.Minor, uint16 v.Build, uint16 v.Revision) + | v -> Some (ILVersionInfo (uint16 v.Major, uint16 v.Minor, uint16 v.Build, uint16 v.Revision)) let retargetable = aname.Flags = System.Reflection.AssemblyNameFlags.Retargetable @@ -424,15 +433,15 @@ type ILAssemblyRef(data) = add(aref.Name) match aref.Version with | None -> () - | Some (a, b, c, d) -> + | Some (version) -> add ", Version=" - add (string (int a)) + add (string (int version.Major)) add "." - add (string (int b)) + add (string (int version.Minor)) add "." - add (string (int c)) + add (string (int version.Build)) add "." - add (string (int d)) + add (string (int version.Revision)) add ", Culture=" match aref.Locale with | None -> add "neutral" @@ -3560,7 +3569,7 @@ let et_MVAR = 0x1Euy let et_CMOD_REQD = 0x1Fuy let et_CMOD_OPT = 0x20uy -let formatILVersion ((a, b, c, d):ILVersionInfo) = sprintf "%d.%d.%d.%d" (int a) (int b) (int c) (int d) +let formatILVersion (version: ILVersionInfo) = sprintf "%d.%d.%d.%d" (int version.Major) (int version.Minor) (int version.Build) (int version.Revision) let encodeCustomAttrString s = let arr = string_as_utf8_bytes s @@ -4241,17 +4250,17 @@ let parseILVersion (vstr : string) = let zero32 n = if n < 0 then 0us else uint16(n) // since the minor revision will be -1 if none is specified, we need to truncate to 0 to not break existing code let minorRevision = if version.Revision = -1 then 0us else uint16(version.MinorRevision) - (zero32 version.Major, zero32 version.Minor, zero32 version.Build, minorRevision) + ILVersionInfo(zero32 version.Major, zero32 version.Minor, zero32 version.Build, minorRevision) -let compareILVersions (a1, a2, a3, a4) ((b1, b2, b3, b4) : ILVersionInfo) = - let c = compare a1 b1 +let compareILVersions (version1 : ILVersionInfo) (version2 : ILVersionInfo) = + let c = compare version1.Major version2.Major if c <> 0 then c else - let c = compare a2 b2 + let c = compare version1.Minor version2.Minor if c <> 0 then c else - let c = compare a3 b3 + let c = compare version1.Build version2.Build if c <> 0 then c else - let c = compare a4 b4 + let c = compare version1.Revision version2.Revision if c <> 0 then c else 0 diff --git a/src/absil/il.fsi b/src/absil/il.fsi index 81ea5622514..87fd66932a6 100644 --- a/src/absil/il.fsi +++ b/src/absil/il.fsi @@ -53,7 +53,15 @@ type PublicKey = member KeyToken: byte[] static member KeyAsToken: byte[] -> PublicKey -type ILVersionInfo = uint16 * uint16 * uint16 * uint16 +[] +type ILVersionInfo = + + val Major: uint16 + val Minor: uint16 + val Build: uint16 + val Revision: uint16 + + new : major: uint16 * minor: uint16 * build: uint16 * revision: uint16 -> ILVersionInfo [] type ILAssemblyRef = diff --git a/src/absil/ilprint.fs b/src/absil/ilprint.fs index f9f7fb7af19..2e8cbc0acf1 100644 --- a/src/absil/ilprint.fs +++ b/src/absil/ilprint.fs @@ -963,15 +963,15 @@ and goutput_lambdas env os lambdas = and goutput_tdefs contents enc env os (td: ILTypeDefs) = List.iter (goutput_tdef enc env contents os) td.AsList -let output_ver os (a,b,c,d) = +let output_ver os (version: ILVersionInfo) = output_string os " .ver " - output_u16 os a + output_u16 os version.Major output_string os " : " - output_u16 os b + output_u16 os version.Minor output_string os " : " - output_u16 os c + output_u16 os version.Build output_string os " : " - output_u16 os d + output_u16 os version.Revision let output_locale os s = output_string os " .Locale "; output_qstring os s diff --git a/src/absil/ilread.fs b/src/absil/ilread.fs index b7130c44ba9..9732e543b3d 100644 --- a/src/absil/ilread.fs +++ b/src/absil/ilread.fs @@ -1667,7 +1667,7 @@ and seekReadAssemblyManifest (ctxt: ILMetadataReader) pectxt idx = AuxModuleHashAlgorithm=hash SecurityDeclsStored= ctxt.securityDeclsReader_Assembly PublicKey= pubkey - Version= Some (v1, v2, v3, v4) + Version= Some (ILVersionInfo (v1, v2, v3, v4)) Locale= readStringHeapOption ctxt localeIdx CustomAttrsStored = ctxt.customAttrsReader_Assembly MetadataIndex = idx @@ -1700,12 +1700,12 @@ and seekReadAssemblyRefUncached ctxtH idx = | Some blob -> Some (if (flags &&& 0x0001) <> 0x0 then PublicKey blob else PublicKeyToken blob) ILAssemblyRef.Create - (name=nm, - hash=readBlobHeapOption ctxt hashValueIdx, - publicKey=publicKey, - retargetable=((flags &&& 0x0100) <> 0x0), - version=Some(v1, v2, v3, v4), - locale=readStringHeapOption ctxt localeIdx) + (name = nm, + hash = readBlobHeapOption ctxt hashValueIdx, + publicKey = publicKey, + retargetable = ((flags &&& 0x0100) <> 0x0), + version = Some (ILVersionInfo (v1, v2, v3, v4)), + locale = readStringHeapOption ctxt localeIdx) and seekReadModuleRef (ctxt: ILMetadataReader) mdv idx = let (nameIdx) = seekReadModuleRefRow ctxt mdv idx diff --git a/src/absil/ilreflect.fs b/src/absil/ilreflect.fs index 1381efd591f..f97f6fca425 100644 --- a/src/absil/ilreflect.fs +++ b/src/absil/ilreflect.fs @@ -310,8 +310,8 @@ let convAssemblyRef (aref:ILAssemblyRef) = | None -> () | Some (PublicKey bytes) -> asmName.SetPublicKey(bytes) | Some (PublicKeyToken bytes) -> asmName.SetPublicKeyToken(bytes)) - let setVersion (major, minor, build, rev) = - asmName.Version <- System.Version (int32 major, int32 minor, int32 build, int32 rev) + let setVersion (version: ILVersionInfo) = + asmName.Version <- System.Version (int32 version.Major, int32 version.Minor, int32 version.Build, int32 version.Revision) Option.iter setVersion aref.Version // asmName.ProcessorArchitecture <- System.Reflection.ProcessorArchitecture.MSIL #if !FX_RESHAPED_GLOBALIZATION diff --git a/src/absil/ilwrite.fs b/src/absil/ilwrite.fs index a3a4d61f7f5..5dc02390aa1 100644 --- a/src/absil/ilwrite.fs +++ b/src/absil/ilwrite.fs @@ -709,10 +709,10 @@ let rec GetIdxForTypeDef cenv key = let rec GetAssemblyRefAsRow cenv (aref:ILAssemblyRef) = AssemblyRefRow - ((match aref.Version with None -> 0us | Some (x, _, _, _) -> x), - (match aref.Version with None -> 0us | Some (_, y, _, _) -> y), - (match aref.Version with None -> 0us | Some (_, _, z, _) -> z), - (match aref.Version with None -> 0us | Some (_, _, _, w) -> w), + ((match aref.Version with None -> 0us | Some (version) -> version.Major), + (match aref.Version with None -> 0us | Some (version) -> version.Minor), + (match aref.Version with None -> 0us | Some (version) -> version.Build), + (match aref.Version with None -> 0us | Some (version) -> version.Revision), ((match aref.PublicKey with Some (PublicKey _) -> 0x0001 | _ -> 0x0000) ||| (if aref.Retargetable then 0x0100 else 0x0000)), BlobIndex (match aref.PublicKey with @@ -2822,10 +2822,10 @@ and GenExportedTypesPass3 cenv (ce: ILExportedTypesAndForwarders) = and GetManifsetAsAssemblyRow cenv m = UnsharedRow [|ULong m.AuxModuleHashAlgorithm - UShort (match m.Version with None -> 0us | Some (x, _, _, _) -> x) - UShort (match m.Version with None -> 0us | Some (_, y, _, _) -> y) - UShort (match m.Version with None -> 0us | Some (_, _, z, _) -> z) - UShort (match m.Version with None -> 0us | Some (_, _, _, w) -> w) + UShort (match m.Version with None -> 0us | Some (version) -> version.Major) + UShort (match m.Version with None -> 0us | Some (version) -> version.Minor) + UShort (match m.Version with None -> 0us | Some (version) -> version.Build) + UShort (match m.Version with None -> 0us | Some (version) -> version.Revision) ULong ( (match m.AssemblyLongevity with | ILAssemblyLongevity.Unspecified -> 0x0000 @@ -3091,9 +3091,8 @@ let writeILMetadataAndCode (generatePdb, desiredMetadataVersion, ilg, emitTailca let (mdtableVersionMajor, mdtableVersionMinor) = metadataSchemaVersionSupportedByCLRVersion desiredMetadataVersion - let version = - let (a, b, c, _) = desiredMetadataVersion - System.Text.Encoding.UTF8.GetBytes (sprintf "v%d.%d.%d" a b c) + let version = + System.Text.Encoding.UTF8.GetBytes (sprintf "v%d.%d.%d" desiredMetadataVersion.Major desiredMetadataVersion.Minor desiredMetadataVersion.Build) let paddedVersionLength = align 0x4 (Array.length version) @@ -3634,7 +3633,7 @@ let writeBinaryAndReportMappings (outfile, | ILScopeRef.Module(_) -> failwith "Expected mscorlib to be ILScopeRef.Assembly was ILScopeRef.Module" | ILScopeRef.Assembly(aref) -> match aref.Version with - | Some (2us, _, _, _) -> parseILVersion "2.0.50727.0" + | Some (version) when version.Major = 2us -> parseILVersion "2.0.50727.0" | Some v -> v | None -> failwith "Expected msorlib to have a version number" diff --git a/src/fsharp/TastOps.fs b/src/fsharp/TastOps.fs index 8d659f54aed..e0760e3526a 100644 --- a/src/fsharp/TastOps.fs +++ b/src/fsharp/TastOps.fs @@ -7004,13 +7004,13 @@ let tnames_SignatureDataVersionAttr = splitILTypeName tname_SignatureDataVersion let tref_SignatureDataVersionAttr () = mkILTyRef(IlxSettings.ilxFsharpCoreLibScopeRef (), tname_SignatureDataVersionAttr) -let mkSignatureDataVersionAttr (g:TcGlobals) ((v1, v2, v3, _) : ILVersionInfo) = +let mkSignatureDataVersionAttr (g: TcGlobals) (version: ILVersionInfo) = mkILCustomAttribute g.ilg (tref_SignatureDataVersionAttr(), [g.ilg.typ_Int32;g.ilg.typ_Int32;g.ilg.typ_Int32], - [ILAttribElem.Int32 (int32 v1) - ILAttribElem.Int32 (int32 v2) - ILAttribElem.Int32 (int32 v3)], []) + [ILAttribElem.Int32 (int32 version.Major) + ILAttribElem.Int32 (int32 version.Minor) + ILAttribElem.Int32 (int32 version.Build)], []) let tname_AutoOpenAttr = FSharpLib.Core + ".AutoOpenAttribute" @@ -7040,11 +7040,11 @@ let TryFindInternalsVisibleToAttr ilg cattr = else None -let IsMatchingSignatureDataVersionAttr ilg ((v1, v2, v3, _) : ILVersionInfo) cattr = +let IsMatchingSignatureDataVersionAttr ilg (version: ILVersionInfo) cattr = IsSignatureDataVersionAttr cattr && match decodeILAttribData ilg cattr with | [ILAttribElem.Int32 u1; ILAttribElem.Int32 u2;ILAttribElem.Int32 u3 ], _ -> - (v1 = uint16 u1) && (v2 = uint16 u2) && (v3 = uint16 u3) + (version.Major = uint16 u1) && (version.Minor = uint16 u2) && (version.Build = uint16 u3) | _ -> warning(Failure(FSComp.SR.tastUnexpectedDecodeOfInterfaceDataVersionAttribute())) false diff --git a/src/fsharp/TastPickle.fs b/src/fsharp/TastPickle.fs index c988d3b338f..a8763a87934 100644 --- a/src/fsharp/TastPickle.fs +++ b/src/fsharp/TastPickle.fs @@ -906,7 +906,7 @@ let p_ILPublicKey x st = | PublicKey b -> p_byte 0 st; p_bytes b st | PublicKeyToken b -> p_byte 1 st; p_bytes b st -let p_ILVersion x st = p_tup4 p_uint16 p_uint16 p_uint16 p_uint16 x st +let p_ILVersion (x: ILVersionInfo) st = p_tup4 p_uint16 p_uint16 p_uint16 p_uint16 (x.Major, x.Minor, x.Build, x.Revision) st let p_ILModuleRef (x:ILModuleRef) st = p_tup3 p_string p_bool (p_option p_bytes) (x.Name, x.HasMetadata, x.Hash) st @@ -929,7 +929,9 @@ let u_ILPublicKey st = | 1 -> u_bytes st |> PublicKeyToken | _ -> ufailwith st "u_ILPublicKey" -let u_ILVersion st = u_tup4 u_uint16 u_uint16 u_uint16 u_uint16 st +let u_ILVersion st = + let (major, minor, build, revision) = u_tup4 u_uint16 u_uint16 u_uint16 u_uint16 st + ILVersionInfo(major, minor, build, revision) let u_ILModuleRef st = let (a, b, c) = u_tup3 u_string u_bool (u_option u_bytes) st diff --git a/src/fsharp/fsc.fs b/src/fsharp/fsc.fs index 29701c86e8a..9471ca9d64f 100644 --- a/src/fsharp/fsc.fs +++ b/src/fsharp/fsc.fs @@ -533,18 +533,18 @@ module VersionResourceFormat = for child in children do yield! child |] - let Version((v1, v2, v3, v4):ILVersionInfo) = + let Version(version: ILVersionInfo) = [| // DWORD dwFileVersionMS // Specifies the most significant 32 bits of the file's binary // version number. This member is used with dwFileVersionLS to form a 64-bit value used // for numeric comparisons. - yield! i32 (int32 v1 <<< 16 ||| int32 v2) + yield! i32 (int32 version.Major <<< 16 ||| int32 version.Minor) // DWORD dwFileVersionLS // Specifies the least significant 32 bits of the file's binary // version number. This member is used with dwFileVersionMS to form a 64-bit value used // for numeric comparisons. - yield! i32 (int32 v3 <<< 16 ||| int32 v4) + yield! i32 (int32 version.Build <<< 16 ||| int32 version.Revision) |] let String(string, value) = @@ -824,7 +824,7 @@ module MainModuleBuilder = let productVersion findStringAttr (fileVersion: ILVersionInfo) = let attrName = "System.Reflection.AssemblyInformationalVersionAttribute" - let toDotted (v1, v2, v3, v4) = sprintf "%d.%d.%d.%d" v1 v2 v3 v4 + let toDotted (version: ILVersionInfo) = sprintf "%d.%d.%d.%d" version.Major version.Minor version.Build version.Revision match findStringAttr attrName with | None | Some "" -> fileVersion |> toDotted | Some (AttributeHelpers.ILVersion(v)) -> v |> toDotted @@ -840,7 +840,7 @@ module MainModuleBuilder = |> Seq.takeWhile ((<>) 0us) |> Seq.toList match validParts @ [0us; 0us; 0us; 0us] with - | major :: minor :: build :: rev :: _ -> (major, minor, build, rev) + | major :: minor :: build :: rev :: _ -> ILVersionInfo(major, minor, build, rev) | x -> failwithf "error converting product version '%s' to binary, tried '%A' " version x @@ -986,8 +986,8 @@ module MainModuleBuilder = // specify the major language, and the high-order 6 bits specify the sublanguage. // For a table of valid identifiers see Language Identifiers. // // see e.g. http://msdn.microsoft.com/en-us/library/aa912040.aspx 0000 is neutral and 04b0(hex)=1252(dec) is the code page. - [ ("000004b0", [ yield ("Assembly Version", (let v1, v2, v3, v4 = assemblyVersion in sprintf "%d.%d.%d.%d" v1 v2 v3 v4)) - yield ("FileVersion", (let v1, v2, v3, v4 = fileVersionInfo in sprintf "%d.%d.%d.%d" v1 v2 v3 v4)) + [ ("000004b0", [ yield ("Assembly Version", (sprintf "%d.%d.%d.%d" assemblyVersion.Major assemblyVersion.Minor assemblyVersion.Build assemblyVersion.Revision)) + yield ("FileVersion", (sprintf "%d.%d.%d.%d" fileVersionInfo.Major fileVersionInfo.Minor fileVersionInfo.Build fileVersionInfo.Revision)) yield ("ProductVersion", productVersionString) match tcConfig.outputFile with | Some f -> yield ("OriginalFilename", Path.GetFileName(f)) From 25d69fb70e40b93d62f7483759776e21b073cb14 Mon Sep 17 00:00:00 2001 From: TIHan Date: Fri, 29 Mar 2019 14:33:37 -0700 Subject: [PATCH 2/2] Fixing tests --- .../ProductVersion.fs | 50 +++++++++---------- 1 file changed, 25 insertions(+), 25 deletions(-) diff --git a/tests/FSharp.Compiler.UnitTests/ProductVersion.fs b/tests/FSharp.Compiler.UnitTests/ProductVersion.fs index de528d3329d..84d05f43e32 100644 --- a/tests/FSharp.Compiler.UnitTests/ProductVersion.fs +++ b/tests/FSharp.Compiler.UnitTests/ProductVersion.fs @@ -16,23 +16,23 @@ module FileVersionTest = [] let parseILVersion () = - "0.0.0.0" |> parseILVersion |> Assert.areEqual (0us,0us,0us,0us) - "1.2.3.4" |> parseILVersion |> Assert.areEqual (1us,2us,3us,4us) + "0.0.0.0" |> parseILVersion |> Assert.areEqual (ILVersionInfo(0us,0us,0us,0us)) + "1.2.3.4" |> parseILVersion |> Assert.areEqual (ILVersionInfo(1us,2us,3us,4us)) [] let ``should use AssemblyFileVersionAttribute if set`` () = let findStringAttr n = n |> Assert.areEqual fileVersionAttrName; Some "1.2.3.4" - fileVersion findStringAttr (1us,0us,0us,0us) |> Assert.areEqual (1us,2us,3us,4us) + fileVersion findStringAttr (ILVersionInfo(1us,0us,0us,0us)) |> Assert.areEqual (ILVersionInfo(1us,2us,3us,4us)) [] let ``should fallback if AssemblyFileVersionAttribute is not a valid version`` () = - fileVersion (fun _ -> Some "1.2a.3.3") (3us,7us,8us,6us) - |> Assert.areEqual (3us,7us,8us,6us) + fileVersion (fun _ -> Some "1.2a.3.3") (ILVersionInfo(3us,7us,8us,6us)) + |> Assert.areEqual (ILVersionInfo(3us,7us,8us,6us)) [] let ``should fallback to assemblyVersion if AssemblyFileVersionAttribute not set`` () = let findStringAttr n = n |> Assert.areEqual fileVersionAttrName; None; - fileVersion findStringAttr (1us,0us,0us,4us) |> Assert.areEqual (1us,0us,0us,4us) + fileVersion findStringAttr (ILVersionInfo(1us,0us,0us,4us)) |> Assert.areEqual (ILVersionInfo(1us,0us,0us,4us)) module ProductVersionTest = @@ -43,25 +43,25 @@ module ProductVersionTest = let ``should use AssemblyInformationalVersionAttribute if set`` () = let mutable args = [] let findStrAttr x = args <- List.append args [x]; Some "12.34.56.78" - productVersion findStrAttr (1us,0us,0us,6us) |> Assert.areEqual "12.34.56.78" + productVersion findStrAttr (ILVersionInfo(1us,0us,0us,6us)) |> Assert.areEqual "12.34.56.78" args |> Assert.areEqual [ informationalVersionAttrName ] [] let ``should fallback if AssemblyInformationalVersionAttribute is not a valid version`` () = - productVersion (fun _ -> Some "1.2.3-main (build #12)") (1us,0us,0us,6us) + productVersion (fun _ -> Some "1.2.3-main (build #12)") (ILVersionInfo(1us,0us,0us,6us)) |> Assert.areEqual "1.2.3-main (build #12)" [] let ``should fallback to fileVersion if AssemblyInformationalVersionAttribute not set or empty`` () = - productVersion (fun _ -> None) (3us,2us,1us,0us) |> Assert.areEqual "3.2.1.0" - productVersion (fun _ -> Some "") (3us,2us,1us,0us) |> Assert.areEqual "3.2.1.0" + productVersion (fun _ -> None) (ILVersionInfo(3us,2us,1us,0us)) |> Assert.areEqual "3.2.1.0" + productVersion (fun _ -> Some "") (ILVersionInfo(3us,2us,1us,0us)) |> Assert.areEqual "3.2.1.0" let validValues () = let max = System.UInt16.MaxValue - [ "1.2.3.4", (1us,2us,3us,4us) - "0.0.0.0", (0us,0us,0us,0us) - "3213.57843.32382.59493", (3213us,57843us,32382us,59493us) - (sprintf "%d.%d.%d.%d" max max max max), (max,max,max,max) ] + [ "1.2.3.4", ILVersionInfo(1us,2us,3us,4us) + "0.0.0.0", ILVersionInfo(0us,0us,0us,0us) + "3213.57843.32382.59493", ILVersionInfo(3213us,57843us,32382us,59493us) + (sprintf "%d.%d.%d.%d" max max max max), ILVersionInfo(max,max,max,max) ] [] let ``should use values if valid major.minor.revision.build version format`` () = @@ -69,17 +69,17 @@ module ProductVersionTest = v |> productVersionToILVersionInfo |> Assert.areEqual expected let invalidValues () = - [ "1.2.3.4", (1us,2us,3us,4us) - "1.2.3.4a", (1us,2us,3us,0us) - "1.2.c3.4", (1us,2us,0us,0us) - "1.2-d.3.4", (1us,0us,0us,0us) - "1dd.2.3.4", (0us,0us,0us,0us) - "1dd.2da.d3hj.dd4ds", (0us,0us,0us,0us) - "1.5.6.7.dasd", (1us,5us,6us,7us) - "9.3", (9us,3us,0us,0us) - "", (0us,0us,0us,0us) - "70000.80000.90000.100000", (0us,0us,0us,0us) - (sprintf "%d.70000.80000.90000" System.UInt16.MaxValue), (System.UInt16.MaxValue,0us,0us,0us) ] + [ "1.2.3.4", ILVersionInfo(1us,2us,3us,4us) + "1.2.3.4a", ILVersionInfo(1us,2us,3us,0us) + "1.2.c3.4", ILVersionInfo(1us,2us,0us,0us) + "1.2-d.3.4", ILVersionInfo(1us,0us,0us,0us) + "1dd.2.3.4", ILVersionInfo(0us,0us,0us,0us) + "1dd.2da.d3hj.dd4ds", ILVersionInfo(0us,0us,0us,0us) + "1.5.6.7.dasd", ILVersionInfo(1us,5us,6us,7us) + "9.3", ILVersionInfo(9us,3us,0us,0us) + "", ILVersionInfo(0us,0us,0us,0us) + "70000.80000.90000.100000", ILVersionInfo(0us,0us,0us,0us) + (sprintf "%d.70000.80000.90000" System.UInt16.MaxValue), ILVersionInfo(System.UInt16.MaxValue,0us,0us,0us) ] [] let ``should zero starting from first invalid version part`` () =