Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions src/Fable.Cli/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

* [Beam] Fix dropped top-level side effects — multiple `ActionDeclaration` `main/0` functions are now merged (by @dbrattli)
* [Beam] Fix `%%` escape in string interpolation producing double `%` instead of single (by @dbrattli)
* [Beam] Fix double-quoted atoms for uppercase `CompiledName` on DU cases (e.g. `''EXIT''``'EXIT'`) (by @dbrattli)
* [Beam] Fix cross-project imports producing self-recursive calls when source files share the same name (by @dbrattli)
* [Beam] Support `Type.GetGenericArguments` and `Type.GetInterface` for reflection (by @dbrattli)
* [TS] Correctly resolve type references for `TypeScriptTaggedUnion` (by @MangelMaxime and @jrwone0)
* [TS] Expose optional `stack` property on `Exception` (by @MangelMaxime)
Expand Down
2 changes: 2 additions & 0 deletions src/Fable.Compiler/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

* [Beam] Fix dropped top-level side effects — multiple `ActionDeclaration` `main/0` functions are now merged (by @dbrattli)
* [Beam] Fix `%%` escape in string interpolation producing double `%` instead of single (by @dbrattli)
* [Beam] Fix double-quoted atoms for uppercase `CompiledName` on DU cases (e.g. `''EXIT''` → `'EXIT'`) (by @dbrattli)
* [Beam] Fix cross-project imports producing self-recursive calls when source files share the same name (by @dbrattli)
* [Beam] Support `Type.GetGenericArguments` and `Type.GetInterface` for reflection (by @dbrattli)
* [TS] Correctly resolve type references for `TypeScriptTaggedUnion` (by @MangelMaxime and @jrwone0)
* [Python] Fix `nonlocal`/`global` declarations generated inside `match/case` bodies causing `SyntaxError` (by @dbrattli)
Expand Down
29 changes: 20 additions & 9 deletions src/Fable.Transforms/Beam/Fable2Beam.fs
Original file line number Diff line number Diff line change
Expand Up @@ -104,9 +104,8 @@ let private getUnionCaseAtomExpr (com: IBeamCompiler) (ref: EntityRef) (tag: int
| Some name -> name
| None -> sanitizeErlangName uci.Name

let atomStr = quoteErlangAtom atomName
let isFieldless = uci.UnionCaseFields.IsEmpty
Some(atomStr, isFieldless)
Some(atomName, isFieldless)
| None -> None

let private getDecisionTarget (ctx: Context) targetIndex =
Expand All @@ -125,9 +124,22 @@ let private matchTargetIdentAndValues idents values =
/// Resolve the Erlang module name for an import, returning None if it's the current module.
let resolveImportModuleName (com: IBeamCompiler) (importPath: string) =
let name = moduleNameFromFile importPath
let currentModule = moduleNameFromFile com.CurrentFile

if name = currentModule then
// Resolve the import path to an absolute path so we can reliably compare
// against the current file. Import paths may be relative (e.g., "../Foo/Types.fs")
// or absolute. Without resolving, two different files with the same base name
// (e.g., Agent/Types.fs vs Reactive/Types.fs) would both produce module name "types"
// and the import would be incorrectly treated as a local (self-recursive) call.
let resolvedImportPath =
if System.IO.Path.IsPathRooted(importPath) then
System.IO.Path.GetFullPath(importPath)
else
let currentDir = System.IO.Path.GetDirectoryName(com.CurrentFile)
System.IO.Path.GetFullPath(System.IO.Path.Combine(currentDir, importPath))

let currentFileFull = System.IO.Path.GetFullPath(com.CurrentFile)

if resolvedImportPath = currentFileFull then
None
else
Some name
Expand Down Expand Up @@ -1919,7 +1931,6 @@ and transformReceive (com: IBeamCompiler) (ctx: Context) (emitInfo: EmitInfo) (t
| Some name -> name
| None -> sanitizeErlangName uci.Name

let atomStr = quoteErlangAtom atomName
let fields = uci.UnionCaseFields
let fieldCount = fields.Length

Expand All @@ -1928,20 +1939,20 @@ and transformReceive (com: IBeamCompiler) (ctx: Context) (emitInfo: EmitInfo) (t

let pattern =
if fieldCount = 0 then
Beam.ErlPattern.PLiteral(Beam.ErlLiteral.AtomLit(Beam.Atom atomStr))
Beam.ErlPattern.PLiteral(Beam.ErlLiteral.AtomLit(Beam.Atom atomName))
else
Beam.ErlPattern.PTuple(
Beam.ErlPattern.PLiteral(Beam.ErlLiteral.AtomLit(Beam.Atom atomStr))
Beam.ErlPattern.PLiteral(Beam.ErlLiteral.AtomLit(Beam.Atom atomName))
:: (fieldVars |> List.map Beam.ErlPattern.PVar)
)

// Build body: atom-tagged DU representation
let body =
if fieldCount = 0 then
Beam.ErlExpr.Literal(Beam.ErlLiteral.AtomLit(Beam.Atom atomStr)) // bare atom
Beam.ErlExpr.Literal(Beam.ErlLiteral.AtomLit(Beam.Atom atomName)) // bare atom
else
Beam.ErlExpr.Tuple(
Beam.ErlExpr.Literal(Beam.ErlLiteral.AtomLit(Beam.Atom atomStr))
Beam.ErlExpr.Literal(Beam.ErlLiteral.AtomLit(Beam.Atom atomName))
:: (fieldVars |> List.map Beam.ErlExpr.Variable)
)

Expand Down
15 changes: 15 additions & 0 deletions tests/Beam/InteropTests.fs
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,7 @@ type RecvMsg =
| Ping
| [<CompiledName("custom_tag")>] CustomTag of value: int
| DataMsg of x: int * y: string
| [<CompiledName("EXIT")>] Exit of pid: int * reason: string

#endif

Expand Down Expand Up @@ -336,6 +337,20 @@ let ``test Erlang receive with multi-field DU case`` () =
()
#endif

[<Fact>]
let ``test Erlang receive with uppercase CompiledName atom tag`` () =
#if FABLE_COMPILER
// Send {'EXIT', 1, <<"normal">>} to self — uppercase atoms must be single-quoted
emitErlExpr () "erlang:self() ! {'EXIT', 1, <<\"normal\">>}"
match Erlang.receive<RecvMsg> 1000 with
| Some(Exit(pid, reason)) ->
equal 1 pid
equal "normal" reason
| _ -> equal 0 1 // fail
#else
()
#endif

[<Fact>]
let ``test Erlang receive blocking with self-send`` () =
#if FABLE_COMPILER
Expand Down
Loading