diff --git a/src/Fable.Compiler/Globbing.fs b/src/Fable.Compiler/Globbing.fs index fb9e7d923..e311fdfca 100644 --- a/src/Fable.Compiler/Globbing.fs +++ b/src/Fable.Compiler/Globbing.fs @@ -54,7 +54,7 @@ module Glob = | Drive name :: t -> let subDirs = List.collect (checkSubDirs true name) acc buildPaths subDirs t - | Recursive :: [] -> + | [ Recursive ] -> let dirs = Seq.collect (fun dir -> diff --git a/src/Fable.Transforms/Dart/Replacements.fs b/src/Fable.Transforms/Dart/Replacements.fs index a99dfc9ef..96b180bb9 100644 --- a/src/Fable.Transforms/Dart/Replacements.fs +++ b/src/Fable.Transforms/Dart/Replacements.fs @@ -2406,13 +2406,13 @@ let intrinsicFunctions (com: ICompiler) (ctx: Context) r t (i: CallInfo) (thisAr Helper.LibCall(com, "Decimal", "pow", t, args, i.SignatureArgTypes, genArgs = i.GenericArgs, ?loc = r) |> Some // reference: https://msdn.microsoft.com/visualfsharpdocs/conceptual/operatorintrinsics.rangechar-function-%5bfsharp%5d - // Type: RangeChar : char -> char -> seq + // Type: RangeChar : char -> char -> char seq // Usage: RangeChar start stop | "RangeChar", None, _ -> Helper.LibCall(com, "Range", "rangeChar", t, args, i.SignatureArgTypes, genArgs = i.GenericArgs, ?loc = r) |> Some // reference: https://msdn.microsoft.com/visualfsharpdocs/conceptual/operatorintrinsics.rangedouble-function-%5bfsharp%5d - // Type: RangeDouble: float -> float -> float -> seq + // Type: RangeDouble: float -> float -> float -> float seq // Usage: RangeDouble start step stop | ("RangeSByte" | "RangeByte" | "RangeInt16" | "RangeUInt16" | "RangeInt32" | "RangeUInt32" | "RangeSingle" | "RangeDouble"), None, diff --git a/src/Fable.Transforms/FSharp2Fable.Util.fs b/src/Fable.Transforms/FSharp2Fable.Util.fs index 4b8225569..3ff82f83c 100644 --- a/src/Fable.Transforms/FSharp2Fable.Util.fs +++ b/src/Fable.Transforms/FSharp2Fable.Util.fs @@ -710,7 +710,7 @@ module Helpers = if ent.IsFSharpModule then match trimRootModule, entName with | TrimRootModule com, _ when com.Options.Language = Rust -> memb.CompiledName, Naming.NoMemberPart // module prefix for Rust - | _, "" -> memb.CompiledName, Naming.NoMemberPart + | _, s when System.String.IsNullOrEmpty(s) -> memb.CompiledName, Naming.NoMemberPart | _, moduleName -> moduleName, Naming.StaticMemberPart(memb.CompiledName, "") else let overloadSuffix = getOverloadSuffixFrom ent memb @@ -1374,7 +1374,7 @@ module TypeHelpers = // Filter measure generic arguments here? (for that we need to pass the compiler, which needs a bigger refactoring) // Currently for Dart we're doing it in the Fable2Dart step - let makeTypeGenArgsWithConstraints withConstraints ctxTypeArgs (genArgs: seq) = + let makeTypeGenArgsWithConstraints withConstraints ctxTypeArgs (genArgs: FSharpType seq) = genArgs |> Seq.mapToList (fun genArg -> if genArg.IsGenericParameter then @@ -1383,7 +1383,7 @@ module TypeHelpers = makeTypeWithConstraints withConstraints ctxTypeArgs genArg ) - let makeTypeGenArgs ctxTypeArgs (genArgs: seq) = + let makeTypeGenArgs ctxTypeArgs (genArgs: FSharpType seq) = makeTypeGenArgsWithConstraints true ctxTypeArgs genArgs let makeTypeFromDelegate withConstraints ctxTypeArgs (genArgs: IList) (tdef: FSharpEntity) = diff --git a/src/Fable.Transforms/FSharp2Fable.fs b/src/Fable.Transforms/FSharp2Fable.fs index 18f55c831..a5a989e8b 100644 --- a/src/Fable.Transforms/FSharp2Fable.fs +++ b/src/Fable.Transforms/FSharp2Fable.fs @@ -2009,7 +2009,7 @@ let rec private getUsedRootNames (com: Compiler) (usedNames: Set) decls usedNames else match getEntityDeclarationName com entRef with - | "" -> usedNames + | s when System.String.IsNullOrEmpty(s) -> usedNames | entName -> let reflectionSuffix = match com.Options.Language with @@ -2056,7 +2056,7 @@ let rec private transformDeclarations (com: FableCompiler) ctx fsDecls = // If the file is empty F# creates a class for the module, but Fable clears the name // because it matches the root module so it becomes invalid JS, see #2350 match getEntityDeclarationName com entRef with - | "" -> [] + | s when System.String.IsNullOrEmpty(s) -> [] | name -> [ Fable.ClassDeclaration diff --git a/src/Fable.Transforms/Fable2Babel.fs b/src/Fable.Transforms/Fable2Babel.fs index a4865fdbe..8ea85c7e9 100644 --- a/src/Fable.Transforms/Fable2Babel.fs +++ b/src/Fable.Transforms/Fable2Babel.fs @@ -1010,7 +1010,7 @@ module Util = str.Split('\n') |> Array.skipWhile (fun line -> match line.Trim() with - | "" -> true + | s when System.String.IsNullOrEmpty(s) -> true | Naming.Regex IMPORT_REGEX (_ :: selector :: path :: _) -> if selector.StartsWith("{", StringComparison.Ordinal) then for selector in selector.TrimStart('{').TrimEnd('}').Split(',') do diff --git a/src/Fable.Transforms/Global/Prelude.fs b/src/Fable.Transforms/Global/Prelude.fs index 94a9aa486..0dccbf8a3 100644 --- a/src/Fable.Transforms/Global/Prelude.fs +++ b/src/Fable.Transforms/Global/Prelude.fs @@ -418,7 +418,7 @@ module Path = let toPath = addDummyFile toIsDir toFullPath |> normalizePath match (pathDifference fromPath toPath).Replace(dummyFile, "") with - | "" -> "." + | s when System.String.IsNullOrEmpty(s) -> "." // Some folders start with a period, see #1599 | path when isRelativePath path -> path | path -> "./" + path @@ -458,7 +458,7 @@ module Path = commonPrefix.Length >= parent.Length - let getCommonBaseDir (filePaths: seq) = + let getCommonBaseDir (filePaths: string seq) = filePaths |> Seq.map (fun filePath -> filePath diff --git a/src/Fable.Transforms/Php/Fable2Php.fs b/src/Fable.Transforms/Php/Fable2Php.fs index 1bd460321..084890f42 100644 --- a/src/Fable.Transforms/Php/Fable2Php.fs +++ b/src/Fable.Transforms/Php/Fable2Php.fs @@ -1205,7 +1205,7 @@ let rec convertExpr (com: IPhpCompiler) (expr: Fable.Expr) = //| _ -> printfn "%A" t match fixNsName (Path.GetFileNameWithoutExtension(info.Path)) with - | "" -> + | s when System.String.IsNullOrEmpty(s) -> match com.IsImport info.Selector with | Some true -> let name = fixName info.Selector diff --git a/src/Fable.Transforms/Python/Fable2Python.Annotation.fs b/src/Fable.Transforms/Python/Fable2Python.Annotation.fs index 0df69428e..2d1f4f7be 100644 --- a/src/Fable.Transforms/Python/Fable2Python.Annotation.fs +++ b/src/Fable.Transforms/Python/Fable2Python.Annotation.fs @@ -336,7 +336,7 @@ let stdlibModuleTypeHint com ctx moduleName memberName genArgs repeatedGenerics let makeGenTypeParamInst com ctx (genArgs: Fable.Type list) (repeatedGenerics: Set option) = match genArgs with | [] -> [] - | _ -> genArgs |> List.map (typeAnnotation com ctx repeatedGenerics) |> List.map fst + | _ -> genArgs |> List.map (typeAnnotation com ctx repeatedGenerics >> fst) let makeGenericTypeAnnotation (com: IPythonCompiler) diff --git a/src/Fable.Transforms/Python/Fable2Python.Transforms.fs b/src/Fable.Transforms/Python/Fable2Python.Transforms.fs index 097022d85..b5e21f97b 100644 --- a/src/Fable.Transforms/Python/Fable2Python.Transforms.fs +++ b/src/Fable.Transforms/Python/Fable2Python.Transforms.fs @@ -1233,7 +1233,7 @@ let private getExceptionTypeExpr (com: IPythonCompiler) ctx = | Fable.DeclaredType(entRef, _) -> Annotation.tryPyConstructor com ctx (com.GetEntity(entRef)) | _ -> None -let transformTryCatch com (ctx: Context) r returnStrategy (body, catch: option, finalizer) = +let transformTryCatch com (ctx: Context) r returnStrategy (body, catch: (Fable.Ident * Fable.Expr) option, finalizer) = // try .. catch statements cannot be tail call optimized let ctx = { ctx with TailCallOpportunity = None } @@ -3278,32 +3278,35 @@ let declareDataClassType let interfaceBases = ent.AllInterfaces |> List.ofSeq - |> List.filter (fun int -> + |> List.choose (fun int -> let name = Helpers.removeNamespace (int.Entity.FullName) - allowedInterfaces |> List.contains name - ) - |> List.map (fun int -> - // Filter out self-referential generic arguments to avoid forward reference errors - let genericArgs = - int.GenericArgs - |> List.filter (fun genArg -> - match genArg with - | Fable.DeclaredType({ FullName = fullName }, _) -> Helpers.removeNamespace (fullName) <> entName - | _ -> true - ) - // Generate the EnumerableBase reference from bases module - if List.isEmpty genericArgs then - libValue com ctx "bases" "EnumerableBase" + if not (allowedInterfaces |> List.contains name) then + None else - let typeArgs = - genericArgs - |> List.map (fun genArg -> - let arg, _ = Annotation.typeAnnotation com ctx None genArg - arg + // Filter out self-referential generic arguments to avoid forward reference errors + let genericArgs = + int.GenericArgs + |> List.filter (fun genArg -> + match genArg with + | Fable.DeclaredType({ FullName = fullName }, _) -> + Helpers.removeNamespace (fullName) <> entName + | _ -> true ) - Expression.subscript (libValue com ctx "bases" "EnumerableBase", Expression.tuple typeArgs) + // Generate the EnumerableBase reference from bases module + if List.isEmpty genericArgs then + libValue com ctx "bases" "EnumerableBase" |> Some + else + let typeArgs = + genericArgs + |> List.map (fun genArg -> + let arg, _ = Annotation.typeAnnotation com ctx None genArg + arg + ) + + Expression.subscript (libValue com ctx "bases" "EnumerableBase", Expression.tuple typeArgs) + |> Some ) let bases = (baseExpr |> Option.toList) @ interfaceBases @@ -4473,8 +4476,12 @@ let transformInterface (com: IPythonCompiler) ctx (classEnt: Fable.Entity) (_cla let interfaces = classEnt.AllInterfaces |> List.ofSeq - |> List.map (fun int -> int.Entity) - |> List.filter (fun ent -> ent.FullName <> classEnt.FullName) + |> List.choose (fun int -> + if int.Entity.FullName <> classEnt.FullName then + Some int.Entity + else + None + ) for ref in interfaces do let entity = com.TryGetEntity(ref) diff --git a/src/Fable.Transforms/Python/Fable2Python.Util.fs b/src/Fable.Transforms/Python/Fable2Python.Util.fs index 835896b41..95d3c6d1a 100644 --- a/src/Fable.Transforms/Python/Fable2Python.Util.fs +++ b/src/Fable.Transforms/Python/Fable2Python.Util.fs @@ -731,7 +731,7 @@ module Util = let makeStringArray strings = strings |> List.map (fun x -> Expression.stringConstant x) |> Expression.list - let makePyObject (pairs: seq) = + let makePyObject (pairs: (string * Expression) seq) = pairs |> Seq.map (fun (name, value) -> let prop = Expression.stringConstant name diff --git a/src/Fable.Transforms/Python/Replacements.fs b/src/Fable.Transforms/Python/Replacements.fs index b9a84aa0d..9bfb9ecd2 100644 --- a/src/Fable.Transforms/Python/Replacements.fs +++ b/src/Fable.Transforms/Python/Replacements.fs @@ -2510,13 +2510,13 @@ let intrinsicFunctions (com: ICompiler) (ctx: Context) r t (i: CallInfo) (thisAr Helper.LibCall(com, "decimal", "pow", t, args, i.SignatureArgTypes, ?loc = r) |> Some // reference: https://msdn.microsoft.com/visualfsharpdocs/conceptual/operatorintrinsics.rangechar-function-%5bfsharp%5d - // Type: RangeChar : char -> char -> seq + // Type: RangeChar : char -> char -> char seq // Usage: RangeChar start stop | "RangeChar", None, _ -> Helper.LibCall(com, "range", "rangeChar", t, args, i.SignatureArgTypes, ?loc = r) |> Some // reference: https://msdn.microsoft.com/visualfsharpdocs/conceptual/operatorintrinsics.rangedouble-function-%5bfsharp%5d - // Type: RangeDouble: float -> float -> float -> seq + // Type: RangeDouble: float -> float -> float -> float seq // Usage: RangeDouble start step stop | ("RangeSByte" | "RangeByte" | "RangeInt16" | "RangeUInt16" | "RangeInt32" | "RangeUInt32" | "RangeSingle" | "RangeDouble"), None, diff --git a/src/Fable.Transforms/Replacements.fs b/src/Fable.Transforms/Replacements.fs index 78a3d91c2..7f0bfe3a5 100644 --- a/src/Fable.Transforms/Replacements.fs +++ b/src/Fable.Transforms/Replacements.fs @@ -2760,13 +2760,13 @@ let intrinsicFunctions (com: ICompiler) (ctx: Context) r t (i: CallInfo) (thisAr Helper.LibCall(com, "Decimal", "pow", t, args, i.SignatureArgTypes, ?loc = r) |> Some // reference: https://msdn.microsoft.com/visualfsharpdocs/conceptual/operatorintrinsics.rangechar-function-%5bfsharp%5d - // Type: RangeChar : char -> char -> seq + // Type: RangeChar : char -> char -> char seq // Usage: RangeChar start stop | "RangeChar", None, _ -> Helper.LibCall(com, "Range", "rangeChar", t, args, i.SignatureArgTypes, ?loc = r) |> Some // reference: https://msdn.microsoft.com/visualfsharpdocs/conceptual/operatorintrinsics.rangedouble-function-%5bfsharp%5d - // Type: RangeDouble: float -> float -> float -> seq + // Type: RangeDouble: float -> float -> float -> float seq // Usage: RangeDouble start step stop | ("RangeSByte" | "RangeByte" | "RangeInt16" | "RangeUInt16" | "RangeInt32" | "RangeUInt32" | "RangeSingle" | "RangeDouble"), None, diff --git a/src/Fable.Transforms/Rust/AST/Rust.AST.Helpers.fs b/src/Fable.Transforms/Rust/AST/Rust.AST.Helpers.fs index 49a695f43..7b6a4d5f5 100644 --- a/src/Fable.Transforms/Rust/AST/Rust.AST.Helpers.fs +++ b/src/Fable.Transforms/Rust/AST/Rust.AST.Helpers.fs @@ -1198,7 +1198,7 @@ module Funcs = let mkExtern (extOpt: Symbol option) : Extern = match extOpt with - | Some("") -> Extern.Implicit + | Some(s) when System.String.IsNullOrEmpty(s) -> Extern.Implicit | Some(abi) -> Extern.Explicit(mkStrLitFrom abi None) | None -> Extern.None diff --git a/src/Fable.Transforms/Rust/Fable2Rust.fs b/src/Fable.Transforms/Rust/Fable2Rust.fs index 7891a9bd0..6d939cdfa 100644 --- a/src/Fable.Transforms/Rust/Fable2Rust.fs +++ b/src/Fable.Transforms/Rust/Fable2Rust.fs @@ -378,8 +378,12 @@ module TypeInfo = let getEntityGenParamNames (ent: Fable.Entity) = ent.GenericParameters - |> List.filter (fun p -> not p.IsMeasure) - |> List.map (fun p -> p.Name) + |> List.choose (fun p -> + if not p.IsMeasure then + Some p.Name + else + None + ) |> Set.ofList let hasMutableFields (com: IRustCompiler) (ent: Fable.Entity) = @@ -707,8 +711,12 @@ module TypeInfo = let transformGenTypes com ctx genArgs : Rust.Ty list = genArgs - |> List.filter (isUnitOfMeasure >> not) - |> List.map (transformType com ctx) + |> List.choose (fun g -> + if isUnitOfMeasure g then + None + else + Some(transformType com ctx g) + ) let transformGenArgs com ctx genArgs : Rust.GenericArgs option = genArgs |> transformGenTypes com ctx |> mkTypesGenericArgs @@ -1365,8 +1373,7 @@ module Util = let genParams = argTypes @ [ body.Type ] |> FSharp2Fable.Util.getGenParams - |> List.filter (fst >> isLambdaOrGenArgNotInScope) - |> List.filter (fst >> isNotLambdaOrGenArgInScope) + |> List.filter (fun (name, _) -> isLambdaOrGenArgNotInScope name && isNotLambdaOrGenArgInScope name) let genArgTypes = genParams |> List.map snd let genArgNames = genParams |> List.map fst |> Set.ofList @@ -3989,11 +3996,13 @@ module Util = let makeGenericParams com ctx (genParams: Fable.GenericParam list) = genParams - |> List.filter (fun p -> not p.IsMeasure) - |> List.map (fun p -> - let typeBounds = makeTypeBounds com ctx p.Name p.Constraints - let typeBounds = typeBounds @ defaultTypeBounds - mkGenericParamFromName [] p.Name typeBounds + |> List.choose (fun p -> + if p.IsMeasure then + None + else + let typeBounds = makeTypeBounds com ctx p.Name p.Constraints + let typeBounds = typeBounds @ defaultTypeBounds + mkGenericParamFromName [] p.Name typeBounds |> Some ) let makeGenericParamsFromArgs com ctx (genArgs: Fable.Type list) = @@ -4928,8 +4937,12 @@ module Util = let nonInterfaceImpls = let memberItems = nonInterfaceMembers - |> List.filter (snd >> isIgnoredMember >> not) - |> List.map (makeMemberItem com ctx true) + |> List.choose (fun m -> + if isIgnoredMember (snd m) then + None + else + Some(makeMemberItem com ctx true m) + ) let memberItems = if isObjectExpr then @@ -4985,8 +4998,12 @@ module Util = let memberItems = interfaceMembers - |> List.filter (fun (d, m) -> Set.contains m.FullName memberNames) - |> List.map (makeMemberItem com ctx false) + |> List.choose (fun (d, m) -> + if Set.contains m.FullName memberNames then + Some(makeMemberItem com ctx false (d, m)) + else + None + ) memberItems |> makeInterfaceTraitImpls com ctx entName genParams ifcEntRef ifcGenArgs @@ -5225,7 +5242,7 @@ module Util = [ "crate" ] match import.Selector with - | "" + | s when System.String.IsNullOrEmpty(s) -> [] | "*" | "default" -> // let useItem = mkGlobUseItem [] modPath @@ -5248,7 +5265,7 @@ module Util = let getIdentForImport (ctx: Context) (path: string) (selector: string) = match selector with - | "" + | s when System.String.IsNullOrEmpty(s) -> Path.GetFileNameWithoutExtension(path) | "*" | "default" -> Path.GetFileNameWithoutExtension(path) | _ -> splitNameParts selector |> List.last diff --git a/src/Fable.Transforms/Rust/Replacements.fs b/src/Fable.Transforms/Rust/Replacements.fs index 47ad85bf7..7a7b3c824 100644 --- a/src/Fable.Transforms/Rust/Replacements.fs +++ b/src/Fable.Transforms/Rust/Replacements.fs @@ -2286,13 +2286,13 @@ let intrinsicFunctions (com: ICompiler) (ctx: Context) r t (i: CallInfo) (thisAr Helper.LibCall(com, "Decimal", "pown", t, args, i.SignatureArgTypes, ?loc = r) |> Some // reference: https://msdn.microsoft.com/visualfsharpdocs/conceptual/operatorintrinsics.rangechar-function-%5bfsharp%5d - // Type: RangeChar : char -> char -> seq + // Type: RangeChar : char -> char -> char seq // Usage: RangeChar start stop | "RangeChar", None, _ -> Helper.LibCall(com, "Range", "rangeChar", t, args, i.SignatureArgTypes, ?loc = r) |> Some // reference: https://msdn.microsoft.com/visualfsharpdocs/conceptual/operatorintrinsics.rangedouble-function-%5bfsharp%5d - // Type: RangeDouble: float -> float -> float -> seq + // Type: RangeDouble: float -> float -> float -> float seq // Usage: RangeDouble start step stop | ("RangeSByte" | "RangeByte" | "RangeInt16" | "RangeUInt16" | "RangeInt32" | "RangeUInt32" | "RangeInt64" | "RangeUInt64" | "RangeSingle" | "RangeDouble"), None,