diff --git a/src/Fable.Cli/CHANGELOG.md b/src/Fable.Cli/CHANGELOG.md index 47e6815384..6fda4c8a02 100644 --- a/src/Fable.Cli/CHANGELOG.md +++ b/src/Fable.Cli/CHANGELOG.md @@ -12,6 +12,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 * [Rust] Added basic class inheritance support (by @ncave) * [Rust] Added String.Replace(char, char) and test (by @ncave) * [Rust] Support type extensions for external types (by @ncave) +* [Rust] Support more System.Array methods and tests (by @ncave) ## 4.22.0 - 2024-10-02 diff --git a/src/Fable.Cli/Main.fs b/src/Fable.Cli/Main.fs index a85fb92dd3..842fb01fb9 100644 --- a/src/Fable.Cli/Main.fs +++ b/src/Fable.Cli/Main.fs @@ -489,19 +489,10 @@ and FableCompiler(checker: InteractiveChecker, projCracked: ProjectCracked, fabl let startInThreadPool toMsg work = postTo toMsg work |> Async.Start - let runSynchronously toMsg work = - postTo toMsg work |> Async.RunSynchronously - let fableCompile state fileName = let fableProj = state.FableProj - let runner = - // for Rust, sequential compilation captures all imports and namespaces - match projCracked.CliArgs.CompilerOptions.Language with - | Rust -> runSynchronously // sequential file compilation - | _ -> startInThreadPool // parallel file compilation - - runner + startInThreadPool FableFileCompiled (fun () -> async { @@ -577,6 +568,17 @@ and FableCompiler(checker: InteractiveChecker, projCracked: ProjectCracked, fabl return! loop state | FSharpFileTypeChecked file -> + // It seems when there's a pair .fsi/.fs the F# compiler gives the .fsi extension to the implementation file + let fileName = file.FileName |> Path.normalizePath |> Path.ensureFsExtension + + // For Rust, delay last file's compilation until other files finish compiling + if + projCracked.CliArgs.CompilerOptions.Language = Rust + && fileName = Array.last state.FilesToCompile + && state.FableFilesCompiledCount < state.FableFilesToCompileExpectedCount - 1 + then + do! Async.Sleep(100) + Log.verbose ( lazy $"Type checked: {IO.Path.GetRelativePath(projCracked.CliArgs.RootDir, file.FileName)}" ) @@ -587,9 +589,6 @@ and FableCompiler(checker: InteractiveChecker, projCracked: ProjectCracked, fabl let outDir = IO.Path.GetDirectoryName(outPath) Printers.printAst outDir [ file ] - // It seems when there's a pair .fsi/.fs the F# compiler gives the .fsi extension to the implementation file - let fileName = file.FileName |> Path.normalizePath |> Path.ensureFsExtension - let state = if not (state.FilesToCompileSet.Contains(fileName)) then state diff --git a/src/Fable.Transforms/Rust/Replacements.fs b/src/Fable.Transforms/Rust/Replacements.fs index d1f0f88153..4d44619e8c 100644 --- a/src/Fable.Transforms/Rust/Replacements.fs +++ b/src/Fable.Transforms/Rust/Replacements.fs @@ -148,7 +148,7 @@ let makeRefFromMutableFunc com ctx r t (value: Expr) = value let toNativeIndex expr = TypeCast(expr, UNativeInt.Number) let toLowerFirstWithArgsCountSuffix (args: Expr list) meth = - let argCount = List.length args + let argCount = List.length args - 1 // don't count first arg let meth = Naming.lowerFirst meth if argCount > 1 then @@ -1185,11 +1185,7 @@ let chars (com: ICompiler) (ctx: Context) r t (i: CallInfo) (thisArg: Expr optio Helper.LibCall(com, "Char", meth, t, args, i.SignatureArgTypes, ?loc = r) |> Some - | ("GetNumericValue" - // | "GetUnicodeCategory" - | "ConvertToUtf32" as meth), - None, - _ -> + | ("GetNumericValue" | "GetUnicodeCategory" | "ConvertToUtf32" as meth), None, _ -> let meth = getMethod meth args Helper.LibCall(com, "Char", meth, t, args, i.SignatureArgTypes, ?loc = r) @@ -1641,7 +1637,7 @@ let resizeArrays (com: ICompiler) (ctx: Context) r (t: Type) (i: CallInfo) (this Helper.LibCall(com, "NativeArray", meth, t, (ar :: args), ?loc = r) |> Some | ("BinarySearch" | "CopyTo" | "IndexOf" | "LastIndexOf" | "Reverse") as meth, Some ar, args -> // methods with some overrides - let meth = meth |> toLowerFirstWithArgsCountSuffix args + let meth = meth |> toLowerFirstWithArgsCountSuffix (ar :: args) Helper.LibCall(com, "NativeArray", meth, t, (ar :: args), ?loc = r) |> Some | "Sort", Some ar, [] -> Helper.LibCall(com, "NativeArray", "sort", t, (ar :: args), ?loc = r) |> Some | "Sort", Some ar, [ ExprType(DelegateType _) ] -> @@ -1728,11 +1724,17 @@ let arrays (com: ICompiler) (ctx: Context) r (t: Type) (i: CallInfo) (thisArg: E | "Copy", None, [ _source; _sourceIndex; _target; _targetIndex; _count ] -> copyToArray com r t i args | "Copy", None, [ source; target; count ] -> copyToArray com r t i [ source; makeIntConst 0; target; makeIntConst 0; count ] - | "ConvertAll", None, [ source; mapping ] -> - Helper.LibCall(com, "NativeArray", "convertAll", t, args, ?loc = r) |> Some - | "IndexOf", None, [ ar; arg ] -> Helper.LibCall(com, "NativeArray", "indexOf", t, args, ?loc = r) |> Some | "GetEnumerator", Some ar, _ -> Helper.LibCall(com, "Seq", "Enumerable::ofArray", t, [ ar ], ?loc = r) |> Some - | "Reverse", None, [ ar ] -> Helper.LibCall(com, "NativeArray", "reverse", t, args, ?loc = r) |> Some + | ("ConvertAll" | "Exists" | "GetRange" | "ForEach" | "FindAll" | "Find" | "FindLast" | "FindIndex" | "FindLastIndex" | "TrueForAll") as meth, + None, + args -> + // methods without overrides + let meth = Naming.lowerFirst meth + Helper.LibCall(com, "NativeArray", meth, t, args, ?loc = r) |> Some + | ("BinarySearch" | "CopyTo" | "IndexOf" | "LastIndexOf" | "Reverse") as meth, None, args -> + // methods with some overrides + let meth = meth |> toLowerFirstWithArgsCountSuffix args + Helper.LibCall(com, "NativeArray", meth, t, args, ?loc = r) |> Some | "Sort", None, [ ar ] -> Helper.LibCall(com, "NativeArray", "sort", t, args, ?loc = r) |> Some | "Sort", None, [ ar; ExprType(DelegateType _) as comparer ] -> Helper.LibCall(com, "NativeArray", "sortBy", t, args, ?loc = r) |> Some diff --git a/src/fable-library-rust/src/Char.rs b/src/fable-library-rust/src/Char.rs index 219995cb77..33e7ab4f11 100644 --- a/src/fable-library-rust/src/Char.rs +++ b/src/fable-library-rust/src/Char.rs @@ -3,39 +3,39 @@ pub mod Char_ { use crate::Native_::{compare, Lrc, MutCell, ToString, Vec}; use crate::String_::{getCharAt, length, string, toString}; - // // https://docs.microsoft.com/en-us/dotnet/api/system.globalization.unicodecategory?view=net-6.0 - // pub mod UnicodeCategory { - // pub const UppercaseLetter: u8 = 0; - // pub const LowercaseLetter: u8 = 1; - // pub const TitlecaseLetter: u8 = 2; - // pub const ModifierLetter: u8 = 3; - // pub const OtherLetter: u8 = 4; - // pub const NonSpacingMark: u8 = 5; - // pub const SpacingCombiningMark: u8 = 6; - // pub const EnclosingMark: u8 = 7; - // pub const DecimalDigitNumber: u8 = 8; - // pub const LetterNumber: u8 = 9; - // pub const OtherNumber: u8 = 10; - // pub const SpaceSeparator: u8 = 11; - // pub const LineSeparator: u8 = 12; - // pub const ParagraphSeparator: u8 = 13; - // pub const Control: u8 = 14; - // pub const Format: u8 = 15; - // pub const Surrogate: u8 = 16; - // pub const PrivateUse: u8 = 17; - // pub const ConnectorPunctuation: u8 = 18; - // pub const DashPunctuation: u8 = 19; - // pub const OpenPunctuation: u8 = 20; - // pub const ClosePunctuation: u8 = 21; - // pub const InitialQuotePunctuation: u8 = 22; - // pub const FinalQuotePunctuation: u8 = 23; - // pub const OtherPunctuation: u8 = 24; - // pub const MathSymbol: u8 = 25; - // pub const CurrencySymbol: u8 = 26; - // pub const ModifierSymbol: u8 = 27; - // pub const OtherSymbol: u8 = 28; - // pub const OtherNotAssigned: u8 = 29; - // } + // https://docs.microsoft.com/en-us/dotnet/api/system.globalization.unicodecategory?view=net-6.0 + pub mod UnicodeCategory { + pub const UppercaseLetter: u8 = 0; + pub const LowercaseLetter: u8 = 1; + pub const TitlecaseLetter: u8 = 2; + pub const ModifierLetter: u8 = 3; + pub const OtherLetter: u8 = 4; + pub const NonSpacingMark: u8 = 5; + pub const SpacingCombiningMark: u8 = 6; + pub const EnclosingMark: u8 = 7; + pub const DecimalDigitNumber: u8 = 8; + pub const LetterNumber: u8 = 9; + pub const OtherNumber: u8 = 10; + pub const SpaceSeparator: u8 = 11; + pub const LineSeparator: u8 = 12; + pub const ParagraphSeparator: u8 = 13; + pub const Control: u8 = 14; + pub const Format: u8 = 15; + pub const Surrogate: u8 = 16; + pub const PrivateUse: u8 = 17; + pub const ConnectorPunctuation: u8 = 18; + pub const DashPunctuation: u8 = 19; + pub const OpenPunctuation: u8 = 20; + pub const ClosePunctuation: u8 = 21; + pub const InitialQuotePunctuation: u8 = 22; + pub const FinalQuotePunctuation: u8 = 23; + pub const OtherPunctuation: u8 = 24; + pub const MathSymbol: u8 = 25; + pub const CurrencySymbol: u8 = 26; + pub const ModifierSymbol: u8 = 27; + pub const OtherSymbol: u8 = 28; + pub const OtherNotAssigned: u8 = 29; + } // The maximum character value. pub const MaxValue: char = '\u{FFFF}'; @@ -84,31 +84,31 @@ pub mod Char_ { // | 1 << UnicodeCategory::LineSeparator // | 1 << UnicodeCategory::ParagraphSeparator; - // // Contains information about the C0, Basic Latin, C1, and Latin-1 Supplement ranges [ U+0000..U+00FF ], with: - // // - 0x80 bit if set means 'is whitespace' - // // - 0x40 bit if set means 'is uppercase letter' - // // - 0x20 bit if set means 'is lowercase letter' - // // - bottom 5 bits are the of: UnicodeCategory the character - // #[cfg_attr(rustfmt, rustfmt::skip)] - // const Latin1CharInfo: &[u8; 256] = &[ - // // 0 1 2 3 4 5 6 7 8 9 A B C D E F - // 0x0E, 0x0E, 0x0E, 0x0E, 0x0E, 0x0E, 0x0E, 0x0E, 0x0E, 0x8E, 0x8E, 0x8E, 0x8E, 0x8E, 0x0E, 0x0E, // U+0000..U+000F - // 0x0E, 0x0E, 0x0E, 0x0E, 0x0E, 0x0E, 0x0E, 0x0E, 0x0E, 0x0E, 0x0E, 0x0E, 0x0E, 0x0E, 0x0E, 0x0E, // U+0010..U+001F - // 0x8B, 0x18, 0x18, 0x18, 0x1A, 0x18, 0x18, 0x18, 0x14, 0x15, 0x18, 0x19, 0x18, 0x13, 0x18, 0x18, // U+0020..U+002F - // 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x18, 0x18, 0x19, 0x19, 0x19, 0x18, // U+0030..U+003F - // 0x18, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, // U+0040..U+004F - // 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x14, 0x18, 0x15, 0x1B, 0x12, // U+0050..U+005F - // 0x1B, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, // U+0060..U+006F - // 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x14, 0x19, 0x15, 0x19, 0x0E, // U+0070..U+007F - // 0x0E, 0x0E, 0x0E, 0x0E, 0x0E, 0x8E, 0x0E, 0x0E, 0x0E, 0x0E, 0x0E, 0x0E, 0x0E, 0x0E, 0x0E, 0x0E, // U+0080..U+008F - // 0x0E, 0x0E, 0x0E, 0x0E, 0x0E, 0x0E, 0x0E, 0x0E, 0x0E, 0x0E, 0x0E, 0x0E, 0x0E, 0x0E, 0x0E, 0x0E, // U+0090..U+009F - // 0x8B, 0x18, 0x1A, 0x1A, 0x1A, 0x1A, 0x1C, 0x18, 0x1B, 0x1C, 0x04, 0x16, 0x19, 0x0F, 0x1C, 0x1B, // U+00A0..U+00AF - // 0x1C, 0x19, 0x0A, 0x0A, 0x1B, 0x21, 0x18, 0x18, 0x1B, 0x0A, 0x04, 0x17, 0x0A, 0x0A, 0x0A, 0x18, // U+00B0..U+00BF - // 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, // U+00C0..U+00CF - // 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x19, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x21, // U+00D0..U+00DF - // 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, // U+00E0..U+00EF - // 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x19, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, // U+00F0..U+00FF - // ]; + // Contains information about the C0, Basic Latin, C1, and Latin-1 Supplement ranges [ U+0000..U+00FF ], with: + // - 0x80 bit if set means 'is whitespace' + // - 0x40 bit if set means 'is uppercase letter' + // - 0x20 bit if set means 'is lowercase letter' + // - bottom 5 bits are the of: UnicodeCategory the character + #[cfg_attr(rustfmt, rustfmt::skip)] + const Latin1CharInfo: &[u8; 256] = &[ + // 0 1 2 3 4 5 6 7 8 9 A B C D E F + 0x0E, 0x0E, 0x0E, 0x0E, 0x0E, 0x0E, 0x0E, 0x0E, 0x0E, 0x8E, 0x8E, 0x8E, 0x8E, 0x8E, 0x0E, 0x0E, // U+0000..U+000F + 0x0E, 0x0E, 0x0E, 0x0E, 0x0E, 0x0E, 0x0E, 0x0E, 0x0E, 0x0E, 0x0E, 0x0E, 0x0E, 0x0E, 0x0E, 0x0E, // U+0010..U+001F + 0x8B, 0x18, 0x18, 0x18, 0x1A, 0x18, 0x18, 0x18, 0x14, 0x15, 0x18, 0x19, 0x18, 0x13, 0x18, 0x18, // U+0020..U+002F + 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x18, 0x18, 0x19, 0x19, 0x19, 0x18, // U+0030..U+003F + 0x18, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, // U+0040..U+004F + 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x14, 0x18, 0x15, 0x1B, 0x12, // U+0050..U+005F + 0x1B, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, // U+0060..U+006F + 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x14, 0x19, 0x15, 0x19, 0x0E, // U+0070..U+007F + 0x0E, 0x0E, 0x0E, 0x0E, 0x0E, 0x8E, 0x0E, 0x0E, 0x0E, 0x0E, 0x0E, 0x0E, 0x0E, 0x0E, 0x0E, 0x0E, // U+0080..U+008F + 0x0E, 0x0E, 0x0E, 0x0E, 0x0E, 0x0E, 0x0E, 0x0E, 0x0E, 0x0E, 0x0E, 0x0E, 0x0E, 0x0E, 0x0E, 0x0E, // U+0090..U+009F + 0x8B, 0x18, 0x1A, 0x1A, 0x1A, 0x1A, 0x1C, 0x18, 0x1B, 0x1C, 0x04, 0x16, 0x19, 0x0F, 0x1C, 0x1B, // U+00A0..U+00AF + 0x1C, 0x19, 0x0A, 0x0A, 0x1B, 0x21, 0x18, 0x18, 0x1B, 0x0A, 0x04, 0x17, 0x0A, 0x0A, 0x0A, 0x18, // U+00B0..U+00BF + 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, // U+00C0..U+00CF + 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x19, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x21, // U+00D0..U+00DF + 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, // U+00E0..U+00EF + 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x19, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, // U+00F0..U+00FF + ]; // true for all characters below or equal U+00ff, which is ASCII + Latin-1 Supplement. #[inline] @@ -121,19 +121,28 @@ pub mod Char_ { // ((1 << uc) & uc_mask) != 0 // } - // pub fn GetUnicodeCategory(c: char) -> u8 { - // if (isLatin1(c)) { - // (Latin1CharInfo[c as usize] & UnicodeCategoryMask) - // } else { - // //TODO: implement this - // 0 - // } - // } - - // pub fn GetUnicodeCategory_2(s: string, index: i32) -> u8 { - // let c: char = getCharAt(s, index); - // GetUnicodeCategory(c) - // } + pub fn GetUnicodeCategory(c: char) -> i32 { + let category = if (isLatin1(c)) { + (Latin1CharInfo[c as usize] & UnicodeCategoryMask) + } else { + match c { + // very incomplete, TODO: get real unicode categories + c if IsUpper(c) => UnicodeCategory::UppercaseLetter, + c if IsLower(c) => UnicodeCategory::LowercaseLetter, + c if IsLetter(c) => UnicodeCategory::OtherLetter, + c if IsDigit(c) => UnicodeCategory::DecimalDigitNumber, + c if IsControl(c) => UnicodeCategory::Control, + c if IsSurrogate(c) => UnicodeCategory::Surrogate, + c => UnicodeCategory::OtherNotAssigned, + } + }; + category as i32 + } + + pub fn GetUnicodeCategory_2(s: string, index: i32) -> i32 { + let c: char = getCharAt(s, index); + GetUnicodeCategory(c) + } pub fn GetNumericValue(c: char) -> f64 { match c.to_digit(10) { diff --git a/src/fable-library-rust/src/String.rs b/src/fable-library-rust/src/String.rs index 9d8a4fe071..95f8973322 100644 --- a/src/fable-library-rust/src/String.rs +++ b/src/fable-library-rust/src/String.rs @@ -694,7 +694,7 @@ pub mod String_ { } pub fn splitStrings(s: string, ps: Array, options: i32) -> Array { - let mut a: Vec<&str> = vec![s.as_str()]; + let mut a: Vec<&str> = [s.as_str()].into_iter().collect(); for p in ps.iter() { a = a.iter().flat_map(|&s| s.split(p.as_str())).collect(); } diff --git a/src/fable-standalone/test/bench-compiler/package.json b/src/fable-standalone/test/bench-compiler/package.json index 7950dd9378..e3df589712 100644 --- a/src/fable-standalone/test/bench-compiler/package.json +++ b/src/fable-standalone/test/bench-compiler/package.json @@ -12,7 +12,7 @@ "prebuild-cli-js": "npm run clean && FABLE=fable-cli npm run build-lib-ts", "build-cli-js": "npm run fable-cli -- src/bench-compiler.fsproj --outDir ./out-node --fableLib ./out-lib-js", "postbuild-cli-js": "npm run rollup-bundle", - "build-cli-rust": "npm run fable-cli -- src/bench-compiler.fsproj --outDir ./out-rust --lang Rust --noCache --noParallelTypeCheck --test:MSBuildCracker", + "build-cli-rust": "npm run fable-cli -- src/bench-compiler.fsproj --outDir ./out-rust --lang Rust --noCache --test:MSBuildCracker", "fable": "dotnet run -c Release --project src/bench-compiler.fsproj", "prebuild-js": "npm run clean && FABLE=fable npm run build-lib-ts", @@ -98,7 +98,8 @@ "speedscope": "speedscope profile.v8log.json", "flamegraph": "perf script | ../../../../../FlameGraph/stackcollapse-perf.pl | ../../../../../FlameGraph/flamegraph.pl > perf.svg", "trace-node": "node --trace-deopt out-node/app.js src/bench-compiler.fsproj --outDir ./out-node2 > deopt.log", - "trace-rust": "dotnet trace collect --duration 00:00:01:00 --format speedscope -- dotnet src/bin/Release/net8.0/bench-compiler.dll ../../../../tests/Rust/Fable.Tests.Rust.fsproj --outDir ./out-tests-rust --fableLib ./out-lib-rust --lang Rust", + "trace-rust": "dotnet trace collect --duration 00:00:03:00 --format speedscope -- dotnet src/bin/Release/net8.0/bench-compiler.dll src/bench-compiler.fsproj --outDir ./out-rust2 --fableLib ./out-lib-rust --lang Rust", + "trace-rust-tests": "dotnet trace collect --duration 00:00:01:00 --format speedscope -- dotnet src/bin/Release/net8.0/bench-compiler.dll ../../../../tests/Rust/Fable.Tests.Rust.fsproj --outDir ./out-tests-rust --fableLib ./out-lib-rust --lang Rust", "heaptrack-native": "heaptrack ./src/bin/Release/net8.0/linux-x64/native/bench-compiler src/bench-compiler.fsproj --outDir ./out-node2 --benchmark", "heaptrack-print": "heaptrack_print heaptrack.*.gz -F heap_alloc.log", "heaptrack-flamegraph": "../../../../../FlameGraph/flamegraph.pl --title \"heaptrack: allocations\" --colors mem --countname allocations < heap_alloc.log > heap_alloc.svg", diff --git a/src/fable-standalone/test/bench-compiler/src/app.fs b/src/fable-standalone/test/bench-compiler/src/app.fs index fe47e02aca..6b783d1cd9 100644 --- a/src/fable-standalone/test/bench-compiler/src/app.fs +++ b/src/fable-standalone/test/bench-compiler/src/app.fs @@ -291,8 +291,9 @@ let parseFiles projectFileName options = for fileName in fileNames do // transform F# AST to target language AST + printf $"File: %s{fileName}" let res, ms2 = measureTime parseFable (parseRes, fileName) - printfn $"File: %s{fileName}, Fable time: %d{ms2} ms" + printfn $", Fable time: %d{ms2} ms" res.FableErrors |> printErrors showWarnings // get output path diff --git a/tests/Dart/src/ArrayTests.fs b/tests/Dart/src/ArrayTests.fs index e58f77ebb2..dba3f2a9d1 100644 --- a/tests/Dart/src/ArrayTests.fs +++ b/tests/Dart/src/ArrayTests.fs @@ -35,6 +35,8 @@ type Things = { MainThing: int OtherThing: string } +type Animal = Duck of int | Dog of int + let tests () = testCase "Pattern matching with arrays works" <| fun () -> match [||] with [||] -> true | _ -> false @@ -139,7 +141,7 @@ let tests () = let xs = [| 1.; 2.; 3.; 4. |] xs.Length |> equal 4 - testCase "Array.ConvertAll works" <| fun () -> + testCase "System.Array.ConvertAll works" <| fun () -> let xs = [| 1.; 2.; 3.; 4. |] let ys = System.Array.ConvertAll(xs, System.Converter(fun x -> int x)) ys |> Seq.toList |> equal [1;2;3;4] @@ -318,6 +320,16 @@ let tests () = xs |> Array.find ((=) 2us) |> equal 2us + // testCase "System.Array.IndexOf works with non-primitive types" <| fun _ -> + // let myArray = [|Duck 5|] + // System.Array.IndexOf(myArray, Duck 3) |> equal -1 + // System.Array.IndexOf(myArray, Dog 5) |> equal -1 + // System.Array.IndexOf(myArray, Duck 5) |> equal 0 + // let myArray = [|Duck 5; Dog 3|] + // System.Array.IndexOf(myArray, Dog 3) |> equal 1 + // System.Array.IndexOf(myArray, Dog 3, 0, 1) |> equal -1 + // System.Array.IndexOf(myArray, Duck 5, 1) |> equal -1 + testCase "Array.findIndex works" <| fun () -> let xs = [|1.f; 2.f; 3.f; 4.f|] xs |> Array.findIndex ((=) 2.f) diff --git a/tests/Js/Main/ArrayTests.fs b/tests/Js/Main/ArrayTests.fs index f064a137bd..079e6c25c7 100644 --- a/tests/Js/Main/ArrayTests.fs +++ b/tests/Js/Main/ArrayTests.fs @@ -224,7 +224,7 @@ let tests = let xs = [| 1.; 2.; 3.; 4. |] xs.Length |> equal 4 - testCase "Array.ConvertAll works" <| fun () -> + testCase "System.Array.ConvertAll works" <| fun () -> let xs = [| 1.; 2.; 3.; 4. |] let ys = System.Array.ConvertAll(xs, System.Converter(fun x -> int x)) ys |> Seq.toList |> equal [1;2;3;4] @@ -431,15 +431,15 @@ let tests = xs |> Array.find ((=) 2us) |> equal 2us - testCase "Array.IndexOf works with non-primitive types" <| fun _ -> - let myArray = [|Duck 5|] - Array.IndexOf(myArray, Duck 3) |> equal -1 - Array.IndexOf(myArray, Dog 5) |> equal -1 - Array.IndexOf(myArray, Duck 5) |> equal 0 - let myArray = [|Duck 5; Dog 3|] - Array.IndexOf(myArray, Dog 3) |> equal 1 - Array.IndexOf(myArray, Dog 3, 0, 1) |> equal -1 - Array.IndexOf(myArray, Duck 5, 1) |> equal -1 + testCase "System.Array.IndexOf works with non-primitive types" <| fun _ -> + let myArray = [|Duck 5|] + System.Array.IndexOf(myArray, Duck 3) |> equal -1 + System.Array.IndexOf(myArray, Dog 5) |> equal -1 + System.Array.IndexOf(myArray, Duck 5) |> equal 0 + let myArray = [|Duck 5; Dog 3|] + System.Array.IndexOf(myArray, Dog 3) |> equal 1 + System.Array.IndexOf(myArray, Dog 3, 0, 1) |> equal -1 + System.Array.IndexOf(myArray, Duck 5, 1) |> equal -1 testCase "Array.findIndex works" <| fun () -> let xs = [|1.f; 2.f; 3.f; 4.f|] diff --git a/tests/Python/TestArray.fs b/tests/Python/TestArray.fs index c6e89ee517..aec03c37ce 100644 --- a/tests/Python/TestArray.fs +++ b/tests/Python/TestArray.fs @@ -43,6 +43,8 @@ type Things = { MainThing: int OtherThing: string } +type Animal = Duck of int | Dog of int + [] let ``test Pattern matching with arrays works`` () = match [||] with [||] -> true | _ -> false @@ -176,6 +178,12 @@ let ``test Array.create works`` () = equal 2 xs.Length Array.sum xs |> equal 10 +// [] +// let ``test System.Array.ConvertAll works`` () = +// let xs = [| 1.; 2.; 3.; 4. |] +// let ys = System.Array.ConvertAll(xs, System.Converter(fun x -> int x)) +// ys |> Seq.toList |> equal [1;2;3;4] + [] let ``test Array.blit works`` () = let xs = [| 1..10 |] @@ -360,6 +368,17 @@ let ``test Array.find works`` () = xs |> Array.find ((=) 2us) |> equal 2us +// [] +// let ``test System.Array.IndexOf works with non-primitive types`` () = +// let myArray = [|Duck 5|] +// System.Array.IndexOf(myArray, Duck 3) |> equal -1 +// System.Array.IndexOf(myArray, Dog 5) |> equal -1 +// System.Array.IndexOf(myArray, Duck 5) |> equal 0 +// let myArray = [|Duck 5; Dog 3|] +// System.Array.IndexOf(myArray, Dog 3) |> equal 1 +// System.Array.IndexOf(myArray, Dog 3, 0, 1) |> equal -1 +// System.Array.IndexOf(myArray, Duck 5, 1) |> equal -1 + [] let ``test Array.findIndex works`` () = let xs = [|1.f; 2.f; 3.f; 4.f|] diff --git a/tests/Rust/tests/src/ArrayTests.fs b/tests/Rust/tests/src/ArrayTests.fs index 43d24addb8..651b516bf4 100644 --- a/tests/Rust/tests/src/ArrayTests.fs +++ b/tests/Rust/tests/src/ArrayTests.fs @@ -46,6 +46,8 @@ type Things = { MainThing: int OtherThing: string } +type Animal = Duck of int | Dog of int + [] let ``Array expressions works`` () = let a1: int[] = [||] @@ -210,10 +212,12 @@ let ``Array.zeroCreate with struct tuple works`` () = // xs.Length |> equal 3 // //xs |> equal [|null; null; null|] -[] -let ``Array.length works`` () = - let xs = [|1;2;3|] - Array.length xs |> equal 3 +// // See https://github.com/fable-compiler/repl/issues/96 +// [] +// let ``Array.zeroCreate works with KeyValuePair`` () = +// let a = Array.zeroCreate> 3 +// equal 0. a[1].Key +// equal false a[2].Value [] let ``Array.copy works`` () = @@ -339,6 +343,11 @@ let ``Array setter works`` () = Array.set x 3 10. equal 10. x[3] +[] +let ``Array.length works`` () = + let xs = [|1;2;3|] + Array.length xs |> equal 3 + [] let ``Array.Length works`` () = let xs = [| 1.; 2.; 3.; 4. |] @@ -349,18 +358,11 @@ let ``Array.length works with non-numeric arrays`` () = let xs = [|"a"; "a"; "a"; "a"|] Array.length xs |> equal 4 -// [] -// let ``Array.ConvertAll works`` () = -// let xs = [| 1.; 2.; 3.; 4. |] -// let ys = System.Array.ConvertAll(xs, System.Converter(fun x -> int x)) -// ys |> Seq.toList |> equal [1;2;3;4] - -// // See https://github.com/fable-compiler/repl/issues/96 -// [] -// let ``Array.zeroCreate works with KeyValuePair`` () = -// let a = Array.zeroCreate> 3 -// equal 0. a[1].Key -// equal false a[2].Value +[] +let ``System.Array.ConvertAll works`` () = + let xs = [| 1.; 2.; 3.; 4. |] + let ys = System.Array.ConvertAll(xs, System.Converter(fun x -> int x)) + ys |> Seq.toList |> equal [1;2;3;4] [] let ``Array.blit works`` () = @@ -547,6 +549,17 @@ let ``Array.find works`` () = xs |> Array.find ((=) 2us) |> equal 2us +[] +let ``System.Array.IndexOf works with non-primitive types`` () = + let myArray = [|Duck 5|] + System.Array.IndexOf(myArray, Duck 3) |> equal -1 + System.Array.IndexOf(myArray, Dog 5) |> equal -1 + System.Array.IndexOf(myArray, Duck 5) |> equal 0 + let myArray = [|Duck 5; Dog 3|] + System.Array.IndexOf(myArray, Dog 3) |> equal 1 + System.Array.IndexOf(myArray, Dog 3, 0, 1) |> equal -1 + System.Array.IndexOf(myArray, Duck 5, 1) |> equal -1 + [] let ``Array.findIndex works`` () = let xs = [|1.f; 2.f; 3.f; 4.f|] diff --git a/tests/Rust/tests/src/CharTests.fs b/tests/Rust/tests/src/CharTests.fs index 2c4e1b21da..100f361b65 100644 --- a/tests/Rust/tests/src/CharTests.fs +++ b/tests/Rust/tests/src/CharTests.fs @@ -2,6 +2,7 @@ module Fable.Tests.CharTests open System open Util.Testing +open System.Globalization [] let ``Char.ToUpper works`` () = @@ -23,17 +24,17 @@ let ``Char.ToLowerInvariant works`` () = let ``Char.ToString works`` () = Char.ToString('b') |> equal "b" -// [] -// let ``Char.GetUnicodeCategory works`` () = -// Char.GetUnicodeCategory('a') |> equal UnicodeCategory.LowercaseLetter -// Char.GetUnicodeCategory('1') |> equal UnicodeCategory.DecimalDigitNumber +[] +let ``Char.GetUnicodeCategory works`` () = + Char.GetUnicodeCategory('a') |> equal UnicodeCategory.LowercaseLetter + Char.GetUnicodeCategory('1') |> equal UnicodeCategory.DecimalDigitNumber -// [] -// let ``Char.GetUnicodeCategory with two args works`` () = -// let str = "Ba6" -// Char.GetUnicodeCategory(str,0) |> int |> equal 0 //UnicodeCategory.UppercaseLetter -// Char.GetUnicodeCategory(str,1) |> int |> equal 1 //UnicodeCategory.LowercaseLetter -// Char.GetUnicodeCategory(str,2) |> int |> equal 8 //UnicodeCategory.DecimalDigitNumber +[] +let ``Char.GetUnicodeCategory with two args works`` () = + let str = "Ba6" + Char.GetUnicodeCategory(str, 0) |> equal UnicodeCategory.UppercaseLetter + Char.GetUnicodeCategory(str, 1) |> equal UnicodeCategory.LowercaseLetter + Char.GetUnicodeCategory(str, 2) |> equal UnicodeCategory.DecimalDigitNumber [] let ``Char.IsControl works`` () =