Skip to content

Commit 742449a

Browse files
authored
Implement langversion switch for openstaticclasses (#7195)
* Add langver support and tests for open static classes language feature * features flag * Feedback * neg tests do not yet work on coreclr
1 parent b6f0be9 commit 742449a

8 files changed

Lines changed: 260 additions & 83 deletions

File tree

src/fsharp/LanguageFeatures.fs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ type LanguageFeature =
2626
| RelaxWhitespace = 4
2727
| NameOf = 5
2828
| ImplicitYield = 6
29-
29+
| OpenStaticClasses = 7
3030

3131
/// LanguageVersion management
3232
type LanguageVersion (specifiedVersion) =
@@ -52,6 +52,7 @@ type LanguageVersion (specifiedVersion) =
5252
LanguageFeature.RelaxWhitespace, previewVersion
5353
LanguageFeature.NameOf, previewVersion
5454
LanguageFeature.ImplicitYield, previewVersion
55+
LanguageFeature.OpenStaticClasses, previewVersion
5556
|]
5657

5758
let specified =

src/fsharp/LanguageFeatures.fsi

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ type LanguageFeature =
1313
| RelaxWhitespace = 4
1414
| NameOf = 5
1515
| ImplicitYield = 6
16-
16+
| OpenStaticClasses = 7
1717

1818
/// LanguageVersion management
1919
type LanguageVersion =

src/fsharp/NameResolution.fs

Lines changed: 28 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -756,29 +756,33 @@ let AddUnionCases2 bulkAddMode (eUnqualifiedItems: UnqualifiedItems) (ucrefs: Un
756756
let item = Item.UnionCase(GeneralizeUnionCaseRef ucref, false)
757757
acc.Add (ucref.CaseName, item))
758758

759-
let AddStaticContentOfTyconRefToNameEnv (g:TcGlobals) (amap: Import.ImportMap) m (nenv: NameResolutionEnv) (tcref:TyconRef) =
760-
let ty = generalizedTyconRef tcref
761-
let infoReader = InfoReader(g,amap)
762-
let items =
763-
[| let methGroups =
764-
AllMethInfosOfTypeInScope ResultCollectionSettings.AllResults infoReader nenv None AccessorDomain.AccessibleFromSomeFSharpCode PreferOverrides m ty
765-
|> List.groupBy (fun m -> m.LogicalName)
766-
767-
for (methName, methGroup) in methGroups do
768-
let methGroup = methGroup |> List.filter (fun m -> not m.IsInstance && not m.IsClassConstructor)
769-
if not methGroup.IsEmpty then
770-
yield KeyValuePair(methName, Item.MethodGroup(methName, methGroup, None))
759+
let AddStaticContentOfTyconRefToNameEnv (g:TcGlobals) (amap: Import.ImportMap) m (nenv: NameResolutionEnv) (tcref:TyconRef) =
760+
// If OpenStaticClasses is not enabled then don't do this
761+
if amap.g.langVersion.SupportsFeature LanguageFeature.OpenStaticClasses then
762+
let ty = generalizedTyconRef tcref
763+
let infoReader = InfoReader(g,amap)
764+
let items =
765+
[| let methGroups =
766+
AllMethInfosOfTypeInScope ResultCollectionSettings.AllResults infoReader nenv None AccessorDomain.AccessibleFromSomeFSharpCode PreferOverrides m ty
767+
|> List.groupBy (fun m -> m.LogicalName)
768+
769+
for (methName, methGroup) in methGroups do
770+
let methGroup = methGroup |> List.filter (fun m -> not m.IsInstance && not m.IsClassConstructor)
771+
if not methGroup.IsEmpty then
772+
yield KeyValuePair(methName, Item.MethodGroup(methName, methGroup, None))
771773

772-
let propInfos =
773-
AllPropInfosOfTypeInScope ResultCollectionSettings.AllResults infoReader nenv None AccessorDomain.AccessibleFromSomeFSharpCode PreferOverrides m ty
774-
|> List.groupBy (fun m -> m.PropertyName)
774+
let propInfos =
775+
AllPropInfosOfTypeInScope ResultCollectionSettings.AllResults infoReader nenv None AccessorDomain.AccessibleFromSomeFSharpCode PreferOverrides m ty
776+
|> List.groupBy (fun m -> m.PropertyName)
775777

776-
for (propName, propInfos) in propInfos do
777-
let propInfos = propInfos |> List.filter (fun m -> m.IsStatic)
778-
for propInfo in propInfos do
779-
yield KeyValuePair(propName , Item.Property(propName,[propInfo])) |]
778+
for (propName, propInfos) in propInfos do
779+
let propInfos = propInfos |> List.filter (fun m -> m.IsStatic)
780+
for propInfo in propInfos do
781+
yield KeyValuePair(propName , Item.Property(propName,[propInfo])) |]
780782

