Skip to content

Commit b88ba3c

Browse files
committed
Update for fix8351
1 parent b024d51 commit b88ba3c

6 files changed

Lines changed: 248 additions & 80 deletions

File tree

src/absil/il.fs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1243,12 +1243,12 @@ type ILMethodBody =
12431243

12441244
[<RequireQualifiedAccess>]
12451245
type ILMemberAccess =
1246+
| Assembly
12461247
| CompilerControlled
1248+
| FamilyAndAssembly
1249+
| FamilyOrAssembly
1250+
| Family
12471251
| Private
1248-
| FamilyAndAssembly // protected and internal
1249-
| Family // protected
1250-
| Assembly // internal
1251-
| FamilyOrAssembly // protected or internal
12521252
| Public
12531253

12541254
[<RequireQualifiedAccess; StructuralEquality; StructuralComparison>]

src/absil/il.fsi

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -727,17 +727,16 @@ type ILMethodBody =
727727
SourceMarker: ILSourceMarker option }
728728

729729
/// Member Access
730-
// important: order of definition matters for AccessibilityLogic.GetILAccessOfILPropInfo
731730
[<RequireQualifiedAccess>]
732731
type ILMemberAccess =
732+
| Assembly
733733
| CompilerControlled
734-
| Private
735-
| FamilyAndAssembly // protected and internal
736-
| Family // protected
737-
| Assembly // internal
738-
| FamilyOrAssembly // protected or internal
739-
| Public
740-
734+
| FamilyAndAssembly
735+
| FamilyOrAssembly
736+
| Family
737+
| Private
738+
| Public
739+
741740
[<RequireQualifiedAccess>]
742741
type ILAttribElem =
743742
/// Represents a custom attribute parameter of type 'string'. These may be null, in which case they are encoded in a special

src/fsharp/AccessibilityLogic.fs

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -252,12 +252,32 @@ let GetILAccessOfILPropInfo (ILPropInfo(tinfo, pdef)) =
252252
match pdef.GetMethod, pdef.SetMethod with
253253
| Some mref, None
254254
| None, Some mref -> (resolveILMethodRef tdef mref).Access
255+
255256
| Some mrefGet, Some mrefSet ->
256257
let getA = (resolveILMethodRef tdef mrefGet).Access
257258
let setA = (resolveILMethodRef tdef mrefSet).Access
258-
// pick most accessible
259-
max getA setA
259+
260+
// use the accessors to determine the visibility of the property
261+
match getA, setA with
262+
| ILMemberAccess.Public, _
263+
| _, ILMemberAccess.Public -> ILMemberAccess.Public
264+
265+
| ILMemberAccess.FamilyOrAssembly, _
266+
| _, ILMemberAccess.FamilyOrAssembly -> ILMemberAccess.FamilyOrAssembly
267+
268+
| ILMemberAccess.Assembly, _
269+
| _, ILMemberAccess.Assembly -> ILMemberAccess.Assembly
270+
271+
| ILMemberAccess.Family, _
272+
| _, ILMemberAccess.Family -> ILMemberAccess.Family
273+
274+
| ILMemberAccess.FamilyAndAssembly, _
275+
| _, ILMemberAccess.FamilyAndAssembly -> ILMemberAccess.FamilyAndAssembly
276+
277+
| _ -> ILMemberAccess.Private
278+
260279
| None, None -> ILMemberAccess.Public
280+
261281
ilAccess
262282

