未验证 提交 a053e8eb 编写于 作者: E Edgar Gonzalez 提交者: GitHub

Compiler error when declaring abstract members on static classes (#14593)

* Compiler error when declaring abstract members on static classes

* Compiler error only for inteface instance member
上级 1c6d1e18
......@@ -1668,8 +1668,12 @@ let private ReportErrorOnStaticClass (synMembers: SynMemberDefn list) =
errorR(Error(FSComp.SR.chkInstanceMemberOnStaticClasses(), m))
| SynMemberDefn.LetBindings(isStatic = false; range = range) ->
errorR(Error(FSComp.SR.chkInstanceLetBindingOnStaticClasses(), range))
| SynMemberDefn.Interface(range = range) ->
errorR(Error(FSComp.SR.chkImplementingInterfacesOnStaticClasses(), range))
| SynMemberDefn.Interface(members= Some(synMemberDefs)) ->
for mem in synMemberDefs do
match mem with
| SynMemberDefn.Member(SynBinding(valData = SynValData(memberFlags = Some memberFlags)), m) when memberFlags.MemberKind = SynMemberKind.Member && memberFlags.IsInstance ->
errorR(Error(FSComp.SR.chkImplementingInterfacesOnStaticClasses(), m))
| _ -> ()
| _ -> ()
/// Check and generalize the interface implementations, members, 'let' definitions in a mutually recursive group of definitions.
......@@ -1778,6 +1782,11 @@ let TcMutRecDefns_Phase2 (cenv: cenv) envInitial mBinds scopem mutRecNSInfo (env
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
ReportErrorOnStaticClass synMembers
match tyconOpt with
| Some tycon ->
for slot in tycon.FSharpObjectModelTypeInfo.fsobjmodel_vslots do
errorR(Error(FSComp.SR.chkAbstractMembersDeclarationsOnStaticClasses(), slot.Range))
| None -> ()
let envForDecls =
// This allows to implement protected interface methods if it's a DIM.
......
......@@ -1670,4 +1670,5 @@ featureEscapeBracesInFormattableString,"Escapes curly braces before calling Form
3553,chkAdditionalConstructorOnStaticClasses,"If a type uses both [<Sealed>] and [<AbstractClass>] attributes, it means it is static. Additional constructor is not allowed."
3554,chkInstanceMemberOnStaticClasses,"If a type uses both [<Sealed>] and [<AbstractClass>] attributes, it means it is static. Instance members are not allowed."
3555,chkInstanceLetBindingOnStaticClasses,"If a type uses both [<Sealed>] and [<AbstractClass>] attributes, it means it is static. Instance let bindings are not allowed."
3556,chkImplementingInterfacesOnStaticClasses,"If a type uses both [<Sealed>] and [<AbstractClass>] attributes, it means it is static. Implementing interfaces is not allowed."
\ No newline at end of file
3556,chkImplementingInterfacesOnStaticClasses,"If a type uses both [<Sealed>] and [<AbstractClass>] attributes, it means it is static. Implementing interfaces is not allowed."
3557,chkAbstractMembersDeclarationsOnStaticClasses,"If a type uses both [<Sealed>] and [<AbstractClass>] attributes, it means it is static. Abstract member declarations are not allowed."
\ No newline at end of file
......@@ -22,6 +22,11 @@
<target state="translated">Soubor {0} má nerozpoznanou příponu. Zdrojové soubory musí mít příponu .fs, .fsi, .fsx nebo .fsscript.</target>
<note />
</trans-unit>
<trans-unit id="chkAbstractMembersDeclarationsOnStaticClasses">
<source>If a type uses both [&lt;Sealed&gt;] and [&lt;AbstractClass&gt;] attributes, it means it is static. Abstract member declarations are not allowed.</source>
<target state="new">If a type uses both [&lt;Sealed&gt;] and [&lt;AbstractClass&gt;] attributes, it means it is static. Abstract member declarations are not allowed.</target>
<note />
</trans-unit>
<trans-unit id="chkAdditionalConstructorOnStaticClasses">
<source>If a type uses both [&lt;Sealed&gt;] and [&lt;AbstractClass&gt;] attributes, it means it is static. Additional constructor is not allowed.</source>
<target state="new">If a type uses both [&lt;Sealed&gt;] and [&lt;AbstractClass&gt;] attributes, it means it is static. Additional constructor is not allowed.</target>
......
......@@ -22,6 +22,11 @@
<target state="translated">Die Dateierweiterung von „{0}“ wurde nicht erkannt. Quelldateien müssen die Erweiterung .fs, .fsi, .fsx oder .fsscript haben</target>
<note />
</trans-unit>
<trans-unit id="chkAbstractMembersDeclarationsOnStaticClasses">
<source>If a type uses both [&lt;Sealed&gt;] and [&lt;AbstractClass&gt;] attributes, it means it is static. Abstract member declarations are not allowed.</source>
<target state="new">If a type uses both [&lt;Sealed&gt;] and [&lt;AbstractClass&gt;] attributes, it means it is static. Abstract member declarations are not allowed.</target>
<note />
</trans-unit>
<trans-unit id="chkAdditionalConstructorOnStaticClasses">
<source>If a type uses both [&lt;Sealed&gt;] and [&lt;AbstractClass&gt;] attributes, it means it is static. Additional constructor is not allowed.</source>
<target state="new">If a type uses both [&lt;Sealed&gt;] and [&lt;AbstractClass&gt;] attributes, it means it is static. Additional constructor is not allowed.</target>
......
......@@ -22,6 +22,11 @@
<target state="translated">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</target>
<note />
</trans-unit>
<trans-unit id="chkAbstractMembersDeclarationsOnStaticClasses">
<source>If a type uses both [&lt;Sealed&gt;] and [&lt;AbstractClass&gt;] attributes, it means it is static. Abstract member declarations are not allowed.</source>
<target state="new">If a type uses both [&lt;Sealed&gt;] and [&lt;AbstractClass&gt;] attributes, it means it is static. Abstract member declarations are not allowed.</target>
<note />
</trans-unit>
<trans-unit id="chkAdditionalConstructorOnStaticClasses">
<source>If a type uses both [&lt;Sealed&gt;] and [&lt;AbstractClass&gt;] attributes, it means it is static. Additional constructor is not allowed.</source>
<target state="new">If a type uses both [&lt;Sealed&gt;] and [&lt;AbstractClass&gt;] attributes, it means it is static. Additional constructor is not allowed.</target>
......
......@@ -22,6 +22,11 @@
<target state="translated">L'extension de fichier de '{0}' n'est pas reconnue. Les fichiers sources doivent avoir l'extension .fs, .fsi, .fsx, ou .fsscript.</target>
<note />
</trans-unit>
<trans-unit id="chkAbstractMembersDeclarationsOnStaticClasses">
<source>If a type uses both [&lt;Sealed&gt;] and [&lt;AbstractClass&gt;] attributes, it means it is static. Abstract member declarations are not allowed.</source>
<target state="new">If a type uses both [&lt;Sealed&gt;] and [&lt;AbstractClass&gt;] attributes, it means it is static. Abstract member declarations are not allowed.</target>
<note />
</trans-unit>
<trans-unit id="chkAdditionalConstructorOnStaticClasses">
<source>If a type uses both [&lt;Sealed&gt;] and [&lt;AbstractClass&gt;] attributes, it means it is static. Additional constructor is not allowed.</source>
<target state="new">If a type uses both [&lt;Sealed&gt;] and [&lt;AbstractClass&gt;] attributes, it means it is static. Additional constructor is not allowed.</target>
......
......@@ -22,6 +22,11 @@
<target state="translated">Estensione di file di '{0}' non riconosciuta. I file di origine devono avere estensione .fs, .fsi, .fsx or .fsscript</target>
<note />
</trans-unit>
<trans-unit id="chkAbstractMembersDeclarationsOnStaticClasses">
<source>If a type uses both [&lt;Sealed&gt;] and [&lt;AbstractClass&gt;] attributes, it means it is static. Abstract member declarations are not allowed.</source>
<target state="new">If a type uses both [&lt;Sealed&gt;] and [&lt;AbstractClass&gt;] attributes, it means it is static. Abstract member declarations are not allowed.</target>
<note />
</trans-unit>
<trans-unit id="chkAdditionalConstructorOnStaticClasses">
<source>If a type uses both [&lt;Sealed&gt;] and [&lt;AbstractClass&gt;] attributes, it means it is static. Additional constructor is not allowed.</source>
<target state="new">If a type uses both [&lt;Sealed&gt;] and [&lt;AbstractClass&gt;] attributes, it means it is static. Additional constructor is not allowed.</target>
......
......@@ -22,6 +22,11 @@
<target state="translated">'{0}' のファイル拡張子は認識されません。ソース ファイルの拡張子は .fs、.fsi、.fsx、または .fsscript にする必要があります。</target>
<note />
</trans-unit>
<trans-unit id="chkAbstractMembersDeclarationsOnStaticClasses">
<source>If a type uses both [&lt;Sealed&gt;] and [&lt;AbstractClass&gt;] attributes, it means it is static. Abstract member declarations are not allowed.</source>
<target state="new">If a type uses both [&lt;Sealed&gt;] and [&lt;AbstractClass&gt;] attributes, it means it is static. Abstract member declarations are not allowed.</target>
<note />
</trans-unit>
<trans-unit id="chkAdditionalConstructorOnStaticClasses">
<source>If a type uses both [&lt;Sealed&gt;] and [&lt;AbstractClass&gt;] attributes, it means it is static. Additional constructor is not allowed.</source>
<target state="new">If a type uses both [&lt;Sealed&gt;] and [&lt;AbstractClass&gt;] attributes, it means it is static. Additional constructor is not allowed.</target>
......
......@@ -22,6 +22,11 @@
<target state="translated">'{0}'의 파일 확장명을 인식할 수 없습니다. 원본 파일의 확장명은 .fs, .fsi, .fsx 또는 .fsscript여야 합니다.</target>
<note />
</trans-unit>
<trans-unit id="chkAbstractMembersDeclarationsOnStaticClasses">
<source>If a type uses both [&lt;Sealed&gt;] and [&lt;AbstractClass&gt;] attributes, it means it is static. Abstract member declarations are not allowed.</source>
<target state="new">If a type uses both [&lt;Sealed&gt;] and [&lt;AbstractClass&gt;] attributes, it means it is static. Abstract member declarations are not allowed.</target>
<note />
</trans-unit>
<trans-unit id="chkAdditionalConstructorOnStaticClasses">
<source>If a type uses both [&lt;Sealed&gt;] and [&lt;AbstractClass&gt;] attributes, it means it is static. Additional constructor is not allowed.</source>
<target state="new">If a type uses both [&lt;Sealed&gt;] and [&lt;AbstractClass&gt;] attributes, it means it is static. Additional constructor is not allowed.</target>
......
......@@ -22,6 +22,11 @@
<target state="translated">Rozszerzenie pliku "{0}" nie zostało rozpoznane. Pliki źródłowe muszą mieć rozszerzenie .fs, .fsi, .fsx lub .fsscript</target>
<note />
</trans-unit>
<trans-unit id="chkAbstractMembersDeclarationsOnStaticClasses">
<source>If a type uses both [&lt;Sealed&gt;] and [&lt;AbstractClass&gt;] attributes, it means it is static. Abstract member declarations are not allowed.</source>
<target state="new">If a type uses both [&lt;Sealed&gt;] and [&lt;AbstractClass&gt;] attributes, it means it is static. Abstract member declarations are not allowed.</target>
<note />
</trans-unit>
<trans-unit id="chkAdditionalConstructorOnStaticClasses">
<source>If a type uses both [&lt;Sealed&gt;] and [&lt;AbstractClass&gt;] attributes, it means it is static. Additional constructor is not allowed.</source>
<target state="new">If a type uses both [&lt;Sealed&gt;] and [&lt;AbstractClass&gt;] attributes, it means it is static. Additional constructor is not allowed.</target>
......
......@@ -22,6 +22,11 @@
<target state="translated">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</target>
<note />
</trans-unit>
<trans-unit id="chkAbstractMembersDeclarationsOnStaticClasses">
<source>If a type uses both [&lt;Sealed&gt;] and [&lt;AbstractClass&gt;] attributes, it means it is static. Abstract member declarations are not allowed.</source>
<target state="new">If a type uses both [&lt;Sealed&gt;] and [&lt;AbstractClass&gt;] attributes, it means it is static. Abstract member declarations are not allowed.</target>
<note />
</trans-unit>
<trans-unit id="chkAdditionalConstructorOnStaticClasses">
<source>If a type uses both [&lt;Sealed&gt;] and [&lt;AbstractClass&gt;] attributes, it means it is static. Additional constructor is not allowed.</source>
<target state="new">If a type uses both [&lt;Sealed&gt;] and [&lt;AbstractClass&gt;] attributes, it means it is static. Additional constructor is not allowed.</target>
......
......@@ -22,6 +22,11 @@
<target state="translated">Расширение файла "{0}" не распознано. Исходные файлы должны иметь расширения FS, FSI, FSX или FSSCRIPT</target>
<note />
</trans-unit>
<trans-unit id="chkAbstractMembersDeclarationsOnStaticClasses">
<source>If a type uses both [&lt;Sealed&gt;] and [&lt;AbstractClass&gt;] attributes, it means it is static. Abstract member declarations are not allowed.</source>
<target state="new">If a type uses both [&lt;Sealed&gt;] and [&lt;AbstractClass&gt;] attributes, it means it is static. Abstract member declarations are not allowed.</target>
<note />
</trans-unit>
<trans-unit id="chkAdditionalConstructorOnStaticClasses">
<source>If a type uses both [&lt;Sealed&gt;] and [&lt;AbstractClass&gt;] attributes, it means it is static. Additional constructor is not allowed.</source>
<target state="new">If a type uses both [&lt;Sealed&gt;] and [&lt;AbstractClass&gt;] attributes, it means it is static. Additional constructor is not allowed.</target>
......
......@@ -22,6 +22,11 @@
<target state="translated">'{0}' kaynak dosyasının dosya uzantısı tanınmadı. Kaynak dosyaların uzantısı .fs, .fsi, .fsx veya .fsscript olmalıdır.</target>
<note />
</trans-unit>
<trans-unit id="chkAbstractMembersDeclarationsOnStaticClasses">
<source>If a type uses both [&lt;Sealed&gt;] and [&lt;AbstractClass&gt;] attributes, it means it is static. Abstract member declarations are not allowed.</source>
<target state="new">If a type uses both [&lt;Sealed&gt;] and [&lt;AbstractClass&gt;] attributes, it means it is static. Abstract member declarations are not allowed.</target>
<note />
</trans-unit>
<trans-unit id="chkAdditionalConstructorOnStaticClasses">
<source>If a type uses both [&lt;Sealed&gt;] and [&lt;AbstractClass&gt;] attributes, it means it is static. Additional constructor is not allowed.</source>
<target state="new">If a type uses both [&lt;Sealed&gt;] and [&lt;AbstractClass&gt;] attributes, it means it is static. Additional constructor is not allowed.</target>
......
......@@ -22,6 +22,11 @@
<target state="translated">无法识别“{0}”的文件扩展名。源文件必须具有扩展名 .fs、.fsi、.fsx 或 .fsscript</target>
<note />
</trans-unit>
<trans-unit id="chkAbstractMembersDeclarationsOnStaticClasses">
<source>If a type uses both [&lt;Sealed&gt;] and [&lt;AbstractClass&gt;] attributes, it means it is static. Abstract member declarations are not allowed.</source>
<target state="new">If a type uses both [&lt;Sealed&gt;] and [&lt;AbstractClass&gt;] attributes, it means it is static. Abstract member declarations are not allowed.</target>
<note />
</trans-unit>
<trans-unit id="chkAdditionalConstructorOnStaticClasses">
<source>If a type uses both [&lt;Sealed&gt;] and [&lt;AbstractClass&gt;] attributes, it means it is static. Additional constructor is not allowed.</source>
<target state="new">If a type uses both [&lt;Sealed&gt;] and [&lt;AbstractClass&gt;] attributes, it means it is static. Additional constructor is not allowed.</target>
......
......@@ -22,6 +22,11 @@
<target state="translated">無法辨識 '{0}' 的副檔名。來源檔案的副檔名必須是 .fs、.fsi、.fsx 或 .fsscript。</target>
<note />
</trans-unit>
<trans-unit id="chkAbstractMembersDeclarationsOnStaticClasses">
<source>If a type uses both [&lt;Sealed&gt;] and [&lt;AbstractClass&gt;] attributes, it means it is static. Abstract member declarations are not allowed.</source>
<target state="new">If a type uses both [&lt;Sealed&gt;] and [&lt;AbstractClass&gt;] attributes, it means it is static. Abstract member declarations are not allowed.</target>
<note />
</trans-unit>
<trans-unit id="chkAdditionalConstructorOnStaticClasses">
<source>If a type uses both [&lt;Sealed&gt;] and [&lt;AbstractClass&gt;] attributes, it means it is static. Additional constructor is not allowed.</source>
<target state="new">If a type uses both [&lt;Sealed&gt;] and [&lt;AbstractClass&gt;] attributes, it means it is static. Additional constructor is not allowed.</target>
......
......@@ -401,7 +401,7 @@ type C() =
|> compile
|> shouldFail
|> withDiagnostics [
(Error 3556, Line 7, Col 5, Line 8, Col 29, "If a type uses both [<Sealed>] and [<AbstractClass>] attributes, it means it is static. Implementing interfaces is not allowed.")
(Error 3556, Line 8, Col 9, Line 8, Col 29, "If a type uses both [<Sealed>] and [<AbstractClass>] attributes, it means it is static. Implementing interfaces is not allowed.")
]
[<Fact>]
......@@ -419,5 +419,134 @@ type C =
|> compile
|> shouldFail
|> withDiagnostics [
(Error 3556, Line 7, Col 5, Line 8, Col 29, "If a type uses both [<Sealed>] and [<AbstractClass>] attributes, it means it is static. Implementing interfaces is not allowed.")
]
\ No newline at end of file
(Error 3556, Line 8, Col 9, Line 8, Col 29, "If a type uses both [<Sealed>] and [<AbstractClass>] attributes, it means it is static. Implementing interfaces is not allowed.")
]
[<Fact>]
let ``Sealed and AbstractClass on a type implicit constructor declaring abstract members in Lang 70`` () =
Fsx """
[<Sealed; AbstractClass>]
type T =
abstract A : int
abstract B : int with get, set
abstract C : i:int -> int
abstract D : i:int -> int
"""
|> withLangVersion70
|> compile
|> shouldSucceed
[<Fact>]
let ``Sealed and AbstractClass on a type declaring abstract members in Lang 70`` () =
Fsx """
[<Sealed; AbstractClass>]
type T() =
abstract A : int
abstract B : int with get, set
abstract C : i:int -> int
abstract D : i:int -> int
"""
|> withLangVersion70
|> compile
|> shouldSucceed
[<Fact>]
let ``Sealed and AbstractClass on a type with implicit constructor declaring abstract members in Lang preview`` () =
Fsx """
[<Sealed; AbstractClass>]
type T =
abstract C : i:int -> int
abstract D : i:int -> int
"""
|> withLangVersionPreview
|> compile
|> shouldFail
|> withDiagnostics [
(Error 3557, Line 4, Col 14, Line 4, Col 15, "If a type uses both [<Sealed>] and [<AbstractClass>] attributes, it means it is static. Abstract member declarations are not allowed.")
(Error 3557, Line 5, Col 14, Line 5, Col 15, "If a type uses both [<Sealed>] and [<AbstractClass>] attributes, it means it is static. Abstract member declarations are not allowed.")
]
[<Fact>]
let ``Sealed and AbstractClass on a type declaring abstract members in Lang preview`` () =
Fsx """
[<Sealed; AbstractClass>]
type T() =
abstract C : i:int -> int
abstract D : i:int -> int
"""
|> withLangVersionPreview
|> compile
|> shouldFail
|> withDiagnostics [
(Error 3557, Line 4, Col 14, Line 4, Col 15, "If a type uses both [<Sealed>] and [<AbstractClass>] attributes, it means it is static. Abstract member declarations are not allowed.")
(Error 3557, Line 5, Col 14, Line 5, Col 15, "If a type uses both [<Sealed>] and [<AbstractClass>] attributes, it means it is static. Abstract member declarations are not allowed.")
]
#if !NETCOREAPP
[<Fact(Skip = "IWSAMs are not supported by NET472.")>]
#else
[<Fact>]
#endif
let ``Sealed and AbstractClass on a type implementing an interface with static abstract members in Lang 70`` () =
Fsx """
[<Interface>]
type InputRetriever<'T when 'T:>InputRetriever<'T>> =
static abstract Read: unit -> string
[<AbstractClass;Sealed>]
type ConsoleRetriever =
interface InputRetriever<ConsoleRetriever> with
static member Read() =
stdout.WriteLine("Please enter a value and press enter")
stdin.ReadLine()
"""
|> withNoWarn 3535
|> withLangVersion70
|> compile
|> shouldSucceed
#if !NETCOREAPP
[<Fact(Skip = "IWSAMs are not supported by NET472.")>]
#else
[<Fact>]
#endif
let ``Sealed and AbstractClass on a type implicit constructor implementing an interface with static abstract members in Lang preview`` () =
Fsx """
[<Interface>]
type InputRetriever<'T when 'T:>InputRetriever<'T>> =
static abstract Read: unit -> string
[<AbstractClass;Sealed>]
type ConsoleRetriever =
interface InputRetriever<ConsoleRetriever> with
static member Read() =
stdout.WriteLine("Please enter a value and press enter")
stdin.ReadLine()
"""
|> withNoWarn 3535
|> withLangVersionPreview
|> compile
|> shouldSucceed
#if !NETCOREAPP
[<Fact(Skip = "IWSAMs are not supported by NET472.")>]
#else
[<Fact>]
#endif
let ``Sealed and AbstractClass on a type implementing an interface with static abstract members in Lang preview`` () =
Fsx """
[<Interface>]
type InputRetriever<'T when 'T:>InputRetriever<'T>> =
static abstract Read: unit -> string
[<AbstractClass;Sealed>]
type ConsoleRetriever() =
interface InputRetriever<ConsoleRetriever> with
static member Read() =
stdout.WriteLine("Please enter a value and press enter")
stdin.ReadLine()
"""
|> withNoWarn 3535
|> withLangVersionPreview
|> compile
|> shouldSucceed
\ No newline at end of file
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册