Skip to content

Commit 763cf17

Browse files
T-GroCopilot
andauthored
Fix #3939: Hide compiler-generated auto-property symbols from Symbols API (#19498)
* Fix #3939: Hide compiler-generated auto-property symbols from Symbols API Fixes #3939 Mark the compiler-generated `v` setter parameter and backing field identifiers in auto-property desugaring with synthetic ranges, so they are excluded from GetAllUsesOfAllSymbolsInFile(). Previously these internal symbols leaked through the API with empty EnclosingEntity and misleading DisplayName/CompiledName values. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Fix CI: update ProjectAnalysisTests to match synthetic auto-property symbols Remove compiler-generated auto-property backing fields and setter parameter 'v' from expected symbol arrays in 'Test Project24 all symbols' and 'Test symbol uses of properties with both getters and setters'. These symbols are now correctly hidden by MakeSynthetic() ranges. Also merge with latest main. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Bump FSBuildVersion to 101: packages 11.0.100 and 43.12.100 already published Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --------- Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
1 parent 2bd5398 commit 763cf17

3 files changed

Lines changed: 16 additions & 23 deletions

File tree

src/Compiler/Checking/CheckDeclarations.fs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4418,7 +4418,7 @@ module TcDeclarations =
44184418
// Only the keep the field-targeted attributes
44194419
let attribs = attribs |> List.filter (fun a -> match a.Target with Some t when t.idText = "field" -> true | _ -> false)
44204420
let mLetPortion = synExpr.Range
4421-
let fldId = ident (CompilerGeneratedName id.idText, mLetPortion)
4421+
let fldId = ident (CompilerGeneratedName id.idText, mLetPortion.MakeSynthetic())
44224422
let headPat = SynPat.LongIdent (SynLongIdent([fldId], [], [None]), None, Some noInferredTypars, SynArgPats.Pats [], None, mLetPortion)
44234423
let retInfo = match tyOpt with None -> None | Some ty -> Some (None, SynReturnInfo((ty, SynInfo.unnamedRetVal), ty.Range))
44244424
let isMutable =
@@ -4446,7 +4446,7 @@ module TcDeclarations =
44464446
let mMemberPortion = id.idRange
44474447
// Only the keep the non-field-targeted attributes
44484448
let attribs = attribs |> List.filter (fun a -> match a.Target with Some t when t.idText = "field" -> false | _ -> true)
4449-
let fldId = ident (CompilerGeneratedName id.idText, mMemberPortion)
4449+
let fldId = ident (CompilerGeneratedName id.idText, mMemberPortion.MakeSynthetic())
44504450
let headPatIds = if isStatic then [id] else [ident ("__", mMemberPortion);id]
44514451
let headPat = SynPat.LongIdent (SynLongIdent(headPatIds, [], List.replicate headPatIds.Length None), None, Some noInferredTypars, SynArgPats.Pats [], None, mMemberPortion)
44524452
let memberFlags = { memberFlags with GetterOrSetterIsCompilerGenerated = true }
@@ -4475,7 +4475,7 @@ module TcDeclarations =
44754475
| SynMemberKind.PropertySet
44764476
| SynMemberKind.PropertyGetSet ->
44774477
let setter =
4478-
let vId = ident("v", mMemberPortion)
4478+
let vId = ident("v", mMemberPortion.MakeSynthetic())
44794479
let headPat = SynPat.LongIdent (SynLongIdent(headPatIds, [], List.replicate headPatIds.Length None), None, Some noInferredTypars, SynArgPats.Pats [mkSynPatVar None vId], None, mMemberPortion)
44804480
let rhsExpr = mkSynAssign (SynExpr.Ident fldId) (SynExpr.Ident vId)
44814481
let binding = mkSynBinding (xmlDoc, headPat) (setterAccess, false, false, mMemberPortion, DebugPointAtBinding.NoneAtInvisible, None, rhsExpr, rhsExpr.Range, [], [], Some memberFlagsForSet, SynBindingTrivia.Zero)

tests/FSharp.Compiler.Service.Tests/ProjectAnalysisTests.fs