263283
let IsILPropInfoAccessible g amap m ad pinfo =
Lines changed: 214 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,214 @@
1+
// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information.
2+
3+
namespace FSharp.Compiler.UnitTests
4+
5+
open FSharp.Compiler.SourceCodeServices
6+
open FSharp.Reflection
7+
open FSharp.TestHelpers
8+
open FSharp.TestHelpers.Utilities
9+
open NUnit.Framework
10+
11+
[<TestFixture>]
12+
module ILMemberAccessTests =
13+
14+
let csharpBaseClass = """
15+
namespace ExhaustiveCombinations
16+
{
17+
public class CSharpBaseClass
18+
{
19+
public string GetPublicSetInternal { get; internal set; }
20+
public string GetPublicSetProtected { get; protected set; }
21+
public string GetPublicSetPrivateProtected { get; private protected set; }
22+
public string GetPublicSetProtectedInternal { get; protected internal set; }
23+
public string GetPublicSetPrivate { get; private set; }
24+
25+
public string SetPublicGetInternal { internal get; set; }
26+
public string SetPublicGetProtected { protected get; set; }
27+
public string SetPublicGetPrivateProtected { private protected get; set; }
28+
public string SetPublicGetProtectedInternal { protected internal get; set; }
29+
public string SetPublicGetPrivate { private get; set; }
30+
}
31+
}
32+
"""
33+
34+
let fsharpBaseClass = """
35+
namespace ExhaustiveCombinations
36+
37+
open System
38+
39+
type FSharpBaseClass () =
40+
41+
member this.GetPublicSetInternal with public get() = "" and internal set (parameter:string) = ignore parameter
42+
member this.GetPublicSetPrivate with public get() = "" and private set (parameter:string) = ignore parameter
43+
member this.SetPublicGetInternal with internal get() = "" and public set (parameter:string) = ignore parameter
44+
member this.SetPublicGetPrivate with private get() = "" and public set (parameter:string) = ignore parameter
45+
46+
"""
47+
48+
49+
[<Test>]
50+
let ``VerifyVisibility of Properties C# class F# derived class -- AccessPublicStuff`` () =
51+
52+
let fsharpSource =
53+
fsharpBaseClass + """
54+
open System
55+
open ExhaustiveCombinations
56+
57+
type MyFSharpClass () =
58+
inherit CSharpBaseClass()
59+
60+
member this.AccessPublicStuff() =
61+
62+
this.GetPublicSetInternal <- "1" // Inaccessible
63+
let _ = this.GetPublicSetInternal // Accessible
64+
65+
this.GetPublicSetPrivateProtected <- "1" // Accessible
66+
let _ = this.GetPublicSetPrivateProtected // Accessible
67+
68+
this.GetPublicSetProtectedInternal <- "1" // Accessible
69+
let _ = this.GetPublicSetProtectedInternal // Accessible
70+
71+
this.GetPublicSetProtected <- "1" // Accessible
72+
let _ = this.GetPublicSetProtected // Accessible
73+
74+
this.GetPublicSetPrivate <- "1" // Inaccessible
75+
let _ = this.GetPublicSetPrivate // Accessible
76+
()
77+
"""
78+
79+
let csCmpl =
80+
CompilationUtil.CreateCSharpCompilation(csharpBaseClass, CSharpLanguageVersion.CSharp8, TargetFramework.NetCoreApp30)
81+
|> CompilationReference.Create
82+
83+
let fsCmpl =
84+
Compilation.Create(fsharpSource, Fsx, Exe, options = [|"--langversion:preview"|], cmplRefs = [csCmpl])
85+
86+
CompilerAssert.CompileWithErrors(fsCmpl, [|
87+
(FSharpErrorSeverity.Error, 491, (22, 9, 22, 41),
88+
"The member or object constructor 'GetPublicSetInternal' is not accessible. Private members may only be accessed from within the declaring type. Protected members may only be accessed from an extending type and cannot be accessed from inner lambda expressions.");
89+
(FSharpErrorSeverity.Error, 491, (25, 9, 25, 49),
90+
"The member or object constructor 'GetPublicSetPrivateProtected' is not accessible. Private members may only be accessed from within the declaring type. Protected members may only be accessed from an extending type and cannot be accessed from inner lambda expressions.");
91+
(FSharpErrorSeverity.Error, 491, (34, 9, 34, 40),
92+
"The member or object constructor 'GetPublicSetPrivate' is not accessible. Private members may only be accessed from within the declaring type. Protected members may only be accessed from an extending type and cannot be accessed from inner lambda expressions.")|])
93+
94+
[<Test>]
95+
let ``VerifyVisibility of Properties C# class F# non-derived class -- AccessPublicStuff`` () =
96+
97+
let fsharpSource =
98+
fsharpBaseClass + """
99+
open System
100+
open ExhaustiveCombinations
101+
102+
type MyFSharpClass () =
103+
104+
member _.AccessPublicStuff() =
105+
let bc = new CSharpBaseClass()
106+
107+
bc.GetPublicSetInternal <- "1" // Inaccessible
108+
let _ = bc.GetPublicSetInternal // Accessible
109+
110+
bc.GetPublicSetPrivateProtected <- "1" // Inaccessible
111+
let _ = bc.GetPublicSetPrivateProtected // Accessible
112+
113+
bc.GetPublicSetProtectedInternal <- "1" // Accessible
114+
let _ = bc.GetPublicSetProtectedInternal // Inaccessible
115+
116+
bc.GetPublicSetProtected <- "1" // Inaccessible
117+
let _ = bc.SetPublicGetProtected // Accessible
118+
119+
bc.GetPublicSetPrivate <- "1" // Inaccessible
120+
let _ = bc.GetPublicSetPrivate // Accessible
121+
()
122+
"""
123+
124+
let csCmpl =
125+
CompilationUtil.CreateCSharpCompilation(csharpBaseClass, CSharpLanguageVersion.CSharp8, TargetFramework.NetCoreApp30)
126+
|> CompilationReference.Create
127+
128+
let fsCmpl =
129+
Compilation.Create(fsharpSource, Fsx, Exe, options = [|"--langversion:preview"|], cmplRefs = [csCmpl])
130+
131+
CompilerAssert.CompileWithErrors(fsCmpl, [|
132+
(FSharpErrorSeverity.Error, 491, (22, 9, 22, 39),
133+
"The member or object constructor 'GetPublicSetInternal' is not accessible. Private members may only be accessed from within the declaring type. Protected members may only be accessed from an extending type and cannot be accessed from inner lambda expressions.");
134+
(FSharpErrorSeverity.Error, 491, (25, 9, 25, 47),
135+
"The member or object constructor 'GetPublicSetPrivateProtected' is not accessible. Private members may only be accessed from within the declaring type. Protected members may only be accessed from an extending type and cannot be accessed from inner lambda expressions.");
136+
(FSharpErrorSeverity.Error, 491, (28, 9, 28, 48),
137+
"The member or object constructor 'GetPublicSetProtectedInternal' is not accessible. Private members may only be accessed from within the declaring type. Protected members may only be accessed from an extending type and cannot be accessed from inner lambda expressions.");
138+
(FSharpErrorSeverity.Error, 491, (31, 9, 31, 40),
139+
"The member or object constructor 'GetPublicSetProtected' is not accessible. Private members may only be accessed from within the declaring type. Protected members may only be accessed from an extending type and cannot be accessed from inner lambda expressions.");
140+
(FSharpErrorSeverity.Error, 491, (32, 17, 32, 41),
141+
"The member or object constructor 'SetPublicGetProtected' is not accessible. Private members may only be accessed from within the declaring type. Protected members may only be accessed from an extending type and cannot be accessed from inner lambda expressions.");
142+
(FSharpErrorSeverity.Error, 491, (34, 9, 34, 38),
143+
"The member or object constructor 'GetPublicSetPrivate' is not accessible. Private members may only be accessed from within the declaring type. Protected members may only be accessed from an extending type and cannot be accessed from inner lambda expressions.")|])
144+
145+
146+
[<Test>]
147+
let ``VerifyVisibility of Properties F# base F# derived class -- AccessPublicStuff`` () =
148+
149+
let fsharpSource =
150+
fsharpBaseClass + """
151+
open System
152+
open ExhaustiveCombinations
153+
154+
type MyFSharpClass () =
155+
inherit FSharpBaseClass()
156+
157+
member this.AccessPublicStuff() =
158+
159+
this.GetPublicSetInternal <- "1" // Inaccessible
160+
let _ = this.GetPublicSetInternal // Accessible
161+
162+
this.GetPublicSetPrivate <- "1" // Inaccessible
163+
let _ = this.GetPublicSetPrivate // Accessible
164+
()
165+
"""
166+
167+
let csCmpl =
168+
CompilationUtil.CreateCSharpCompilation(csharpBaseClass, CSharpLanguageVersion.CSharp8, TargetFramework.NetCoreApp30)
169+
|> CompilationReference.Create
170+
171+
let fsCmpl =
172+
Compilation.Create(fsharpSource, Fsx, Exe, options = [|"--langversion:preview"|], cmplRefs = [csCmpl])
173+
174+
CompilerAssert.CompileWithErrors(fsCmpl, [|
175+
(FSharpErrorSeverity.Error, 810, (25, 9, 25, 33),
176+
"Property 'GetPublicSetPrivate' cannot be set")
177+
|])
178+
179+
180+
[<Test>]
181+
let ``VerifyVisibility of Properties F# class F# non-derived class -- AccessPublicStuff`` () =
182+
183+
let fsharpSource =
184+
fsharpBaseClass + """
185+
open System
186+
open ExhaustiveCombinations
187+
188+
type MyFSharpClass () =
189+
190+
member _.AccessPublicStuff() =
191+
let bc = new FSharpBaseClass()
192+
193+
bc.GetPublicSetInternal <- "1" // Inaccessible
194+
let _ = bc.GetPublicSetInternal // Accessible
195+
196+
bc.GetPublicSetPrivate <- "1" // Inaccessible
197+
let _ = bc.GetPublicSetPrivate // Accessible
198+
()
199+
"""
200+
201+
let csCmpl =
202+
CompilationUtil.CreateCSharpCompilation(csharpBaseClass, CSharpLanguageVersion.CSharp8, TargetFramework.NetCoreApp30)
203+
|> CompilationReference.Create
204+
205+
let fsCmpl =
206+
Compilation.Create(fsharpSource, Fsx, Exe, options = [|"--langversion:preview"|], cmplRefs = [csCmpl])
207+
208+
CompilerAssert.CompileWithErrors(fsCmpl, [|
209+
(FSharpErrorSeverity.Error, 810, (25, 9, 25, 31),
210+
"Property 'GetPublicSetPrivate' cannot be set")|])
211+
212+
213+
214+
// Todo: Repeat these tests with a seperate F# assembly