781-
{ nenv with eUnqualifiedItems = nenv.eUnqualifiedItems.AddAndMarkAsCollapsible items }
783+
{ nenv with eUnqualifiedItems = nenv.eUnqualifiedItems.AddAndMarkAsCollapsible items }
784+
else
785+
nenv
782786

783787
/// Add any implied contents of a type definition to the environment.
784788
let private AddPartsOfTyconRefToNameEnv bulkAddMode ownDefinition (g: TcGlobals) amap m nenv (tcref: TyconRef) =
@@ -1992,7 +1996,10 @@ let CheckForTypeLegitimacyAndMultipleGenericTypeAmbiguities
19921996
//-------------------------------------------------------------------------
19931997

19941998
/// Perform name resolution for an identifier which must resolve to be a namespace or module.
1995-
let rec ResolveLongIndentAsModuleOrNamespaceOrStaticClass sink (atMostOne: ResultCollectionSettings) amap m allowStaticClasses first fullyQualified (nenv: NameResolutionEnv) ad (id:Ident) (rest: Ident list) isOpenDecl =
1999+
let rec ResolveLongIndentAsModuleOrNamespaceOrStaticClass sink (atMostOne: ResultCollectionSettings) (amap: Import.ImportMap) m allowStaticClasses first fullyQualified (nenv: NameResolutionEnv) ad (id:Ident) (rest: Ident list) isOpenDecl =
2000+
2001+
// If the selected language version doesn't support open static classes then turn them off.
2002+
let allowStaticClasses = allowStaticClasses && amap.g.langVersion.SupportsFeature LanguageFeature.OpenStaticClasses
19962003
if first && id.idText = MangledGlobalName then
19972004
match rest with
19982005
| [] ->

tests/fsharp/core/longnames/test.fsx

Lines changed: 0 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -688,66 +688,6 @@ module rec Ok23 =
688688

689689
test "lkneecec09iew23" (typeof<A.Dummy>.FullName.Contains("AModule") )
690690

691-
692-
[<AbstractClass; Sealed>]
693-
type MyMath() =
694-
static member Min(a: double, b: double) = System.Math.Min(a, b)
695-
static member Min(a: int, b: int) = System.Math.Min(a, b)
696-
697-
[<AbstractClass; Sealed; AutoOpen>]
698-
type AutoOpenMyMath() =
699-
static member AutoMin(a: double, b: double) = System.Math.Min(a, b)
700-
static member AutoMin(a: int, b: int) = System.Math.Min(a, b)
701-
702-
[<AbstractClass; Sealed; RequireQualifiedAccess>]
703-
type NotAllowedToOpen() =
704-
static member QualifiedMin(a: double, b: double) = System.Math.Min(a, b)
705-
static member QualifiedMin(a: int, b: int) = System.Math.Min(a, b)
706-
707-
module OpenSystemMathOnce =
708-
709-
open System.Math
710-
let x = Min(1.0, 2.0)
711-
test "vwejhweoiu" (x = 1.0)
712-
713-
714-
module OpenSystemMathTwice =
715-
716-
open System.Math
717-
let x = Min(1.0, 2.0)
718-
719-
open System.Math
720-
let x2 = Min(2.0, 1.0)
721-
722-
test "vwejhweoiu2" (x2 = 1.0)
723-
724-
module OpenMyMathOnce =
725-
726-
open MyMath
727-
let x = Min(1.0, 2.0)
728-
let x2 = Min(1, 2)
729-
730-
test "vwejhweoiu2" (x = 1.0)
731-
test "vwejhweoiu3" (x2 = 1)
732-
733-
module DontOpenAutoMath =
734-
735-
let x = AutoMin(1.0, 2.0)
736-
let x2 = AutoMin(1, 2)
737-
738-
test "vwejhweoiu2" (x = 1.0)
739-
test "vwejhweoiu3" (x2 = 1)
740-
741-
module OpenAutoMath =
742-
open AutoOpenMyMath
743-
//open NotAllowedToOpen
744-
745-
let x = AutoMin(1.0, 2.0)
746-
let x2 = AutoMin(1, 2)
747-
748-
test "vwejhweoiu2" (x = 1.0)
749-
test "vwejhweoiu3" (x2 = 1)
750-
751691
#if TESTS_AS_APP
752692
let RUN() = !failures
753693
#else

