From 07e91a976ee24d5e83507ff32fc9a3c58e9ea602 Mon Sep 17 00:00:00 2001 From: Edgar Gonzalez Date: Sun, 25 Dec 2022 18:15:44 +0100 Subject: [PATCH 01/11] Not constructor arguments are allowed in static classes --- src/Compiler/Checking/CheckDeclarations.fs | 16 +- src/Compiler/FSComp.txt | 4 +- src/Compiler/Facilities/LanguageFeatures.fs | 5 +- src/Compiler/Facilities/LanguageFeatures.fsi | 1 + src/Compiler/xlf/FSComp.txt.cs.xlf | 10 ++ src/Compiler/xlf/FSComp.txt.de.xlf | 10 ++ src/Compiler/xlf/FSComp.txt.es.xlf | 10 ++ src/Compiler/xlf/FSComp.txt.fr.xlf | 10 ++ src/Compiler/xlf/FSComp.txt.it.xlf | 10 ++ src/Compiler/xlf/FSComp.txt.ja.xlf | 10 ++ src/Compiler/xlf/FSComp.txt.ko.xlf | 10 ++ src/Compiler/xlf/FSComp.txt.pl.xlf | 10 ++ src/Compiler/xlf/FSComp.txt.pt-BR.xlf | 10 ++ src/Compiler/xlf/FSComp.txt.ru.xlf | 10 ++ src/Compiler/xlf/FSComp.txt.tr.xlf | 10 ++ src/Compiler/xlf/FSComp.txt.zh-Hans.xlf | 10 ++ src/Compiler/xlf/FSComp.txt.zh-Hant.xlf | 10 ++ .../FSharp.Compiler.ComponentTests.fsproj | 1 + .../Language/StaticClassTests.fs | 138 ++++++++++++++++++ 19 files changed, 290 insertions(+), 5 deletions(-) create mode 100644 tests/FSharp.Compiler.ComponentTests/Language/StaticClassTests.fs diff --git a/src/Compiler/Checking/CheckDeclarations.fs b/src/Compiler/Checking/CheckDeclarations.fs index 4f74ce59c61..bb41dfd1e55 100644 --- a/src/Compiler/Checking/CheckDeclarations.fs +++ b/src/Compiler/Checking/CheckDeclarations.fs @@ -4027,9 +4027,13 @@ module TcDeclarations = /// where simpleRepr can contain inherit type, declared fields and virtual slots. /// body = members /// where members contain methods/overrides, also implicit ctor, inheritCall and local definitions. - let rec private SplitTyconDefn (SynTypeDefn(typeInfo=synTyconInfo;typeRepr=trepr; members=extraMembers)) = + let rec private SplitTyconDefn (cenv: cenv) envInitial (SynTypeDefn(typeInfo=SynComponentInfo(attributes= Attributes synAttrs) as synTyconInfo; typeRepr=trepr; members=extraMembers)) = let extraMembers = desugarGetSetMembers extraMembers let implements1 = List.choose (function SynMemberDefn.Interface (interfaceType=ty) -> Some(ty, ty.Range) | _ -> None) extraMembers + let attrs = TcAttributes cenv envInitial AttributeTargets.TyconDecl synAttrs + let isStaticClass = HasFSharpAttribute cenv.g cenv.g.attrib_SealedAttribute attrs && HasFSharpAttribute cenv.g cenv.g.attrib_AbstractClassAttribute attrs + let reportErrorOnStaticClass = isStaticClass && cenv.g.langVersion.SupportsFeature(LanguageFeature.ErrorReportingOnStaticClasses) + match trepr with | SynTypeDefnRepr.ObjectModel(kind, cspec, m) -> let cspec = desugarGetSetMembers cspec @@ -4047,7 +4051,13 @@ module TcDeclarations = let members = let membersIncludingAutoProps = cspec |> List.filter (fun memb -> - match memb with + match memb with + | SynMemberDefn.ImplicitCtor(ctorArgs= SynSimplePats.SimplePats(pats, _)) when not pats.IsEmpty && reportErrorOnStaticClass -> + for pat in pats do + errorR(Error(FSComp.SR.chkErrorOnStaticClasses "constructor arguments are", pat.Range)) + false + | SynMemberDefn.Member(SynBinding(valData = SynValData(Some memberFlags, _, _)), m) when memberFlags.MemberKind = SynMemberKind.Constructor && reportErrorOnStaticClass -> + errorR(Error(FSComp.SR.chkErrorOnStaticClasses "additional constructors are", m)); false | SynMemberDefn.Interface _ | SynMemberDefn.Member _ | SynMemberDefn.GetSetMember _ @@ -4204,7 +4214,7 @@ module TcDeclarations = // Split the definitions into "core representations" and "members". The code to process core representations // is shared between processing of signature files and implementation files. - let mutRecDefnsAfterSplit = mutRecDefns |> MutRecShapes.mapTycons SplitTyconDefn + let mutRecDefnsAfterSplit = MutRecShapes.mapTycons (SplitTyconDefn cenv envInitial) mutRecDefns // Create the entities for each module and type definition, and process the core representation of each type definition. let tycons, envMutRecPrelim, mutRecDefnsAfterCore = diff --git a/src/Compiler/FSComp.txt b/src/Compiler/FSComp.txt index 82659f91d88..91d7e90d6a9 100644 --- a/src/Compiler/FSComp.txt +++ b/src/Compiler/FSComp.txt @@ -1560,6 +1560,7 @@ featureCSharpExtensionAttributeNotRequired,"Allow implicit Extension attribute o featureErrorForNonVirtualMembersOverrides,"Raises errors for non-virtual members overrides" featureWarningWhenInliningMethodImplNoInlineMarkedFunction,"Raises warnings when 'let inline ... =' is used together with [] attribute. Function is not getting inlined." featureArithmeticInLiterals,"Allow arithmetic and logical operations in literals" +featureErrorReportingOnStaticClasses,"Error reporting on static classes" 3353,fsiInvalidDirective,"Invalid directive '#%s %s'" 3354,tcNotAFunctionButIndexerNamedIndexingNotYetEnabled,"This value supports indexing, e.g. '%s.[index]'. The syntax '%s[index]' requires /langversion:preview. See https://aka.ms/fsharp-index-notation." 3354,tcNotAFunctionButIndexerIndexingNotYetEnabled,"This expression supports indexing, e.g. 'expr.[index]'. The syntax 'expr[index]' requires /langversion:preview. See https://aka.ms/fsharp-index-notation." @@ -1663,4 +1664,5 @@ reprStateMachineInvalidForm,"The state machine has an unexpected form" 3548,matchNotAllowedForUnionCaseWithNoData,"Pattern discard is not allowed for union case that takes no data." 3549,tcSynTypeOrInvalidInDeclaration,"SynType.Or is not permitted in this declaration" 3550,chkDuplicatedMethodParameter,"Duplicate parameter. The parameter '%s' has been used more that once in this method." -featureEscapeBracesInFormattableString,"Escapes curly braces before calling FormattableStringFactory.Create when interpolated string literal is typed as FormattableString" \ No newline at end of file +featureEscapeBracesInFormattableString,"Escapes curly braces before calling FormattableStringFactory.Create when interpolated string literal is typed as FormattableString" +3551,chkErrorOnStaticClasses,"if a type uses both [] and [] it means it is static. No %s allowed" \ No newline at end of file diff --git a/src/Compiler/Facilities/LanguageFeatures.fs b/src/Compiler/Facilities/LanguageFeatures.fs index 7dfedf0be08..e7654bea422 100644 --- a/src/Compiler/Facilities/LanguageFeatures.fs +++ b/src/Compiler/Facilities/LanguageFeatures.fs @@ -60,7 +60,8 @@ type LanguageFeature = | WarningWhenInliningMethodImplNoInlineMarkedFunction | EscapeDotnetFormattableStrings | ArithmeticInLiterals - + | ErrorReportingOnStaticClasses + /// LanguageVersion management type LanguageVersion(versionText) = @@ -136,6 +137,7 @@ type LanguageVersion(versionText) = LanguageFeature.WarningWhenInliningMethodImplNoInlineMarkedFunction, previewVersion LanguageFeature.EscapeDotnetFormattableStrings, previewVersion LanguageFeature.ArithmeticInLiterals, previewVersion + LanguageFeature.ErrorReportingOnStaticClasses, previewVersion ] @@ -249,6 +251,7 @@ type LanguageVersion(versionText) = | LanguageFeature.WarningWhenInliningMethodImplNoInlineMarkedFunction -> FSComp.SR.featureWarningWhenInliningMethodImplNoInlineMarkedFunction () | LanguageFeature.EscapeDotnetFormattableStrings -> FSComp.SR.featureEscapeBracesInFormattableString () | LanguageFeature.ArithmeticInLiterals -> FSComp.SR.featureArithmeticInLiterals () + | LanguageFeature.ErrorReportingOnStaticClasses -> FSComp.SR.featureErrorReportingOnStaticClasses () /// Get a version string associated with the given feature. static member GetFeatureVersionString feature = diff --git a/src/Compiler/Facilities/LanguageFeatures.fsi b/src/Compiler/Facilities/LanguageFeatures.fsi index ac1ae354599..d070a8b4e36 100644 --- a/src/Compiler/Facilities/LanguageFeatures.fsi +++ b/src/Compiler/Facilities/LanguageFeatures.fsi @@ -50,6 +50,7 @@ type LanguageFeature = | WarningWhenInliningMethodImplNoInlineMarkedFunction | EscapeDotnetFormattableStrings | ArithmeticInLiterals + | ErrorReportingOnStaticClasses /// LanguageVersion management type LanguageVersion = diff --git a/src/Compiler/xlf/FSComp.txt.cs.xlf b/src/Compiler/xlf/FSComp.txt.cs.xlf index 3d4773937e3..da1b5891f2e 100644 --- a/src/Compiler/xlf/FSComp.txt.cs.xlf +++ b/src/Compiler/xlf/FSComp.txt.cs.xlf @@ -22,6 +22,11 @@ Duplicate parameter. The parameter '{0}' has been used more that once in this method. + + if a type uses both [<Sealed>] and [<AbstractClass>] it means it is static. No {0} allowed + if a type uses both [<Sealed>] and [<AbstractClass>] it means it is static. No {0} allowed + + Feature '{0}' is not available in F# {1}. Please use language version {2} or greater. Funkce {0} není v jazyce F# {1} dostupná. Použijte prosím jazyk verze {2} nebo vyšší. @@ -192,6 +197,11 @@ chyba při zastaralém přístupu konstruktoru s atributem RequireQualifiedAccess + + Error reporting on static classes + Error reporting on static classes + + Escapes curly braces before calling FormattableStringFactory.Create when interpolated string literal is typed as FormattableString Escapes curly braces before calling FormattableStringFactory.Create when interpolated string literal is typed as FormattableString diff --git a/src/Compiler/xlf/FSComp.txt.de.xlf b/src/Compiler/xlf/FSComp.txt.de.xlf index ee9e314307b..a549e6986e6 100644 --- a/src/Compiler/xlf/FSComp.txt.de.xlf +++ b/src/Compiler/xlf/FSComp.txt.de.xlf @@ -22,6 +22,11 @@ Duplicate parameter. The parameter '{0}' has been used more that once in this method. + + if a type uses both [<Sealed>] and [<AbstractClass>] it means it is static. No {0} allowed + if a type uses both [<Sealed>] and [<AbstractClass>] it means it is static. No {0} allowed + + Feature '{0}' is not available in F# {1}. Please use language version {2} or greater. Das Feature "{0}" ist in F# {1} nicht verfügbar. Verwenden Sie Sprachversion {2} oder höher. @@ -192,6 +197,11 @@ Beim veralteten Zugriff auf das Konstrukt mit dem RequireQualifiedAccess-Attribut wird ein Fehler ausgegeben. + + Error reporting on static classes + Error reporting on static classes + + Escapes curly braces before calling FormattableStringFactory.Create when interpolated string literal is typed as FormattableString Escapes curly braces before calling FormattableStringFactory.Create when interpolated string literal is typed as FormattableString diff --git a/src/Compiler/xlf/FSComp.txt.es.xlf b/src/Compiler/xlf/FSComp.txt.es.xlf index 8a61a345311..7c79580e718 100644 --- a/src/Compiler/xlf/FSComp.txt.es.xlf +++ b/src/Compiler/xlf/FSComp.txt.es.xlf @@ -22,6 +22,11 @@ Duplicate parameter. The parameter '{0}' has been used more that once in this method. + + if a type uses both [<Sealed>] and [<AbstractClass>] it means it is static. No {0} allowed + if a type uses both [<Sealed>] and [<AbstractClass>] it means it is static. No {0} allowed + + Feature '{0}' is not available in F# {1}. Please use language version {2} or greater. La característica "{0}" no está disponible en F# {1}. Use la versión {2} del lenguaje o una posterior. @@ -192,6 +197,11 @@ error en el acceso en desuso de la construcción con el atributo RequireQualifiedAccess + + Error reporting on static classes + Error reporting on static classes + + Escapes curly braces before calling FormattableStringFactory.Create when interpolated string literal is typed as FormattableString Escapes curly braces before calling FormattableStringFactory.Create when interpolated string literal is typed as FormattableString diff --git a/src/Compiler/xlf/FSComp.txt.fr.xlf b/src/Compiler/xlf/FSComp.txt.fr.xlf index 00a9cde1c40..e04841e00b6 100644 --- a/src/Compiler/xlf/FSComp.txt.fr.xlf +++ b/src/Compiler/xlf/FSComp.txt.fr.xlf @@ -22,6 +22,11 @@ Duplicate parameter. The parameter '{0}' has been used more that once in this method. + + if a type uses both [<Sealed>] and [<AbstractClass>] it means it is static. No {0} allowed + if a type uses both [<Sealed>] and [<AbstractClass>] it means it is static. No {0} allowed + + Feature '{0}' is not available in F# {1}. Please use language version {2} or greater. La fonctionnalité '{0}' n'est pas disponible en F# {1}. Utilisez la version de langage {2} ou une version ultérieure. @@ -192,6 +197,11 @@ donner une erreur sur l’accès déconseillé de la construction avec l’attribut RequireQualifiedAccess + + Error reporting on static classes + Error reporting on static classes + + Escapes curly braces before calling FormattableStringFactory.Create when interpolated string literal is typed as FormattableString Escapes curly braces before calling FormattableStringFactory.Create when interpolated string literal is typed as FormattableString diff --git a/src/Compiler/xlf/FSComp.txt.it.xlf b/src/Compiler/xlf/FSComp.txt.it.xlf index 72ad89e8855..3570c2ceb79 100644 --- a/src/Compiler/xlf/FSComp.txt.it.xlf +++ b/src/Compiler/xlf/FSComp.txt.it.xlf @@ -22,6 +22,11 @@ Duplicate parameter. The parameter '{0}' has been used more that once in this method. + + if a type uses both [<Sealed>] and [<AbstractClass>] it means it is static. No {0} allowed + if a type uses both [<Sealed>] and [<AbstractClass>] it means it is static. No {0} allowed + + Feature '{0}' is not available in F# {1}. Please use language version {2} or greater. La funzionalità '{0}' non è disponibile in F# {1}. Usare la versione {2} o versioni successive del linguaggio. @@ -192,6 +197,11 @@ errore durante l'accesso deprecato del costrutto con l'attributo RequireQualifiedAccess + + Error reporting on static classes + Error reporting on static classes + + Escapes curly braces before calling FormattableStringFactory.Create when interpolated string literal is typed as FormattableString Escapes curly braces before calling FormattableStringFactory.Create when interpolated string literal is typed as FormattableString diff --git a/src/Compiler/xlf/FSComp.txt.ja.xlf b/src/Compiler/xlf/FSComp.txt.ja.xlf index 0b0868abe54..805832a99a2 100644 --- a/src/Compiler/xlf/FSComp.txt.ja.xlf +++ b/src/Compiler/xlf/FSComp.txt.ja.xlf @@ -22,6 +22,11 @@ Duplicate parameter. The parameter '{0}' has been used more that once in this method. + + if a type uses both [<Sealed>] and [<AbstractClass>] it means it is static. No {0} allowed + if a type uses both [<Sealed>] and [<AbstractClass>] it means it is static. No {0} allowed + + Feature '{0}' is not available in F# {1}. Please use language version {2} or greater. 機能 '{0}' は F# {1} では使用できません。{2} 以上の言語バージョンをお使いください。 @@ -192,6 +197,11 @@ RequireQualifiedAccess 属性を持つコンストラクトの非推奨アクセスでエラーが発生しました + + Error reporting on static classes + Error reporting on static classes + + Escapes curly braces before calling FormattableStringFactory.Create when interpolated string literal is typed as FormattableString Escapes curly braces before calling FormattableStringFactory.Create when interpolated string literal is typed as FormattableString diff --git a/src/Compiler/xlf/FSComp.txt.ko.xlf b/src/Compiler/xlf/FSComp.txt.ko.xlf index fca2e1357d9..cc5f6b85d14 100644 --- a/src/Compiler/xlf/FSComp.txt.ko.xlf +++ b/src/Compiler/xlf/FSComp.txt.ko.xlf @@ -22,6 +22,11 @@ Duplicate parameter. The parameter '{0}' has been used more that once in this method. + + if a type uses both [<Sealed>] and [<AbstractClass>] it means it is static. No {0} allowed + if a type uses both [<Sealed>] and [<AbstractClass>] it means it is static. No {0} allowed + + Feature '{0}' is not available in F# {1}. Please use language version {2} or greater. '{0}' 기능은 F# {1}에서 사용할 수 없습니다. {2} 이상의 언어 버전을 사용하세요. @@ -192,6 +197,11 @@ RequireQualifiedAccess 특성을 사용하여 사용되지 않는 구문 액세스에 대한 오류 제공 + + Error reporting on static classes + Error reporting on static classes + + Escapes curly braces before calling FormattableStringFactory.Create when interpolated string literal is typed as FormattableString Escapes curly braces before calling FormattableStringFactory.Create when interpolated string literal is typed as FormattableString diff --git a/src/Compiler/xlf/FSComp.txt.pl.xlf b/src/Compiler/xlf/FSComp.txt.pl.xlf index 39b430d241e..0dfc9940d0b 100644 --- a/src/Compiler/xlf/FSComp.txt.pl.xlf +++ b/src/Compiler/xlf/FSComp.txt.pl.xlf @@ -22,6 +22,11 @@ Duplicate parameter. The parameter '{0}' has been used more that once in this method. + + if a type uses both [<Sealed>] and [<AbstractClass>] it means it is static. No {0} allowed + if a type uses both [<Sealed>] and [<AbstractClass>] it means it is static. No {0} allowed + + Feature '{0}' is not available in F# {1}. Please use language version {2} or greater. Funkcja „{0}” nie jest dostępna w języku F# {1}. Użyj języka w wersji {2} lub nowszej. @@ -192,6 +197,11 @@ wskazywanie błędu w przypadku przestarzałego dostępu do konstrukcji z atrybutem RequireQualifiedAccess + + Error reporting on static classes + Error reporting on static classes + + Escapes curly braces before calling FormattableStringFactory.Create when interpolated string literal is typed as FormattableString Escapes curly braces before calling FormattableStringFactory.Create when interpolated string literal is typed as FormattableString diff --git a/src/Compiler/xlf/FSComp.txt.pt-BR.xlf b/src/Compiler/xlf/FSComp.txt.pt-BR.xlf index 26960045d90..13bb27af3e8 100644 --- a/src/Compiler/xlf/FSComp.txt.pt-BR.xlf +++ b/src/Compiler/xlf/FSComp.txt.pt-BR.xlf @@ -22,6 +22,11 @@ Duplicate parameter. The parameter '{0}' has been used more that once in this method. + + if a type uses both [<Sealed>] and [<AbstractClass>] it means it is static. No {0} allowed + if a type uses both [<Sealed>] and [<AbstractClass>] it means it is static. No {0} allowed + + Feature '{0}' is not available in F# {1}. Please use language version {2} or greater. O recurso '{0}' não está disponível no F# {1}. Use a versão da linguagem {2} ou superior. @@ -192,6 +197,11 @@ fornecer erro no acesso preterido do constructo com o atributo RequireQualifiedAccess + + Error reporting on static classes + Error reporting on static classes + + Escapes curly braces before calling FormattableStringFactory.Create when interpolated string literal is typed as FormattableString Escapes curly braces before calling FormattableStringFactory.Create when interpolated string literal is typed as FormattableString diff --git a/src/Compiler/xlf/FSComp.txt.ru.xlf b/src/Compiler/xlf/FSComp.txt.ru.xlf index 6ce6165a590..7e8c5e46dad 100644 --- a/src/Compiler/xlf/FSComp.txt.ru.xlf +++ b/src/Compiler/xlf/FSComp.txt.ru.xlf @@ -22,6 +22,11 @@ Duplicate parameter. The parameter '{0}' has been used more that once in this method. + + if a type uses both [<Sealed>] and [<AbstractClass>] it means it is static. No {0} allowed + if a type uses both [<Sealed>] and [<AbstractClass>] it means it is static. No {0} allowed + + Feature '{0}' is not available in F# {1}. Please use language version {2} or greater. Компонент "{0}" недоступен в F# {1}. Используйте версию языка {2} или выше. @@ -192,6 +197,11 @@ выдать ошибку при устаревшем доступе к конструкции с атрибутом RequireQualifiedAccess + + Error reporting on static classes + Error reporting on static classes + + Escapes curly braces before calling FormattableStringFactory.Create when interpolated string literal is typed as FormattableString Escapes curly braces before calling FormattableStringFactory.Create when interpolated string literal is typed as FormattableString diff --git a/src/Compiler/xlf/FSComp.txt.tr.xlf b/src/Compiler/xlf/FSComp.txt.tr.xlf index 5b53bdd6a3f..2d78eb77fe8 100644 --- a/src/Compiler/xlf/FSComp.txt.tr.xlf +++ b/src/Compiler/xlf/FSComp.txt.tr.xlf @@ -22,6 +22,11 @@ Duplicate parameter. The parameter '{0}' has been used more that once in this method. + + if a type uses both [<Sealed>] and [<AbstractClass>] it means it is static. No {0} allowed + if a type uses both [<Sealed>] and [<AbstractClass>] it means it is static. No {0} allowed + + Feature '{0}' is not available in F# {1}. Please use language version {2} or greater. '{0}' özelliği F# {1} sürümünde kullanılamıyor. Lütfen {2} veya daha yüksek bir dil sürümünü kullanın. @@ -192,6 +197,11 @@ RequireQualifiedAccess özniteliğine sahip yapının kullanım dışı erişiminde hata + + Error reporting on static classes + Error reporting on static classes + + Escapes curly braces before calling FormattableStringFactory.Create when interpolated string literal is typed as FormattableString Escapes curly braces before calling FormattableStringFactory.Create when interpolated string literal is typed as FormattableString diff --git a/src/Compiler/xlf/FSComp.txt.zh-Hans.xlf b/src/Compiler/xlf/FSComp.txt.zh-Hans.xlf index 7ee6ac2bdc9..59b81cfa80e 100644 --- a/src/Compiler/xlf/FSComp.txt.zh-Hans.xlf +++ b/src/Compiler/xlf/FSComp.txt.zh-Hans.xlf @@ -22,6 +22,11 @@ Duplicate parameter. The parameter '{0}' has been used more that once in this method. + + if a type uses both [<Sealed>] and [<AbstractClass>] it means it is static. No {0} allowed + if a type uses both [<Sealed>] and [<AbstractClass>] it means it is static. No {0} allowed + + Feature '{0}' is not available in F# {1}. Please use language version {2} or greater. 功能“{0}”在 F# {1} 中不可用。请使用 {2} 或更高的语言版本。 @@ -192,6 +197,11 @@ 对具有 RequireQualifiedAccess 属性的构造进行弃用的访问时出错 + + Error reporting on static classes + Error reporting on static classes + + Escapes curly braces before calling FormattableStringFactory.Create when interpolated string literal is typed as FormattableString Escapes curly braces before calling FormattableStringFactory.Create when interpolated string literal is typed as FormattableString diff --git a/src/Compiler/xlf/FSComp.txt.zh-Hant.xlf b/src/Compiler/xlf/FSComp.txt.zh-Hant.xlf index 46eae156525..a203029a64a 100644 --- a/src/Compiler/xlf/FSComp.txt.zh-Hant.xlf +++ b/src/Compiler/xlf/FSComp.txt.zh-Hant.xlf @@ -22,6 +22,11 @@ Duplicate parameter. The parameter '{0}' has been used more that once in this method. + + if a type uses both [<Sealed>] and [<AbstractClass>] it means it is static. No {0} allowed + if a type uses both [<Sealed>] and [<AbstractClass>] it means it is static. No {0} allowed + + Feature '{0}' is not available in F# {1}. Please use language version {2} or greater. F# {1} 中無法使用 '{0}' 功能。請使用語言版本 {2} 或更新的版本。 @@ -192,6 +197,11 @@ 對具有 RequireQualifiedAccess 屬性的建構的已取代存取發出錯誤 + + Error reporting on static classes + Error reporting on static classes + + Escapes curly braces before calling FormattableStringFactory.Create when interpolated string literal is typed as FormattableString Escapes curly braces before calling FormattableStringFactory.Create when interpolated string literal is typed as FormattableString diff --git a/tests/FSharp.Compiler.ComponentTests/FSharp.Compiler.ComponentTests.fsproj b/tests/FSharp.Compiler.ComponentTests/FSharp.Compiler.ComponentTests.fsproj index 1262a9dc28a..ad93633d8da 100644 --- a/tests/FSharp.Compiler.ComponentTests/FSharp.Compiler.ComponentTests.fsproj +++ b/tests/FSharp.Compiler.ComponentTests/FSharp.Compiler.ComponentTests.fsproj @@ -177,6 +177,7 @@ + diff --git a/tests/FSharp.Compiler.ComponentTests/Language/StaticClassTests.fs b/tests/FSharp.Compiler.ComponentTests/Language/StaticClassTests.fs new file mode 100644 index 00000000000..f3b262aab1e --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/Language/StaticClassTests.fs @@ -0,0 +1,138 @@ +namespace FSharp.Compiler.ComponentTests.Language + +open Xunit +open FSharp.Test.Compiler + +module StaticClassTests = + + [] + let ``Sealed and AbstractClass on a type in lang version70`` () = + Fsx """ +[] +type T = class end + """ + |> withLangVersion70 + |> compile + |> shouldSucceed + + [] + let ``Sealed and AbstractClass on a type in lang preview`` () = + Fsx """ +[] +type T = class end + """ + |> withLangVersionPreview + |> compile + |> shouldSucceed + + [] + let ``Sealed and AbstractClass on a type with constructor in lang preview`` () = + Fsx """ +[] +type T() = class end + """ + |> withLangVersionPreview + |> compile + |> shouldSucceed + + [] + let ``Sealed and AbstractClass on a type with constructor in lang version70`` () = + Fsx """ +[] +type T() = class end + """ + |> withLangVersion70 + |> compile + |> shouldSucceed + + [] + let ``Sealed and AbstractClass on a type with constructor with arguments in lang preview`` () = + Fsx """ +[] +type T(x: int) = class end + """ + |> withLangVersionPreview + |> compile + |> shouldFail + |> withDiagnostics [ + (Error 3551, Line 3, Col 8, Line 3, Col 14, "if a type uses both [] and [] it means it is static. No constructor arguments are allowed") + ] + + [] + let ``Sealed and AbstractClass on a type with constructor with arguments in lang version70`` () = + Fsx """ +[] +type T(x: int) = class end + """ + |> withLangVersion70 + |> compile + |> shouldSucceed + + [] + let ``When Sealed and AbstractClass on a type with additional constructors in lang preview`` () = + Fsx """ +[] +type T = + new () = {} + """ + |> withLangVersionPreview + |> compile + |> shouldFail + |> withDiagnostics [ + (Error 3551, Line 4, Col 5, Line 4, Col 16, "if a type uses both [] and [] it means it is static. No additional constructors are allowed") + ] + + [] + let ``When Sealed and AbstractClass on a type with additional constructors in lang version70`` () = + Fsx """ +[] +type T = + new () = {} + """ + |> withLangVersion70 + |> compile + |> shouldSucceed + + [] + let ``When Sealed and AbstractClass on a type with a primary(parameters) and additional constructor in lang preview`` () = + Fsx """ +[] +type T(x: int) = + new () = {} + """ + |> withLangVersionPreview + |> compile + |> shouldFail + |> withDiagnostics [ + (Error 3551, Line 3, Col 8, Line 3, Col 14, "if a type uses both [] and [] it means it is static. No constructor arguments are allowed") + (Error 3551, Line 4, Col 5, Line 4, Col 16, "if a type uses both [] and [] it means it is static. No additional constructors are allowed") + ] + + [] + let ``When Sealed and AbstractClass on a type with explicit fields and constructor in lang version70`` () = + Fsx """ +[] +type B = + val F : int + val mutable G : int + new () = { F = 3; G = 3 } + """ + |> withLangVersion70 + |> compile + |> shouldSucceed + + [] + let ``When Sealed and AbstractClass on a type with explicit fields and constructor in lang preview`` () = + Fsx """ +[] +type B = + val F : int + val mutable G : int + new () = { F = 3; G = 3 } + """ + |> withLangVersionPreview + |> compile + |> shouldFail + |> withDiagnostics [ + (Error 3551, Line 6, Col 5, Line 6, Col 30, "if a type uses both [] and [] it means it is static. No additional constructors are allowed") + ] \ No newline at end of file From 656d4aabe98024f576104a10f79c829a554cc431 Mon Sep 17 00:00:00 2001 From: Edgar Gonzalez Date: Wed, 28 Dec 2022 22:45:52 +0100 Subject: [PATCH 02/11] More tests --- .../Language/StaticClassTests.fs | 22 +++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/tests/FSharp.Compiler.ComponentTests/Language/StaticClassTests.fs b/tests/FSharp.Compiler.ComponentTests/Language/StaticClassTests.fs index f3b262aab1e..b446f0c0137 100644 --- a/tests/FSharp.Compiler.ComponentTests/Language/StaticClassTests.fs +++ b/tests/FSharp.Compiler.ComponentTests/Language/StaticClassTests.fs @@ -120,6 +120,28 @@ type B = |> withLangVersion70 |> compile |> shouldSucceed + [] + let ``When Sealed and AbstractClass on a generic type with constructor in lang version70`` () = + Fsx """ +[] +type ListDebugView<'T>(l: 'T list) = class end + """ + |> withLangVersion70 + |> compile + |> shouldSucceed + + [] + let ``When Sealed and AbstractClass on a generic type with constructor in lang preview`` () = + Fsx """ +[] +type ListDebugView<'T>(l: 'T list) = class end + """ + |> withLangVersionPreview + |> compile + |> shouldFail + |> withDiagnostics [ + (Error 3551, Line 3, Col 24, Line 3, Col 34, "if a type uses both [] and [] it means it is static. No constructor arguments are allowed") + ] [] let ``When Sealed and AbstractClass on a type with explicit fields and constructor in lang preview`` () = From 63b85955ee4799bee37fc00f19badcb583c03024 Mon Sep 17 00:00:00 2001 From: Tomas Grosup Date: Thu, 29 Dec 2022 11:17:43 +0100 Subject: [PATCH 03/11] Repro of failing bootstrap build added --- .../Language/StaticClassTests.fs | 44 ++++++++++++++++++- 1 file changed, 43 insertions(+), 1 deletion(-) diff --git a/tests/FSharp.Compiler.ComponentTests/Language/StaticClassTests.fs b/tests/FSharp.Compiler.ComponentTests/Language/StaticClassTests.fs index b446f0c0137..5b61c318b81 100644 --- a/tests/FSharp.Compiler.ComponentTests/Language/StaticClassTests.fs +++ b/tests/FSharp.Compiler.ComponentTests/Language/StaticClassTests.fs @@ -157,4 +157,46 @@ type B = |> shouldFail |> withDiagnostics [ (Error 3551, Line 6, Col 5, Line 6, Col 30, "if a type uses both [] and [] it means it is static. No additional constructors are allowed") - ] \ No newline at end of file + ] + + + [] + let ``Annoying bug``() = + let code = """ + module Test + + open System.Diagnostics + + [] + [>)>] + [] + [] + type MyCustomList<'T> = + | Empty + | NonEmpty of Head: 'T * Tail: MyCustomList<'T> + + and MyImbaAlias<'T> = MyCustomList<'T> + + //------------------------------------------------------------------------- + // List (debug view) + //------------------------------------------------------------------------- + + and + MyCustomListDebugView<'T>(l: MyCustomList<'T>) = + let asList = + let rec toList ml = + match ml with + | Empty -> [] + | NonEmpty (head,tail) -> head :: (toList tail) + toList l + + [] + member x.Items = asList |> List.toArray + + [] + member x._FullList = asList |> List.toArray + + """ + Fs code + |> compile + |> shouldSucceed \ No newline at end of file From 335da6e2e17c54a8c213032d437e0455db5198d9 Mon Sep 17 00:00:00 2001 From: Tomas Grosup Date: Thu, 29 Dec 2022 11:40:26 +0100 Subject: [PATCH 04/11] Make it work for langversion 7.0 at least --- src/Compiler/Checking/CheckDeclarations.fs | 20 ++++++++++++------- .../Language/StaticClassTests.fs | 9 ++++++--- 2 files changed, 19 insertions(+), 10 deletions(-) diff --git a/src/Compiler/Checking/CheckDeclarations.fs b/src/Compiler/Checking/CheckDeclarations.fs index bb41dfd1e55..b17601994e7 100644 --- a/src/Compiler/Checking/CheckDeclarations.fs +++ b/src/Compiler/Checking/CheckDeclarations.fs @@ -4027,12 +4027,17 @@ module TcDeclarations = /// where simpleRepr can contain inherit type, declared fields and virtual slots. /// body = members /// where members contain methods/overrides, also implicit ctor, inheritCall and local definitions. - let rec private SplitTyconDefn (cenv: cenv) envInitial (SynTypeDefn(typeInfo=SynComponentInfo(attributes= Attributes synAttrs) as synTyconInfo; typeRepr=trepr; members=extraMembers)) = + let rec private SplitTyconDefn (cenv: cenv) envInitial (SynTypeDefn(typeInfo=synTyconInfo;typeRepr=trepr; members=extraMembers)) = let extraMembers = desugarGetSetMembers extraMembers let implements1 = List.choose (function SynMemberDefn.Interface (interfaceType=ty) -> Some(ty, ty.Range) | _ -> None) extraMembers - let attrs = TcAttributes cenv envInitial AttributeTargets.TyconDecl synAttrs - let isStaticClass = HasFSharpAttribute cenv.g cenv.g.attrib_SealedAttribute attrs && HasFSharpAttribute cenv.g cenv.g.attrib_AbstractClassAttribute attrs - let reportErrorOnStaticClass = isStaticClass && cenv.g.langVersion.SupportsFeature(LanguageFeature.ErrorReportingOnStaticClasses) + + let reportErrorOnStaticClass = + cenv.g.langVersion.SupportsFeature(LanguageFeature.ErrorReportingOnStaticClasses) && + (let (SynComponentInfo(attributes=Attributes(synAttrs))) = synTyconInfo + let attrs = TcAttributes cenv envInitial AttributeTargets.TyconDecl synAttrs + let isStaticClass = HasFSharpAttribute cenv.g cenv.g.attrib_SealedAttribute attrs && HasFSharpAttribute cenv.g cenv.g.attrib_AbstractClassAttribute attrs + isStaticClass) + match trepr with | SynTypeDefnRepr.ObjectModel(kind, cspec, m) -> @@ -4052,12 +4057,13 @@ module TcDeclarations = let membersIncludingAutoProps = cspec |> List.filter (fun memb -> match memb with - | SynMemberDefn.ImplicitCtor(ctorArgs= SynSimplePats.SimplePats(pats, _)) when not pats.IsEmpty && reportErrorOnStaticClass -> + | SynMemberDefn.ImplicitCtor(ctorArgs= SynSimplePats.SimplePats(pats, _)) when (not pats.IsEmpty) && reportErrorOnStaticClass -> for pat in pats do errorR(Error(FSComp.SR.chkErrorOnStaticClasses "constructor arguments are", pat.Range)) - false + true | SynMemberDefn.Member(SynBinding(valData = SynValData(Some memberFlags, _, _)), m) when memberFlags.MemberKind = SynMemberKind.Constructor && reportErrorOnStaticClass -> - errorR(Error(FSComp.SR.chkErrorOnStaticClasses "additional constructors are", m)); false + errorR(Error(FSComp.SR.chkErrorOnStaticClasses "additional constructors are", m)); + true | SynMemberDefn.Interface _ | SynMemberDefn.Member _ | SynMemberDefn.GetSetMember _ diff --git a/tests/FSharp.Compiler.ComponentTests/Language/StaticClassTests.fs b/tests/FSharp.Compiler.ComponentTests/Language/StaticClassTests.fs index 5b61c318b81..88273515dcc 100644 --- a/tests/FSharp.Compiler.ComponentTests/Language/StaticClassTests.fs +++ b/tests/FSharp.Compiler.ComponentTests/Language/StaticClassTests.fs @@ -160,8 +160,10 @@ type B = ] - [] - let ``Annoying bug``() = + [] + [] + [] + let ``Annoying bug``(langVersion) = let code = """ module Test @@ -170,7 +172,7 @@ type B = [] [>)>] [] - [] + [] type MyCustomList<'T> = | Empty | NonEmpty of Head: 'T * Tail: MyCustomList<'T> @@ -198,5 +200,6 @@ type B = """ Fs code + |> withLangVersion langVersion |> compile |> shouldSucceed \ No newline at end of file From c17acae03c0288a066d460f05a5c3ac8ebf002d2 Mon Sep 17 00:00:00 2001 From: Tomas Grosup Date: Thu, 29 Dec 2022 12:05:11 +0100 Subject: [PATCH 05/11] Fix the general case, leaving out a comment of what is wrong => this solution is not production ready --- src/Compiler/Checking/CheckDeclarations.fs | 13 ++++++++----- .../Language/StaticClassTests.fs | 4 ++-- 2 files changed, 10 insertions(+), 7 deletions(-) diff --git a/src/Compiler/Checking/CheckDeclarations.fs b/src/Compiler/Checking/CheckDeclarations.fs index b17601994e7..f1b7f5ede5e 100644 --- a/src/Compiler/Checking/CheckDeclarations.fs +++ b/src/Compiler/Checking/CheckDeclarations.fs @@ -4027,15 +4027,18 @@ module TcDeclarations = /// where simpleRepr can contain inherit type, declared fields and virtual slots. /// body = members /// where members contain methods/overrides, also implicit ctor, inheritCall and local definitions. - let rec private SplitTyconDefn (cenv: cenv) envInitial (SynTypeDefn(typeInfo=synTyconInfo;typeRepr=trepr; members=extraMembers)) = + let rec private SplitTyconDefn (g:TcGlobals) (SynTypeDefn(typeInfo=synTyconInfo;typeRepr=trepr; members=extraMembers)) = let extraMembers = desugarGetSetMembers extraMembers let implements1 = List.choose (function SynMemberDefn.Interface (interfaceType=ty) -> Some(ty, ty.Range) | _ -> None) extraMembers let reportErrorOnStaticClass = - cenv.g.langVersion.SupportsFeature(LanguageFeature.ErrorReportingOnStaticClasses) && + g.langVersion.SupportsFeature(LanguageFeature.ErrorReportingOnStaticClasses) && (let (SynComponentInfo(attributes=Attributes(synAttrs))) = synTyconInfo - let attrs = TcAttributes cenv envInitial AttributeTargets.TyconDecl synAttrs - let isStaticClass = HasFSharpAttribute cenv.g cenv.g.attrib_SealedAttribute attrs && HasFSharpAttribute cenv.g cenv.g.attrib_AbstractClassAttribute attrs + let hasAttr possibleNames = synAttrs |> List.exists (fun a -> possibleNames |> Array.contains (a.TypeName.LongIdent |> List.last).idText) + let isStaticClass = hasAttr [|"SealedAttribute";"Sealed"|] && hasAttr [|"AbstractClassAttribute";"AbstractClass"|] + // At this point in time, type checking attributes is too soon. Possibly, this entire check could move to be done after recursive definitions are processed. + // Or, use attribute scanning that will not do eager type checking, but only scan for Selaed and AbstractClass attributes from the runtime -> those will not suffer from mut-rec problem + // Current string solution of course is bad, because that matches any attribute with that name, even user defined. isStaticClass) @@ -4220,7 +4223,7 @@ module TcDeclarations = // Split the definitions into "core representations" and "members". The code to process core representations // is shared between processing of signature files and implementation files. - let mutRecDefnsAfterSplit = MutRecShapes.mapTycons (SplitTyconDefn cenv envInitial) mutRecDefns + let mutRecDefnsAfterSplit = MutRecShapes.mapTycons (SplitTyconDefn cenv.g) mutRecDefns // Create the entities for each module and type definition, and process the core representation of each type definition. let tycons, envMutRecPrelim, mutRecDefnsAfterCore = diff --git a/tests/FSharp.Compiler.ComponentTests/Language/StaticClassTests.fs b/tests/FSharp.Compiler.ComponentTests/Language/StaticClassTests.fs index 88273515dcc..6fd720477f0 100644 --- a/tests/FSharp.Compiler.ComponentTests/Language/StaticClassTests.fs +++ b/tests/FSharp.Compiler.ComponentTests/Language/StaticClassTests.fs @@ -98,14 +98,14 @@ type T = Fsx """ [] type T(x: int) = - new () = {} + new () = T(42) """ |> withLangVersionPreview |> compile |> shouldFail |> withDiagnostics [ (Error 3551, Line 3, Col 8, Line 3, Col 14, "if a type uses both [] and [] it means it is static. No constructor arguments are allowed") - (Error 3551, Line 4, Col 5, Line 4, Col 16, "if a type uses both [] and [] it means it is static. No additional constructors are allowed") + (Error 3551, Line 4, Col 5, Line 4, Col 19, "if a type uses both [] and [] it means it is static. No additional constructors are allowed") ] [] From 9df0f5042cdb9dd9a623f44a07aff1217bbbbc37 Mon Sep 17 00:00:00 2001 From: Edgar Gonzalez Date: Thu, 29 Dec 2022 22:54:47 +0100 Subject: [PATCH 06/11] Move the static elements check after the type check --- src/Compiler/Checking/CheckDeclarations.fs | 66 ++++++++++++------- .../Language/StaticClassTests.fs | 3 +- 2 files changed, 45 insertions(+), 24 deletions(-) diff --git a/src/Compiler/Checking/CheckDeclarations.fs b/src/Compiler/Checking/CheckDeclarations.fs index f1b7f5ede5e..f2a143e460c 100644 --- a/src/Compiler/Checking/CheckDeclarations.fs +++ b/src/Compiler/Checking/CheckDeclarations.fs @@ -4027,21 +4027,10 @@ module TcDeclarations = /// where simpleRepr can contain inherit type, declared fields and virtual slots. /// body = members /// where members contain methods/overrides, also implicit ctor, inheritCall and local definitions. - let rec private SplitTyconDefn (g:TcGlobals) (SynTypeDefn(typeInfo=synTyconInfo;typeRepr=trepr; members=extraMembers)) = + let rec private SplitTyconDefn (SynTypeDefn(typeInfo=synTyconInfo;typeRepr=trepr; members=extraMembers)) = let extraMembers = desugarGetSetMembers extraMembers let implements1 = List.choose (function SynMemberDefn.Interface (interfaceType=ty) -> Some(ty, ty.Range) | _ -> None) extraMembers - - let reportErrorOnStaticClass = - g.langVersion.SupportsFeature(LanguageFeature.ErrorReportingOnStaticClasses) && - (let (SynComponentInfo(attributes=Attributes(synAttrs))) = synTyconInfo - let hasAttr possibleNames = synAttrs |> List.exists (fun a -> possibleNames |> Array.contains (a.TypeName.LongIdent |> List.last).idText) - let isStaticClass = hasAttr [|"SealedAttribute";"Sealed"|] && hasAttr [|"AbstractClassAttribute";"AbstractClass"|] - // At this point in time, type checking attributes is too soon. Possibly, this entire check could move to be done after recursive definitions are processed. - // Or, use attribute scanning that will not do eager type checking, but only scan for Selaed and AbstractClass attributes from the runtime -> those will not suffer from mut-rec problem - // Current string solution of course is bad, because that matches any attribute with that name, even user defined. - isStaticClass) - - + match trepr with | SynTypeDefnRepr.ObjectModel(kind, cspec, m) -> let cspec = desugarGetSetMembers cspec @@ -4060,13 +4049,6 @@ module TcDeclarations = let membersIncludingAutoProps = cspec |> List.filter (fun memb -> match memb with - | SynMemberDefn.ImplicitCtor(ctorArgs= SynSimplePats.SimplePats(pats, _)) when (not pats.IsEmpty) && reportErrorOnStaticClass -> - for pat in pats do - errorR(Error(FSComp.SR.chkErrorOnStaticClasses "constructor arguments are", pat.Range)) - true - | SynMemberDefn.Member(SynBinding(valData = SynValData(Some memberFlags, _, _)), m) when memberFlags.MemberKind = SynMemberKind.Constructor && reportErrorOnStaticClass -> - errorR(Error(FSComp.SR.chkErrorOnStaticClasses "additional constructors are", m)); - true | SynMemberDefn.Interface _ | SynMemberDefn.Member _ | SynMemberDefn.GetSetMember _ @@ -4223,7 +4205,7 @@ module TcDeclarations = // Split the definitions into "core representations" and "members". The code to process core representations // is shared between processing of signature files and implementation files. - let mutRecDefnsAfterSplit = MutRecShapes.mapTycons (SplitTyconDefn cenv.g) mutRecDefns + let mutRecDefnsAfterSplit = mutRecDefns |> MutRecShapes.mapTycons SplitTyconDefn // Create the entities for each module and type definition, and process the core representation of each type definition. let tycons, envMutRecPrelim, mutRecDefnsAfterCore = @@ -4856,7 +4838,7 @@ let rec TcModuleOrNamespaceElementNonMutRec (cenv: cenv) parent typeNames scopem let moduleEntity = Construct.NewModuleOrNamespace (Some env.eCompPath) vis id xmlDoc modAttrs (MaybeLazy.Strict moduleTy) // Now typecheck. - let! moduleContents, topAttrsNew, envAtEnd = TcModuleOrNamespaceElements cenv (Parent (mkLocalModuleRef moduleEntity)) endm envForModule xml None [] moduleDefs + let! moduleContents, topAttrsNew, envAtEnd = TcModuleOrNamespaceElements cenv (Parent (mkLocalModuleRef moduleEntity)) endm envForModule xml None [] moduleDefs // Get the inferred type of the decls and record it in the modul. moduleEntity.entity_modul_type <- MaybeLazy.Strict moduleTyAcc.Value @@ -4945,6 +4927,15 @@ let rec TcModuleOrNamespaceElementNonMutRec (cenv: cenv) parent typeNames scopem MutRecBindingChecking.TcMutRecDefns_UpdateNSContents nsInfo + if cenv.g.langVersion.SupportsFeature(LanguageFeature.ErrorReportingOnStaticClasses) then + do for def in defs do + match def with + | SynModuleDecl.NestedModule(decls = synModuleDecls) -> + CheckStaticClassElements cenv envAtEnd synModuleDecls + | _ -> () + + + let env, openDecls = if isNil enclosingNamespacePath then envAtEnd, [] @@ -5093,6 +5084,37 @@ and TcMutRecDefsFinish cenv defs m = [ ModuleOrNamespaceBinding.Module(moduleEntity, moduleContents) ]) TMDefRec(true, opens, tycons, binds, m) + +and CheckStaticClassElements cenv env (synModuleDecls: SynModuleDecl list) = + let typeDefs = + synModuleDecls + |> List.collect (fun decl -> + match decl with + | SynModuleDecl.Types (typeDefns = typeDefs) -> typeDefs + | _ -> []) + |> List.choose (fun synTypeDef -> + match synTypeDef with + | SynTypeDefn(typeInfo= synTyconInfo; typeRepr= trepr; members= extraMembers) -> + let (SynComponentInfo(attributes=Attributes(synAttrs))) = synTyconInfo + Some (TcAttributes cenv env AttributeTargets.TyconDecl synAttrs, trepr, extraMembers)) + + for attrs, tRepr, _members in typeDefs do + let isStaticClass = HasFSharpAttribute cenv.g cenv.g.attrib_SealedAttribute attrs && HasFSharpAttribute cenv.g cenv.g.attrib_AbstractClassAttribute attrs + + if isStaticClass then + match tRepr with + | SynTypeDefnRepr.ObjectModel(_, synMemberDefns, _) -> + let cspec = desugarGetSetMembers synMemberDefns + for memb in cspec do + match memb with + | SynMemberDefn.ImplicitCtor(ctorArgs= SynSimplePats.SimplePats(pats, _)) when (not pats.IsEmpty) -> + for pat in pats do + errorR(Error(FSComp.SR.chkErrorOnStaticClasses "constructor arguments are", pat.Range)) + + | SynMemberDefn.Member(SynBinding(valData = SynValData(Some memberFlags, _, _)), m) when memberFlags.MemberKind = SynMemberKind.Constructor -> + errorR(Error(FSComp.SR.chkErrorOnStaticClasses "additional constructors are", m)); + | _ -> () + | _ -> () and TcModuleOrNamespaceElements cenv parent endm env xml mutRecNSInfo openDecls0 synModuleDecls = cancellable { diff --git a/tests/FSharp.Compiler.ComponentTests/Language/StaticClassTests.fs b/tests/FSharp.Compiler.ComponentTests/Language/StaticClassTests.fs index 6fd720477f0..8157113586a 100644 --- a/tests/FSharp.Compiler.ComponentTests/Language/StaticClassTests.fs +++ b/tests/FSharp.Compiler.ComponentTests/Language/StaticClassTests.fs @@ -159,11 +159,10 @@ type B = (Error 3551, Line 6, Col 5, Line 6, Col 30, "if a type uses both [] and [] it means it is static. No additional constructors are allowed") ] - [] [] [] - let ``Annoying bug``(langVersion) = + let ``Mutually recursive type definition that using custom attributes``(langVersion) = let code = """ module Test From 79b01cf3e169891ac2c9649aa105d8f7dec54987 Mon Sep 17 00:00:00 2001 From: Edgar Gonzalez Date: Mon, 2 Jan 2023 20:31:17 +0100 Subject: [PATCH 07/11] Move the static class check where attributes are no longer SynAttrs, but already typed --- src/Compiler/Checking/CheckDeclarations.fs | 61 ++++++------------- src/Compiler/FSComp.txt | 2 +- .../Language/StaticClassTests.fs | 12 ++-- 3 files changed, 25 insertions(+), 50 deletions(-) diff --git a/src/Compiler/Checking/CheckDeclarations.fs b/src/Compiler/Checking/CheckDeclarations.fs index f2a143e460c..03bcc8e50f5 100644 --- a/src/Compiler/Checking/CheckDeclarations.fs +++ b/src/Compiler/Checking/CheckDeclarations.fs @@ -1654,6 +1654,18 @@ module MutRecBindingChecking = mBinds defnsEs, envMutRec + +let private CheckStaticClassElements (synMembers: SynMemberDefn list) = + for mem in synMembers do + match mem with + | SynMemberDefn.ImplicitCtor(ctorArgs= SynSimplePats.SimplePats(pats= pats)) when (not pats.IsEmpty) -> + for pat in pats do + errorR(Error(FSComp.SR.chkErrorOnStaticClasses "constructor arguments are", pat.Range)) + + | SynMemberDefn.Member(SynBinding(valData = SynValData(memberFlags = Some memberFlags)), m) when memberFlags.MemberKind = SynMemberKind.Constructor -> + errorR(Error(FSComp.SR.chkErrorOnStaticClasses "additional constructors are", m)); + | _ -> () + /// Check and generalize the interface implementations, members, 'let' definitions in a mutually recursive group of definitions. let TcMutRecDefns_Phase2 (cenv: cenv) envInitial mBinds scopem mutRecNSInfo (envMutRec: TcEnv) (mutRecDefns: MutRecDefnsPhase2Data) isMutRec = @@ -1755,7 +1767,11 @@ let TcMutRecDefns_Phase2 (cenv: cenv) envInitial mBinds scopem mutRecNSInfo (env let binds: MutRecDefnsPhase2Info = (envMutRec, mutRecDefns) ||> MutRecShapes.mapTyconsWithEnv (fun envForDecls tyconData -> - let (MutRecDefnsPhase2DataForTycon(tyconOpt, _, declKind, tcref, _, _, declaredTyconTypars, _, _, _, fixupFinalAttrs)) = tyconData + let (MutRecDefnsPhase2DataForTycon(tyconOpt, _x, declKind, tcref, _, _, declaredTyconTypars, synMembers, _, _, fixupFinalAttrs)) = tyconData + let isStaticClass = HasFSharpAttribute cenv.g cenv.g.attrib_SealedAttribute tcref.Attribs && HasFSharpAttribute cenv.g cenv.g.attrib_AbstractClassAttribute tcref.Attribs + if isStaticClass && cenv.g.langVersion.SupportsFeature(LanguageFeature.ErrorReportingOnStaticClasses) then + CheckStaticClassElements synMembers + let envForDecls = // This allows to implement protected interface methods if it's a DIM. // Does not need to be hidden behind a lang version as it needs to be possible to @@ -4925,17 +4941,7 @@ let rec TcModuleOrNamespaceElementNonMutRec (cenv: cenv) parent typeNames scopem let! moduleContents, topAttrs, envAtEnd = TcModuleOrNamespaceElements cenv parent endm envNS xml mutRecNSInfo [] defs - MutRecBindingChecking.TcMutRecDefns_UpdateNSContents nsInfo - - if cenv.g.langVersion.SupportsFeature(LanguageFeature.ErrorReportingOnStaticClasses) then - do for def in defs do - match def with - | SynModuleDecl.NestedModule(decls = synModuleDecls) -> - CheckStaticClassElements cenv envAtEnd synModuleDecls - | _ -> () - - - + MutRecBindingChecking.TcMutRecDefns_UpdateNSContents nsInfo let env, openDecls = if isNil enclosingNamespacePath then envAtEnd, [] @@ -5084,37 +5090,6 @@ and TcMutRecDefsFinish cenv defs m = [ ModuleOrNamespaceBinding.Module(moduleEntity, moduleContents) ]) TMDefRec(true, opens, tycons, binds, m) - -and CheckStaticClassElements cenv env (synModuleDecls: SynModuleDecl list) = - let typeDefs = - synModuleDecls - |> List.collect (fun decl -> - match decl with - | SynModuleDecl.Types (typeDefns = typeDefs) -> typeDefs - | _ -> []) - |> List.choose (fun synTypeDef -> - match synTypeDef with - | SynTypeDefn(typeInfo= synTyconInfo; typeRepr= trepr; members= extraMembers) -> - let (SynComponentInfo(attributes=Attributes(synAttrs))) = synTyconInfo - Some (TcAttributes cenv env AttributeTargets.TyconDecl synAttrs, trepr, extraMembers)) - - for attrs, tRepr, _members in typeDefs do - let isStaticClass = HasFSharpAttribute cenv.g cenv.g.attrib_SealedAttribute attrs && HasFSharpAttribute cenv.g cenv.g.attrib_AbstractClassAttribute attrs - - if isStaticClass then - match tRepr with - | SynTypeDefnRepr.ObjectModel(_, synMemberDefns, _) -> - let cspec = desugarGetSetMembers synMemberDefns - for memb in cspec do - match memb with - | SynMemberDefn.ImplicitCtor(ctorArgs= SynSimplePats.SimplePats(pats, _)) when (not pats.IsEmpty) -> - for pat in pats do - errorR(Error(FSComp.SR.chkErrorOnStaticClasses "constructor arguments are", pat.Range)) - - | SynMemberDefn.Member(SynBinding(valData = SynValData(Some memberFlags, _, _)), m) when memberFlags.MemberKind = SynMemberKind.Constructor -> - errorR(Error(FSComp.SR.chkErrorOnStaticClasses "additional constructors are", m)); - | _ -> () - | _ -> () and TcModuleOrNamespaceElements cenv parent endm env xml mutRecNSInfo openDecls0 synModuleDecls = cancellable { diff --git a/src/Compiler/FSComp.txt b/src/Compiler/FSComp.txt index 91d7e90d6a9..de94d4ed5f5 100644 --- a/src/Compiler/FSComp.txt +++ b/src/Compiler/FSComp.txt @@ -1665,4 +1665,4 @@ reprStateMachineInvalidForm,"The state machine has an unexpected form" 3549,tcSynTypeOrInvalidInDeclaration,"SynType.Or is not permitted in this declaration" 3550,chkDuplicatedMethodParameter,"Duplicate parameter. The parameter '%s' has been used more that once in this method." featureEscapeBracesInFormattableString,"Escapes curly braces before calling FormattableStringFactory.Create when interpolated string literal is typed as FormattableString" -3551,chkErrorOnStaticClasses,"if a type uses both [] and [] it means it is static. No %s allowed" \ No newline at end of file +3552,chkErrorOnStaticClasses,"if a type uses both [] and [] it means it is static. No %s allowed" \ No newline at end of file diff --git a/tests/FSharp.Compiler.ComponentTests/Language/StaticClassTests.fs b/tests/FSharp.Compiler.ComponentTests/Language/StaticClassTests.fs index 8157113586a..03dab99b660 100644 --- a/tests/FSharp.Compiler.ComponentTests/Language/StaticClassTests.fs +++ b/tests/FSharp.Compiler.ComponentTests/Language/StaticClassTests.fs @@ -55,7 +55,7 @@ type T(x: int) = class end |> compile |> shouldFail |> withDiagnostics [ - (Error 3551, Line 3, Col 8, Line 3, Col 14, "if a type uses both [] and [] it means it is static. No constructor arguments are allowed") + (Error 3552, Line 3, Col 8, Line 3, Col 14, "if a type uses both [] and [] it means it is static. No constructor arguments are allowed") ] [] @@ -79,7 +79,7 @@ type T = |> compile |> shouldFail |> withDiagnostics [ - (Error 3551, Line 4, Col 5, Line 4, Col 16, "if a type uses both [] and [] it means it is static. No additional constructors are allowed") + (Error 3552, Line 4, Col 5, Line 4, Col 16, "if a type uses both [] and [] it means it is static. No additional constructors are allowed") ] [] @@ -104,8 +104,8 @@ type T(x: int) = |> compile |> shouldFail |> withDiagnostics [ - (Error 3551, Line 3, Col 8, Line 3, Col 14, "if a type uses both [] and [] it means it is static. No constructor arguments are allowed") - (Error 3551, Line 4, Col 5, Line 4, Col 19, "if a type uses both [] and [] it means it is static. No additional constructors are allowed") + (Error 3552, Line 3, Col 8, Line 3, Col 14, "if a type uses both [] and [] it means it is static. No constructor arguments are allowed") + (Error 3552, Line 4, Col 5, Line 4, Col 19, "if a type uses both [] and [] it means it is static. No additional constructors are allowed") ] [] @@ -140,7 +140,7 @@ type ListDebugView<'T>(l: 'T list) = class end |> compile |> shouldFail |> withDiagnostics [ - (Error 3551, Line 3, Col 24, Line 3, Col 34, "if a type uses both [] and [] it means it is static. No constructor arguments are allowed") + (Error 3552, Line 3, Col 24, Line 3, Col 34, "if a type uses both [] and [] it means it is static. No constructor arguments are allowed") ] [] @@ -156,7 +156,7 @@ type B = |> compile |> shouldFail |> withDiagnostics [ - (Error 3551, Line 6, Col 5, Line 6, Col 30, "if a type uses both [] and [] it means it is static. No additional constructors are allowed") + (Error 3552, Line 6, Col 5, Line 6, Col 30, "if a type uses both [] and [] it means it is static. No additional constructors are allowed") ] [] From ba89f419fc4fe892b246f01b4ec4956e676df40f Mon Sep 17 00:00:00 2001 From: Edgar Gonzalez Date: Tue, 3 Jan 2023 21:35:57 +0100 Subject: [PATCH 08/11] Update FSComp to include a new error message --- src/Compiler/FSComp.txt | 3 ++- src/Compiler/xlf/FSComp.txt.cs.xlf | 15 ++++++++++----- src/Compiler/xlf/FSComp.txt.de.xlf | 15 ++++++++++----- src/Compiler/xlf/FSComp.txt.es.xlf | 15 ++++++++++----- src/Compiler/xlf/FSComp.txt.fr.xlf | 15 ++++++++++----- src/Compiler/xlf/FSComp.txt.it.xlf | 15 ++++++++++----- src/Compiler/xlf/FSComp.txt.ja.xlf | 15 ++++++++++----- src/Compiler/xlf/FSComp.txt.ko.xlf | 15 ++++++++++----- src/Compiler/xlf/FSComp.txt.pl.xlf | 15 ++++++++++----- src/Compiler/xlf/FSComp.txt.pt-BR.xlf | 15 ++++++++++----- src/Compiler/xlf/FSComp.txt.ru.xlf | 15 ++++++++++----- src/Compiler/xlf/FSComp.txt.tr.xlf | 15 ++++++++++----- src/Compiler/xlf/FSComp.txt.zh-Hans.xlf | 15 ++++++++++----- src/Compiler/xlf/FSComp.txt.zh-Hant.xlf | 15 ++++++++++----- 14 files changed, 132 insertions(+), 66 deletions(-) diff --git a/src/Compiler/FSComp.txt b/src/Compiler/FSComp.txt index 7605cf432de..9022743033c 100644 --- a/src/Compiler/FSComp.txt +++ b/src/Compiler/FSComp.txt @@ -1666,4 +1666,5 @@ reprStateMachineInvalidForm,"The state machine has an unexpected form" 3550,chkDuplicatedMethodParameter,"Duplicate parameter. The parameter '%s' has been used more that once in this method." featureEscapeBracesInFormattableString,"Escapes curly braces before calling FormattableStringFactory.Create when interpolated string literal is typed as FormattableString" 3551,buildDuplicateFile,"The source file '%s' (at position %d/%d) already appeared in the compilation list (at position %d/%d). Please verify that it is included only once in the project file." -3552,chkErrorOnStaticClasses,"if a type uses both [] and [] it means it is static. No %s allowed" +3552,chkConstructorWithArgumentsOnStaticClasses,"If a type uses both [] and [] attributes, it means it is static. constructor with arguments is not allowed." +3553,chkAdditionalConstructorOnStaticClasses,"If a type uses both [] and [] attributes, it means it is static. additional constructor is not allowed." diff --git a/src/Compiler/xlf/FSComp.txt.cs.xlf b/src/Compiler/xlf/FSComp.txt.cs.xlf index d9948e3d7a6..52d93f3e0c9 100644 --- a/src/Compiler/xlf/FSComp.txt.cs.xlf +++ b/src/Compiler/xlf/FSComp.txt.cs.xlf @@ -22,16 +22,21 @@ Soubor {0} má nerozpoznanou příponu. Zdrojové soubory musí mít příponu .fs, .fsi, .fsx nebo .fsscript. + + If a type uses both [<Sealed>] and [<AbstractClass>] attributes, it means it is static. additional constructor is not allowed. + If a type uses both [<Sealed>] and [<AbstractClass>] attributes, it means it is static. additional constructor is not allowed. + + + + If a type uses both [<Sealed>] and [<AbstractClass>] attributes, it means it is static. constructor with arguments is not allowed. + If a type uses both [<Sealed>] and [<AbstractClass>] attributes, it means it is static. constructor with arguments is not allowed. + + Duplicate parameter. The parameter '{0}' has been used more that once in this method. Duplicate parameter. The parameter '{0}' has been used more that once in this method. - - if a type uses both [<Sealed>] and [<AbstractClass>] it means it is static. No {0} allowed - if a type uses both [<Sealed>] and [<AbstractClass>] it means it is static. No {0} allowed - - Feature '{0}' is not available in F# {1}. Please use language version {2} or greater. Funkce {0} není v jazyce F# {1} dostupná. Použijte prosím jazyk verze {2} nebo vyšší. diff --git a/src/Compiler/xlf/FSComp.txt.de.xlf b/src/Compiler/xlf/FSComp.txt.de.xlf index 552c49a4d05..4005c4b8078 100644 --- a/src/Compiler/xlf/FSComp.txt.de.xlf +++ b/src/Compiler/xlf/FSComp.txt.de.xlf @@ -22,16 +22,21 @@ Die Dateierweiterung von „{0}“ wurde nicht erkannt. Quelldateien müssen die Erweiterung .fs, .fsi, .fsx oder .fsscript haben + + If a type uses both [<Sealed>] and [<AbstractClass>] attributes, it means it is static. additional constructor is not allowed. + If a type uses both [<Sealed>] and [<AbstractClass>] attributes, it means it is static. additional constructor is not allowed. + + + + If a type uses both [<Sealed>] and [<AbstractClass>] attributes, it means it is static. constructor with arguments is not allowed. + If a type uses both [<Sealed>] and [<AbstractClass>] attributes, it means it is static. constructor with arguments is not allowed. + + Duplicate parameter. The parameter '{0}' has been used more that once in this method. Duplicate parameter. The parameter '{0}' has been used more that once in this method. - - if a type uses both [<Sealed>] and [<AbstractClass>] it means it is static. No {0} allowed - if a type uses both [<Sealed>] and [<AbstractClass>] it means it is static. No {0} allowed - - Feature '{0}' is not available in F# {1}. Please use language version {2} or greater. Das Feature "{0}" ist in F# {1} nicht verfügbar. Verwenden Sie Sprachversion {2} oder höher. diff --git a/src/Compiler/xlf/FSComp.txt.es.xlf b/src/Compiler/xlf/FSComp.txt.es.xlf index 016b674c6b4..7f6046a7ea0 100644 --- a/src/Compiler/xlf/FSComp.txt.es.xlf +++ b/src/Compiler/xlf/FSComp.txt.es.xlf @@ -22,16 +22,21 @@ No se reconoce la extensión de archivo de '{0}'. Los archivos de código fuente deben tener las extensiones .fs, .fsi, .fsx o .fsscript + + If a type uses both [<Sealed>] and [<AbstractClass>] attributes, it means it is static. additional constructor is not allowed. + If a type uses both [<Sealed>] and [<AbstractClass>] attributes, it means it is static. additional constructor is not allowed. + + + + If a type uses both [<Sealed>] and [<AbstractClass>] attributes, it means it is static. constructor with arguments is not allowed. + If a type uses both [<Sealed>] and [<AbstractClass>] attributes, it means it is static. constructor with arguments is not allowed. + + Duplicate parameter. The parameter '{0}' has been used more that once in this method. Duplicate parameter. The parameter '{0}' has been used more that once in this method. - - if a type uses both [<Sealed>] and [<AbstractClass>] it means it is static. No {0} allowed - if a type uses both [<Sealed>] and [<AbstractClass>] it means it is static. No {0} allowed - - Feature '{0}' is not available in F# {1}. Please use language version {2} or greater. La característica "{0}" no está disponible en F# {1}. Use la versión {2} del lenguaje o una posterior. diff --git a/src/Compiler/xlf/FSComp.txt.fr.xlf b/src/Compiler/xlf/FSComp.txt.fr.xlf index 6905c0a0d88..b8c0aa42df1 100644 --- a/src/Compiler/xlf/FSComp.txt.fr.xlf +++ b/src/Compiler/xlf/FSComp.txt.fr.xlf @@ -22,16 +22,21 @@ L'extension de fichier de '{0}' n'est pas reconnue. Les fichiers sources doivent avoir l'extension .fs, .fsi, .fsx, ou .fsscript. + + If a type uses both [<Sealed>] and [<AbstractClass>] attributes, it means it is static. additional constructor is not allowed. + If a type uses both [<Sealed>] and [<AbstractClass>] attributes, it means it is static. additional constructor is not allowed. + + + + If a type uses both [<Sealed>] and [<AbstractClass>] attributes, it means it is static. constructor with arguments is not allowed. + If a type uses both [<Sealed>] and [<AbstractClass>] attributes, it means it is static. constructor with arguments is not allowed. + + Duplicate parameter. The parameter '{0}' has been used more that once in this method. Duplicate parameter. The parameter '{0}' has been used more that once in this method. - - if a type uses both [<Sealed>] and [<AbstractClass>] it means it is static. No {0} allowed - if a type uses both [<Sealed>] and [<AbstractClass>] it means it is static. No {0} allowed - - Feature '{0}' is not available in F# {1}. Please use language version {2} or greater. La fonctionnalité '{0}' n'est pas disponible en F# {1}. Utilisez la version de langage {2} ou une version ultérieure. diff --git a/src/Compiler/xlf/FSComp.txt.it.xlf b/src/Compiler/xlf/FSComp.txt.it.xlf index bd2bdfe1fca..08debfef071 100644 --- a/src/Compiler/xlf/FSComp.txt.it.xlf +++ b/src/Compiler/xlf/FSComp.txt.it.xlf @@ -22,16 +22,21 @@ Estensione di file di '{0}' non riconosciuta. I file di origine devono avere estensione .fs, .fsi, .fsx or .fsscript + + If a type uses both [<Sealed>] and [<AbstractClass>] attributes, it means it is static. additional constructor is not allowed. + If a type uses both [<Sealed>] and [<AbstractClass>] attributes, it means it is static. additional constructor is not allowed. + + + + If a type uses both [<Sealed>] and [<AbstractClass>] attributes, it means it is static. constructor with arguments is not allowed. + If a type uses both [<Sealed>] and [<AbstractClass>] attributes, it means it is static. constructor with arguments is not allowed. + + Duplicate parameter. The parameter '{0}' has been used more that once in this method. Duplicate parameter. The parameter '{0}' has been used more that once in this method. - - if a type uses both [<Sealed>] and [<AbstractClass>] it means it is static. No {0} allowed - if a type uses both [<Sealed>] and [<AbstractClass>] it means it is static. No {0} allowed - - Feature '{0}' is not available in F# {1}. Please use language version {2} or greater. La funzionalità '{0}' non è disponibile in F# {1}. Usare la versione {2} o versioni successive del linguaggio. diff --git a/src/Compiler/xlf/FSComp.txt.ja.xlf b/src/Compiler/xlf/FSComp.txt.ja.xlf index fb4a486a5b5..19951b097f6 100644 --- a/src/Compiler/xlf/FSComp.txt.ja.xlf +++ b/src/Compiler/xlf/FSComp.txt.ja.xlf @@ -22,16 +22,21 @@ '{0}' のファイル拡張子は認識されません。ソース ファイルの拡張子は .fs、.fsi、.fsx、または .fsscript にする必要があります。 + + If a type uses both [<Sealed>] and [<AbstractClass>] attributes, it means it is static. additional constructor is not allowed. + If a type uses both [<Sealed>] and [<AbstractClass>] attributes, it means it is static. additional constructor is not allowed. + + + + If a type uses both [<Sealed>] and [<AbstractClass>] attributes, it means it is static. constructor with arguments is not allowed. + If a type uses both [<Sealed>] and [<AbstractClass>] attributes, it means it is static. constructor with arguments is not allowed. + + Duplicate parameter. The parameter '{0}' has been used more that once in this method. Duplicate parameter. The parameter '{0}' has been used more that once in this method. - - if a type uses both [<Sealed>] and [<AbstractClass>] it means it is static. No {0} allowed - if a type uses both [<Sealed>] and [<AbstractClass>] it means it is static. No {0} allowed - - Feature '{0}' is not available in F# {1}. Please use language version {2} or greater. 機能 '{0}' は F# {1} では使用できません。{2} 以上の言語バージョンをお使いください。 diff --git a/src/Compiler/xlf/FSComp.txt.ko.xlf b/src/Compiler/xlf/FSComp.txt.ko.xlf index e0c7a7652a6..cfdaa467c57 100644 --- a/src/Compiler/xlf/FSComp.txt.ko.xlf +++ b/src/Compiler/xlf/FSComp.txt.ko.xlf @@ -22,16 +22,21 @@ '{0}'의 파일 확장명을 인식할 수 없습니다. 원본 파일의 확장명은 .fs, .fsi, .fsx 또는 .fsscript여야 합니다. + + If a type uses both [<Sealed>] and [<AbstractClass>] attributes, it means it is static. additional constructor is not allowed. + If a type uses both [<Sealed>] and [<AbstractClass>] attributes, it means it is static. additional constructor is not allowed. + + + + If a type uses both [<Sealed>] and [<AbstractClass>] attributes, it means it is static. constructor with arguments is not allowed. + If a type uses both [<Sealed>] and [<AbstractClass>] attributes, it means it is static. constructor with arguments is not allowed. + + Duplicate parameter. The parameter '{0}' has been used more that once in this method. Duplicate parameter. The parameter '{0}' has been used more that once in this method. - - if a type uses both [<Sealed>] and [<AbstractClass>] it means it is static. No {0} allowed - if a type uses both [<Sealed>] and [<AbstractClass>] it means it is static. No {0} allowed - - Feature '{0}' is not available in F# {1}. Please use language version {2} or greater. '{0}' 기능은 F# {1}에서 사용할 수 없습니다. {2} 이상의 언어 버전을 사용하세요. diff --git a/src/Compiler/xlf/FSComp.txt.pl.xlf b/src/Compiler/xlf/FSComp.txt.pl.xlf index d673c2626ef..a17a005ebf4 100644 --- a/src/Compiler/xlf/FSComp.txt.pl.xlf +++ b/src/Compiler/xlf/FSComp.txt.pl.xlf @@ -22,16 +22,21 @@ Rozszerzenie pliku "{0}" nie zostało rozpoznane. Pliki źródłowe muszą mieć rozszerzenie .fs, .fsi, .fsx lub .fsscript + + If a type uses both [<Sealed>] and [<AbstractClass>] attributes, it means it is static. additional constructor is not allowed. + If a type uses both [<Sealed>] and [<AbstractClass>] attributes, it means it is static. additional constructor is not allowed. + + + + If a type uses both [<Sealed>] and [<AbstractClass>] attributes, it means it is static. constructor with arguments is not allowed. + If a type uses both [<Sealed>] and [<AbstractClass>] attributes, it means it is static. constructor with arguments is not allowed. + + Duplicate parameter. The parameter '{0}' has been used more that once in this method. Duplicate parameter. The parameter '{0}' has been used more that once in this method. - - if a type uses both [<Sealed>] and [<AbstractClass>] it means it is static. No {0} allowed - if a type uses both [<Sealed>] and [<AbstractClass>] it means it is static. No {0} allowed - - Feature '{0}' is not available in F# {1}. Please use language version {2} or greater. Funkcja „{0}” nie jest dostępna w języku F# {1}. Użyj języka w wersji {2} lub nowszej. diff --git a/src/Compiler/xlf/FSComp.txt.pt-BR.xlf b/src/Compiler/xlf/FSComp.txt.pt-BR.xlf index 0c6af0530e3..53f56475de3 100644 --- a/src/Compiler/xlf/FSComp.txt.pt-BR.xlf +++ b/src/Compiler/xlf/FSComp.txt.pt-BR.xlf @@ -22,16 +22,21 @@ A extensão do arquivo de '{0}' não foi reconhecida. Os arquivos de origem devem ter a extensão .fs, .fsi, .fsx or .fsscript + + If a type uses both [<Sealed>] and [<AbstractClass>] attributes, it means it is static. additional constructor is not allowed. + If a type uses both [<Sealed>] and [<AbstractClass>] attributes, it means it is static. additional constructor is not allowed. + + + + If a type uses both [<Sealed>] and [<AbstractClass>] attributes, it means it is static. constructor with arguments is not allowed. + If a type uses both [<Sealed>] and [<AbstractClass>] attributes, it means it is static. constructor with arguments is not allowed. + + Duplicate parameter. The parameter '{0}' has been used more that once in this method. Duplicate parameter. The parameter '{0}' has been used more that once in this method. - - if a type uses both [<Sealed>] and [<AbstractClass>] it means it is static. No {0} allowed - if a type uses both [<Sealed>] and [<AbstractClass>] it means it is static. No {0} allowed - - Feature '{0}' is not available in F# {1}. Please use language version {2} or greater. O recurso '{0}' não está disponível no F# {1}. Use a versão da linguagem {2} ou superior. diff --git a/src/Compiler/xlf/FSComp.txt.ru.xlf b/src/Compiler/xlf/FSComp.txt.ru.xlf index c8270dcc229..ddb887d88d2 100644 --- a/src/Compiler/xlf/FSComp.txt.ru.xlf +++ b/src/Compiler/xlf/FSComp.txt.ru.xlf @@ -22,16 +22,21 @@ Расширение файла "{0}" не распознано. Исходные файлы должны иметь расширения FS, FSI, FSX или FSSCRIPT + + If a type uses both [<Sealed>] and [<AbstractClass>] attributes, it means it is static. additional constructor is not allowed. + If a type uses both [<Sealed>] and [<AbstractClass>] attributes, it means it is static. additional constructor is not allowed. + + + + If a type uses both [<Sealed>] and [<AbstractClass>] attributes, it means it is static. constructor with arguments is not allowed. + If a type uses both [<Sealed>] and [<AbstractClass>] attributes, it means it is static. constructor with arguments is not allowed. + + Duplicate parameter. The parameter '{0}' has been used more that once in this method. Duplicate parameter. The parameter '{0}' has been used more that once in this method. - - if a type uses both [<Sealed>] and [<AbstractClass>] it means it is static. No {0} allowed - if a type uses both [<Sealed>] and [<AbstractClass>] it means it is static. No {0} allowed - - Feature '{0}' is not available in F# {1}. Please use language version {2} or greater. Компонент "{0}" недоступен в F# {1}. Используйте версию языка {2} или выше. diff --git a/src/Compiler/xlf/FSComp.txt.tr.xlf b/src/Compiler/xlf/FSComp.txt.tr.xlf index 4c02b546f23..9b46b30928c 100644 --- a/src/Compiler/xlf/FSComp.txt.tr.xlf +++ b/src/Compiler/xlf/FSComp.txt.tr.xlf @@ -22,16 +22,21 @@ '{0}' kaynak dosyasının dosya uzantısı tanınmadı. Kaynak dosyaların uzantısı .fs, .fsi, .fsx veya .fsscript olmalıdır. + + If a type uses both [<Sealed>] and [<AbstractClass>] attributes, it means it is static. additional constructor is not allowed. + If a type uses both [<Sealed>] and [<AbstractClass>] attributes, it means it is static. additional constructor is not allowed. + + + + If a type uses both [<Sealed>] and [<AbstractClass>] attributes, it means it is static. constructor with arguments is not allowed. + If a type uses both [<Sealed>] and [<AbstractClass>] attributes, it means it is static. constructor with arguments is not allowed. + + Duplicate parameter. The parameter '{0}' has been used more that once in this method. Duplicate parameter. The parameter '{0}' has been used more that once in this method. - - if a type uses both [<Sealed>] and [<AbstractClass>] it means it is static. No {0} allowed - if a type uses both [<Sealed>] and [<AbstractClass>] it means it is static. No {0} allowed - - Feature '{0}' is not available in F# {1}. Please use language version {2} or greater. '{0}' özelliği F# {1} sürümünde kullanılamıyor. Lütfen {2} veya daha yüksek bir dil sürümünü kullanın. diff --git a/src/Compiler/xlf/FSComp.txt.zh-Hans.xlf b/src/Compiler/xlf/FSComp.txt.zh-Hans.xlf index 7b173c96099..1941e3624f5 100644 --- a/src/Compiler/xlf/FSComp.txt.zh-Hans.xlf +++ b/src/Compiler/xlf/FSComp.txt.zh-Hans.xlf @@ -22,16 +22,21 @@ 无法识别“{0}”的文件扩展名。源文件必须具有扩展名 .fs、.fsi、.fsx 或 .fsscript + + If a type uses both [<Sealed>] and [<AbstractClass>] attributes, it means it is static. additional constructor is not allowed. + If a type uses both [<Sealed>] and [<AbstractClass>] attributes, it means it is static. additional constructor is not allowed. + + + + If a type uses both [<Sealed>] and [<AbstractClass>] attributes, it means it is static. constructor with arguments is not allowed. + If a type uses both [<Sealed>] and [<AbstractClass>] attributes, it means it is static. constructor with arguments is not allowed. + + Duplicate parameter. The parameter '{0}' has been used more that once in this method. Duplicate parameter. The parameter '{0}' has been used more that once in this method. - - if a type uses both [<Sealed>] and [<AbstractClass>] it means it is static. No {0} allowed - if a type uses both [<Sealed>] and [<AbstractClass>] it means it is static. No {0} allowed - - Feature '{0}' is not available in F# {1}. Please use language version {2} or greater. 功能“{0}”在 F# {1} 中不可用。请使用 {2} 或更高的语言版本。 diff --git a/src/Compiler/xlf/FSComp.txt.zh-Hant.xlf b/src/Compiler/xlf/FSComp.txt.zh-Hant.xlf index 882b7b1812f..8c5642c1226 100644 --- a/src/Compiler/xlf/FSComp.txt.zh-Hant.xlf +++ b/src/Compiler/xlf/FSComp.txt.zh-Hant.xlf @@ -22,16 +22,21 @@ 無法辨識 '{0}' 的副檔名。來源檔案的副檔名必須是 .fs、.fsi、.fsx 或 .fsscript。 + + If a type uses both [<Sealed>] and [<AbstractClass>] attributes, it means it is static. additional constructor is not allowed. + If a type uses both [<Sealed>] and [<AbstractClass>] attributes, it means it is static. additional constructor is not allowed. + + + + If a type uses both [<Sealed>] and [<AbstractClass>] attributes, it means it is static. constructor with arguments is not allowed. + If a type uses both [<Sealed>] and [<AbstractClass>] attributes, it means it is static. constructor with arguments is not allowed. + + Duplicate parameter. The parameter '{0}' has been used more that once in this method. Duplicate parameter. The parameter '{0}' has been used more that once in this method. - - if a type uses both [<Sealed>] and [<AbstractClass>] it means it is static. No {0} allowed - if a type uses both [<Sealed>] and [<AbstractClass>] it means it is static. No {0} allowed - - Feature '{0}' is not available in F# {1}. Please use language version {2} or greater. F# {1} 中無法使用 '{0}' 功能。請使用語言版本 {2} 或更新的版本。 From dd40362619089ff48a92cf5a5a6b1de4218b08b3 Mon Sep 17 00:00:00 2001 From: Edgar Gonzalez Date: Tue, 3 Jan 2023 21:39:32 +0100 Subject: [PATCH 09/11] Use the new error messages --- src/Compiler/Checking/CheckDeclarations.fs | 13 +++++++------ .../Language/StaticClassTests.fs | 12 ++++++------ 2 files changed, 13 insertions(+), 12 deletions(-) diff --git a/src/Compiler/Checking/CheckDeclarations.fs b/src/Compiler/Checking/CheckDeclarations.fs index 03bcc8e50f5..22c6b3b0b0a 100644 --- a/src/Compiler/Checking/CheckDeclarations.fs +++ b/src/Compiler/Checking/CheckDeclarations.fs @@ -1654,19 +1654,18 @@ module MutRecBindingChecking = mBinds defnsEs, envMutRec - -let private CheckStaticClassElements (synMembers: SynMemberDefn list) = + +let private ReportErrorOnStaticClass (synMembers: SynMemberDefn list) = for mem in synMembers do match mem with | SynMemberDefn.ImplicitCtor(ctorArgs= SynSimplePats.SimplePats(pats= pats)) when (not pats.IsEmpty) -> for pat in pats do - errorR(Error(FSComp.SR.chkErrorOnStaticClasses "constructor arguments are", pat.Range)) + errorR(Error(FSComp.SR.chkConstructorWithArgumentsOnStaticClasses(), pat.Range)) | SynMemberDefn.Member(SynBinding(valData = SynValData(memberFlags = Some memberFlags)), m) when memberFlags.MemberKind = SynMemberKind.Constructor -> - errorR(Error(FSComp.SR.chkErrorOnStaticClasses "additional constructors are", m)); + errorR(Error(FSComp.SR.chkAdditionalConstructorOnStaticClasses(), m)); | _ -> () - /// Check and generalize the interface implementations, members, 'let' definitions in a mutually recursive group of definitions. let TcMutRecDefns_Phase2 (cenv: cenv) envInitial mBinds scopem mutRecNSInfo (envMutRec: TcEnv) (mutRecDefns: MutRecDefnsPhase2Data) isMutRec = let g = cenv.g @@ -1768,9 +1767,11 @@ let TcMutRecDefns_Phase2 (cenv: cenv) envInitial mBinds scopem mutRecNSInfo (env let binds: MutRecDefnsPhase2Info = (envMutRec, mutRecDefns) ||> MutRecShapes.mapTyconsWithEnv (fun envForDecls tyconData -> let (MutRecDefnsPhase2DataForTycon(tyconOpt, _x, declKind, tcref, _, _, declaredTyconTypars, synMembers, _, _, fixupFinalAttrs)) = tyconData + + // If a tye uses both [] and [] attributes it means it is a static class. let isStaticClass = HasFSharpAttribute cenv.g cenv.g.attrib_SealedAttribute tcref.Attribs && HasFSharpAttribute cenv.g cenv.g.attrib_AbstractClassAttribute tcref.Attribs if isStaticClass && cenv.g.langVersion.SupportsFeature(LanguageFeature.ErrorReportingOnStaticClasses) then - CheckStaticClassElements synMembers + ReportErrorOnStaticClass synMembers let envForDecls = // This allows to implement protected interface methods if it's a DIM. diff --git a/tests/FSharp.Compiler.ComponentTests/Language/StaticClassTests.fs b/tests/FSharp.Compiler.ComponentTests/Language/StaticClassTests.fs index 03dab99b660..848f5d18366 100644 --- a/tests/FSharp.Compiler.ComponentTests/Language/StaticClassTests.fs +++ b/tests/FSharp.Compiler.ComponentTests/Language/StaticClassTests.fs @@ -55,7 +55,7 @@ type T(x: int) = class end |> compile |> shouldFail |> withDiagnostics [ - (Error 3552, Line 3, Col 8, Line 3, Col 14, "if a type uses both [] and [] it means it is static. No constructor arguments are allowed") + (Error 3552, Line 3, Col 8, Line 3, Col 14, "If a type uses both [] and [] attributes, it means it is static. constructor with arguments is not allowed.") ] [] @@ -79,7 +79,7 @@ type T = |> compile |> shouldFail |> withDiagnostics [ - (Error 3552, Line 4, Col 5, Line 4, Col 16, "if a type uses both [] and [] it means it is static. No additional constructors are allowed") + (Error 3553, Line 4, Col 5, Line 4, Col 16, "If a type uses both [] and [] attributes, it means it is static. additional constructor is not allowed.") ] [] @@ -104,8 +104,8 @@ type T(x: int) = |> compile |> shouldFail |> withDiagnostics [ - (Error 3552, Line 3, Col 8, Line 3, Col 14, "if a type uses both [] and [] it means it is static. No constructor arguments are allowed") - (Error 3552, Line 4, Col 5, Line 4, Col 19, "if a type uses both [] and [] it means it is static. No additional constructors are allowed") + (Error 3552, Line 3, Col 8, Line 3, Col 14, "If a type uses both [] and [] attributes, it means it is static. constructor with arguments is not allowed.") + (Error 3553, Line 4, Col 5, Line 4, Col 19, "If a type uses both [] and [] attributes, it means it is static. additional constructor is not allowed.") ] [] @@ -140,7 +140,7 @@ type ListDebugView<'T>(l: 'T list) = class end |> compile |> shouldFail |> withDiagnostics [ - (Error 3552, Line 3, Col 24, Line 3, Col 34, "if a type uses both [] and [] it means it is static. No constructor arguments are allowed") + (Error 3552, Line 3, Col 24, Line 3, Col 34, "If a type uses both [] and [] attributes, it means it is static. constructor with arguments is not allowed.") ] [] @@ -156,7 +156,7 @@ type B = |> compile |> shouldFail |> withDiagnostics [ - (Error 3552, Line 6, Col 5, Line 6, Col 30, "if a type uses both [] and [] it means it is static. No additional constructors are allowed") + (Error 3553, Line 6, Col 5, Line 6, Col 30, "If a type uses both [] and [] attributes, it means it is static. additional constructor is not allowed.") ] [] From ba234353dfea399061b2a8fdfc8b89477a911548 Mon Sep 17 00:00:00 2001 From: Edgar Gonzalez Date: Thu, 5 Jan 2023 13:43:23 +0100 Subject: [PATCH 10/11] Update src/Compiler/Checking/CheckDeclarations.fs Co-authored-by: Petr Pokorny --- src/Compiler/Checking/CheckDeclarations.fs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Compiler/Checking/CheckDeclarations.fs b/src/Compiler/Checking/CheckDeclarations.fs index 22c6b3b0b0a..f37281a9334 100644 --- a/src/Compiler/Checking/CheckDeclarations.fs +++ b/src/Compiler/Checking/CheckDeclarations.fs @@ -1658,11 +1658,11 @@ module MutRecBindingChecking = let private ReportErrorOnStaticClass (synMembers: SynMemberDefn list) = for mem in synMembers do match mem with - | SynMemberDefn.ImplicitCtor(ctorArgs= SynSimplePats.SimplePats(pats= pats)) when (not pats.IsEmpty) -> + | SynMemberDefn.ImplicitCtor(ctorArgs = SynSimplePats.SimplePats(pats = pats)) when (not pats.IsEmpty) -> for pat in pats do errorR(Error(FSComp.SR.chkConstructorWithArgumentsOnStaticClasses(), pat.Range)) - | SynMemberDefn.Member(SynBinding(valData = SynValData(memberFlags = Some memberFlags)), m) when memberFlags.MemberKind = SynMemberKind.Constructor -> + | SynMemberDefn.Member(SynBinding(valData = SynValData(memberFlags = Some memberFlags)), m) when memberFlags.MemberKind = SynMemberKind.Constructor -> errorR(Error(FSComp.SR.chkAdditionalConstructorOnStaticClasses(), m)); | _ -> () From 5c14b0573b008dd8f462bdd0993740e1b641d520 Mon Sep 17 00:00:00 2001 From: Edgar Gonzalez Date: Thu, 5 Jan 2023 13:44:46 +0100 Subject: [PATCH 11/11] Fix capitalization --- src/Compiler/FSComp.txt | 4 ++-- src/Compiler/xlf/FSComp.txt.cs.xlf | 8 ++++---- src/Compiler/xlf/FSComp.txt.de.xlf | 8 ++++---- src/Compiler/xlf/FSComp.txt.es.xlf | 8 ++++---- src/Compiler/xlf/FSComp.txt.fr.xlf | 8 ++++---- src/Compiler/xlf/FSComp.txt.it.xlf | 8 ++++---- src/Compiler/xlf/FSComp.txt.ja.xlf | 8 ++++---- src/Compiler/xlf/FSComp.txt.ko.xlf | 8 ++++---- src/Compiler/xlf/FSComp.txt.pl.xlf | 8 ++++---- src/Compiler/xlf/FSComp.txt.pt-BR.xlf | 8 ++++---- src/Compiler/xlf/FSComp.txt.ru.xlf | 8 ++++---- src/Compiler/xlf/FSComp.txt.tr.xlf | 8 ++++---- src/Compiler/xlf/FSComp.txt.zh-Hans.xlf | 8 ++++---- src/Compiler/xlf/FSComp.txt.zh-Hant.xlf | 8 ++++---- .../Language/StaticClassTests.fs | 12 ++++++------ 15 files changed, 60 insertions(+), 60 deletions(-) diff --git a/src/Compiler/FSComp.txt b/src/Compiler/FSComp.txt index 9022743033c..f3093995c52 100644 --- a/src/Compiler/FSComp.txt +++ b/src/Compiler/FSComp.txt @@ -1666,5 +1666,5 @@ reprStateMachineInvalidForm,"The state machine has an unexpected form" 3550,chkDuplicatedMethodParameter,"Duplicate parameter. The parameter '%s' has been used more that once in this method." featureEscapeBracesInFormattableString,"Escapes curly braces before calling FormattableStringFactory.Create when interpolated string literal is typed as FormattableString" 3551,buildDuplicateFile,"The source file '%s' (at position %d/%d) already appeared in the compilation list (at position %d/%d). Please verify that it is included only once in the project file." -3552,chkConstructorWithArgumentsOnStaticClasses,"If a type uses both [] and [] attributes, it means it is static. constructor with arguments is not allowed." -3553,chkAdditionalConstructorOnStaticClasses,"If a type uses both [] and [] attributes, it means it is static. additional constructor is not allowed." +3552,chkConstructorWithArgumentsOnStaticClasses,"If a type uses both [] and [] attributes, it means it is static. Constructor with arguments is not allowed." +3553,chkAdditionalConstructorOnStaticClasses,"If a type uses both [] and [] attributes, it means it is static. Additional constructor is not allowed." diff --git a/src/Compiler/xlf/FSComp.txt.cs.xlf b/src/Compiler/xlf/FSComp.txt.cs.xlf index 52d93f3e0c9..130db8ee110 100644 --- a/src/Compiler/xlf/FSComp.txt.cs.xlf +++ b/src/Compiler/xlf/FSComp.txt.cs.xlf @@ -23,13 +23,13 @@ - If a type uses both [<Sealed>] and [<AbstractClass>] attributes, it means it is static. additional constructor is not allowed. - If a type uses both [<Sealed>] and [<AbstractClass>] attributes, it means it is static. additional constructor is not allowed. + If a type uses both [<Sealed>] and [<AbstractClass>] attributes, it means it is static. Additional constructor is not allowed. + If a type uses both [<Sealed>] and [<AbstractClass>] attributes, it means it is static. Additional constructor is not allowed. - If a type uses both [<Sealed>] and [<AbstractClass>] attributes, it means it is static. constructor with arguments is not allowed. - If a type uses both [<Sealed>] and [<AbstractClass>] attributes, it means it is static. constructor with arguments is not allowed. + If a type uses both [<Sealed>] and [<AbstractClass>] attributes, it means it is static. Constructor with arguments is not allowed. + If a type uses both [<Sealed>] and [<AbstractClass>] attributes, it means it is static. Constructor with arguments is not allowed. diff --git a/src/Compiler/xlf/FSComp.txt.de.xlf b/src/Compiler/xlf/FSComp.txt.de.xlf index 4005c4b8078..b26f864cffd 100644 --- a/src/Compiler/xlf/FSComp.txt.de.xlf +++ b/src/Compiler/xlf/FSComp.txt.de.xlf @@ -23,13 +23,13 @@ - If a type uses both [<Sealed>] and [<AbstractClass>] attributes, it means it is static. additional constructor is not allowed. - If a type uses both [<Sealed>] and [<AbstractClass>] attributes, it means it is static. additional constructor is not allowed. + If a type uses both [<Sealed>] and [<AbstractClass>] attributes, it means it is static. Additional constructor is not allowed. + If a type uses both [<Sealed>] and [<AbstractClass>] attributes, it means it is static. Additional constructor is not allowed. - If a type uses both [<Sealed>] and [<AbstractClass>] attributes, it means it is static. constructor with arguments is not allowed. - If a type uses both [<Sealed>] and [<AbstractClass>] attributes, it means it is static. constructor with arguments is not allowed. + If a type uses both [<Sealed>] and [<AbstractClass>] attributes, it means it is static. Constructor with arguments is not allowed. + If a type uses both [<Sealed>] and [<AbstractClass>] attributes, it means it is static. Constructor with arguments is not allowed. diff --git a/src/Compiler/xlf/FSComp.txt.es.xlf b/src/Compiler/xlf/FSComp.txt.es.xlf index 7f6046a7ea0..d16f78b54c6 100644 --- a/src/Compiler/xlf/FSComp.txt.es.xlf +++ b/src/Compiler/xlf/FSComp.txt.es.xlf @@ -23,13 +23,13 @@ - If a type uses both [<Sealed>] and [<AbstractClass>] attributes, it means it is static. additional constructor is not allowed. - If a type uses both [<Sealed>] and [<AbstractClass>] attributes, it means it is static. additional constructor is not allowed. + If a type uses both [<Sealed>] and [<AbstractClass>] attributes, it means it is static. Additional constructor is not allowed. + If a type uses both [<Sealed>] and [<AbstractClass>] attributes, it means it is static. Additional constructor is not allowed. - If a type uses both [<Sealed>] and [<AbstractClass>] attributes, it means it is static. constructor with arguments is not allowed. - If a type uses both [<Sealed>] and [<AbstractClass>] attributes, it means it is static. constructor with arguments is not allowed. + If a type uses both [<Sealed>] and [<AbstractClass>] attributes, it means it is static. Constructor with arguments is not allowed. + If a type uses both [<Sealed>] and [<AbstractClass>] attributes, it means it is static. Constructor with arguments is not allowed. diff --git a/src/Compiler/xlf/FSComp.txt.fr.xlf b/src/Compiler/xlf/FSComp.txt.fr.xlf index b8c0aa42df1..8f6f1db98e5 100644 --- a/src/Compiler/xlf/FSComp.txt.fr.xlf +++ b/src/Compiler/xlf/FSComp.txt.fr.xlf @@ -23,13 +23,13 @@ - If a type uses both [<Sealed>] and [<AbstractClass>] attributes, it means it is static. additional constructor is not allowed. - If a type uses both [<Sealed>] and [<AbstractClass>] attributes, it means it is static. additional constructor is not allowed. + If a type uses both [<Sealed>] and [<AbstractClass>] attributes, it means it is static. Additional constructor is not allowed. + If a type uses both [<Sealed>] and [<AbstractClass>] attributes, it means it is static. Additional constructor is not allowed. - If a type uses both [<Sealed>] and [<AbstractClass>] attributes, it means it is static. constructor with arguments is not allowed. - If a type uses both [<Sealed>] and [<AbstractClass>] attributes, it means it is static. constructor with arguments is not allowed. + If a type uses both [<Sealed>] and [<AbstractClass>] attributes, it means it is static. Constructor with arguments is not allowed. + If a type uses both [<Sealed>] and [<AbstractClass>] attributes, it means it is static. Constructor with arguments is not allowed. diff --git a/src/Compiler/xlf/FSComp.txt.it.xlf b/src/Compiler/xlf/FSComp.txt.it.xlf index 08debfef071..ea56b0f7e4a 100644 --- a/src/Compiler/xlf/FSComp.txt.it.xlf +++ b/src/Compiler/xlf/FSComp.txt.it.xlf @@ -23,13 +23,13 @@ - If a type uses both [<Sealed>] and [<AbstractClass>] attributes, it means it is static. additional constructor is not allowed. - If a type uses both [<Sealed>] and [<AbstractClass>] attributes, it means it is static. additional constructor is not allowed. + If a type uses both [<Sealed>] and [<AbstractClass>] attributes, it means it is static. Additional constructor is not allowed. + If a type uses both [<Sealed>] and [<AbstractClass>] attributes, it means it is static. Additional constructor is not allowed. - If a type uses both [<Sealed>] and [<AbstractClass>] attributes, it means it is static. constructor with arguments is not allowed. - If a type uses both [<Sealed>] and [<AbstractClass>] attributes, it means it is static. constructor with arguments is not allowed. + If a type uses both [<Sealed>] and [<AbstractClass>] attributes, it means it is static. Constructor with arguments is not allowed. + If a type uses both [<Sealed>] and [<AbstractClass>] attributes, it means it is static. Constructor with arguments is not allowed. diff --git a/src/Compiler/xlf/FSComp.txt.ja.xlf b/src/Compiler/xlf/FSComp.txt.ja.xlf index 19951b097f6..8cda9edc1d7 100644 --- a/src/Compiler/xlf/FSComp.txt.ja.xlf +++ b/src/Compiler/xlf/FSComp.txt.ja.xlf @@ -23,13 +23,13 @@ - If a type uses both [<Sealed>] and [<AbstractClass>] attributes, it means it is static. additional constructor is not allowed. - If a type uses both [<Sealed>] and [<AbstractClass>] attributes, it means it is static. additional constructor is not allowed. + If a type uses both [<Sealed>] and [<AbstractClass>] attributes, it means it is static. Additional constructor is not allowed. + If a type uses both [<Sealed>] and [<AbstractClass>] attributes, it means it is static. Additional constructor is not allowed. - If a type uses both [<Sealed>] and [<AbstractClass>] attributes, it means it is static. constructor with arguments is not allowed. - If a type uses both [<Sealed>] and [<AbstractClass>] attributes, it means it is static. constructor with arguments is not allowed. + If a type uses both [<Sealed>] and [<AbstractClass>] attributes, it means it is static. Constructor with arguments is not allowed. + If a type uses both [<Sealed>] and [<AbstractClass>] attributes, it means it is static. Constructor with arguments is not allowed. diff --git a/src/Compiler/xlf/FSComp.txt.ko.xlf b/src/Compiler/xlf/FSComp.txt.ko.xlf index cfdaa467c57..4e77efd30d0 100644 --- a/src/Compiler/xlf/FSComp.txt.ko.xlf +++ b/src/Compiler/xlf/FSComp.txt.ko.xlf @@ -23,13 +23,13 @@ - If a type uses both [<Sealed>] and [<AbstractClass>] attributes, it means it is static. additional constructor is not allowed. - If a type uses both [<Sealed>] and [<AbstractClass>] attributes, it means it is static. additional constructor is not allowed. + If a type uses both [<Sealed>] and [<AbstractClass>] attributes, it means it is static. Additional constructor is not allowed. + If a type uses both [<Sealed>] and [<AbstractClass>] attributes, it means it is static. Additional constructor is not allowed. - If a type uses both [<Sealed>] and [<AbstractClass>] attributes, it means it is static. constructor with arguments is not allowed. - If a type uses both [<Sealed>] and [<AbstractClass>] attributes, it means it is static. constructor with arguments is not allowed. + If a type uses both [<Sealed>] and [<AbstractClass>] attributes, it means it is static. Constructor with arguments is not allowed. + If a type uses both [<Sealed>] and [<AbstractClass>] attributes, it means it is static. Constructor with arguments is not allowed. diff --git a/src/Compiler/xlf/FSComp.txt.pl.xlf b/src/Compiler/xlf/FSComp.txt.pl.xlf index a17a005ebf4..a7033af6dfb 100644 --- a/src/Compiler/xlf/FSComp.txt.pl.xlf +++ b/src/Compiler/xlf/FSComp.txt.pl.xlf @@ -23,13 +23,13 @@ - If a type uses both [<Sealed>] and [<AbstractClass>] attributes, it means it is static. additional constructor is not allowed. - If a type uses both [<Sealed>] and [<AbstractClass>] attributes, it means it is static. additional constructor is not allowed. + If a type uses both [<Sealed>] and [<AbstractClass>] attributes, it means it is static. Additional constructor is not allowed. + If a type uses both [<Sealed>] and [<AbstractClass>] attributes, it means it is static. Additional constructor is not allowed. - If a type uses both [<Sealed>] and [<AbstractClass>] attributes, it means it is static. constructor with arguments is not allowed. - If a type uses both [<Sealed>] and [<AbstractClass>] attributes, it means it is static. constructor with arguments is not allowed. + If a type uses both [<Sealed>] and [<AbstractClass>] attributes, it means it is static. Constructor with arguments is not allowed. + If a type uses both [<Sealed>] and [<AbstractClass>] attributes, it means it is static. Constructor with arguments is not allowed. diff --git a/src/Compiler/xlf/FSComp.txt.pt-BR.xlf b/src/Compiler/xlf/FSComp.txt.pt-BR.xlf index 53f56475de3..1c55ec02e84 100644 --- a/src/Compiler/xlf/FSComp.txt.pt-BR.xlf +++ b/src/Compiler/xlf/FSComp.txt.pt-BR.xlf @@ -23,13 +23,13 @@ - If a type uses both [<Sealed>] and [<AbstractClass>] attributes, it means it is static. additional constructor is not allowed. - If a type uses both [<Sealed>] and [<AbstractClass>] attributes, it means it is static. additional constructor is not allowed. + If a type uses both [<Sealed>] and [<AbstractClass>] attributes, it means it is static. Additional constructor is not allowed. + If a type uses both [<Sealed>] and [<AbstractClass>] attributes, it means it is static. Additional constructor is not allowed. - If a type uses both [<Sealed>] and [<AbstractClass>] attributes, it means it is static. constructor with arguments is not allowed. - If a type uses both [<Sealed>] and [<AbstractClass>] attributes, it means it is static. constructor with arguments is not allowed. + If a type uses both [<Sealed>] and [<AbstractClass>] attributes, it means it is static. Constructor with arguments is not allowed. + If a type uses both [<Sealed>] and [<AbstractClass>] attributes, it means it is static. Constructor with arguments is not allowed. diff --git a/src/Compiler/xlf/FSComp.txt.ru.xlf b/src/Compiler/xlf/FSComp.txt.ru.xlf index ddb887d88d2..157486c8073 100644 --- a/src/Compiler/xlf/FSComp.txt.ru.xlf +++ b/src/Compiler/xlf/FSComp.txt.ru.xlf @@ -23,13 +23,13 @@ - If a type uses both [<Sealed>] and [<AbstractClass>] attributes, it means it is static. additional constructor is not allowed. - If a type uses both [<Sealed>] and [<AbstractClass>] attributes, it means it is static. additional constructor is not allowed. + If a type uses both [<Sealed>] and [<AbstractClass>] attributes, it means it is static. Additional constructor is not allowed. + If a type uses both [<Sealed>] and [<AbstractClass>] attributes, it means it is static. Additional constructor is not allowed. - If a type uses both [<Sealed>] and [<AbstractClass>] attributes, it means it is static. constructor with arguments is not allowed. - If a type uses both [<Sealed>] and [<AbstractClass>] attributes, it means it is static. constructor with arguments is not allowed. + If a type uses both [<Sealed>] and [<AbstractClass>] attributes, it means it is static. Constructor with arguments is not allowed. + If a type uses both [<Sealed>] and [<AbstractClass>] attributes, it means it is static. Constructor with arguments is not allowed. diff --git a/src/Compiler/xlf/FSComp.txt.tr.xlf b/src/Compiler/xlf/FSComp.txt.tr.xlf index 9b46b30928c..0923ca2d0f7 100644 --- a/src/Compiler/xlf/FSComp.txt.tr.xlf +++ b/src/Compiler/xlf/FSComp.txt.tr.xlf @@ -23,13 +23,13 @@ - If a type uses both [<Sealed>] and [<AbstractClass>] attributes, it means it is static. additional constructor is not allowed. - If a type uses both [<Sealed>] and [<AbstractClass>] attributes, it means it is static. additional constructor is not allowed. + If a type uses both [<Sealed>] and [<AbstractClass>] attributes, it means it is static. Additional constructor is not allowed. + If a type uses both [<Sealed>] and [<AbstractClass>] attributes, it means it is static. Additional constructor is not allowed. - If a type uses both [<Sealed>] and [<AbstractClass>] attributes, it means it is static. constructor with arguments is not allowed. - If a type uses both [<Sealed>] and [<AbstractClass>] attributes, it means it is static. constructor with arguments is not allowed. + If a type uses both [<Sealed>] and [<AbstractClass>] attributes, it means it is static. Constructor with arguments is not allowed. + If a type uses both [<Sealed>] and [<AbstractClass>] attributes, it means it is static. Constructor with arguments is not allowed. diff --git a/src/Compiler/xlf/FSComp.txt.zh-Hans.xlf b/src/Compiler/xlf/FSComp.txt.zh-Hans.xlf index 1941e3624f5..3aa9bc0222c 100644 --- a/src/Compiler/xlf/FSComp.txt.zh-Hans.xlf +++ b/src/Compiler/xlf/FSComp.txt.zh-Hans.xlf @@ -23,13 +23,13 @@ - If a type uses both [<Sealed>] and [<AbstractClass>] attributes, it means it is static. additional constructor is not allowed. - If a type uses both [<Sealed>] and [<AbstractClass>] attributes, it means it is static. additional constructor is not allowed. + If a type uses both [<Sealed>] and [<AbstractClass>] attributes, it means it is static. Additional constructor is not allowed. + If a type uses both [<Sealed>] and [<AbstractClass>] attributes, it means it is static. Additional constructor is not allowed. - If a type uses both [<Sealed>] and [<AbstractClass>] attributes, it means it is static. constructor with arguments is not allowed. - If a type uses both [<Sealed>] and [<AbstractClass>] attributes, it means it is static. constructor with arguments is not allowed. + If a type uses both [<Sealed>] and [<AbstractClass>] attributes, it means it is static. Constructor with arguments is not allowed. + If a type uses both [<Sealed>] and [<AbstractClass>] attributes, it means it is static. Constructor with arguments is not allowed. diff --git a/src/Compiler/xlf/FSComp.txt.zh-Hant.xlf b/src/Compiler/xlf/FSComp.txt.zh-Hant.xlf index 8c5642c1226..7452751a967 100644 --- a/src/Compiler/xlf/FSComp.txt.zh-Hant.xlf +++ b/src/Compiler/xlf/FSComp.txt.zh-Hant.xlf @@ -23,13 +23,13 @@ - If a type uses both [<Sealed>] and [<AbstractClass>] attributes, it means it is static. additional constructor is not allowed. - If a type uses both [<Sealed>] and [<AbstractClass>] attributes, it means it is static. additional constructor is not allowed. + If a type uses both [<Sealed>] and [<AbstractClass>] attributes, it means it is static. Additional constructor is not allowed. + If a type uses both [<Sealed>] and [<AbstractClass>] attributes, it means it is static. Additional constructor is not allowed. - If a type uses both [<Sealed>] and [<AbstractClass>] attributes, it means it is static. constructor with arguments is not allowed. - If a type uses both [<Sealed>] and [<AbstractClass>] attributes, it means it is static. constructor with arguments is not allowed. + If a type uses both [<Sealed>] and [<AbstractClass>] attributes, it means it is static. Constructor with arguments is not allowed. + If a type uses both [<Sealed>] and [<AbstractClass>] attributes, it means it is static. Constructor with arguments is not allowed. diff --git a/tests/FSharp.Compiler.ComponentTests/Language/StaticClassTests.fs b/tests/FSharp.Compiler.ComponentTests/Language/StaticClassTests.fs index 848f5d18366..c612d762c2b 100644 --- a/tests/FSharp.Compiler.ComponentTests/Language/StaticClassTests.fs +++ b/tests/FSharp.Compiler.ComponentTests/Language/StaticClassTests.fs @@ -55,7 +55,7 @@ type T(x: int) = class end |> compile |> shouldFail |> withDiagnostics [ - (Error 3552, Line 3, Col 8, Line 3, Col 14, "If a type uses both [] and [] attributes, it means it is static. constructor with arguments is not allowed.") + (Error 3552, Line 3, Col 8, Line 3, Col 14, "If a type uses both [] and [] attributes, it means it is static. Constructor with arguments is not allowed.") ] [] @@ -79,7 +79,7 @@ type T = |> compile |> shouldFail |> withDiagnostics [ - (Error 3553, Line 4, Col 5, Line 4, Col 16, "If a type uses both [] and [] attributes, it means it is static. additional constructor is not allowed.") + (Error 3553, Line 4, Col 5, Line 4, Col 16, "If a type uses both [] and [] attributes, it means it is static. Additional constructor is not allowed.") ] [] @@ -104,8 +104,8 @@ type T(x: int) = |> compile |> shouldFail |> withDiagnostics [ - (Error 3552, Line 3, Col 8, Line 3, Col 14, "If a type uses both [] and [] attributes, it means it is static. constructor with arguments is not allowed.") - (Error 3553, Line 4, Col 5, Line 4, Col 19, "If a type uses both [] and [] attributes, it means it is static. additional constructor is not allowed.") + (Error 3552, Line 3, Col 8, Line 3, Col 14, "If a type uses both [] and [] attributes, it means it is static. Constructor with arguments is not allowed.") + (Error 3553, Line 4, Col 5, Line 4, Col 19, "If a type uses both [] and [] attributes, it means it is static. Additional constructor is not allowed.") ] [] @@ -140,7 +140,7 @@ type ListDebugView<'T>(l: 'T list) = class end |> compile |> shouldFail |> withDiagnostics [ - (Error 3552, Line 3, Col 24, Line 3, Col 34, "If a type uses both [] and [] attributes, it means it is static. constructor with arguments is not allowed.") + (Error 3552, Line 3, Col 24, Line 3, Col 34, "If a type uses both [] and [] attributes, it means it is static. Constructor with arguments is not allowed.") ] [] @@ -156,7 +156,7 @@ type B = |> compile |> shouldFail |> withDiagnostics [ - (Error 3553, Line 6, Col 5, Line 6, Col 30, "If a type uses both [] and [] attributes, it means it is static. additional constructor is not allowed.") + (Error 3553, Line 6, Col 5, Line 6, Col 30, "If a type uses both [] and [] attributes, it means it is static. Additional constructor is not allowed.") ] []