Skip to content

Commit

Permalink
[All/Rust] Removed Regex.Replace from hot paths (#3937)
Browse files Browse the repository at this point in the history
  • Loading branch information
ncave authored Oct 24, 2024
1 parent 891605c commit 5355b7c
Show file tree
Hide file tree
Showing 4 changed files with 58 additions and 41 deletions.
1 change: 1 addition & 0 deletions src/Fable.Cli/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

* [Rust] Fixed try finally handler order of execution (by @ncave)
* [JS/TS/Python/Rust] Fixed String.StartsWith/EndsWith (#3934) (by @ncave)
* [All/Rust] Removed Regex.Replace from hot paths (by @ncave)

## 4.22.0 - 2024-10-02

Expand Down
25 changes: 17 additions & 8 deletions src/Fable.Transforms/FSharp2Fable.Util.fs
Original file line number Diff line number Diff line change
Expand Up @@ -609,19 +609,27 @@ module Helpers =
name.Replace('.', '_').Replace('`', '$')

let cleanNameAsRustIdentifier (name: string) =
// name |> Naming.sanitizeIdentForbiddenChars
let name = Regex.Replace(name, @"[\s`'"".]", "_")

let name =
if name.Length > 0 && Char.IsDigit(name, 0) then
"_" + name
else
name

let name =
Regex.Replace(name, @"[^\w]", (fun c -> String.Format(@"_{0:x4}", int c.Value[0])))

name
if name |> String.exists (fun c -> not (c = '_' || Char.IsLetterOrDigit(c))) then
name
|> String.collect (
function
| '_'
| ' '
| '`'
| '.'
| '\''
| '\"' -> "_"
| c when Char.IsLetterOrDigit(c) -> string c
| c -> String.Format(@"_{0:x4}", int c)
)
else
name

let memberNameAsRustIdentifier (name: string) part =
let f = cleanNameAsRustIdentifier
Expand Down Expand Up @@ -1692,7 +1700,8 @@ module Identifiers =
// The F# compiler sometimes adds a numeric suffix. Remove it because it's not deterministic.
// See https://github.com/fable-compiler/Fable/issues/2869#issuecomment-1169574962
if fsRef.IsCompilerGenerated then
Regex.Replace(fsRef.CompiledName, @"\d+$", "", RegexOptions.Compiled)
// Regex.Replace(fsRef.CompiledName, @"\d+$", "", RegexOptions.Compiled)
fsRef.CompiledName.TrimEnd([| '0'; '1'; '2'; '3'; '4'; '5'; '6'; '7'; '8'; '9' |])
else
fsRef.CompiledName

Expand Down
58 changes: 34 additions & 24 deletions src/Fable.Transforms/Rust/AST/Rust.AST.Adapters.fs
Original file line number Diff line number Diff line change
Expand Up @@ -164,34 +164,44 @@ type System.String with
Some(self.Chars(self.Length - 1))

member self.escape_debug() =
// escapes \\, \', \", \t, \r, \n, [\x00-\x1F]
let res = self.Replace("\\", @"\\").Replace("\'", @"\'").Replace("\"", @"\""")

let res = res.Replace("\t", @"\t").Replace("\r", @"\r").Replace("\n", @"\n")

let res =
System.Text.RegularExpressions.Regex.Replace(
res,
@"[\x00-\x1F]",
fun c -> System.String.Format(@"\u{0}{1:x4}{2}", "{", int c.Value[0], "}")
if
self
|> String.exists (fun c -> c = '\\' || c = '\'' || c = '\"' || System.Char.IsControl(c))
then
self
|> String.collect (
function
| '\t' -> @"\t"
| '\r' -> @"\r"
| '\n' -> @"\n"
| '\\' -> @"\\"
| '\'' -> @"\'"
| '\"' -> @"\"""
| c when System.Char.IsControl(c) -> System.String.Format(@"\u{0}{1:x4}{2}", "{", int c, "}")
| c -> string c
)

res
else
self

member self.escape_default() =
// escapes \\, \', \", \t, \r, \n, [^\x20-\x7F]
let res = self.Replace("\\", @"\\").Replace("\'", @"\'").Replace("\"", @"\""")

let res = res.Replace("\t", @"\t").Replace("\r", @"\r").Replace("\n", @"\n")

let res =
System.Text.RegularExpressions.Regex.Replace(
res,
@"[^\x20-\x7F]",
fun c -> System.String.Format(@"\u{0}{1:x4}{2}", "{", int c.Value[0], "}")
if
self
|> String.exists (fun c -> c = '\\' || c = '\'' || c = '\"' || c < '\x20' || c > '\x7e')
then
self
|> String.collect (
function
| '\t' -> @"\t"
| '\r' -> @"\r"
| '\n' -> @"\n"
| '\\' -> @"\\"
| '\'' -> @"\'"
| '\"' -> @"\"""
| c when c < '\x20' || c > '\x7e' -> System.String.Format(@"\u{0}{1:x4}{2}", "{", int c, "}")
| c -> string c
)

res
else
self

type System.Text.StringBuilder with

Expand Down
15 changes: 6 additions & 9 deletions src/Fable.Transforms/Rust/Fable2Rust.fs
Original file line number Diff line number Diff line change
Expand Up @@ -488,8 +488,8 @@ module TypeInfo =
| _ -> isTypeOfType com isCopyableType isCopyableEntity entNames typ

let isCopyableEntity com entNames (ent: Fable.Entity) =
not (ent.IsInterface)
&& ent.IsValueType
ent.IsValueType
&& not (ent.IsInterface)
&& not (hasMutableFields com ent)
&& (isEntityOfType com isCopyableType entNames ent)

Expand Down Expand Up @@ -2946,13 +2946,10 @@ module Util =
let typ = fableExpr.Type
let nameOpt = tryGetIdentName fableExpr
let patOpt = makeUnionCasePatOpt com ctx typ nameOpt tag

match patOpt with
| Some pat ->
let expr = makeRefForPatternMatch com ctx typ nameOpt fableExpr
let letExpr = mkLetExpr pat expr
letExpr
| _ -> failwith "unreachable"
let pat = patOpt |> Option.defaultValue WILD_PAT
let expr = makeRefForPatternMatch com ctx typ nameOpt fableExpr
let letExpr = mkLetExpr pat expr
letExpr

let makeTest isSome thenValue elseValue =
if isSome then
Expand Down

0 comments on commit 5355b7c

Please sign in to comment.