tests/fsharp/core/longnames/version46/test.bsl

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
2+
test.fs(34,17,34,21): typecheck error FS0039: The namespace 'Math' is not defined.
3+
4+
test.fs(35,13,35,16): typecheck error FS0039: The value or constructor 'Min' is not defined. Maybe you want one of the following:
5+
min
6+
sin
7+
8+
test.fs(41,17,41,21): typecheck error FS0039: The namespace 'Math' is not defined.
9+
10+
test.fs(42,13,42,16): typecheck error FS0039: The value or constructor 'Min' is not defined. Maybe you want one of the following:
11+
min
12+
sin
13+
14+
test.fs(44,17,44,21): typecheck error FS0039: The namespace 'Math' is not defined.
15+
16+
test.fs(45,14,45,17): typecheck error FS0039: The value or constructor 'Min' is not defined. Maybe you want one of the following:
17+
min
18+
sin
19+
20+
test.fs(51,10,51,16): typecheck error FS0039: The namespace or module 'MyMath' is not defined. Maybe you want one of the following:
21+
Math
22+
23+
test.fs(52,13,52,16): typecheck error FS0039: The value or constructor 'Min' is not defined. Maybe you want one of the following:
24+
min
25+
sin
26+
27+
test.fs(53,14,53,17): typecheck error FS0039: The value or constructor 'Min' is not defined. Maybe you want one of the following:
28+
min
29+
sin
30+
31+
test.fs(60,13,60,20): typecheck error FS0039: The value or constructor 'AutoMin' is not defined.
32+
33+
test.fs(61,14,61,21): typecheck error FS0039: The value or constructor 'AutoMin' is not defined.
34+
35+
test.fs(67,10,67,24): typecheck error FS0039: The namespace or module 'AutoOpenMyMath' is not defined.
36+
37+
test.fs(70,13,70,20): typecheck error FS0039: The value or constructor 'AutoMin' is not defined.
38+
39+
test.fs(71,14,71,21): typecheck error FS0039: The value or constructor 'AutoMin' is not defined.
Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
module Core_longnames
2+
let failures = ref []
3+
4+
let report_failure (s : string) =
5+
stderr.Write" NO: "
6+
stderr.WriteLine s
7+
failures := !failures @ [s]
8+
9+
let test (s : string) b =
10+
stderr.Write(s)
11+
if b then stderr.WriteLine " OK"
12+
else report_failure (s)
13+
14+
let check s b1 b2 = test s (b1 = b2)
15+
16+
(* Some test expressions *)
17+
[<AbstractClass; Sealed>]
18+
type MyMath() =
19+
static member Min(a: double, b: double) = System.Math.Min(a, b)
20+
static member Min(a: int, b: int) = System.Math.Min(a, b)
21+
22+
[<AbstractClass; Sealed; AutoOpen>]
23+
type AutoOpenMyMath() =
24+
static member AutoMin(a: double, b: double) = System.Math.Min(a, b)
25+
static member AutoMin(a: int, b: int) = System.Math.Min(a, b)
26+
27+
[<AbstractClass; Sealed; RequireQualifiedAccess>]
28+
type NotAllowedToOpen() =
29+
static member QualifiedMin(a: double, b: double) = System.Math.Min(a, b)
30+
static member QualifiedMin(a: int, b: int) = System.Math.Min(a, b)
31+
32+
module OpenSystemMathOnce =
33+
34+
open System.Math
35+
let x = Min(1.0, 2.0)
36+
test "vwejhweoiu" (x = 1.0)
37+
38+
39+
module OpenSystemMathTwice =
40+
41+
open System.Math
42+
let x = Min(1.0, 2.0)
43+
44+
open System.Math
45+
let x2 = Min(2.0, 1.0)
46+
47+
test "vwejhweoiu2" (x2 = 1.0)
48+
49+
module OpenMyMathOnce =
50+
51+
open MyMath
52+
let x = Min(1.0, 2.0)
53+
let x2 = Min(1, 2)
54+
55+
test "vwejhweoiu2" (x = 1.0)
56+
test "vwejhweoiu3" (x2 = 1)
57+
58+
module DontOpenAutoMath =
59+
60+
let x = AutoMin(1.0, 2.0)
61+
let x2 = AutoMin(1, 2)
62+
63+
test "vwejhweoiu2" (x = 1.0)
64+
test "vwejhweoiu3" (x2 = 1)
65+
66+
module OpenAutoMath =
67+
open AutoOpenMyMath
68+
//open NotAllowedToOpen
69+
70+
let x = AutoMin(1.0, 2.0)
71+
let x2 = AutoMin(1, 2)
72+
73+
test "vwejhweoiu2" (x = 1.0)
74+
test "vwejhweoiu3" (x2 = 1)
75+
76+
let RUN() =
77+
match !failures with
78+
| [] ->
79+
stdout.WriteLine "Test Passed"
80+
System.IO.File.WriteAllText("test.ok","ok")
81+
exit 0
82+
| _ ->
83+
stdout.WriteLine "Test Failed"
84+
exit 1
Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
// #Conformance #ObjectConstructors
2+
#if TESTS_AS_APP
3+
module Core_longnames
4+
#endif
5+
let failures = ref []
6+
7+
let report_failure (s : string) =
8+
stderr.Write" NO: "
9+
stderr.WriteLine s
10+
failures := !failures @ [s]
11+
12+
let test (s : string) b =
13+
stderr.Write(s)
14+
if b then stderr.WriteLine " OK"
15+
else report_failure (s)
16+
17+
let check s b1 b2 = test s (b1 = b2)
18+
19+
(* Some test expressions *)
20+
[<AbstractClass; Sealed>]
21+
type MyMath() =
22+
static member Min(a: double, b: double) = System.Math.Min(a, b)
23+
static member Min(a: int, b: int) = System.Math.Min(a, b)
24+
25+
[<AbstractClass; Sealed; AutoOpen>]
26+
type AutoOpenMyMath() =
27+
static member AutoMin(a: double, b: double) = System.Math.Min(a, b)
28+
static member AutoMin(a: int, b: int) = System.Math.Min(a, b)
29+
30+
[<AbstractClass; Sealed; RequireQualifiedAccess>]
31+
type NotAllowedToOpen() =
32+
static member QualifiedMin(a: double, b: double) = System.Math.Min(a, b)
33+
static member QualifiedMin(a: int, b: int) = System.Math.Min(a, b)
34+
35+
module OpenSystemMathOnce =
36+
37+
open System.Math
38+
let x = Min(1.0, 2.0)
39+
test "vwejhweoiu" (x = 1.0)
40+
41+
42+
module OpenSystemMathTwice =
43+
44+
open System.Math
45+
let x = Min(1.0, 2.0)
46+
47+
open System.Math
48+
let x2 = Min(2.0, 1.0)
49+
50+
test "vwejhweoiu2" (x2 = 1.0)
51+
52+
module OpenMyMathOnce =
53+
54+
open MyMath
55+
let x = Min(1.0, 2.0)
56+
let x2 = Min(1, 2)
57+
58+
test "vwejhweoiu2" (x = 1.0)
59+
test "vwejhweoiu3" (x2 = 1)
60+
61+
module DontOpenAutoMath =
62+
63+
let x = AutoMin(1.0, 2.0)
64+
let x2 = AutoMin(1, 2)
65+
66+
test "vwejhweoiu2" (x = 1.0)
67+
test "vwejhweoiu3" (x2 = 1)
68+
69+
module OpenAutoMath =
70+
open AutoOpenMyMath
71+
//open NotAllowedToOpen
72+
73+
let x = AutoMin(1.0, 2.0)
74+
let x2 = AutoMin(1, 2)
75+
76+
test "vwejhweoiu2" (x = 1.0)
77+
test "vwejhweoiu3" (x2 = 1)
78+
79+
#if TESTS_AS_APP
80+
let RUN() = !failures
81+
#else
82+
let aa =
83+
match !failures with
84+
| [] ->
85+
stdout.WriteLine "Test Passed"
86+
System.IO.File.WriteAllText("test.ok","ok")
87+
exit 0
88+
| _ ->
89+
stdout.WriteLine "Test Failed"
90+
exit 1
91+
#endif

