提交 473a3f41 编写于 作者: N Neal Gafter 提交者: GitHub

Add tests for basic `private protected` functionality. (#20831)

* Add tests for basic `private protected` functionality.
* Constrain private protected to language version 7.2.
* Add tests for VB, and adjust existing VB tests as needed.
* Add test for SyntaxFacts production of source for private protected.
* Add VB tests corresponding to all C# tests for private protected
* Mention `private protected` in the compiler test plan.
上级 80d0adc2
......@@ -20,11 +20,12 @@ efforts behind them.
| Feature | Branch | State | Developers | Reviewer | LDM Champ |
| ------- | ------ | ----- | ---------- | -------- | --------- |
| [ref readonly](https://github.com/dotnet/csharplang/blob/master/proposals/readonly-ref.md) | [readonly-ref](https://github.com/dotnet/roslyn/tree/features/readonly-ref) | Prototype | [vsadov](https://github.com/vsadov), [omar](https://github.com/OmarTawfikw) | [cston](https://github.com/cston) | [jaredpar](https://github.com/jaredpar) |
| [ref readonly](https://github.com/dotnet/csharplang/blob/master/proposals/readonly-ref.md) | [readonly-ref](https://github.com/dotnet/roslyn/tree/features/readonly-ref) | Prototype | [vsadov](https://github.com/vsadov), [omar](https://github.com/OmarTawfikw) | [cston](https://github.com/cston),[gafter](https://github.com/gafter) | [jaredpar](https://github.com/jaredpar) |
| [blittable](https://github.com/dotnet/csharplang/pull/206) | None | Proposal | None | | [jaredpar](https://github.com/jaredpar) |
| strongname | [strongname](https://github.com/dotnet/roslyn/tree/features/strongname) | In Progress | [Ty Overby](https://github.com/tyoverby) | | [jaredpar](https://github.com/jaredpar) |
| [interior pointer](https://github.com/dotnet/csharplang/pull/264) | None | Proposal | [vsadov](https://github.com/vsadov) | [jaredpar](https://github.com/jaredpar) | [jaredpar](https://github.com/jaredpar) |
| [non-trailing named arguments](https://github.com/dotnet/csharplang/blob/master/proposals/non-trailing-named-arguments.md) | [non-trailing](https://github.com/dotnet/roslyn/tree/features/non-trailing) | Prototype | [jcouv](https://github.com/jcouv) | TBD | [jcouv](https://github.com/jcouv) |
| [non-trailing named arguments](https://github.com/dotnet/csharplang/blob/master/proposals/non-trailing-named-arguments.md) | [non-trailing](https://github.com/dotnet/roslyn/tree/features/non-trailing) | Prototype | [jcouv](https://github.com/jcouv) | [gafter](https://github.com/gafter) | [jcouv](https://github.com/jcouv) |
| [private protected](https://github.com/dotnet/csharplang/blob/master/proposals/private-protected.md) | [privateProtected](https://github.com/dotnet/roslyn/tree/features/privateProtected) | In Progress | [gafter](https://github.com/gafter) | [jcouv](https://github.com/jcouv) | [gafter](https://github.com/gafter) |
# C# 8.0
......
This document provides guidance for thinking about language interactions and testing compiler changes.
This document provides guidance for thinking about language interactions and testing compiler changes.
# General concerns:
- Completeness of the specification as a guide for testing (is the spec complete enough to suggest what the compiler should do in each scenario?)
......@@ -30,7 +30,7 @@
- Performance and stress testing
# Type and members
- Access modifiers (public, protected, internal, protected internal, private), static modifier
- Access modifiers (public, protected, internal, protected internal, private protected, private), static modifier
- Parameter modifiers (ref, out, params)
- Attributes (including security attribute)
- Generics (type arguments, constraints, variance)
......
......@@ -2063,13 +2063,17 @@ private AssemblySymbol GetForwardedToAssembly(string fullName, int arity, Diagno
internal static bool CheckFeatureAvailability(SyntaxNode syntax, MessageID feature, DiagnosticBag diagnostics, Location locationOpt = null)
{
var options = (CSharpParseOptions)syntax.SyntaxTree.Options;
return CheckFeatureAvailability(syntax.SyntaxTree, feature, diagnostics, locationOpt ?? syntax.GetLocation());
}
internal static bool CheckFeatureAvailability(SyntaxTree tree, MessageID feature, DiagnosticBag diagnostics, Location location)
{
var options = (CSharpParseOptions)tree.Options;
if (options.IsFeatureEnabled(feature))
{
return true;
}
var location = locationOpt ?? syntax.GetLocation();
string requiredFeature = feature.RequiredFeature();
if (requiredFeature != null)
{
......
......@@ -6866,7 +6866,7 @@ internal class CSharpResources {
}
/// <summary>
/// Looks up a localized string similar to Elements defined in a namespace cannot be explicitly declared as private, protected, or protected internal.
/// Looks up a localized string similar to Elements defined in a namespace cannot be explicitly declared as private, protected, protected internal, or private protected.
/// </summary>
internal static string ERR_NoNamespacePrivate {
get {
......@@ -10331,6 +10331,15 @@ internal class CSharpResources {
}
}
/// <summary>
/// Looks up a localized string similar to private protected.
/// </summary>
internal static string IDS_FeaturePrivateProtected {
get {
return ResourceManager.GetString("IDS_FeaturePrivateProtected", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to access modifiers on properties.
/// </summary>
......
......@@ -210,6 +210,9 @@
<data name="IDS_FeatureDefaultLiteral" xml:space="preserve">
<value>default literal</value>
</data>
<data name="IDS_FeaturePrivateProtected" xml:space="preserve">
<value>private protected</value>
</data>
<data name="IDS_FeatureNullable" xml:space="preserve">
<value>nullable types</value>
</data>
......@@ -2471,7 +2474,7 @@ A catch() block after a catch (System.Exception e) block can catch non-CLS excep
<value>A new expression requires (), [], or {} after type</value>
</data>
<data name="ERR_NoNamespacePrivate" xml:space="preserve">
<value>Elements defined in a namespace cannot be explicitly declared as private, protected, or protected internal</value>
<value>Elements defined in a namespace cannot be explicitly declared as private, protected, protected internal, or private protected</value>
</data>
<data name="ERR_BadVarDecl" xml:space="preserve">
<value>Expected ; or = (cannot specify constructor arguments in declaration)</value>
......
......@@ -132,6 +132,7 @@ internal enum MessageID
IDS_FeatureGenericPatternMatching = MessageBase + 12720,
IDS_FeatureAsyncMain = MessageBase + 12721,
IDS_LangVersions = MessageBase + 12722,
IDS_FeaturePrivateProtected = MessageBase + 12723,
}
// Message IDs may refer to strings that need to be localized.
......@@ -188,6 +189,9 @@ internal static LanguageVersion RequiredVersion(this MessageID feature)
// Checks are in the LanguageParser unless otherwise noted.
switch (feature)
{
case MessageID.IDS_FeaturePrivateProtected:
return LanguageVersion.CSharp7_2;
// C# 7.1 features.
case MessageID.IDS_FeatureAsyncMain:
case MessageID.IDS_FeatureDefaultLiteral:
......
......@@ -62,7 +62,14 @@ internal static class ModifierUtils
if (isMethod && ((result & (DeclarationModifiers.Partial | DeclarationModifiers.Private)) == (DeclarationModifiers.Partial | DeclarationModifiers.Private)))
{
diagnostics.Add(ErrorCode.ERR_PartialMethodInvalidModifier, errorLocation);
modifierErrors = true;
}
if ((result & DeclarationModifiers.PrivateProtected) != 0)
{
modifierErrors |= !Binder.CheckFeatureAvailability(errorLocation.SourceTree, MessageID.IDS_FeaturePrivateProtected, diagnostics, errorLocation);
}
return result;
}
......@@ -232,24 +239,6 @@ private static DeclarationModifiers ToDeclarationModifier(SyntaxKind kind)
seenNoDuplicates = false;
}
}
else
{
if ((allModifiers & DeclarationModifiers.AccessibilityMask) != 0 && (modifierKind & DeclarationModifiers.AccessibilityMask) != 0)
{
// Can't have two different access modifiers.
// Exception: "internal protected" or "protected internal" is allowed.
if (!(((modifierKind == DeclarationModifiers.Protected) && (allModifiers & DeclarationModifiers.Internal) != 0) ||
((modifierKind == DeclarationModifiers.Internal) && (allModifiers & DeclarationModifiers.Protected) != 0)))
{
if (seenNoAccessibilityDuplicates)
{
diagnostics.Add(ErrorCode.ERR_BadMemberProtection, modifierToken.GetLocation());
}
seenNoAccessibilityDuplicates = false;
}
}
}
}
internal static CSDiagnosticInfo CheckAccessibility(DeclarationModifiers modifiers)
......
......@@ -332,19 +332,35 @@ private DeclarationModifiers MakeModifiers(TypeKind typeKind, DiagnosticBag diag
missingPartial = true;
}
if (!modifierErrors)
{
mods = ModifierUtils.CheckModifiers(
mods, allowedModifiers, declaration.Declarations[i].NameLocation, diagnostics,
modifierTokensOpt: null, modifierErrors: out modifierErrors);
// It is an error for the same modifier to appear multiple times.
if (!modifierErrors)
{
var info = ModifierUtils.CheckAccessibility(mods);
if (info != null)
{
diagnostics.Add(info, self.Locations[0]);
modifierErrors = true;
}
}
}
if (result == DeclarationModifiers.Unset)
{
result = mods;
continue;
}
else
{
result |= mods;
}
result |= mods;
}
result = ModifierUtils.CheckModifiers(
result, allowedModifiers, self.Locations[0], diagnostics,
modifierTokensOpt: null, modifierErrors: out modifierErrors);
if ((result & DeclarationModifiers.AccessibilityMask) == 0)
{
result |= defaultAccess;
......
......@@ -390,7 +390,7 @@ internal override NamespaceExtent Extent
{
//types declared at the namespace level may only have declared accessibility of public or internal (Section 3.5.1)
Accessibility declaredAccessibility = nts.DeclaredAccessibility;
if ((declaredAccessibility & (Accessibility.Public | Accessibility.Internal)) != declaredAccessibility)
if (declaredAccessibility != Accessibility.Public && declaredAccessibility != Accessibility.Internal)
{
diagnostics.Add(ErrorCode.ERR_NoNamespacePrivate, symbol.Locations[0]);
}
......
此差异已折叠。
......@@ -638,6 +638,41 @@ class C2 {
SymbolDisplayPartKind.Punctuation);
}
[Fact]
public void TestPrivateProtected()
{
var text = @"class C2 { private protected void M() {} }";
Func<NamespaceSymbol, Symbol> findSymbol = global =>
global.GetTypeMembers("C2").Single().
GetMembers("M").Single();
var format = new SymbolDisplayFormat(
memberOptions:
SymbolDisplayMemberOptions.IncludeParameters |
SymbolDisplayMemberOptions.IncludeModifiers |
SymbolDisplayMemberOptions.IncludeAccessibility |
SymbolDisplayMemberOptions.IncludeType |
SymbolDisplayMemberOptions.IncludeContainingType);
TestSymbolDescription(
text,
findSymbol,
format,
"private protected void C2.M()",
SymbolDisplayPartKind.Keyword, // private
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.Keyword, // protected
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.Keyword, // void
SymbolDisplayPartKind.Space,
SymbolDisplayPartKind.ClassName, //C2
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.MethodName, //M
SymbolDisplayPartKind.Punctuation,
SymbolDisplayPartKind.Punctuation);
}
[Fact]
public void TestNullParameters()
{
......
......@@ -203,12 +203,26 @@ sealed enum Figure0 { Zero }; // sealed not valid
}";
//VerifyEnumsValue(text, "TestEnum", 0, 1);
var comp = CreateStandardCompilation(text);
DiagnosticsUtils.VerifyErrorCodesNoLineColumn(comp.GetDiagnostics(), new ErrorDescription { Code = (int)ErrorCode.ERR_BadMemberFlag },
new ErrorDescription { Code = (int)ErrorCode.ERR_BadMemberFlag },
new ErrorDescription { Code = (int)ErrorCode.ERR_BadMemberProtection },
new ErrorDescription { Code = (int)ErrorCode.ERR_DuplicateModifier },
new ErrorDescription { Code = (int)ErrorCode.WRN_NewNotRequired },
new ErrorDescription { Code = (int)ErrorCode.WRN_NewNotRequired });
comp.VerifyDiagnostics(
// (5,19): error CS0106: The modifier 'abstract' is not valid for this item
// abstract enum Figure3 { Zero }; // abstract not valid
Diagnostic(ErrorCode.ERR_BadMemberFlag, "Figure3").WithArguments("abstract").WithLocation(5, 19),
// (6,13): error CS1004: Duplicate 'private' modifier
// private private enum Figure4 { One = 1 }; // Duplicate modifier is not OK
Diagnostic(ErrorCode.ERR_DuplicateModifier, "private").WithArguments("private").WithLocation(6, 13),
// (7,25): error CS0107: More than one protection modifier
// private public enum Figure5 { }; // More than one protection modifiers is not OK
Diagnostic(ErrorCode.ERR_BadMemberProtection, "Figure5").WithLocation(7, 25),
// (8,17): error CS0106: The modifier 'sealed' is not valid for this item
// sealed enum Figure0 { Zero }; // sealed not valid
Diagnostic(ErrorCode.ERR_BadMemberFlag, "Figure0").WithArguments("sealed").WithLocation(8, 17),
// (9,14): warning CS0109: The member 'Program.Figure' does not hide an accessible member. The new keyword is not required.
// new enum Figure { Zero }; // OK
Diagnostic(ErrorCode.WRN_NewNotRequired, "Figure").WithArguments("Program.Figure").WithLocation(9, 14),
// (4,21): warning CS0109: The member 'Program.Figure2' does not hide an accessible member. The new keyword is not required.
// new public enum Figure2 { Zero = 0 }; // new + protection modifier is OK
Diagnostic(ErrorCode.WRN_NewNotRequired, "Figure2").WithArguments("Program.Figure2").WithLocation(4, 21)
);
}
[WorkItem(527757, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/527757")]
......
......@@ -3357,10 +3357,18 @@ internal partial struct S { }
}
}
";
var comp = DiagnosticsUtils.VerifyErrorsAndGetCompilationWithMscorlib(text,
new ErrorDescription { Code = (int)ErrorCode.ERR_PartialModifierConflict, Line = 3, Column = 30 },
new ErrorDescription { Code = (int)ErrorCode.ERR_PartialModifierConflict, Line = 9, Column = 32 },
new ErrorDescription { Code = (int)ErrorCode.ERR_PartialModifierConflict, Line = 12, Column = 32 });
var comp = CreateStandardCompilation(text);
comp.VerifyDiagnostics(
// (3,30): error CS0262: Partial declarations of 'I' have conflicting accessibility modifiers
// public partial interface I { }
Diagnostic(ErrorCode.ERR_PartialModifierConflict, "I").WithArguments("NS.I").WithLocation(3, 30),
// (9,32): error CS0262: Partial declarations of 'A.C' have conflicting accessibility modifiers
// internal partial class C { }
Diagnostic(ErrorCode.ERR_PartialModifierConflict, "C").WithArguments("NS.A.C").WithLocation(9, 32),
// (12,32): error CS0262: Partial declarations of 'A.S' have conflicting accessibility modifiers
// private partial struct S { }
Diagnostic(ErrorCode.ERR_PartialModifierConflict, "S").WithArguments("NS.A.S").WithLocation(12, 32)
);
var ns = comp.SourceModule.GlobalNamespace.GetMembers("NS").Single() as NamespaceSymbol;
// TODO...
......
......@@ -115,22 +115,43 @@ public void CS0107ERR_BadMemberProtection()
{
var test = @"
public class C
{
{
private internal void f() {}
public static int Main()
{
public private int F = 1;
public private int P { get => 1; }
public int Q { get => 1; private public set {} }
public private C() {}
public private static int Main()
{
return 1;
}
}
}
";
ParseAndValidate(test);
CreateStandardCompilation(test).VerifyDiagnostics(
// (4,13): error CS0107: More than one protection modifier
// private internal void f() {}
Diagnostic(ErrorCode.ERR_BadMemberProtection, "internal").WithLocation(4, 13),
// (4,27): error CS0107: More than one protection modifier
// private internal void f() {}
Diagnostic(ErrorCode.ERR_BadMemberProtection, "f").WithLocation(4, 27));
Diagnostic(ErrorCode.ERR_BadMemberProtection, "f").WithLocation(4, 27),
// (5,24): error CS0107: More than one protection modifier
// public private int F = 1;
Diagnostic(ErrorCode.ERR_BadMemberProtection, "F").WithLocation(5, 24),
// (6,24): error CS0107: More than one protection modifier
// public private int P { get => 1; }
Diagnostic(ErrorCode.ERR_BadMemberProtection, "P").WithLocation(6, 24),
// (7,45): error CS0107: More than one protection modifier
// public int Q { get => 1; private public set {} }
Diagnostic(ErrorCode.ERR_BadMemberProtection, "set").WithLocation(7, 45),
// (7,45): error CS0273: The accessibility modifier of the 'C.Q.set' accessor must be more restrictive than the property or indexer 'C.Q'
// public int Q { get => 1; private public set {} }
Diagnostic(ErrorCode.ERR_InvalidPropertyAccessMod, "set").WithArguments("C.Q.set", "C.Q").WithLocation(7, 45),
// (8,20): error CS0107: More than one protection modifier
// public private C() {}
Diagnostic(ErrorCode.ERR_BadMemberProtection, "C").WithLocation(8, 20),
// (9,31): error CS0107: More than one protection modifier
// public private static int Main()
Diagnostic(ErrorCode.ERR_BadMemberProtection, "Main").WithLocation(9, 31)
);
}
[Fact, WorkItem(543622, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/543622")]
......
......@@ -16,6 +16,7 @@ public static class TestOptions
public static readonly CSharpParseOptions Regular6 = Regular.WithLanguageVersion(LanguageVersion.CSharp6);
public static readonly CSharpParseOptions Regular7 = Regular.WithLanguageVersion(LanguageVersion.CSharp7);
public static readonly CSharpParseOptions Regular7_1 = Regular.WithLanguageVersion(LanguageVersion.CSharp7_1);
public static readonly CSharpParseOptions Regular7_2 = Regular.WithLanguageVersion(LanguageVersion.CSharp7_2);
public static readonly CSharpParseOptions RegularWithDocumentationComments = new CSharpParseOptions(kind: SourceCodeKind.Regular, documentationMode: DocumentationMode.Diagnose);
private static readonly SmallDictionary<string, string> s_experimentalFeatures = new SmallDictionary<string, string> { };
......
......@@ -182,12 +182,13 @@ Friend Module CompilationUtils
sources As XElement,
Optional additionalRefs As MetadataReference() = Nothing,
Optional options As VisualBasicCompilationOptions = Nothing,
Optional parseOptions As VisualBasicParseOptions = Nothing) As VisualBasicCompilation
Optional parseOptions As VisualBasicParseOptions = Nothing,
Optional assemblyName As String = Nothing) As VisualBasicCompilation
If additionalRefs Is Nothing Then additionalRefs = {}
Dim references = {MscorlibRef, SystemRef, MsvbRef}.Concat(additionalRefs)
Return CreateCompilationWithReferences(sources, references, options, parseOptions:=parseOptions)
Return CreateCompilationWithReferences(sources, references, options, parseOptions:=parseOptions, assemblyName:=assemblyName)
End Function
Public Function CreateCompilationWithMscorlibAndVBRuntime(trees As IEnumerable(Of SyntaxTree),
......@@ -263,8 +264,8 @@ Friend Module CompilationUtils
Public Function CreateCompilationWithReferences(sources As XElement,
references As IEnumerable(Of MetadataReference),
Optional options As VisualBasicCompilationOptions = Nothing,
Optional parseOptions As VisualBasicParseOptions = Nothing) As VisualBasicCompilation
Dim assemblyName As String = Nothing
Optional parseOptions As VisualBasicParseOptions = Nothing,
Optional assemblyName As String = Nothing) As VisualBasicCompilation
Dim sourceTrees = ParseSouceXml(sources, parseOptions, assemblyName)
Return CreateCompilationWithReferences(sourceTrees, references, options, assemblyName)
End Function
......
......@@ -143,6 +143,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic
defaultAccessibility As Accessibility,
diagBag As DiagnosticBag) As MemberModifiers
Dim foundModifiers As SourceMemberFlags = Nothing
Dim privateProtectedToken As SyntaxToken = Nothing
' Go through each modifiers, accumulating flags of what we've seen and reporting errors.
For Each keywordSyntax In syntax
......@@ -160,7 +161,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic
ElseIf (currentModifier And SourceMemberFlags.AllAccessibilityModifiers) <> 0 AndAlso
(foundModifiers And SourceMemberFlags.AllAccessibilityModifiers) <> 0 AndAlso
Not ((foundModifiers Or currentModifier) And SourceMemberFlags.AllAccessibilityModifiers) = (SourceMemberFlags.Protected Or SourceMemberFlags.Friend) AndAlso
Not (((foundModifiers Or currentModifier) And SourceMemberFlags.AllAccessibilityModifiers) = (SourceMemberFlags.Protected Or SourceMemberFlags.Private) AndAlso Me.Compilation.Feature("privateProtected") <> Nothing) Then
Not (((foundModifiers Or currentModifier) And SourceMemberFlags.AllAccessibilityModifiers) = (SourceMemberFlags.Protected Or SourceMemberFlags.Private)) Then
ReportDiagnostic(diagBag, keywordSyntax, ERRID.ERR_DuplicateAccessCategoryUsed)
ElseIf (currentModifier And SourceMemberFlags.AllOverrideModifiers) <> 0 AndAlso
(foundModifiers And SourceMemberFlags.AllOverrideModifiers) <> 0 Then
......@@ -198,6 +199,9 @@ Namespace Microsoft.CodeAnalysis.VisualBasic
' Note: Need to be present both MustInherit & NotInheritable for properly reporting #30926
foundModifiers = foundModifiers Or currentModifier
Else
If currentModifier = SourceMemberFlags.Private OrElse currentModifier = SourceMemberFlags.Protected Then
privateProtectedToken = keywordSyntax
End If
foundModifiers = foundModifiers Or currentModifier
End If
Next
......@@ -210,6 +214,11 @@ Namespace Microsoft.CodeAnalysis.VisualBasic
access = Accessibility.ProtectedOrFriend
ElseIf (foundModifiers And (SourceMemberFlags.Private Or SourceMemberFlags.Protected)) = (SourceMemberFlags.Private Or SourceMemberFlags.Protected) Then
access = Accessibility.ProtectedAndFriend
InternalSyntax.Parser.CheckFeatureAvailability(
diagBag,
privateProtectedToken.GetLocation(),
DirectCast(privateProtectedToken.SyntaxTree, VisualBasicSyntaxTree).Options.LanguageVersion,
InternalSyntax.Feature.PrivateProtected)
ElseIf (foundModifiers And SourceMemberFlags.Friend) <> 0 Then
access = Accessibility.Friend
ElseIf (foundModifiers And SourceMemberFlags.Protected) <> 0 Then
......@@ -660,58 +669,58 @@ Namespace Microsoft.CodeAnalysis.VisualBasic
End If
' default type is object.
Return GetSpecialType(specialType.System_Object, identifier, diagBag)
Return GetSpecialType(SpecialType.System_Object, identifier, diagBag)
End If
End Function
Public Shared Function GetSpecialTypeForTypeCharacter(typeChar As TypeCharacter, ByRef typeCharacterString As String) As SpecialType
Dim specialType As SpecialType = specialType.None
Dim specialType As SpecialType = SpecialType.None
Select Case typeChar
Case TypeCharacter.Decimal
specialType = specialType.System_Decimal
specialType = SpecialType.System_Decimal
typeCharacterString = "@"
Case TypeCharacter.DecimalLiteral
specialType = specialType.System_Decimal
specialType = SpecialType.System_Decimal
typeCharacterString = "D"
Case TypeCharacter.Double
specialType = specialType.System_Double
specialType = SpecialType.System_Double
typeCharacterString = "#"
Case TypeCharacter.DoubleLiteral
specialType = specialType.System_Double
specialType = SpecialType.System_Double
typeCharacterString = "R"
Case TypeCharacter.Integer
specialType = specialType.System_Int32
specialType = SpecialType.System_Int32
typeCharacterString = "%"
Case TypeCharacter.IntegerLiteral
specialType = specialType.System_Int32
specialType = SpecialType.System_Int32
typeCharacterString = "I"
Case TypeCharacter.Long
specialType = specialType.System_Int64
specialType = SpecialType.System_Int64
typeCharacterString = "&"
Case TypeCharacter.LongLiteral
specialType = specialType.System_Int64
specialType = SpecialType.System_Int64
typeCharacterString = "L"
Case TypeCharacter.ShortLiteral
specialType = specialType.System_Int16
specialType = SpecialType.System_Int16
typeCharacterString = "S"
Case TypeCharacter.Single
specialType = specialType.System_Single
specialType = SpecialType.System_Single
typeCharacterString = "!"
Case TypeCharacter.SingleLiteral
specialType = specialType.System_Single
specialType = SpecialType.System_Single
typeCharacterString = "F"
Case TypeCharacter.String
specialType = specialType.System_String
specialType = SpecialType.System_String
typeCharacterString = "$"
Case TypeCharacter.UIntegerLiteral
specialType = specialType.System_UInt32
specialType = SpecialType.System_UInt32
typeCharacterString = "UI"
Case TypeCharacter.ULongLiteral
specialType = specialType.System_UInt64
specialType = SpecialType.System_UInt64
typeCharacterString = "UL"
Case TypeCharacter.UShortLiteral
specialType = specialType.System_UInt16
specialType = SpecialType.System_UInt16
typeCharacterString = "US"
Case TypeCharacter.None
typeCharacterString = Nothing
......
......@@ -2009,5 +2009,6 @@ Namespace Microsoft.CodeAnalysis.VisualBasic
FEATURE_BinaryLiterals
FEATURE_Tuples
FEATURE_IOperation
FEATURE_PrivateProtected
End Enum
End Namespace
......@@ -34,6 +34,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.Syntax.InternalSyntax
Tuples
IOperation
InferredTupleNames
PrivateProtected
End Enum
Friend Module FeatureExtensions
......@@ -90,6 +91,9 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.Syntax.InternalSyntax
Case Feature.InferredTupleNames
Return LanguageVersion.VisualBasic15_3
Case Feature.PrivateProtected
Return LanguageVersion.VisualBasic15_5
Case Else
Throw ExceptionUtilities.UnexpectedValue(feature)
End Select
......@@ -153,6 +157,8 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.Syntax.InternalSyntax
Return ERRID.FEATURE_Tuples
Case Feature.IOperation
Return ERRID.FEATURE_IOperation
Case Feature.PrivateProtected
Return ERRID.FEATURE_PrivateProtected
Case Else
Throw ExceptionUtilities.UnexpectedValue(feature)
End Select
......
......@@ -509,16 +509,6 @@ Namespace Microsoft.CodeAnalysis.VisualBasic
' Get the accessibility modifier for a symbol to put into an error message.
Public Shared Function GetAccessibilityForErrorMessage(sym As Symbol, fromAssembly As AssemblySymbol) As String
Dim access = sym.DeclaredAccessibility
If access = Accessibility.ProtectedAndFriend Then
' No exact VB equivalent for this. If its in an accessible assembly, treat as protected,
' otherwise treat as friend.
If AccessCheck.IsSymbolAccessible(sym.ContainingAssembly, fromAssembly, useSiteDiagnostics:=Nothing) Then
access = Accessibility.Protected
Else
access = Accessibility.Friend
End If
End If
Return access.ToDisplay()
End Function
......
......@@ -12099,6 +12099,15 @@ Namespace Microsoft.CodeAnalysis.VisualBasic
End Get
End Property
'''<summary>
''' Looks up a localized string similar to Private Protected.
'''</summary>
Friend ReadOnly Property FEATURE_PrivateProtected() As String
Get
Return ResourceManager.GetString("FEATURE_PrivateProtected", resourceCulture)
End Get
End Property
'''<summary>
''' Looks up a localized string similar to readonly auto-implemented properties.
'''</summary>
......
......@@ -5407,6 +5407,9 @@
<data name="FEATURE_Tuples" xml:space="preserve">
<value>tuples</value>
</data>
<data name="FEATURE_PrivateProtected" xml:space="preserve">
<value>Private Protected</value>
</data>
<data name="ERR_DebugEntryPointNotSourceMethodDefinition" xml:space="preserve">
<value>Debug entry point must be a definition of a method declared in the current compilation.</value>
</data>
......
此差异已折叠。
......@@ -406,7 +406,7 @@ BC33011: Operators must be declared 'Public'.
BC33011: Operators must be declared 'Public'.
Private Protected Shared Operator IsFalse(x As A1) As Boolean 'BIND5:"A1"
~~~~~~~
BC30176: Only one of 'Public', 'Private', 'Protected', 'Friend', or 'Protected Friend' can be specified.
BC36716: Visual Basic 15.0 does not support Private Protected.
Private Protected Shared Operator IsFalse(x As A1) As Boolean 'BIND5:"A1"
~~~~~~~~~
BC33012: Operators must be declared 'Shared'.
......
......@@ -22010,7 +22010,7 @@ End Class
</compilation>)
Dim expectedErrors = <errors><![CDATA[
BC30176: Only one of 'Public', 'Private', 'Protected', 'Friend', or 'Protected Friend' can be specified.
BC36716: Visual Basic 15.0 does not support Private Protected.
Protected Private Sub m1()
~~~~~~~
BC30177: Only one of 'NotOverridable', 'MustOverride', or 'Overridable' can be specified.
......
......@@ -38,6 +38,7 @@ private void ValidIdentifier(string identifier, bool expectedValid)
public void SyntaxFactsMethods()
{
Assert.Equal("protected internal", SyntaxFacts.GetText(Accessibility.ProtectedOrInternal));
Assert.Equal("private protected", SyntaxFacts.GetText(Accessibility.ProtectedAndInternal));
Assert.Equal("??", SyntaxFacts.GetText(SyntaxKind.QuestionQuestionToken));
Assert.Equal("this", SyntaxFacts.GetText(SyntaxKind.ThisKeyword));
......
......@@ -36,6 +36,7 @@ End Class ' exact text round trip, including comments and whitespace
<Fact>
Sub SyntaxFactsMethods()
Assert.Equal("Protected Friend", SyntaxFacts.GetText(Accessibility.ProtectedOrFriend))
Assert.Equal("Private Protected", SyntaxFacts.GetText(Accessibility.ProtectedAndFriend))
Assert.Equal("Me", SyntaxFacts.GetText(SyntaxKind.MeKeyword))
Assert.Equal(SyntaxKind.CharacterLiteralExpression, SyntaxFacts.GetLiteralExpression(SyntaxKind.CharacterLiteralToken))
Assert.Equal(False, SyntaxFacts.IsPunctuation(SyntaxKind.StringLiteralToken))
......
......@@ -22,5 +22,6 @@ public enum CompilerFeature
Patterns,
DefaultLiteral,
AsyncMain,
PrivateProtected,
}
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册