Lines changed: 0 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -3512,12 +3512,6 @@ let ``Test Project24 all symbols`` () =
35123512
("v", "file1", ((22, 17), (22, 18)), ["defn"], []);
35133513
("int", "file1", ((25, 21), (25, 24)), ["type"], ["abbrev"]);
35143514
("v", "file1", ((25, 18), (25, 19)), ["defn"], []);
3515-
("``AutoPropGet@``", "file1", ((27, 15), (27, 26)), [], ["compgen"]);
3516-
("``AutoPropGetSet@``", "file1", ((28, 15), (28, 29)), [], ["compgen"; "mutable"])
3517-
("v", "file1", ((28, 15), (28, 29)), ["defn"], []);
3518-
("``StaticAutoPropGet@``", "file1", ((30, 22), (30, 39)), [], ["compgen"]);
3519-
("``StaticAutoPropGetSet@``", "file1", ((31, 22), (31, 42)), [],
3520-
["compgen"; "mutable"]); ("v", "file1", ((31, 22), (31, 42)), ["defn"], []);
35213515
("``.cctor``", "file1", ((4, 5), (4, 23)), ["defn"], ["member"]);
35223516
("TypeWithProperties", "file1", ((33, 9), (33, 27)), [], ["member"; "ctor"]);
35233517
("NameGetSet", "file1", ((33, 9), (33, 40)), [], ["member"; "prop"]);
@@ -3614,12 +3608,6 @@ let ``Test symbol uses of properties with both getters and setters`` () =
36143608
("v", "file1", ((22, 17), (22, 18)), []);
36153609
("int", "file1", ((25, 21), (25, 24)), ["abbrev"]);
36163610
("v", "file1", ((25, 18), (25, 19)), []);
3617-
("``AutoPropGet@``", "file1", ((27, 15), (27, 26)), ["compgen"]);
3618-
("``AutoPropGetSet@``", "file1", ((28, 15), (28, 29)), ["compgen"; "mutable"]);
3619-
("v", "file1", ((28, 15), (28, 29)), []);
3620-
("``StaticAutoPropGet@``", "file1", ((30, 22), (30, 39)), ["compgen"]);
3621-
("``StaticAutoPropGetSet@``", "file1", ((31, 22), (31, 42)),
3622-
["compgen"; "mutable"]); ("v", "file1", ((31, 22), (31, 42)), []);
36233611
("``.cctor``", "file1", ((4, 5), (4, 23)), ["member"]);
36243612
("TypeWithProperties", "file1", ((33, 9), (33, 27)), ["member"; "ctor"]);
36253613
("NameGetSet", "file1", ((33, 9), (33, 40)), ["member"; "prop"]);

tests/FSharp.Compiler.Service.Tests/Symbols.fs

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -634,18 +634,23 @@ type Foo =
634634
Assert.True(setMfv.CompiledName.StartsWith("set_"))
635635
| _ -> failwith $"Expected three symbols, got %A{symbols}"
636636

637-
[<Fact(Skip = "Should not resolve the `v` name")>]
638-
let ``AutoProperty with get, set has property symbol 02`` () =
639-
let symbol = Checker.getSymbolUse """
637+
// https://github.com/dotnet/fsharp/issues/3939
638+
[<Fact>]
639+
let ``AutoProperty with get, set does not expose compiler-generated v symbol`` () =
640+
let _, checkResults = getParseAndCheckResults """
640641
namespace Foo
641642
642643
type Foo =
643-
member val AutoPropGetSet{caret} = 0 with get, set
644+
member val AutoPropGetSet = 0 with get, set
644645
"""
645-
// The setter should have a symbol for the generated parameter `v`.
646-
let setVMfv = symbol |> chooseMemberOrFunctionOrValue
647-
if Option.isNone setVMfv then
648-
failwith "No generated v symbol for the setter was found"
646+
let allSymbols = checkResults.GetAllUsesOfAllSymbolsInFile()
647+
let allMfvs = allSymbols |> Seq.choose (fun su -> match su.Symbol with :? FSharpMemberOrFunctionOrValue as mfv -> Some mfv | _ -> None) |> Seq.toList
648+
// The compiler-generated `v` setter parameter should NOT appear in symbol uses
649+
let vSymbols = allMfvs |> List.filter (fun mfv -> mfv.DisplayName = "v")
650+
Assert.True(vSymbols.IsEmpty, $"Compiler-generated 'v' symbol should not be exposed via GetAllUsesOfAllSymbolsInFile, but found {vSymbols.Length} occurrences")
651+
// The compiler-generated backing field should also not appear
652+
let backingFieldSymbols = allMfvs |> List.filter (fun mfv -> mfv.DisplayName.Contains("@"))
653+
Assert.True(backingFieldSymbols.IsEmpty, $"Compiler-generated backing field should not appear, but found: {backingFieldSymbols |> List.map (fun m -> m.DisplayName)}")
649654

650655
[<Fact>]
651656
let ``Property symbol is resolved for property`` () =

0 commit comments

Comments
 (0)