tests/fsharp/tests.fs

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1302,6 +1302,21 @@ module CoreTests =
13021302
[<Test>]
13031303
let ``longnames-FSI_BASIC`` () = singleTestBuildAndRun "core/longnames" FSI_BASIC
13041304

1305+
#if !FSHARP_SUITE_DRIVES_CORECLR_TESTS
1306+
[<Test>]
1307+
let ``longnames-version46`` () =
1308+
let cfg = testConfig "core/longnames/version46"
1309+
// For some reason this warning is off by default in the test framework but in this case we are testing for it
1310+
let cfg = { cfg with fsc_flags = cfg.fsc_flags.Replace("--nowarn:20", "") }
1311+
singleVersionedNegTest cfg "4.6" "test"
1312+
#endif
1313+
1314+
[<Test>]
1315+
let ``longnames-version47-FSC_BASIC`` () = singleTestBuildAndRunVersion "core/longnames/version47" FSC_BASIC "preview"
1316+
1317+
[<Test>]
1318+
let ``longnames-version47-FSI_BASIC`` () = singleTestBuildAndRunVersion "core/longnames/version47" FSI_BASIC "preview"
1319+
13051320
[<Test>]
13061321
let ``math-numbersVS2008-FSC_BASIC`` () = singleTestBuildAndRun "core/math/numbersVS2008" FSC_BASIC
13071322

0 commit comments

Comments
 (0)