tests/fsharp/Compiler/ILMemberAccessTests.fs

Lines changed: 0 additions & 65 deletions
This file was deleted.

tests/fsharp/FSharpSuite.Tests.fsproj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,14 +27,14 @@
2727
<Compile Include="single-test.fs" />
2828
<Compile Include="TypeProviderTests.fs" />
2929
<Compile Include="tests.fs" />
30-
<Compile Include="Compiler\ILMemberAccessTests.fs" />
3130
<Compile Include="Compiler\CodeGen\EmittedIL\StaticMember.fs" />
3231
<Compile Include="Compiler\CodeGen\EmittedIL\StaticLinkTests.fs" />
3332
<Compile Include="Compiler\CodeGen\EmittedIL\LiteralValue.fs" />
3433
<Compile Include="Compiler\CodeGen\EmittedIL\Mutation.fs" />
3534
<Compile Include="Compiler\CodeGen\EmittedIL\TailCalls.fs" />
3635
<Compile Include="Compiler\Conformance\DataExpressions\ComputationExpressions.fs" />
3736
<Compile Include="Compiler\Conformance\BasicGrammarElements\BasicConstants.fs" />
37+
<Compile Include="Compiler\Conformance\Properties\ILMemberAccessTests.fs" />
3838
<Compile Include="Compiler\ErrorMessages\ConstructorTests.fs" />
3939
<Compile Include="Compiler\ErrorMessages\ClassesTests.fs" />
4040
<Compile Include="Compiler\ErrorMessages\AccessOfTypeAbbreviationTests.fs" />

0 commit comments

Comments
 (0)