Skip to content

Commit e98cf5e

Browse files
authored
[JS/TS] Don't generate the setter code if a property is decorated with [<Erase>] (#3997)
Fix #3948
1 parent b4eb58f commit e98cf5e

File tree

7 files changed

+67
-1
lines changed

7 files changed

+67
-1
lines changed

src/Fable.Cli/CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
1212
* [TS] Make discriminated union `.Is*` properties works (@MangelMaxime)
1313
* [JS/TS/Python] Fix `h` in `DateTime.ToString` (@MangelMaxime)
1414
* [JS/TS] Fix `hh` in `DateTime.ToString` (@MangelMaxime)
15+
* [JS/TS] Don't generate the setter code if a property is decorated with `[<Erase>]` (@MangelMaxime)
1516

1617
## 5.0.0-alpha.3 - 2024-12-18
1718

src/Fable.Transforms/FSharp2Fable.fs

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1899,6 +1899,22 @@ let private transformMemberDecl
18991899
UsedNamesInDeclarationScope = HashSet()
19001900
}
19011901

1902+
let isErasedPropertySetter (memb: FSharpMemberOrFunctionOrValue) =
1903+
if memb.IsPropertySetterMethod then
1904+
match memb.DeclaringEntity with
1905+
| Some ent ->
1906+
// Remove the "set_" prefix
1907+
let logicalName = memb.LogicalName.Substring(4)
1908+
1909+
ent.MembersFunctionsAndValues
1910+
|> Seq.tryFind (fun (m: FSharpMemberOrFunctionOrValue) ->
1911+
m.LogicalName = logicalName && hasAttrib Atts.erase m.Attributes
1912+
)
1913+
|> Option.isSome
1914+
| _ -> false
1915+
else
1916+
false
1917+
19021918
if isIgnoredNonAttachedMember memb then
19031919
if memb.IsMutable && isNotPrivate memb && hasAttrib Atts.global_ memb.Attributes then
19041920
"Global members cannot be mutable and public, please make it private: "
@@ -1921,7 +1937,11 @@ let private transformMemberDecl
19211937
elif isCompilerGenerated memb args then
19221938
[]
19231939
// Ignore members that are decorated with [<Erase>]
1924-
elif hasAttrib Atts.erase memb.Attributes then
1940+
elif
1941+
hasAttrib Atts.erase memb.Attributes || isErasedPropertySetter memb
1942+
// Attributes are not universally propagated so for setter properties we need
1943+
// to check the declaring entity, https://github.com/fable-compiler/Fable/issues/3948
1944+
then
19251945
[]
19261946
elif memb.IsOverrideOrExplicitInterfaceImplementation then
19271947
if not memb.IsCompilerGenerated then
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
module ErasedProperty
2+
3+
open Fable.Core
4+
5+
6+
// This test is to make sure that we are retrieving the Erase attribute from the erased property
7+
// and not the declaring type
8+
9+
type internal LanguageInjectionAttribute() =
10+
11+
[<Erase>]
12+
member val Prefix = "" with get, set
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
import { class_type } from "./fable_modules/fable-library-js.5.0.0-alpha.3/Reflection.js";
2+
3+
export class LanguageInjectionAttribute {
4+
constructor() {
5+
this["Prefix@"] = "";
6+
}
7+
}
8+
9+
export function LanguageInjectionAttribute_$reflection() {
10+
return class_type("ErasedProperty.LanguageInjectionAttribute", undefined, LanguageInjectionAttribute);
11+
}
12+
13+
export function LanguageInjectionAttribute_$ctor() {
14+
return new LanguageInjectionAttribute();
15+
}
16+
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
module ErasedTypeWithProperty
2+
3+
open Fable.Core
4+
5+
[<Erase>]
6+
type internal LanguageInjectionAttribute() =
7+
8+
[<Erase>]
9+
member val Prefix = "" with get, set
10+
11+
// Force Fable to generate a file, otherwise because everything is erased, it will not generate anything
12+
let a = 0
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
2+
export const a = 0;
3+

tests/Integration/Integration/data/eraseAttribute/eraseAttribute.fsproj

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@
88

99
<ItemGroup>
1010
<Compile Include="Members.fs" />
11+
<Compile Include="ErasedTypeWithProperty.fs" />
12+
<Compile Include="ErasedProperty.fs" />
1113
</ItemGroup>
1214

1315
<ItemGroup>

0 commit comments

Comments
 (0)