diff --git a/src/fsharp/LanguageFeatures.fs b/src/fsharp/LanguageFeatures.fs index a88ebdcf9a1..5d426516093 100644 --- a/src/fsharp/LanguageFeatures.fs +++ b/src/fsharp/LanguageFeatures.fs @@ -26,7 +26,7 @@ type LanguageFeature = | RelaxWhitespace = 4 | NameOf = 5 | ImplicitYield = 6 - + | OpenStaticClasses = 7 /// LanguageVersion management type LanguageVersion (specifiedVersion) = @@ -52,6 +52,7 @@ type LanguageVersion (specifiedVersion) = LanguageFeature.RelaxWhitespace, previewVersion LanguageFeature.NameOf, previewVersion LanguageFeature.ImplicitYield, previewVersion + LanguageFeature.OpenStaticClasses, previewVersion |] let specified = diff --git a/src/fsharp/LanguageFeatures.fsi b/src/fsharp/LanguageFeatures.fsi index 44eb178840b..2dd2aaef62f 100644 --- a/src/fsharp/LanguageFeatures.fsi +++ b/src/fsharp/LanguageFeatures.fsi @@ -13,7 +13,7 @@ type LanguageFeature = | RelaxWhitespace = 4 | NameOf = 5 | ImplicitYield = 6 - + | OpenStaticClasses = 7 /// LanguageVersion management type LanguageVersion = diff --git a/src/fsharp/NameResolution.fs b/src/fsharp/NameResolution.fs index 06cade8922d..af800ac659d 100644 --- a/src/fsharp/NameResolution.fs +++ b/src/fsharp/NameResolution.fs @@ -756,29 +756,33 @@ let AddUnionCases2 bulkAddMode (eUnqualifiedItems: UnqualifiedItems) (ucrefs: Un let item = Item.UnionCase(GeneralizeUnionCaseRef ucref, false) acc.Add (ucref.CaseName, item)) -let AddStaticContentOfTyconRefToNameEnv (g:TcGlobals) (amap: Import.ImportMap) m (nenv: NameResolutionEnv) (tcref:TyconRef) = - let ty = generalizedTyconRef tcref - let infoReader = InfoReader(g,amap) - let items = - [| let methGroups = - AllMethInfosOfTypeInScope ResultCollectionSettings.AllResults infoReader nenv None AccessorDomain.AccessibleFromSomeFSharpCode PreferOverrides m ty - |> List.groupBy (fun m -> m.LogicalName) - - for (methName, methGroup) in methGroups do - let methGroup = methGroup |> List.filter (fun m -> not m.IsInstance && not m.IsClassConstructor) - if not methGroup.IsEmpty then - yield KeyValuePair(methName, Item.MethodGroup(methName, methGroup, None)) +let AddStaticContentOfTyconRefToNameEnv (g:TcGlobals) (amap: Import.ImportMap) m (nenv: NameResolutionEnv) (tcref:TyconRef) = + // If OpenStaticClasses is not enabled then don't do this + if amap.g.langVersion.SupportsFeature LanguageFeature.OpenStaticClasses then + let ty = generalizedTyconRef tcref + let infoReader = InfoReader(g,amap) + let items = + [| let methGroups = + AllMethInfosOfTypeInScope ResultCollectionSettings.AllResults infoReader nenv None AccessorDomain.AccessibleFromSomeFSharpCode PreferOverrides m ty + |> List.groupBy (fun m -> m.LogicalName) + + for (methName, methGroup) in methGroups do + let methGroup = methGroup |> List.filter (fun m -> not m.IsInstance && not m.IsClassConstructor) + if not methGroup.IsEmpty then + yield KeyValuePair(methName, Item.MethodGroup(methName, methGroup, None)) - let propInfos = - AllPropInfosOfTypeInScope ResultCollectionSettings.AllResults infoReader nenv None AccessorDomain.AccessibleFromSomeFSharpCode PreferOverrides m ty - |> List.groupBy (fun m -> m.PropertyName) + let propInfos = + AllPropInfosOfTypeInScope ResultCollectionSettings.AllResults infoReader nenv None AccessorDomain.AccessibleFromSomeFSharpCode PreferOverrides m ty + |> List.groupBy (fun m -> m.PropertyName) - for (propName, propInfos) in propInfos do - let propInfos = propInfos |> List.filter (fun m -> m.IsStatic) - for propInfo in propInfos do - yield KeyValuePair(propName , Item.Property(propName,[propInfo])) |] + for (propName, propInfos) in propInfos do + let propInfos = propInfos |> List.filter (fun m -> m.IsStatic) + for propInfo in propInfos do + yield KeyValuePair(propName , Item.Property(propName,[propInfo])) |] - { nenv with eUnqualifiedItems = nenv.eUnqualifiedItems.AddAndMarkAsCollapsible items } + { nenv with eUnqualifiedItems = nenv.eUnqualifiedItems.AddAndMarkAsCollapsible items } + else + nenv /// Add any implied contents of a type definition to the environment. let private AddPartsOfTyconRefToNameEnv bulkAddMode ownDefinition (g: TcGlobals) amap m nenv (tcref: TyconRef) = @@ -1992,7 +1996,10 @@ let CheckForTypeLegitimacyAndMultipleGenericTypeAmbiguities //------------------------------------------------------------------------- /// Perform name resolution for an identifier which must resolve to be a namespace or module. -let rec ResolveLongIndentAsModuleOrNamespaceOrStaticClass sink (atMostOne: ResultCollectionSettings) amap m allowStaticClasses first fullyQualified (nenv: NameResolutionEnv) ad (id:Ident) (rest: Ident list) isOpenDecl = +let rec ResolveLongIndentAsModuleOrNamespaceOrStaticClass sink (atMostOne: ResultCollectionSettings) (amap: Import.ImportMap) m allowStaticClasses first fullyQualified (nenv: NameResolutionEnv) ad (id:Ident) (rest: Ident list) isOpenDecl = + + // If the selected language version doesn't support open static classes then turn them off. + let allowStaticClasses = allowStaticClasses && amap.g.langVersion.SupportsFeature LanguageFeature.OpenStaticClasses if first && id.idText = MangledGlobalName then match rest with | [] -> diff --git a/tests/fsharp/core/longnames/test.fsx b/tests/fsharp/core/longnames/test.fsx index 3692043c7dd..577dc547a6d 100644 --- a/tests/fsharp/core/longnames/test.fsx +++ b/tests/fsharp/core/longnames/test.fsx @@ -688,66 +688,6 @@ module rec Ok23 = test "lkneecec09iew23" (typeof.FullName.Contains("AModule") ) - -[] -type MyMath() = - static member Min(a: double, b: double) = System.Math.Min(a, b) - static member Min(a: int, b: int) = System.Math.Min(a, b) - -[] -type AutoOpenMyMath() = - static member AutoMin(a: double, b: double) = System.Math.Min(a, b) - static member AutoMin(a: int, b: int) = System.Math.Min(a, b) - -[] -type NotAllowedToOpen() = - static member QualifiedMin(a: double, b: double) = System.Math.Min(a, b) - static member QualifiedMin(a: int, b: int) = System.Math.Min(a, b) - -module OpenSystemMathOnce = - - open System.Math - let x = Min(1.0, 2.0) - test "vwejhweoiu" (x = 1.0) - - -module OpenSystemMathTwice = - - open System.Math - let x = Min(1.0, 2.0) - - open System.Math - let x2 = Min(2.0, 1.0) - - test "vwejhweoiu2" (x2 = 1.0) - -module OpenMyMathOnce = - - open MyMath - let x = Min(1.0, 2.0) - let x2 = Min(1, 2) - - test "vwejhweoiu2" (x = 1.0) - test "vwejhweoiu3" (x2 = 1) - -module DontOpenAutoMath = - - let x = AutoMin(1.0, 2.0) - let x2 = AutoMin(1, 2) - - test "vwejhweoiu2" (x = 1.0) - test "vwejhweoiu3" (x2 = 1) - -module OpenAutoMath = - open AutoOpenMyMath - //open NotAllowedToOpen - - let x = AutoMin(1.0, 2.0) - let x2 = AutoMin(1, 2) - - test "vwejhweoiu2" (x = 1.0) - test "vwejhweoiu3" (x2 = 1) - #if TESTS_AS_APP let RUN() = !failures #else diff --git a/tests/fsharp/core/longnames/version46/test.bsl b/tests/fsharp/core/longnames/version46/test.bsl new file mode 100644 index 00000000000..70f110197bb --- /dev/null +++ b/tests/fsharp/core/longnames/version46/test.bsl @@ -0,0 +1,39 @@ + +test.fs(34,17,34,21): typecheck error FS0039: The namespace 'Math' is not defined. + +test.fs(35,13,35,16): typecheck error FS0039: The value or constructor 'Min' is not defined. Maybe you want one of the following: + min + sin + +test.fs(41,17,41,21): typecheck error FS0039: The namespace 'Math' is not defined. + +test.fs(42,13,42,16): typecheck error FS0039: The value or constructor 'Min' is not defined. Maybe you want one of the following: + min + sin + +test.fs(44,17,44,21): typecheck error FS0039: The namespace 'Math' is not defined. + +test.fs(45,14,45,17): typecheck error FS0039: The value or constructor 'Min' is not defined. Maybe you want one of the following: + min + sin + +test.fs(51,10,51,16): typecheck error FS0039: The namespace or module 'MyMath' is not defined. Maybe you want one of the following: + Math + +test.fs(52,13,52,16): typecheck error FS0039: The value or constructor 'Min' is not defined. Maybe you want one of the following: + min + sin + +test.fs(53,14,53,17): typecheck error FS0039: The value or constructor 'Min' is not defined. Maybe you want one of the following: + min + sin + +test.fs(60,13,60,20): typecheck error FS0039: The value or constructor 'AutoMin' is not defined. + +test.fs(61,14,61,21): typecheck error FS0039: The value or constructor 'AutoMin' is not defined. + +test.fs(67,10,67,24): typecheck error FS0039: The namespace or module 'AutoOpenMyMath' is not defined. + +test.fs(70,13,70,20): typecheck error FS0039: The value or constructor 'AutoMin' is not defined. + +test.fs(71,14,71,21): typecheck error FS0039: The value or constructor 'AutoMin' is not defined. diff --git a/tests/fsharp/core/longnames/version46/test.fs b/tests/fsharp/core/longnames/version46/test.fs new file mode 100644 index 00000000000..8c41fdc81f0 --- /dev/null +++ b/tests/fsharp/core/longnames/version46/test.fs @@ -0,0 +1,84 @@ +module Core_longnames +let failures = ref [] + +let report_failure (s : string) = + stderr.Write" NO: " + stderr.WriteLine s + failures := !failures @ [s] + +let test (s : string) b = + stderr.Write(s) + if b then stderr.WriteLine " OK" + else report_failure (s) + +let check s b1 b2 = test s (b1 = b2) + +(* Some test expressions *) +[] +type MyMath() = + static member Min(a: double, b: double) = System.Math.Min(a, b) + static member Min(a: int, b: int) = System.Math.Min(a, b) + +[] +type AutoOpenMyMath() = + static member AutoMin(a: double, b: double) = System.Math.Min(a, b) + static member AutoMin(a: int, b: int) = System.Math.Min(a, b) + +[] +type NotAllowedToOpen() = + static member QualifiedMin(a: double, b: double) = System.Math.Min(a, b) + static member QualifiedMin(a: int, b: int) = System.Math.Min(a, b) + +module OpenSystemMathOnce = + + open System.Math + let x = Min(1.0, 2.0) + test "vwejhweoiu" (x = 1.0) + + +module OpenSystemMathTwice = + + open System.Math + let x = Min(1.0, 2.0) + + open System.Math + let x2 = Min(2.0, 1.0) + + test "vwejhweoiu2" (x2 = 1.0) + +module OpenMyMathOnce = + + open MyMath + let x = Min(1.0, 2.0) + let x2 = Min(1, 2) + + test "vwejhweoiu2" (x = 1.0) + test "vwejhweoiu3" (x2 = 1) + +module DontOpenAutoMath = + + let x = AutoMin(1.0, 2.0) + let x2 = AutoMin(1, 2) + + test "vwejhweoiu2" (x = 1.0) + test "vwejhweoiu3" (x2 = 1) + +module OpenAutoMath = + open AutoOpenMyMath + //open NotAllowedToOpen + + let x = AutoMin(1.0, 2.0) + let x2 = AutoMin(1, 2) + + test "vwejhweoiu2" (x = 1.0) + test "vwejhweoiu3" (x2 = 1) + +let RUN() = + match !failures with + | [] -> + stdout.WriteLine "Test Passed" + System.IO.File.WriteAllText("test.ok","ok") + exit 0 + | _ -> + stdout.WriteLine "Test Failed" + exit 1 diff --git a/tests/fsharp/core/longnames/version47/test.fsx b/tests/fsharp/core/longnames/version47/test.fsx new file mode 100644 index 00000000000..03702cb996b --- /dev/null +++ b/tests/fsharp/core/longnames/version47/test.fsx @@ -0,0 +1,91 @@ +// #Conformance #ObjectConstructors +#if TESTS_AS_APP +module Core_longnames +#endif +let failures = ref [] + +let report_failure (s : string) = + stderr.Write" NO: " + stderr.WriteLine s + failures := !failures @ [s] + +let test (s : string) b = + stderr.Write(s) + if b then stderr.WriteLine " OK" + else report_failure (s) + +let check s b1 b2 = test s (b1 = b2) + +(* Some test expressions *) +[] +type MyMath() = + static member Min(a: double, b: double) = System.Math.Min(a, b) + static member Min(a: int, b: int) = System.Math.Min(a, b) + +[] +type AutoOpenMyMath() = + static member AutoMin(a: double, b: double) = System.Math.Min(a, b) + static member AutoMin(a: int, b: int) = System.Math.Min(a, b) + +[] +type NotAllowedToOpen() = + static member QualifiedMin(a: double, b: double) = System.Math.Min(a, b) + static member QualifiedMin(a: int, b: int) = System.Math.Min(a, b) + +module OpenSystemMathOnce = + + open System.Math + let x = Min(1.0, 2.0) + test "vwejhweoiu" (x = 1.0) + + +module OpenSystemMathTwice = + + open System.Math + let x = Min(1.0, 2.0) + + open System.Math + let x2 = Min(2.0, 1.0) + + test "vwejhweoiu2" (x2 = 1.0) + +module OpenMyMathOnce = + + open MyMath + let x = Min(1.0, 2.0) + let x2 = Min(1, 2) + + test "vwejhweoiu2" (x = 1.0) + test "vwejhweoiu3" (x2 = 1) + +module DontOpenAutoMath = + + let x = AutoMin(1.0, 2.0) + let x2 = AutoMin(1, 2) + + test "vwejhweoiu2" (x = 1.0) + test "vwejhweoiu3" (x2 = 1) + +module OpenAutoMath = + open AutoOpenMyMath + //open NotAllowedToOpen + + let x = AutoMin(1.0, 2.0) + let x2 = AutoMin(1, 2) + + test "vwejhweoiu2" (x = 1.0) + test "vwejhweoiu3" (x2 = 1) + +#if TESTS_AS_APP +let RUN() = !failures +#else +let aa = + match !failures with + | [] -> + stdout.WriteLine "Test Passed" + System.IO.File.WriteAllText("test.ok","ok") + exit 0 + | _ -> + stdout.WriteLine "Test Failed" + exit 1 +#endif diff --git a/tests/fsharp/tests.fs b/tests/fsharp/tests.fs index fe30c684bfa..c6159b58516 100644 --- a/tests/fsharp/tests.fs +++ b/tests/fsharp/tests.fs @@ -1302,6 +1302,21 @@ module CoreTests = [] let ``longnames-FSI_BASIC`` () = singleTestBuildAndRun "core/longnames" FSI_BASIC +#if !FSHARP_SUITE_DRIVES_CORECLR_TESTS + [] + let ``longnames-version46`` () = + let cfg = testConfig "core/longnames/version46" + // For some reason this warning is off by default in the test framework but in this case we are testing for it + let cfg = { cfg with fsc_flags = cfg.fsc_flags.Replace("--nowarn:20", "") } + singleVersionedNegTest cfg "4.6" "test" +#endif + + [] + let ``longnames-version47-FSC_BASIC`` () = singleTestBuildAndRunVersion "core/longnames/version47" FSC_BASIC "preview" + + [] + let ``longnames-version47-FSI_BASIC`` () = singleTestBuildAndRunVersion "core/longnames/version47" FSI_BASIC "preview" + [] let ``math-numbersVS2008-FSC_BASIC`` () = singleTestBuildAndRun "core/math/numbersVS2008" FSC_BASIC