diff --git a/src/Compiler/AbstractIL/il.fs b/src/Compiler/AbstractIL/il.fs index fecefad1434..e9f42370064 100644 --- a/src/Compiler/AbstractIL/il.fs +++ b/src/Compiler/AbstractIL/il.fs @@ -54,10 +54,10 @@ type PrimaryAssembly = static member IsPossiblePrimaryAssembly(fileName: string) = let name = System.IO.Path.GetFileNameWithoutExtension(fileName) - String.Compare(name, "mscorlib", true) <> 0 - || String.Compare(name, "System.Runtime", true) <> 0 - || String.Compare(name, "netstandard", true) <> 0 - || String.Compare(name, "System.Private.CoreLib", true) <> 0 + String.Equals(name, "mscorlib", StringComparison.OrdinalIgnoreCase) + || String.Equals(name, "System.Runtime", StringComparison.OrdinalIgnoreCase) + || String.Equals(name, "netstandard", StringComparison.OrdinalIgnoreCase) + || String.Equals(name, "System.Private.CoreLib", StringComparison.OrdinalIgnoreCase) // -------------------------------------------------------------------- // Utilities: type names diff --git a/src/Compiler/AbstractIL/ilnativeres.fs b/src/Compiler/AbstractIL/ilnativeres.fs index 0d0b6a1c986..a73249f2d10 100644 --- a/src/Compiler/AbstractIL/ilnativeres.fs +++ b/src/Compiler/AbstractIL/ilnativeres.fs @@ -434,7 +434,7 @@ type VersionHelper() = let mutable breakLoop = false while (idx < elements[i].Length) && not breakLoop do - if not (Char.IsDigit elements[i].[idx]) then + if not (isDigit elements[i].[idx]) then invalidFormat <- true VersionHelper.TryGetValue((elements[i].Substring(0, idx)), ref values[i]) diff --git a/src/Compiler/AbstractIL/ilreflect.fs b/src/Compiler/AbstractIL/ilreflect.fs index 748ecafda21..25f3be47037 100644 --- a/src/Compiler/AbstractIL/ilreflect.fs +++ b/src/Compiler/AbstractIL/ilreflect.fs @@ -284,7 +284,7 @@ type TypeBuilder with type OpCode with member opcode.RefEmitName = - (string (Char.ToUpper(opcode.Name[0])) + opcode.Name[1..]) + (string (Char.ToUpperInvariant(opcode.Name[0])) + opcode.Name[1..]) .Replace(".", "_") .Replace("_i4", "_I4") diff --git a/src/Compiler/AbstractIL/ilwrite.fs b/src/Compiler/AbstractIL/ilwrite.fs index f41c8aaa08d..93f466ea798 100644 --- a/src/Compiler/AbstractIL/ilwrite.fs +++ b/src/Compiler/AbstractIL/ilwrite.fs @@ -3756,7 +3756,7 @@ let writePdb ( let pdbfileInfo = FileInfo(pdbfile).FullName // If pdbfilepath matches output filepath then error - if String.Compare(outfileInfo, pdbfileInfo, StringComparison.InvariantCulture) = 0 then + if outfileInfo = pdbfileInfo then errorR(Error(FSComp.SR.optsPdbMatchesOutputFileName(), rangeStartup)) try FileSystem.FileDeleteShim pdbfile with _ -> () use fs = FileSystem.OpenFileForWriteShim(pdbfile, fileMode = FileMode.Create, fileAccess = FileAccess.ReadWrite) diff --git a/src/Compiler/AbstractIL/ilwritepdb.fs b/src/Compiler/AbstractIL/ilwritepdb.fs index fd5ffad27ac..d17e654ae4b 100644 --- a/src/Compiler/AbstractIL/ilwritepdb.fs +++ b/src/Compiler/AbstractIL/ilwritepdb.fs @@ -396,7 +396,7 @@ type PortablePdbGenerator let includeSource file = let isInList = embedSourceList - |> List.exists (fun f -> String.Compare(file, f, StringComparison.OrdinalIgnoreCase) = 0) + |> List.exists (fun f -> String.Equals(file, f, StringComparison.OrdinalIgnoreCase)) if not embedAllSource && not isInList || not (FileSystem.FileExistsShim file) then None diff --git a/src/Compiler/Checking/CheckDeclarations.fs b/src/Compiler/Checking/CheckDeclarations.fs index 457a3489576..ddeec81f3b6 100644 --- a/src/Compiler/Checking/CheckDeclarations.fs +++ b/src/Compiler/Checking/CheckDeclarations.fs @@ -266,7 +266,7 @@ let TryStripPrefixPath (g: TcGlobals) (enclosingNamespacePath: Ident list) = g.isInteractive && not (isNil rest) && p.idText.StartsWithOrdinal FsiDynamicModulePrefix && - p.idText[FsiDynamicModulePrefix.Length..] |> String.forall Char.IsDigit + p.idText[FsiDynamicModulePrefix.Length..] |> String.forall isDigit -> Some(p, rest) | _ -> None diff --git a/src/Compiler/Checking/CheckFormatStrings.fs b/src/Compiler/Checking/CheckFormatStrings.fs index ec8b4ae2b91..3a357a2b583 100644 --- a/src/Compiler/Checking/CheckFormatStrings.fs +++ b/src/Compiler/Checking/CheckFormatStrings.fs @@ -140,13 +140,13 @@ module internal Parse = let rec digitsPrecision (fmt: string) (fmtPos: int) = if fmtPos >= fmt.Length then failwith (FSComp.SR.forBadPrecision()) match fmt[fmtPos] with - | c when System.Char.IsDigit c -> digitsPrecision fmt (fmtPos+1) + | c when isDigit c -> digitsPrecision fmt (fmtPos+1) | _ -> fmtPos let precision (info: FormatInfoRegister) (fmt: string) (fmtPos: int) = if fmtPos >= fmt.Length then failwith (FSComp.SR.forBadWidth()) match fmt[fmtPos] with - | c when System.Char.IsDigit c -> info.precision <- true; false,digitsPrecision fmt (fmtPos+1) + | c when isDigit c -> info.precision <- true; false,digitsPrecision fmt (fmtPos+1) | '*' -> info.precision <- true; true,(fmtPos+1) | _ -> failwith (FSComp.SR.forPrecisionMissingAfterDot()) @@ -161,14 +161,14 @@ module internal Parse = let rec go pos n = if pos >= len then failwith (FSComp.SR.forBadPrecision()) match fmt[pos] with - | c when System.Char.IsDigit c -> go (pos+1) (n*10 + int c - int '0') + | c when isDigit c -> go (pos+1) (n*10 + int c - int '0') | _ -> Some n, optionalDotAndPrecision info fmt pos go fmtPos intAcc let widthAndPrecision (info: FormatInfoRegister) (fmt: string) (fmtPos: int) = if fmtPos >= fmt.Length then failwith (FSComp.SR.forBadPrecision()) match fmt[fmtPos] with - | c when System.Char.IsDigit c -> false,digitsWidthAndPrecision info fmt fmtPos 0 + | c when isDigit c -> false,digitsWidthAndPrecision info fmt fmtPos 0 | '*' -> true, (None, optionalDotAndPrecision info fmt (fmtPos+1)) | _ -> false, (None, optionalDotAndPrecision info fmt fmtPos) @@ -178,7 +178,7 @@ module internal Parse = let rec digitsPosition n pos = if pos >= len then failwith (FSComp.SR.forBadPrecision()) match fmt[pos] with - | c when System.Char.IsDigit c -> digitsPosition (n*10 + int c - int '0') (pos+1) + | c when isDigit c -> digitsPosition (n*10 + int c - int '0') (pos+1) | '$' -> Some n, pos+1 | _ -> None, pos @@ -371,7 +371,7 @@ let parseFormatStringInternal // type checker. They should always have '(...)' after for format string. let requireAndSkipInterpolationHoleFormat i = if i < len && fmt[i] = '(' then - let i2 = fmt.IndexOfOrdinal(")", i+1) + let i2 = fmt.IndexOf(')', i+1) if i2 = -1 then failwith (FSComp.SR.forFormatInvalidForInterpolated3()) else diff --git a/src/Compiler/Checking/NameResolution.fs b/src/Compiler/Checking/NameResolution.fs index 68b333b52d9..596691375ce 100644 --- a/src/Compiler/Checking/NameResolution.fs +++ b/src/Compiler/Checking/NameResolution.fs @@ -275,7 +275,7 @@ type Item = | ValueSome tcref -> tcref.DisplayNameCore | _ -> nm |> DemangleGenericTypeName - | Item.CtorGroup(nm, _) -> nm |> DemangleGenericTypeName + | Item.CtorGroup(nm, _) -> nm |> DemangleGenericTypeName | Item.DelegateCtor ty -> match ty with | AbbrevOrAppTy(tcref, _) -> tcref.DisplayNameCore @@ -2730,14 +2730,14 @@ let rec ResolveLongIdentInTypePrim (ncenv: NameResolver) nenv lookupKind (resInf | None -> success [resInfo, x, rest] | Some _argExpr -> // RFC-1137 prefer extension method when ... - + let ignoreProperty (p: PropInfo) = // do not hide properties if: // * is indexed property e.g.: // ```fsharp - // member x.Prop with + // member x.Prop with // get (indexPiece1:int,indexPiece2: string) = ... - // and set (indexPiece1:int,indexPiece2: string) value = ... + // and set (indexPiece1:int,indexPiece2: string) value = ... // ``` // which is called like this: obj.Prop(1,"a") or obj.Prop(1,"a") <- someValue // * is function type e.g.: @@ -2753,7 +2753,7 @@ let rec ResolveLongIdentInTypePrim (ncenv: NameResolver) nenv lookupKind (resInf | TType_var(typar={typar_solution = Some (TType_fun _) }) -> true | _ -> false - + match x with | Item.Property(info=ps) when ps |> List.exists ignoreProperty -> success [resInfo, x, rest] @@ -2768,7 +2768,7 @@ let rec ResolveLongIdentInTypePrim (ncenv: NameResolver) nenv lookupKind (resInf | None -> // todo: consider if we should check extension method, but we'd probably won't have matched // `Some(PropertyItem psets) when isLookUpExpr` in the first place. - raze (UndefinedName (depth, FSComp.SR.undefinedNameFieldConstructorOrMember, id, NoSuggestions)) + raze (UndefinedName (depth, FSComp.SR.undefinedNameFieldConstructorOrMember, id, NoSuggestions)) | Some(MethodItem msets) when isLookUpExpr -> let minfos = msets |> ExcludeHiddenOfMethInfos g ncenv.amap m @@ -3198,7 +3198,7 @@ let rec ResolveExprLongIdentPrim sink (ncenv: NameResolver) first fullyQualified addToBuffer modref.DisplayName // check if the user forgot to use qualified access - for e in nenv.eTyconsByDemangledNameAndArity do + for e in nenv.eTyconsByDemangledNameAndArity do let hasRequireQualifiedAccessAttribute = HasFSharpAttribute ncenv.g ncenv.g.attrib_RequireQualifiedAccessAttribute e.Value.Attribs if hasRequireQualifiedAccessAttribute then if e.Value.IsUnionTycon && e.Value.UnionCasesArray |> Array.exists (fun c -> c.LogicalName = id.idText) then @@ -4134,7 +4134,7 @@ type AfterResolution = // maybeAppliedArgExpr is used in context of resolving extension method that would override property name, it may contain argExpr coming from the DelayedApp(argExpr: SynExpr) // see RFC-1137 let ResolveLongIdentAsExprAndComputeRange (sink: TcResultsSink) (ncenv: NameResolver) wholem ad nenv typeNameResInfo lid (maybeAppliedArgExpr: SynExpr option) = - match ResolveExprLongIdent sink ncenv wholem ad nenv typeNameResInfo lid maybeAppliedArgExpr with + match ResolveExprLongIdent sink ncenv wholem ad nenv typeNameResInfo lid maybeAppliedArgExpr with | Exception e -> Exception e | Result (tinstEnclosing, item1, rest) -> let itemRange = ComputeItemRange wholem lid rest @@ -4531,7 +4531,7 @@ let ResolveCompletionsInType (ncenv: NameResolver) nenv (completionTargets: Reso if methsWithStaticParams.IsEmpty then minfos else minfos |> List.filter (fun minfo -> let nm = minfo.LogicalName - not (nm.Contains "," && methsWithStaticParams |> List.exists (nm.StartsWithOrdinal))) + not (nm.Contains ',' && methsWithStaticParams |> List.exists nm.StartsWithOrdinal)) #endif minfos @@ -4737,7 +4737,7 @@ let rec ResolvePartialLongIdentInModuleOrNamespace (ncenv: NameResolver) nenv is | [] -> let tycons = mty.TypeDefinitions |> List.filter (fun tcref -> - not (tcref.LogicalName.Contains ",") && + not (tcref.LogicalName.Contains ',') && not (IsTyconUnseen ad g ncenv.amap m (modref.NestedTyconRef tcref))) // Collect up the accessible values in the module, excluding the members @@ -4865,7 +4865,7 @@ let rec ResolvePartialLongIdentPrim (ncenv: NameResolver) (nenv: NameResolutionE let tycons = nenv.TyconsByDemangledNameAndArity(fullyQualified).Values |> Seq.filter (fun tcref -> - not (tcref.LogicalName.Contains ",") && + not (tcref.LogicalName.Contains ',') && not tcref.IsFSharpException && not (IsTyconUnseen ad g ncenv.amap m tcref)) |> Seq.map (ItemOfTyconRef ncenv m) @@ -4945,7 +4945,7 @@ let rec ResolvePartialLongIdentInModuleOrNamespaceForRecordFields (ncenv: NameRe let tycons = mty.TypeDefinitions |> List.filter (fun tcref -> - not (tcref.LogicalName.Contains ",") && + not (tcref.LogicalName.Contains ',') && tcref.IsRecordTycon && not (IsTyconUnseen ad g ncenv.amap m (modref.NestedTyconRef tcref))) @@ -5019,7 +5019,7 @@ and ResolvePartialLongIdentToClassOrRecdFieldsImpl (ncenv: NameResolver) (nenv: let recdTyCons = nenv.TyconsByDemangledNameAndArity(fullyQualified).Values |> Seq.filter (fun tcref -> - not (tcref.LogicalName.Contains ",") && + not (tcref.LogicalName.Contains ',') && tcref.IsRecordTycon && not (IsTyconUnseen ad g ncenv.amap m tcref)) |> Seq.map (ItemOfTyconRef ncenv m) @@ -5223,7 +5223,7 @@ let ResolveCompletionsInTypeForItem (ncenv: NameResolver) nenv m ad statics ty ( if methsWithStaticParams.IsEmpty then minfos else minfos |> List.filter (fun minfo -> let nm = minfo.LogicalName - not (nm.Contains "," && methsWithStaticParams |> List.exists (nm.StartsWithOrdinal))) + not (nm.Contains ',' && methsWithStaticParams |> List.exists nm.StartsWithOrdinal)) #endif minfos @@ -5341,7 +5341,7 @@ let rec ResolvePartialLongIdentInModuleOrNamespaceForItem (ncenv: NameResolver) let tycons = mty.TypeDefinitions |> List.filter (fun tcref -> - not (tcref.LogicalName.Contains ",") && + not (tcref.LogicalName.Contains ',') && not (IsTyconUnseen ad g ncenv.amap m (modref.NestedTyconRef tcref))) // Get all the types and .NET constructor groups accessible from here @@ -5415,7 +5415,7 @@ let rec GetCompletionForItem (ncenv: NameResolver) (nenv: NameResolutionEnv) m a | Item.Types _ -> for tcref in nenv.TyconsByDemangledNameAndArity(OpenQualified).Values do if not tcref.IsFSharpException - && not (tcref.LogicalName.Contains ",") + && not (tcref.LogicalName.Contains ',') && not (IsTyconUnseen ad g ncenv.amap m tcref) then yield ItemOfTyconRef ncenv m tcref diff --git a/src/Compiler/Checking/NicePrint.fs b/src/Compiler/Checking/NicePrint.fs index a09328222c4..cd7ba0d9564 100644 --- a/src/Compiler/Checking/NicePrint.fs +++ b/src/Compiler/Checking/NicePrint.fs @@ -58,7 +58,7 @@ module internal PrintUtilities = let isDiscard (name: string) = name.StartsWithOrdinal("_") let ensureFloat (s: string) = - if String.forall (fun c -> Char.IsDigit c || c = '-') s then + if String.forall (fun c -> isDigit c || c = '-') s then s + ".0" else s @@ -925,7 +925,7 @@ module PrintTypes = if not denv.includeStaticParametersInTypeNames then None, args else - let regex = System.Text.RegularExpressions.Regex(@"\`\d+") + let regex = System.Text.RegularExpressions.Regex(@"\`\d+", System.Text.RegularExpressions.RegexOptions.ECMAScript) let path, skip = (0, tc.CompilationPath.DemangledPath) ||> List.mapFold (fun skip path -> @@ -1962,7 +1962,7 @@ module TastDefinitionPrinting = not (impliedNames.Contains minfo.DisplayName) && IsMethInfoAccessible amap m ad minfo && // Discard method impls such as System.IConvertible.ToBoolean - not (minfo.IsILMethod && minfo.DisplayName.Contains(".")) && + not (minfo.IsILMethod && minfo.DisplayName.Contains('.')) && not minfo.IsUnionCaseTester && not (minfo.DisplayName.Split('.') |> Array.exists isDiscard)) @@ -2440,7 +2440,7 @@ module InferredSigPrinting = | TMDefLet(bind, _) -> ([bind.Var] |> List.filter filterVal - |> List.map (mkLocalValRef >> PrintTastMemberOrVals.prettyLayoutOfValOrMemberNoInst denv infoReader) + |> List.map (mkLocalValRef >> PrintTastMemberOrVals.prettyLayoutOfValOrMemberNoInst denv infoReader) |> aboveListL) | TMDefOpens _ -> emptyL diff --git a/src/Compiler/DependencyManager/DependencyProvider.fs b/src/Compiler/DependencyManager/DependencyProvider.fs index 858cf84fc1a..929f52cbda1 100644 --- a/src/Compiler/DependencyManager/DependencyProvider.fs +++ b/src/Compiler/DependencyManager/DependencyProvider.fs @@ -608,7 +608,7 @@ type DependencyProvider path: string ) : string MaybeNull * IDependencyManagerProvider MaybeNull = try - if path.Contains ":" && not (Path.IsPathRooted path) then + if path.Contains ':' && not (Path.IsPathRooted path) then let managers = RegisteredDependencyManagers compilerTools (Option.ofString outputDir) reportError diff --git a/src/Compiler/Driver/CompilerConfig.fs b/src/Compiler/Driver/CompilerConfig.fs index 54a69b05f8c..2deafdcc5cf 100644 --- a/src/Compiler/Driver/CompilerConfig.fs +++ b/src/Compiler/Driver/CompilerConfig.fs @@ -97,7 +97,7 @@ let GetWarningNumber (m, warningNumber: string) = // #pragma strips FS of the #pragma "FS0004" and validates the warning number // therefore if we have warning id that starts with a numeric digit we convert it to Some (int32) // anything else is ignored None - if Char.IsDigit(warningNumber[0]) then + if isDigit (warningNumber[0]) then Some(int32 warningNumber) elif warningNumber.StartsWithOrdinal "FS" then raise (ArgumentException()) @@ -274,11 +274,11 @@ type AssemblyReference = member x.ProjectReference = (let (AssemblyReference(_, _, contents)) = x in contents) member x.SimpleAssemblyNameIs name = - (String.Compare(FileSystemUtils.fileNameWithoutExtensionWithValidate false x.Text, name, StringComparison.OrdinalIgnoreCase) = 0) - || not (x.Text.Contains "/") - && not (x.Text.Contains "\\") - && not (x.Text.EndsWith(".dll", StringComparison.InvariantCultureIgnoreCase)) - && not (x.Text.EndsWith(".exe", StringComparison.InvariantCultureIgnoreCase)) + String.Equals(FileSystemUtils.fileNameWithoutExtensionWithValidate false x.Text, name, StringComparison.OrdinalIgnoreCase) + || not (x.Text.Contains '/') + && not (x.Text.Contains '\\') + && not (x.Text.EndsWith(".dll", StringComparison.OrdinalIgnoreCase)) + && not (x.Text.EndsWith(".exe", StringComparison.OrdinalIgnoreCase)) && (try let aname = System.Reflection.AssemblyName x.Text in aname.Name = name with _ -> diff --git a/src/Compiler/Driver/CompilerImports.fs b/src/Compiler/Driver/CompilerImports.fs index 090e5597440..0a8045d9812 100644 --- a/src/Compiler/Driver/CompilerImports.fs +++ b/src/Compiler/Driver/CompilerImports.fs @@ -365,17 +365,11 @@ let isHashRReference (r: range) = && not (equals r rangeCmdArgs) && FileSystem.IsPathRootedShim r.FileName -let IsNetModule fileName = - let ext = Path.GetExtension fileName - String.Compare(ext, ".netmodule", StringComparison.OrdinalIgnoreCase) = 0 +let IsNetModule (fileName: string) = fileName.EndsWithOrdinalIgnoreCase ".netmodule" -let IsDLL fileName = - let ext = Path.GetExtension fileName - String.Compare(ext, ".dll", StringComparison.OrdinalIgnoreCase) = 0 +let IsDLL (fileName: string) = fileName.EndsWithOrdinalIgnoreCase ".dll" -let IsExe fileName = - let ext = Path.GetExtension fileName - String.Compare(ext, ".exe", StringComparison.OrdinalIgnoreCase) = 0 +let IsExe (fileName: string) = fileName.EndsWithOrdinalIgnoreCase ".exe" let addConstraintSources(ia: ImportedAssembly) = let contents = ia.FSharpViewOfMetadata.Contents @@ -2403,10 +2397,7 @@ and [] TcImports |> List.tryFind (fun dll -> let baseName = Path.GetFileNameWithoutExtension(dll.resolvedPath) - let res = - String.Compare(baseName, tcConfig.primaryAssembly.Name, StringComparison.OrdinalIgnoreCase) - - res = 0) + String.Equals(baseName, tcConfig.primaryAssembly.Name, StringComparison.OrdinalIgnoreCase)) match path with | Some p -> AssemblyReference(range0, p.resolvedPath, None) diff --git a/src/Compiler/Driver/CompilerOptions.fs b/src/Compiler/Driver/CompilerOptions.fs index e742a20e139..fece04f11fe 100644 --- a/src/Compiler/Driver/CompilerOptions.fs +++ b/src/Compiler/Driver/CompilerOptions.fs @@ -224,7 +224,7 @@ let DumpCompilerOptionBlocks blocks = List.iter dumpCompilerOptionBlock blocks let isSlashOpt (opt: string) = - opt[0] = '/' && (opt.Length = 1 || not (opt[1..].Contains "/")) + opt[0] = '/' && (opt.Length = 1 || not (opt[1..].Contains '/')) module ResponseFile = diff --git a/src/Compiler/Driver/CreateILModule.fs b/src/Compiler/Driver/CreateILModule.fs index 04cda7f6c3f..62cf5de403b 100644 --- a/src/Compiler/Driver/CreateILModule.fs +++ b/src/Compiler/Driver/CreateILModule.fs @@ -267,7 +267,7 @@ module MainModuleBuilder = ((false, ""), v) ||> Seq.fold (fun (finished, v) c -> match finished with - | false when Char.IsDigit(c) -> false, v + c.ToString() + | false when isDigit (c) -> false, v + c.ToString() | _ -> true, v) |> snd diff --git a/src/Compiler/Driver/FxResolver.fs b/src/Compiler/Driver/FxResolver.fs index 42681600f88..39fb65c6306 100644 --- a/src/Compiler/Driver/FxResolver.fs +++ b/src/Compiler/Driver/FxResolver.fs @@ -238,7 +238,7 @@ type internal FxResolver dotnetConfig.IndexOf(pattern, StringComparison.OrdinalIgnoreCase) + pattern.Length - let endPos = dotnetConfig.IndexOfOrdinal("\"", startPos) + let endPos = dotnetConfig.IndexOf('\"', startPos) let ver = dotnetConfig[startPos .. endPos - 1] let path = @@ -427,7 +427,7 @@ type internal FxResolver let name = netcoreApp.Name try - if name.StartsWith(tfmPrefix, StringComparison.InvariantCultureIgnoreCase) then + if name.StartsWithOrdinal(tfmPrefix) then Some( Double.Parse(name.Substring(tfmPrefix.Length), NumberStyles.AllowDecimalPoint, CultureInfo.InvariantCulture) ) @@ -560,7 +560,7 @@ type internal FxResolver dotnetConfig.IndexOf(pattern, StringComparison.OrdinalIgnoreCase) + pattern.Length - let endPos = dotnetConfig.IndexOfOrdinal("\"", startPos) + let endPos = dotnetConfig.IndexOf('\"', startPos) let tfm = dotnetConfig[startPos .. endPos - 1] tfm with _ -> diff --git a/src/Compiler/Driver/ScriptClosure.fs b/src/Compiler/Driver/ScriptClosure.fs index 2374fd6793b..b1e5fd98a16 100644 --- a/src/Compiler/Driver/ScriptClosure.fs +++ b/src/Compiler/Driver/ScriptClosure.fs @@ -604,7 +604,7 @@ module ScriptPreprocessClosure = && (equals m range0 || equals m rangeStartup || equals m rangeCmdArgs) let isThisFileName = - (0 = String.Compare(rootFilename, m.FileName, StringComparison.OrdinalIgnoreCase)) + String.Equals(rootFilename, m.FileName, StringComparison.OrdinalIgnoreCase) isArgParameterWhileNotEditing || isThisFileName | None -> true diff --git a/src/Compiler/Driver/fsc.fs b/src/Compiler/Driver/fsc.fs index 014ed840222..328d1b2de2d 100644 --- a/src/Compiler/Driver/fsc.fs +++ b/src/Compiler/Driver/fsc.fs @@ -428,7 +428,7 @@ let CopyFSharpCore (outFile: string, referencedDlls: AssemblyReference list) = let TryFindVersionAttribute g attrib attribName attribs deterministic = match AttributeHelpers.TryFindStringAttribute g attrib attribs with | Some versionString -> - if deterministic && versionString.Contains("*") then + if deterministic && versionString.Contains('*') then errorR (Error(FSComp.SR.fscAssemblyWildcardAndDeterminism (attribName, versionString), rangeStartup)) try diff --git a/src/Compiler/Facilities/CompilerLocation.fs b/src/Compiler/Facilities/CompilerLocation.fs index 11f944c5f30..150de84676e 100644 --- a/src/Compiler/Facilities/CompilerLocation.fs +++ b/src/Compiler/Facilities/CompilerLocation.fs @@ -41,7 +41,7 @@ module internal FSharpEnvironment = let isRunningOnCoreClr = typeof.Assembly.FullName - .StartsWith("System.Private.CoreLib", StringComparison.InvariantCultureIgnoreCase) + .StartsWith("System.Private.CoreLib", StringComparison.OrdinalIgnoreCase) module Option = /// Convert string into Option string where null and String.Empty result in None @@ -299,7 +299,7 @@ module internal FSharpEnvironment = // How to find dotnet.exe --- woe is me; probing rules make me sad. // Algorithm: // 1. Look for DOTNET_HOST_PATH environment variable - // this is the main user programable override .. provided by user to find a specific dotnet.exe + // this is the main user programmable override .. provided by user to find a specific dotnet.exe // 2. Probe for are we part of an .NetSDK install // In an sdk install we are always installed in: sdk\3.0.100-rc2-014234\FSharp // dotnet or dotnet.exe will be found in the directory that contains the sdk directory diff --git a/src/Compiler/Facilities/prim-lexing.fs b/src/Compiler/Facilities/prim-lexing.fs index 6b927ef4a96..dbd7ed31047 100644 --- a/src/Compiler/Facilities/prim-lexing.fs +++ b/src/Compiler/Facilities/prim-lexing.fs @@ -52,7 +52,7 @@ type StringText(str: string) = yield line line <- reader.ReadLine() - if str.EndsWith("\n", StringComparison.Ordinal) then + if str.Length > 0 && str[str.Length - 1] = '\n' then // last trailing space not returned // http://stackoverflow.com/questions/19365404/stringreader-omits-trailing-linebreak yield String.Empty diff --git a/src/Compiler/Interactive/fsi.fs b/src/Compiler/Interactive/fsi.fs index a6ea4f1867e..199e2c643ea 100644 --- a/src/Compiler/Interactive/fsi.fs +++ b/src/Compiler/Interactive/fsi.fs @@ -992,7 +992,7 @@ type internal FsiCommandLineOptions(fsi: FsiEvaluationSessionHostConfig, argv: s | PlatformID.Unix -> StringComparison.Ordinal | _ -> StringComparison.OrdinalIgnoreCase - if String.Compare(processFileName, commandLineExecutableFileName, stringComparison) = 0 then + if String.Equals(processFileName, commandLineExecutableFileName, stringComparison) then processFileName else sprintf "%s %s" processFileName commandLineExecutableFileName @@ -1526,7 +1526,7 @@ let ConvReflectionTypeToILTypeRef (reflectionTy: Type) = let scoref = ILScopeRef.Assembly aref let fullName = reflectionTy.FullName - let index = fullName.IndexOfOrdinal("[") + let index = fullName.IndexOf('[') let fullName = if index = -1 then @@ -3354,16 +3354,16 @@ type internal MagicAssemblyResolution() = assemblyReference.Text if - String.Compare( + String.Equals( FileSystemUtils.fileNameOfPath assemblyReference.Text, assemblyReferenceTextDll, StringComparison.OrdinalIgnoreCase - ) = 0 - || String.Compare( + ) + || String.Equals( FileSystemUtils.fileNameOfPath assemblyReference.Text, assemblyReferenceTextExe, StringComparison.OrdinalIgnoreCase - ) = 0 + ) then Some( tcImports.TryResolveAssemblyReference( @@ -3550,7 +3550,7 @@ type FsiStdinLexerProvider match str with | Null -> str | NonNull str -> - if str.Contains("\000") then + if str.Contains('\000') then String(str |> Seq.filter (fun c -> c <> '\000') |> Seq.toArray) else str @@ -4346,7 +4346,7 @@ type FsiInteractionProcessor member _.CompletionsForPartialLID(istate, prefix: string) = let lid, stem = - if prefix.IndexOf(".", StringComparison.Ordinal) >= 0 then + if prefix.Contains '.' then let parts = prefix.Split('.') let n = parts.Length Array.sub parts 0 (n - 1) |> Array.toList, parts[n - 1] diff --git a/src/Compiler/Legacy/LegacyHostedCompilerForTesting.fs b/src/Compiler/Legacy/LegacyHostedCompilerForTesting.fs index 688b53643c3..e1960e241fd 100644 --- a/src/Compiler/Legacy/LegacyHostedCompilerForTesting.fs +++ b/src/Compiler/Legacy/LegacyHostedCompilerForTesting.fs @@ -185,21 +185,36 @@ type internal FscCompiler(legacyReferenceResolver) = /// test if --test:ErrorRanges flag is set let errorRangesArg = let regex = - Regex(@"^(/|--)test:ErrorRanges$", RegexOptions.Compiled ||| RegexOptions.IgnoreCase) + Regex( + @"^(/|--)test:ErrorRanges$", + RegexOptions.Compiled + ||| RegexOptions.IgnoreCase + ||| RegexOptions.CultureInvariant + ) fun arg -> regex.IsMatch(arg) /// test if --vserrors flag is set let vsErrorsArg = let regex = - Regex(@"^(/|--)vserrors$", RegexOptions.Compiled ||| RegexOptions.IgnoreCase) + Regex( + @"^(/|--)vserrors$", + RegexOptions.Compiled + ||| RegexOptions.IgnoreCase + ||| RegexOptions.CultureInvariant + ) fun arg -> regex.IsMatch(arg) /// test if an arg is a path to fsc.exe let fscExeArg = let regex = - Regex(@"fsc(\.exe)?$", RegexOptions.Compiled ||| RegexOptions.IgnoreCase) + Regex( + @"fsc(\.exe)?$", + RegexOptions.Compiled + ||| RegexOptions.IgnoreCase + ||| RegexOptions.CultureInvariant + ) fun arg -> regex.IsMatch(arg) diff --git a/src/Compiler/Service/FSharpCheckerResults.fs b/src/Compiler/Service/FSharpCheckerResults.fs index dda21fffd39..186d5927e63 100644 --- a/src/Compiler/Service/FSharpCheckerResults.fs +++ b/src/Compiler/Service/FSharpCheckerResults.fs @@ -2784,7 +2784,7 @@ module internal ParseAndCheckFile = let sameFile file hashLoadInFile = match file with | None -> false - | Some file -> (0 = String.Compare(hashLoadInFile, file, StringComparison.OrdinalIgnoreCase)) + | Some file -> (String.Equals(hashLoadInFile, file, StringComparison.OrdinalIgnoreCase)) // walk the list of #loads and keep the ones for this file. let hashLoadsInFile = diff --git a/src/Compiler/Service/FSharpParseFileResults.fs b/src/Compiler/Service/FSharpParseFileResults.fs index baea32da816..22162319cff 100644 --- a/src/Compiler/Service/FSharpParseFileResults.fs +++ b/src/Compiler/Service/FSharpParseFileResults.fs @@ -14,9 +14,7 @@ open FSharp.Compiler.Text open FSharp.Compiler.Text.Range module SourceFileImpl = - let IsSignatureFile file = - let ext = Path.GetExtension file - 0 = String.Compare(".fsi", ext, StringComparison.OrdinalIgnoreCase) + let IsSignatureFile (file: string) = file.EndsWithOrdinalIgnoreCase ".fsi" /// Additional #defines that should be in place when editing a file in a file editor such as VS. let GetImplicitConditionalDefinesForEditing (isInteractive: bool) = diff --git a/src/Compiler/Service/IncrementalBuild.fs b/src/Compiler/Service/IncrementalBuild.fs index f59a1e9b6a5..ff77d5445a7 100644 --- a/src/Compiler/Service/IncrementalBuild.fs +++ b/src/Compiler/Service/IncrementalBuild.fs @@ -1321,8 +1321,8 @@ type IncrementalBuilder(initialState: IncrementalBuilderInitialState, state: Inc // Get the slot of the given file and force it to build. let CompareFileNames f = let result = - String.Compare(fileName, f.Source.FilePath, StringComparison.CurrentCultureIgnoreCase)=0 - || String.Compare(FileSystem.GetFullPathShim fileName, FileSystem.GetFullPathShim f.Source.FilePath, StringComparison.CurrentCultureIgnoreCase)=0 + String.Equals(fileName, f.Source.FilePath, StringComparison.OrdinalIgnoreCase) + || String.Equals(FileSystem.GetFullPathShim fileName, FileSystem.GetFullPathShim f.Source.FilePath, StringComparison.OrdinalIgnoreCase) result match fileNames |> List.tryFindIndex CompareFileNames with | Some slot -> Some slot diff --git a/src/Compiler/Service/QuickParse.fs b/src/Compiler/Service/QuickParse.fs index 7738d74ad80..3c45130ccd8 100644 --- a/src/Compiler/Service/QuickParse.fs +++ b/src/Compiler/Service/QuickParse.fs @@ -415,7 +415,7 @@ module QuickParse = let partialLongName = AtStartOfIdentifier(0, [], false, None) match List.rev partialLongName.QualifyingIdents with - | s :: _ when s.Length > 0 && Char.IsDigit(s[0]) -> PartialLongName.Empty(index) // "2.0" is not a longId (this might not be right for ``2.0`` but good enough for common case) + | s :: _ when s.Length > 0 && isDigit (s[0]) -> PartialLongName.Empty(index) // "2.0" is not a longId (this might not be right for ``2.0`` but good enough for common case) | plid -> { partialLongName with QualifyingIdents = plid @@ -427,7 +427,7 @@ module QuickParse = | NonNull lineStr -> GetPartialLongNameExAux(lineStr, index) let TokenNameEquals (tokenInfo: FSharpTokenInfo) (token2: string) = - String.Compare(tokenInfo.TokenName, token2, StringComparison.OrdinalIgnoreCase) = 0 + String.Equals(tokenInfo.TokenName, token2, StringComparison.OrdinalIgnoreCase) // The prefix of the sequence of token names to look for in TestMemberOrOverrideDeclaration, in reverse order let private expected = [ [| "dot" |]; [| "ident" |]; [| "member"; "override" |] ] diff --git a/src/Compiler/Service/ServiceAssemblyContent.fs b/src/Compiler/Service/ServiceAssemblyContent.fs index 2b54ed7f229..e55a9a52180 100644 --- a/src/Compiler/Service/ServiceAssemblyContent.fs +++ b/src/Compiler/Service/ServiceAssemblyContent.fs @@ -72,7 +72,7 @@ type Parent = let removeGenericParamsCount (idents: ShortIdents) = idents |> Array.map (fun ident -> - if ident.Length > 0 && Char.IsDigit ident[ident.Length - 1] then + if ident.Length > 0 && isDigit ident[ident.Length - 1] then let lastBacktickIndex = ident.LastIndexOf '`' if lastBacktickIndex <> -1 then ident.Substring(0, lastBacktickIndex) diff --git a/src/Compiler/Service/ServiceInterfaceStubGenerator.fs b/src/Compiler/Service/ServiceInterfaceStubGenerator.fs index e02df4c7da7..ec1a7dbc8b8 100644 --- a/src/Compiler/Service/ServiceInterfaceStubGenerator.fs +++ b/src/Compiler/Service/ServiceInterfaceStubGenerator.fs @@ -186,7 +186,7 @@ module InterfaceStubGenerator = (if typar.IsSolveAtCompileTime then "^" else "'") + typar.Name let internal bracket (str: string) = - if str.Contains(" ") then "(" + str + ")" else str + if str.Contains(' ') then "(" + str + ")" else str let internal formatType ctx (ty: FSharpType) = let genericDefinition = diff --git a/src/Compiler/Service/ServiceLexing.fs b/src/Compiler/Service/ServiceLexing.fs index 9abe2199dc0..6ca04bfe5bc 100644 --- a/src/Compiler/Service/ServiceLexing.fs +++ b/src/Compiler/Service/ServiceLexing.fs @@ -873,7 +873,7 @@ type FSharpLineTokenizer(lexbuf: UnicodeLexing.Lexbuf, maxLength: int option, fi // Process: anywhite* # let processDirective (str: string) directiveLength delay cont = - let hashIdx = str.IndexOf("#", StringComparison.Ordinal) + let hashIdx = str.IndexOf('#') if (hashIdx <> 0) then delay (WHITESPACE cont, 0, hashIdx - 1) diff --git a/src/Compiler/Service/ServiceParsedInputOps.fs b/src/Compiler/Service/ServiceParsedInputOps.fs index f1a8d3e9737..7e9de7ec08e 100644 --- a/src/Compiler/Service/ServiceParsedInputOps.fs +++ b/src/Compiler/Service/ServiceParsedInputOps.fs @@ -17,9 +17,7 @@ open FSharp.Compiler.Text.Position open FSharp.Compiler.Text.Range module SourceFileImpl = - let IsSignatureFile file = - let ext = Path.GetExtension file - 0 = String.Compare(".fsi", ext, StringComparison.OrdinalIgnoreCase) + let IsSignatureFile (file: string) = file.EndsWithOrdinalIgnoreCase ".fsi" /// Additional #defines that should be in place when editing a file in a file editor such as VS. let GetImplicitConditionalDefinesForEditing (isInteractive: bool) = diff --git a/src/Compiler/Service/service.fs b/src/Compiler/Service/service.fs index 103c84e63cf..6c4759f91d4 100644 --- a/src/Compiler/Service/service.fs +++ b/src/Compiler/Service/service.fs @@ -767,11 +767,11 @@ type CompilerEnvironment() = let ext = Path.GetExtension file compilableExtensions - |> List.exists (fun e -> 0 = String.Compare(e, ext, StringComparison.OrdinalIgnoreCase)) + |> List.exists (fun e -> String.Equals(e, ext, StringComparison.OrdinalIgnoreCase)) /// Whether or not this file should be a single-file project static member MustBeSingleFileProject file = let ext = Path.GetExtension file singleFileProjectExtensions - |> List.exists (fun e -> 0 = String.Compare(e, ext, StringComparison.OrdinalIgnoreCase)) + |> List.exists (fun e -> String.Equals(e, ext, StringComparison.OrdinalIgnoreCase)) diff --git a/src/Compiler/Symbols/Symbols.fs b/src/Compiler/Symbols/Symbols.fs index 19fbfe9306b..ea81abe0441 100644 --- a/src/Compiler/Symbols/Symbols.fs +++ b/src/Compiler/Symbols/Symbols.fs @@ -824,7 +824,7 @@ type FSharpEntity(cenv: SymbolEnv, entity: EntityRef, tyargs: TType list) = match fullName with | Some fullName -> match Option.attempt (fun _ -> x.DisplayName) with - | Some shortDisplayName when not (shortDisplayName.Contains ".") -> + | Some shortDisplayName when not (shortDisplayName.Contains '.') -> Some (fullName |> Array.replace (fullName.Length - 1) shortDisplayName) | _ -> Some fullName | None -> None @@ -838,7 +838,7 @@ type FSharpEntity(cenv: SymbolEnv, entity: EntityRef, tyargs: TType list) = match fullName with | Some fullName -> match Option.attempt (fun _ -> x.CompiledName) with - | Some shortCompiledName when not (shortCompiledName.Contains ".") -> + | Some shortCompiledName when not (shortCompiledName.Contains '.') -> Some (fullName |> Array.replace (fullName.Length - 1) shortCompiledName) | _ -> Some fullName | None -> None @@ -2445,7 +2445,7 @@ type FSharpMemberOrFunctionOrValue(cenv, d:FSharpMemberOrValData, item) = match fullName with | Some fullName -> match Option.attempt (fun _ -> x.DisplayName) with - | Some shortDisplayName when not (shortDisplayName.Contains ".") -> + | Some shortDisplayName when not (shortDisplayName.Contains '.') -> Some (fullName |> Array.replace (fullName.Length - 1) shortDisplayName) | _ -> Some fullName | None -> None diff --git a/src/Compiler/SyntaxTree/PrettyNaming.fs b/src/Compiler/SyntaxTree/PrettyNaming.fs index 3000297d866..1aed4786c92 100755 --- a/src/Compiler/SyntaxTree/PrettyNaming.fs +++ b/src/Compiler/SyntaxTree/PrettyNaming.fs @@ -1014,7 +1014,7 @@ exception InvalidMangledStaticArg of string /// Demangle the static parameters let DemangleProvidedTypeName (typeLogicalName: string) = - if typeLogicalName.Contains "," then + if typeLogicalName.Contains ',' then let pieces = splitAroundQuotation typeLogicalName ',' match pieces with diff --git a/src/Compiler/SyntaxTree/SyntaxTreeOps.fs b/src/Compiler/SyntaxTree/SyntaxTreeOps.fs index a02591eb650..279c50663fd 100644 --- a/src/Compiler/SyntaxTree/SyntaxTreeOps.fs +++ b/src/Compiler/SyntaxTree/SyntaxTreeOps.fs @@ -1041,13 +1041,15 @@ let getTypeFromTuplePath (path: SynTupleTypeSegment list) : SynType list = let (|MultiDimensionArrayType|_|) (t: SynType) = match t with | SynType.App(StripParenTypes(SynType.LongIdent(SynLongIdent([ identifier ], _, _))), _, [ elementType ], _, _, true, m) -> - if System.Text.RegularExpressions.Regex.IsMatch(identifier.idText, "^array\d\d?d$") then + if + System.Text.RegularExpressions.Regex.IsMatch( + identifier.idText, + "^array\d\d?d$", + System.Text.RegularExpressions.RegexOptions.ECMAScript + ) + then let rank = - identifier.idText - |> Seq.filter System.Char.IsDigit - |> Seq.toArray - |> System.String - |> int + identifier.idText |> Seq.filter isDigit |> Seq.toArray |> System.String |> int ValueSome(rank, elementType, m) else diff --git a/src/Compiler/SyntaxTree/XmlDoc.fs b/src/Compiler/SyntaxTree/XmlDoc.fs index 74135a6ba33..029c1941e2e 100644 --- a/src/Compiler/SyntaxTree/XmlDoc.fs +++ b/src/Compiler/SyntaxTree/XmlDoc.fs @@ -323,14 +323,14 @@ type XmlDocumentationInfo private (tryGetXmlDocument: unit -> XmlDocument option ) let tryGetSummaryNode (xmlDocSig: string) = - if xmlDocSig.Contains "'" && xmlDocSig.Contains "\"" then + if xmlDocSig.Contains '\'' && xmlDocSig.Contains '\"' then // No easy way to find this signature with XPath None else tryGetXmlDocument () |> Option.bind (fun doc -> let name = - if xmlDocSig.Contains "'" then + if xmlDocSig.Contains '\'' then $"\"{xmlDocSig}\"" else $"'{xmlDocSig}'" diff --git a/src/Compiler/TypedTree/TypeProviders.fs b/src/Compiler/TypedTree/TypeProviders.fs index 9eb76091897..dd626eac3b5 100644 --- a/src/Compiler/TypedTree/TypeProviders.fs +++ b/src/Compiler/TypedTree/TypeProviders.fs @@ -183,7 +183,7 @@ let GetTypeProvidersOfAssembly ( // Check if the attribute is pointing to the file being compiled, in which case ignore it // This checks seems like legacy but is included for compat. | Some designTimeAssemblyName, Some path - when String.Compare(designTimeAssemblyName.Name, Path.GetFileNameWithoutExtension path, StringComparison.OrdinalIgnoreCase) = 0 -> + when String.Equals(designTimeAssemblyName.Name, Path.GetFileNameWithoutExtension path, StringComparison.OrdinalIgnoreCase) -> () | Some _, _ -> diff --git a/src/Compiler/TypedTree/TypedTreeOps.fs b/src/Compiler/TypedTree/TypedTreeOps.fs index 8001c049ece..60045afcd3a 100644 --- a/src/Compiler/TypedTree/TypedTreeOps.fs +++ b/src/Compiler/TypedTree/TypedTreeOps.fs @@ -4215,12 +4215,12 @@ module DebugPrint = | Const.UIntPtr x -> (x |> string)+"un" | Const.Single d -> (let s = d.ToString("g12", System.Globalization.CultureInfo.InvariantCulture) - if String.forall (fun c -> System.Char.IsDigit c || c = '-') s + if String.forall (fun c -> isDigit c || c = '-') s then s + ".0" else s) + "f" | Const.Double d -> let s = d.ToString("g12", System.Globalization.CultureInfo.InvariantCulture) - if String.forall (fun c -> System.Char.IsDigit c || c = '-') s + if String.forall (fun c -> isDigit c || c = '-') s then s + ".0" else s | Const.Char c -> "'" + c.ToString() + "'" diff --git a/src/Compiler/Utilities/illib.fs b/src/Compiler/Utilities/illib.fs index fca3cd54605..1e150b58b40 100644 --- a/src/Compiler/Utilities/illib.fs +++ b/src/Compiler/Utilities/illib.fs @@ -114,6 +114,8 @@ module internal PervasiveAutoOpens = let LOH_SIZE_THRESHOLD_BYTES = 80_000 type String with + // char overload + member inline x.Contains(value: char) = x.IndexOf value <> -1 member inline x.StartsWithOrdinal value = x.StartsWith(value, StringComparison.Ordinal) @@ -133,6 +135,9 @@ module internal PervasiveAutoOpens = member inline x.IndexOfOrdinal(value, startIndex, count) = x.IndexOf(value, startIndex, count, StringComparison.Ordinal) + // Backport of Char.IsAsciiDigit. Do not use Char.IsDigit + let inline isDigit (c: char) = uint (c - '0') <= uint ('9' - '0') + /// Get an initialization hole let getHole (r: _ ref) = match r.Value with @@ -601,7 +606,7 @@ module List = | [] -> failwith "headAndTail" | h :: t -> (h, t) - // WARNING: not tail-recursive + /// WARNING: not tail-recursive let mapHeadTail fhead ftail = function | [] -> [] @@ -785,13 +790,13 @@ module String = match Array.tryHead strArr with | None -> str | Some c -> - strArr[0] <- Char.ToLower c + strArr[0] <- Char.ToLowerInvariant c String strArr let extractTrailingIndex (str: string) = let charr = str.ToCharArray() Array.revInPlace charr - let digits = Array.takeWhile Char.IsDigit charr + let digits = Array.takeWhile isDigit charr Array.revInPlace digits String digits diff --git a/src/Compiler/Utilities/illib.fsi b/src/Compiler/Utilities/illib.fsi index a9ee48c4be9..cd96229ac28 100644 --- a/src/Compiler/Utilities/illib.fsi +++ b/src/Compiler/Utilities/illib.fsi @@ -73,6 +73,8 @@ module internal PervasiveAutoOpens = type String with + member inline Contains: value: char -> bool + member inline StartsWithOrdinal: value: string -> bool member inline EndsWithOrdinal: value: string -> bool @@ -85,6 +87,9 @@ module internal PervasiveAutoOpens = member inline IndexOfOrdinal: value: string * startIndex: int * count: int -> int + /// Returns true if the argument is ASCII digit (0-9). + val inline isDigit: c: char -> bool + type Async with /// Runs the computation synchronously, always starting on the current thread. @@ -207,7 +212,7 @@ module internal List = val headAndTail: l: 'a list -> 'a * 'a list - // WARNING: not tail-recursive + /// WARNING: not tail-recursive val mapHeadTail: fhead: ('a -> 'b) -> ftail: ('a -> 'b) -> _arg1: 'a list -> 'b list val collectFold: f: ('a -> 'b -> 'c list * 'a) -> s: 'a -> l: 'b list -> 'c list * 'a diff --git a/src/Compiler/Utilities/range.fs b/src/Compiler/Utilities/range.fs index 678ab07f452..d1283b9861d 100755 --- a/src/Compiler/Utilities/range.fs +++ b/src/Compiler/Utilities/range.fs @@ -365,7 +365,7 @@ type Range(code1: int64, code2: int64) = |> Seq.skip (m.StartLine - 1) |> Seq.take (m.EndLine - m.StartLine + 1) |> String.concat "\n" - |> fun s -> s.Substring(startCol + 1, s.LastIndexOf("\n", StringComparison.Ordinal) + 1 - startCol + endCol) + |> fun s -> s.Substring(startCol + 1, s.LastIndexOf('\n') + 1 - startCol + endCol) with e -> e.ToString() diff --git a/src/Compiler/Utilities/sformat.fs b/src/Compiler/Utilities/sformat.fs index 2a11d4fee98..6867ba3a230 100644 --- a/src/Compiler/Utilities/sformat.fs +++ b/src/Compiler/Utilities/sformat.fs @@ -1142,9 +1142,9 @@ module Display = let openingBracketIndex = postTextMatch.Groups["prop"].Index - 1 buildObjMessageL remainingPropertyText[openingBracketIndex..] newLayouts - | remaingPropertyText -> + | remainingPropertyText -> // make sure we don't have any stray brackets - let strayClosingMatch = illFormedBracketPatternLookup.IsMatch remaingPropertyText + let strayClosingMatch = illFormedBracketPatternLookup.IsMatch remainingPropertyText if strayClosingMatch then None @@ -1156,7 +1156,7 @@ module Display = List.rev ( (sepL (tagText preText) ^^ alternativeObjL - ^^ sepL (tagText (replaceEscapedBrackets (remaingPropertyText)))) + ^^ sepL (tagText (replaceEscapedBrackets (remainingPropertyText)))) :: layouts ) ) diff --git a/src/Compiler/Utilities/sformat.fsi b/src/Compiler/Utilities/sformat.fsi index 1c740a38dce..b9644ffc06d 100644 --- a/src/Compiler/Utilities/sformat.fsi +++ b/src/Compiler/Utilities/sformat.fsi @@ -394,7 +394,7 @@ module internal Display = val output_layout_tagged: options: FormatOptions -> writer: TaggedTextWriter -> layout: Layout -> unit #else - // Most functions aren't needed in FSharp.Core.dll, but we add one inernal entry for printf + // Most functions aren't needed in FSharp.Core.dll, but we add one internal entry for printf val anyToStringForPrintf: options: FormatOptions -> bindingFlags: System.Reflection.BindingFlags -> value: 'T * Type -> string #endif diff --git a/src/Compiler/lex.fsl b/src/Compiler/lex.fsl index 1e48cc8d0a2..6b956dba50b 100644 --- a/src/Compiler/lex.fsl +++ b/src/Compiler/lex.fsl @@ -94,7 +94,7 @@ let parseInt32 (s:string) = let mutable p = 0 let sign = getSign32 s &p l let specifier = get0OXB s &p l - match Char.ToLower(specifier,CultureInfo.InvariantCulture) with + match Char.ToLowerInvariant(specifier) with | 'x' -> sign * (int32 (Convert.ToUInt32(UInt64.Parse(s.Substring(p), NumberStyles.AllowHexSpecifier,CultureInfo.InvariantCulture)))) | 'b' -> sign * (int32 (Convert.ToUInt32(parseBinaryUInt64 (s.Substring(p))))) | 'o' -> sign * (int32 (Convert.ToUInt32(parseOctalUInt64 (s.Substring(p))))) diff --git a/src/FSharp.Core/printf.fs b/src/FSharp.Core/printf.fs index a326492c672..bae23855c97 100644 --- a/src/FSharp.Core/printf.fs +++ b/src/FSharp.Core/printf.fs @@ -56,7 +56,7 @@ module internal PrintfImpl = /// 1. Final pieces (1..5) - set of functions with arguments number 1..5. /// Primary characteristic - these functions produce final result of the *printf* operation /// 2. Chained pieces (1..5) - set of functions with arguments number 1..5. - /// Primary characteristic - these functions doesn not produce final result by itself, instead they tailed with some another piece (chained or final). + /// Primary characteristic - these functions does not produce final result by itself, instead they tailed with some another piece (chained or final). /// Plain parts correspond to simple format specifiers (that are projected to just one parameter of the function, say %d or %s). However we also have /// format specifiers that can be projected to more than one argument (i.e %a, %t or any simple format specified with * width or precision). /// For them we add special cases (both chained and final to denote that they can either return value themselves or continue with some other piece) @@ -84,6 +84,9 @@ module internal PrintfImpl = let inline isPlusForPositives flags = hasFlag flags FormatFlags.PlusForPositives let inline isSpaceForPositives flags = hasFlag flags FormatFlags.SpaceForPositives + // Backport of Char.IsAsciiDigit. Do not use Char.IsDigit + let inline isDigit (c: char) = uint (c - '0') <= uint ('9' - '0') + /// Used for width and precision to denote that user has specified '*' flag [] let StarValue = -1 @@ -146,15 +149,15 @@ module internal PrintfImpl = padChar, prefix member spec.IsGFormat = - spec.IsDecimalFormat || System.Char.ToLower(spec.TypeChar) = 'g' + spec.IsDecimalFormat || spec.TypeChar = 'g' || spec.TypeChar = 'G' + - /// Set of helpers to parse format string module private FormatString = let intFromString (s: string) (i: byref) = let mutable res = 0 - while (Char.IsDigit s.[i]) do + while (isDigit s[i]) do let n = int s.[i] - int '0' res <- res * 10 + n i <- i + 1 @@ -185,7 +188,7 @@ module internal PrintfImpl = if s.[i] = '*' then i <- i + 1 StarValue - elif Char.IsDigit s.[i] then + elif isDigit s[i] then intFromString s (&i) else NotSpecifiedValue @@ -195,7 +198,7 @@ module internal PrintfImpl = if s.[i + 1] = '*' then i <- i + 2 StarValue - elif Char.IsDigit s.[i + 1] then + elif isDigit s[i + 1] then i <- i + 1 intFromString s (&i) else raise (ArgumentException("invalid precision value")) @@ -210,7 +213,7 @@ module internal PrintfImpl = let parseInterpolatedHoleDotNetFormat typeChar (s: string) (i: byref) = if typeChar = 'P' then if i < s.Length && s.[i] = '(' then - let i2 = s.IndexOf(")", i) + let i2 = s.IndexOf(')', i) if i2 = -1 then ValueNone else diff --git a/src/FSharp.Core/string.fs b/src/FSharp.Core/string.fs index d716b793db1..d07efca4082 100644 --- a/src/FSharp.Core/string.fs +++ b/src/FSharp.Core/string.fs @@ -29,8 +29,9 @@ module String = let concatArray sep (strings: string array) = match length sep with | 0 -> String.Concat strings - // following line should be used when this overload becomes part of .NET Standard (it's only in .NET Core) - //| 1 -> String.Join(sep.[0], strings, 0, strings.Length) +#if NETSTANDARD2_1_OR_GREATER || NETCOREAPP2_0_OR_GREATER + | 1 -> String.Join(sep[0], strings, 0, strings.Length) +#endif | _ -> String.Join(sep, strings, 0, strings.Length) match strings with