未验证 提交 6626a113 编写于 作者: R Rikki Gibson 提交者: GitHub

Readonly members LangVersion checks (#34404)

* Add IDS_FeatureReadOnlyMembers

* Add CheckFeatureAvailability checks for readonly members

* Remove prototype comment

* Ensure LangVersion test is valid with default language version

* Fix DeclarationParsingTests

* Remove unnecessary comment
上级 22ed71ac
......@@ -11482,6 +11482,15 @@ internal class CSharpResources {
}
}
/// <summary>
/// Looks up a localized string similar to readonly members.
/// </summary>
internal static string IDS_FeatureReadOnlyMembers {
get {
return ResourceManager.GetString("IDS_FeatureReadOnlyMembers", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to readonly references.
/// </summary>
......
......@@ -219,6 +219,9 @@
<data name="IDS_FeatureUnmanagedConstructedTypes" xml:space="preserve">
<value>unmanaged constructed types</value>
</data>
<data name="IDS_FeatureReadOnlyMembers" xml:space="preserve">
<value>readonly members</value>
</data>
<data name="IDS_FeatureDefaultLiteral" xml:space="preserve">
<value>default literal</value>
</data>
......
......@@ -175,6 +175,7 @@ internal enum MessageID
IDS_FeatureStaticLocalFunctions = MessageBase + 12755,
IDS_FeatureNameShadowingInNestedFunctions = MessageBase + 12756,
IDS_FeatureUnmanagedConstructedTypes = MessageBase + 12757,
IDS_FeatureReadOnlyMembers = MessageBase + 12758,
}
// Message IDs may refer to strings that need to be localized.
......@@ -279,6 +280,7 @@ internal static LanguageVersion RequiredVersion(this MessageID feature)
case MessageID.IDS_FeatureStaticLocalFunctions:
case MessageID.IDS_FeatureNameShadowingInNestedFunctions:
case MessageID.IDS_FeatureUnmanagedConstructedTypes: // semantic check
case MessageID.IDS_FeatureReadOnlyMembers:
return LanguageVersion.CSharp8;
// C# 7.3 features.
......
......@@ -2388,6 +2388,9 @@ private MemberDeclarationSyntax ParseMemberDeclarationOrStatementCore(SyntaxKind
Debug.Assert(identifierOrThisOpt != null);
// check availability of readonly members feature for indexers, properties and methods
CheckForVersionSpecificModifiers(modifiers, SyntaxKind.ReadOnlyKeyword, MessageID.IDS_FeatureReadOnlyMembers);
if (identifierOrThisOpt.Kind == SyntaxKind.ThisKeyword)
{
return this.ParseIndexerDeclaration(attributes, modifiers, type, explicitInterfaceOpt, identifierOrThisOpt, typeParameterListOpt);
......@@ -3401,6 +3404,9 @@ private AccessorDeclarationSyntax ParseAccessorDeclaration(bool isEvent)
this.ParseAttributeDeclarations(accAttrs);
this.ParseModifiers(accMods, forAccessors: true);
// check availability of readonly members feature for accessors
CheckForVersionSpecificModifiers(accMods, SyntaxKind.ReadOnlyKeyword, MessageID.IDS_FeatureReadOnlyMembers);
if (!isEvent)
{
if (accMods != null && accMods.Count > 0)
......@@ -3965,6 +3971,9 @@ private void ParseParameterModifiers(SyntaxListBuilder modifiers)
this.ParseMemberName(out explicitInterfaceOpt, out identifierOrThisOpt, out typeParameterList, isEvent: true);
// check availability of readonly members feature for custom events
CheckForVersionSpecificModifiers(modifiers, SyntaxKind.ReadOnlyKeyword, MessageID.IDS_FeatureReadOnlyMembers);
// If we got an explicitInterfaceOpt but not an identifier, then we're in the special
// case for ERR_ExplicitEventFieldImpl (see ParseMemberName for details).
if (explicitInterfaceOpt != null && this.CurrentToken.Kind != SyntaxKind.OpenBraceToken)
......
......@@ -752,6 +752,11 @@
<target state="translated">operátor rozsahu</target>
<note />
</trans-unit>
<trans-unit id="IDS_FeatureReadOnlyMembers">
<source>readonly members</source>
<target state="new">readonly members</target>
<note />
</trans-unit>
<trans-unit id="IDS_FeatureRecursivePatterns">
<source>recursive patterns</source>
<target state="translated">rekurzivní vzory</target>
......
......@@ -752,6 +752,11 @@
<target state="translated">Bereichsoperator</target>
<note />
</trans-unit>
<trans-unit id="IDS_FeatureReadOnlyMembers">
<source>readonly members</source>
<target state="new">readonly members</target>
<note />
</trans-unit>
<trans-unit id="IDS_FeatureRecursivePatterns">
<source>recursive patterns</source>
<target state="translated">Rekursive Muster</target>
......
......@@ -754,6 +754,11 @@
<target state="translated">operador de intervalo</target>
<note />
</trans-unit>
<trans-unit id="IDS_FeatureReadOnlyMembers">
<source>readonly members</source>
<target state="new">readonly members</target>
<note />
</trans-unit>
<trans-unit id="IDS_FeatureRecursivePatterns">
<source>recursive patterns</source>
<target state="translated">patrones recursivos</target>
......
......@@ -753,6 +753,11 @@
<target state="translated">opérateur de plage</target>
<note />
</trans-unit>
<trans-unit id="IDS_FeatureReadOnlyMembers">
<source>readonly members</source>
<target state="new">readonly members</target>
<note />
</trans-unit>
<trans-unit id="IDS_FeatureRecursivePatterns">
<source>recursive patterns</source>
<target state="translated">modèles récursifs</target>
......
......@@ -752,6 +752,11 @@
<target state="translated">operatore di intervallo</target>
<note />
</trans-unit>
<trans-unit id="IDS_FeatureReadOnlyMembers">
<source>readonly members</source>
<target state="new">readonly members</target>
<note />
</trans-unit>
<trans-unit id="IDS_FeatureRecursivePatterns">
<source>recursive patterns</source>
<target state="translated">criteri ricorsivi</target>
......
......@@ -752,6 +752,11 @@
<target state="translated">範囲演算子</target>
<note />
</trans-unit>
<trans-unit id="IDS_FeatureReadOnlyMembers">
<source>readonly members</source>
<target state="new">readonly members</target>
<note />
</trans-unit>
<trans-unit id="IDS_FeatureRecursivePatterns">
<source>recursive patterns</source>
<target state="translated">再帰的パターン</target>
......
......@@ -752,6 +752,11 @@
<target state="translated">범위 연산자</target>
<note />
</trans-unit>
<trans-unit id="IDS_FeatureReadOnlyMembers">
<source>readonly members</source>
<target state="new">readonly members</target>
<note />
</trans-unit>
<trans-unit id="IDS_FeatureRecursivePatterns">
<source>recursive patterns</source>
<target state="translated">재귀 패턴</target>
......
......@@ -752,6 +752,11 @@
<target state="translated">operator zakresu</target>
<note />
</trans-unit>
<trans-unit id="IDS_FeatureReadOnlyMembers">
<source>readonly members</source>
<target state="new">readonly members</target>
<note />
</trans-unit>
<trans-unit id="IDS_FeatureRecursivePatterns">
<source>recursive patterns</source>
<target state="translated">wzorce rekursywne</target>
......
......@@ -752,6 +752,11 @@
<target state="translated">operador de intervalo</target>
<note />
</trans-unit>
<trans-unit id="IDS_FeatureReadOnlyMembers">
<source>readonly members</source>
<target state="new">readonly members</target>
<note />
</trans-unit>
<trans-unit id="IDS_FeatureRecursivePatterns">
<source>recursive patterns</source>
<target state="translated">padrões recursivos</target>
......
......@@ -752,6 +752,11 @@
<target state="translated">оператор range</target>
<note />
</trans-unit>
<trans-unit id="IDS_FeatureReadOnlyMembers">
<source>readonly members</source>
<target state="new">readonly members</target>
<note />
</trans-unit>
<trans-unit id="IDS_FeatureRecursivePatterns">
<source>recursive patterns</source>
<target state="translated">рекурсивные шаблоны</target>
......
......@@ -753,6 +753,11 @@
<target state="translated">aralık işleci</target>
<note />
</trans-unit>
<trans-unit id="IDS_FeatureReadOnlyMembers">
<source>readonly members</source>
<target state="new">readonly members</target>
<note />
</trans-unit>
<trans-unit id="IDS_FeatureRecursivePatterns">
<source>recursive patterns</source>
<target state="translated">özyinelemeli desenler</target>
......
......@@ -753,6 +753,11 @@
<target state="translated">范围运算符</target>
<note />
</trans-unit>
<trans-unit id="IDS_FeatureReadOnlyMembers">
<source>readonly members</source>
<target state="new">readonly members</target>
<note />
</trans-unit>
<trans-unit id="IDS_FeatureRecursivePatterns">
<source>recursive patterns</source>
<target state="translated">递归模式</target>
......
......@@ -752,6 +752,11 @@
<target state="translated">範圍運算子</target>
<note />
</trans-unit>
<trans-unit id="IDS_FeatureReadOnlyMembers">
<source>readonly members</source>
<target state="new">readonly members</target>
<note />
</trans-unit>
<trans-unit id="IDS_FeatureRecursivePatterns">
<source>recursive patterns</source>
<target state="translated">遞迴模式</target>
......
......@@ -940,8 +940,6 @@ public static void Main()
);
}
// PROTOTYPE: readonly members features should require C# 8.0 or greater
[Fact]
public void ReadOnlyStructMethod()
{
......@@ -1780,5 +1778,53 @@ public struct S1
// readonly remove {}
Diagnostic(ErrorCode.ERR_NoModifiersOnAccessor, "readonly").WithLocation(9, 9));
}
[Fact]
public void ReadOnlyMembers_LangVersion()
{
var csharp = @"
using System;
public struct S
{
public readonly void M() {}
public readonly int P1 => 42;
public int P2 { readonly get => 123; }
public int P3 { readonly set {} }
public readonly int this[int i] => i;
public int this[int i, int j] { readonly get => i + j; }
public readonly event Action<EventArgs> E { add {} remove {} }
}
";
var comp = CreateCompilation(csharp, parseOptions: TestOptions.Regular7_3);
comp.VerifyDiagnostics(
// (6,12): error CS8652: The feature 'readonly members' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version.
// public readonly void M1() {}
Diagnostic(ErrorCode.ERR_FeatureInPreview, "readonly").WithArguments("readonly members").WithLocation(6, 12),
// (8,12): error CS8652: The feature 'readonly members' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version.
// public readonly int P1 => 42;
Diagnostic(ErrorCode.ERR_FeatureInPreview, "readonly").WithArguments("readonly members").WithLocation(8, 12),
// (9,21): error CS8652: The feature 'readonly members' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version.
// public int P2 { readonly get => 123; }
Diagnostic(ErrorCode.ERR_FeatureInPreview, "readonly").WithArguments("readonly members").WithLocation(9, 21),
// (10,21): error CS8652: The feature 'readonly members' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version.
// public int P3 { readonly set {} }
Diagnostic(ErrorCode.ERR_FeatureInPreview, "readonly").WithArguments("readonly members").WithLocation(10, 21),
// (12,12): error CS8652: The feature 'readonly members' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version.
// public readonly int this[int i] => i;
Diagnostic(ErrorCode.ERR_FeatureInPreview, "readonly").WithArguments("readonly members").WithLocation(12, 12),
// (13,37): error CS8652: The feature 'readonly members' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version.
// public int this[int i, int j] { readonly get => i + j; }
Diagnostic(ErrorCode.ERR_FeatureInPreview, "readonly").WithArguments("readonly members").WithLocation(13, 37),
// (15,12): error CS8652: The feature 'readonly members' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version.
// public readonly event Action<EventArgs> E { add {} remove {} }
Diagnostic(ErrorCode.ERR_FeatureInPreview, "readonly").WithArguments("readonly members").WithLocation(15, 12));
comp = CreateCompilation(csharp);
comp.VerifyDiagnostics();
}
}
}
......@@ -2733,7 +2733,7 @@ public void TestClassMethodWithPartial()
public void TestStructMethodWithReadonly()
{
var text = "struct a { readonly void M() { } }";
var file = this.ParseFile(text);
var file = this.ParseFile(text, TestOptions.Regular);
Assert.NotNull(file);
Assert.Equal(1, file.Members.Count);
......@@ -2780,7 +2780,7 @@ public void TestStructMethodWithReadonly()
public void TestReadOnlyRefReturning()
{
var text = "struct a { readonly ref readonly int M() { } }";
var file = this.ParseFile(text);
var file = this.ParseFile(text, TestOptions.Regular);
Assert.NotNull(file);
Assert.Equal(1, file.Members.Count);
......@@ -2830,7 +2830,7 @@ public void TestReadOnlyRefReturning()
public void TestStructExpressionPropertyWithReadonly()
{
var text = "struct a { readonly int M => 42; }";
var file = this.ParseFile(text);
var file = this.ParseFile(text, TestOptions.Regular);
Assert.NotNull(file);
Assert.Equal(1, file.Members.Count);
......@@ -2871,7 +2871,7 @@ public void TestStructExpressionPropertyWithReadonly()
public void TestStructGetterPropertyWithReadonly()
{
var text = "struct a { int P { readonly get { return 42; } } }";
var file = this.ParseFile(text);
var file = this.ParseFile(text, TestOptions.Regular);
Assert.NotNull(file);
Assert.Equal(1, file.Members.Count);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册