提交 7adc1215 编写于 作者: M Manish Vasani

Move certain Syntax querying APIs down from SyntaxGenerator to ISyntaxFacts....

Move certain Syntax querying APIs down from SyntaxGenerator to ISyntaxFacts. These APIs are used by accessibility related analyzers.

This change also requires explicitly linking in the public type DeclarationKind into CodeStyle layer.
上级 a06a8373
......@@ -26,6 +26,7 @@
<InternalsVisibleTo Include="Microsoft.CodeAnalysis.VisualBasic.CodeStyle.UnitTests" />
</ItemGroup>
<ItemGroup>
<Compile Include="..\..\..\Workspaces\Core\Portable\Editing\DeclarationKind.cs" Link="Editing\DeclarationKind.cs" />
<Compile Include="..\..\..\Workspaces\Core\Portable\Editing\DeclarationModifiers.cs" Link="Editing\DeclarationModifiers.cs" />
<Compile Include="..\..\..\Workspaces\Core\Portable\CodeStyle\CodeStyleOption.cs" Link="Options\CodeStyleOption.cs" />
<Compile Include="..\..\..\Workspaces\Core\Portable\CodeStyle\CodeStyleOptions.cs" Link="Options\CodeStyleOptions.cs" />
......
Microsoft.CodeAnalysis.Internal.Editing.DeclarationKind
Microsoft.CodeAnalysis.Internal.Editing.DeclarationKind.AddAccessor = 26 -> Microsoft.CodeAnalysis.Internal.Editing.DeclarationKind
Microsoft.CodeAnalysis.Internal.Editing.DeclarationKind.Attribute = 22 -> Microsoft.CodeAnalysis.Internal.Editing.DeclarationKind
Microsoft.CodeAnalysis.Internal.Editing.DeclarationKind.Class = 2 -> Microsoft.CodeAnalysis.Internal.Editing.DeclarationKind
Microsoft.CodeAnalysis.Internal.Editing.DeclarationKind.CompilationUnit = 1 -> Microsoft.CodeAnalysis.Internal.Editing.DeclarationKind
Microsoft.CodeAnalysis.Internal.Editing.DeclarationKind.Constructor = 10 -> Microsoft.CodeAnalysis.Internal.Editing.DeclarationKind
Microsoft.CodeAnalysis.Internal.Editing.DeclarationKind.ConversionOperator = 9 -> Microsoft.CodeAnalysis.Internal.Editing.DeclarationKind
Microsoft.CodeAnalysis.Internal.Editing.DeclarationKind.CustomEvent = 17 -> Microsoft.CodeAnalysis.Internal.Editing.DeclarationKind
Microsoft.CodeAnalysis.Internal.Editing.DeclarationKind.Delegate = 6 -> Microsoft.CodeAnalysis.Internal.Editing.DeclarationKind
Microsoft.CodeAnalysis.Internal.Editing.DeclarationKind.Destructor = 11 -> Microsoft.CodeAnalysis.Internal.Editing.DeclarationKind
Microsoft.CodeAnalysis.Internal.Editing.DeclarationKind.Enum = 5 -> Microsoft.CodeAnalysis.Internal.Editing.DeclarationKind
Microsoft.CodeAnalysis.Internal.Editing.DeclarationKind.EnumMember = 15 -> Microsoft.CodeAnalysis.Internal.Editing.DeclarationKind
Microsoft.CodeAnalysis.Internal.Editing.DeclarationKind.Event = 16 -> Microsoft.CodeAnalysis.Internal.Editing.DeclarationKind
Microsoft.CodeAnalysis.Internal.Editing.DeclarationKind.Field = 12 -> Microsoft.CodeAnalysis.Internal.Editing.DeclarationKind
Microsoft.CodeAnalysis.Internal.Editing.DeclarationKind.GetAccessor = 24 -> Microsoft.CodeAnalysis.Internal.Editing.DeclarationKind
Microsoft.CodeAnalysis.Internal.Editing.DeclarationKind.Indexer = 14 -> Microsoft.CodeAnalysis.Internal.Editing.DeclarationKind
Microsoft.CodeAnalysis.Internal.Editing.DeclarationKind.Interface = 4 -> Microsoft.CodeAnalysis.Internal.Editing.DeclarationKind
Microsoft.CodeAnalysis.Internal.Editing.DeclarationKind.LambdaExpression = 23 -> Microsoft.CodeAnalysis.Internal.Editing.DeclarationKind
Microsoft.CodeAnalysis.Internal.Editing.DeclarationKind.Method = 7 -> Microsoft.CodeAnalysis.Internal.Editing.DeclarationKind
Microsoft.CodeAnalysis.Internal.Editing.DeclarationKind.Namespace = 18 -> Microsoft.CodeAnalysis.Internal.Editing.DeclarationKind
Microsoft.CodeAnalysis.Internal.Editing.DeclarationKind.NamespaceImport = 19 -> Microsoft.CodeAnalysis.Internal.Editing.DeclarationKind
Microsoft.CodeAnalysis.Internal.Editing.DeclarationKind.None = 0 -> Microsoft.CodeAnalysis.Internal.Editing.DeclarationKind
Microsoft.CodeAnalysis.Internal.Editing.DeclarationKind.Operator = 8 -> Microsoft.CodeAnalysis.Internal.Editing.DeclarationKind
Microsoft.CodeAnalysis.Internal.Editing.DeclarationKind.Parameter = 20 -> Microsoft.CodeAnalysis.Internal.Editing.DeclarationKind
Microsoft.CodeAnalysis.Internal.Editing.DeclarationKind.Property = 13 -> Microsoft.CodeAnalysis.Internal.Editing.DeclarationKind
Microsoft.CodeAnalysis.Internal.Editing.DeclarationKind.RaiseAccessor = 28 -> Microsoft.CodeAnalysis.Internal.Editing.DeclarationKind
Microsoft.CodeAnalysis.Internal.Editing.DeclarationKind.RemoveAccessor = 27 -> Microsoft.CodeAnalysis.Internal.Editing.DeclarationKind
Microsoft.CodeAnalysis.Internal.Editing.DeclarationKind.SetAccessor = 25 -> Microsoft.CodeAnalysis.Internal.Editing.DeclarationKind
Microsoft.CodeAnalysis.Internal.Editing.DeclarationKind.Struct = 3 -> Microsoft.CodeAnalysis.Internal.Editing.DeclarationKind
Microsoft.CodeAnalysis.Internal.Editing.DeclarationKind.Variable = 21 -> Microsoft.CodeAnalysis.Internal.Editing.DeclarationKind
Microsoft.CodeAnalysis.Internal.Editing.DeclarationModifiers
Microsoft.CodeAnalysis.Internal.Editing.DeclarationModifiers.Equals(Microsoft.CodeAnalysis.Internal.Editing.DeclarationModifiers modifiers) -> bool
Microsoft.CodeAnalysis.Internal.Editing.DeclarationModifiers.IsAbstract.get -> bool
......
......@@ -767,7 +767,7 @@ internal override SyntaxNode AsInterfaceMember(SyntaxNode m)
// convert field into property
case SyntaxKind.FieldDeclaration:
var f = (FieldDeclarationSyntax)member;
GetAccessibilityAndModifiers(f.Modifiers, out acc, out modifiers);
SyntaxFacts.GetAccessibilityAndModifiers(f.Modifiers, out acc, out modifiers, out _);
return this.AsInterfaceMember(
this.PropertyDeclaration(this.GetName(f), this.ClearTrivia(this.GetType(f)), acc, modifiers, getAccessorStatements: null, setAccessorStatements: null));
......@@ -1319,79 +1319,12 @@ private SyntaxNode AsMemberOf(SyntaxNode declaration, SyntaxNode member)
}
}
internal override bool CanHaveAccessibility(SyntaxNode declaration)
{
switch (declaration.Kind())
{
case SyntaxKind.ClassDeclaration:
case SyntaxKind.StructDeclaration:
case SyntaxKind.InterfaceDeclaration:
case SyntaxKind.EnumDeclaration:
case SyntaxKind.DelegateDeclaration:
case SyntaxKind.OperatorDeclaration:
case SyntaxKind.ConversionOperatorDeclaration:
case SyntaxKind.FieldDeclaration:
case SyntaxKind.EventFieldDeclaration:
case SyntaxKind.GetAccessorDeclaration:
case SyntaxKind.SetAccessorDeclaration:
case SyntaxKind.AddAccessorDeclaration:
case SyntaxKind.RemoveAccessorDeclaration:
return true;
case SyntaxKind.VariableDeclaration:
case SyntaxKind.VariableDeclarator:
var declarationKind = this.GetDeclarationKind(declaration);
return declarationKind == DeclarationKind.Field || declarationKind == DeclarationKind.Event;
case SyntaxKind.ConstructorDeclaration:
// Static constructor can't have accessibility
return !((ConstructorDeclarationSyntax)declaration).Modifiers.Any(SyntaxKind.StaticKeyword);
case SyntaxKind.PropertyDeclaration:
return ((PropertyDeclarationSyntax)declaration).ExplicitInterfaceSpecifier == null;
case SyntaxKind.IndexerDeclaration:
return ((IndexerDeclarationSyntax)declaration).ExplicitInterfaceSpecifier == null;
case SyntaxKind.MethodDeclaration:
var method = (MethodDeclarationSyntax)declaration;
if (method.ExplicitInterfaceSpecifier != null)
{
// explicit interface methods can't have accessibility.
return false;
}
if (method.Modifiers.Any(SyntaxKind.PartialKeyword))
{
// partial methods can't have accessibility modifiers.
return false;
}
return true;
case SyntaxKind.EventDeclaration:
return ((EventDeclarationSyntax)declaration).ExplicitInterfaceSpecifier == null;
default:
return false;
}
}
public override Accessibility GetAccessibility(SyntaxNode declaration)
{
if (!this.CanHaveAccessibility(declaration))
{
return Accessibility.NotApplicable;
}
var modifierTokens = GetModifierTokens(declaration);
GetAccessibilityAndModifiers(modifierTokens, out var accessibility, out _);
return accessibility;
}
=> SyntaxFacts.GetAccessibility(declaration);
public override SyntaxNode WithAccessibility(SyntaxNode declaration, Accessibility accessibility)
{
if (!this.CanHaveAccessibility(declaration) &&
if (!SyntaxFacts.CanHaveAccessibility(declaration) &&
accessibility != Accessibility.NotApplicable)
{
return declaration;
......@@ -1399,8 +1332,8 @@ public override SyntaxNode WithAccessibility(SyntaxNode declaration, Accessibili
return this.Isolate(declaration, d =>
{
var tokens = GetModifierTokens(d);
GetAccessibilityAndModifiers(tokens, out _, out var modifiers);
var tokens = SyntaxFacts.GetModifierTokens(d);
SyntaxFacts.GetAccessibilityAndModifiers(tokens, out _, out var modifiers, out _);
var newTokens = Merge(tokens, AsModifierList(accessibility, modifiers));
return SetModifierTokens(d, newTokens);
});
......@@ -1559,8 +1492,8 @@ private static DeclarationModifiers GetAllowedModifiers(SyntaxKind kind)
public override DeclarationModifiers GetModifiers(SyntaxNode declaration)
{
var modifierTokens = GetModifierTokens(declaration);
GetAccessibilityAndModifiers(modifierTokens, out _, out var modifiers);
var modifierTokens = SyntaxFacts.GetModifierTokens(declaration);
SyntaxFacts.GetAccessibilityAndModifiers(modifierTokens, out _, out var modifiers, out _);
return modifiers;
}
......@@ -1578,8 +1511,8 @@ private SyntaxNode WithModifiersInternal(SyntaxNode declaration, DeclarationModi
{
return this.Isolate(declaration, d =>
{
var tokens = GetModifierTokens(d);
GetAccessibilityAndModifiers(tokens, out var accessibility, out var tmp);
var tokens = SyntaxFacts.GetModifierTokens(d);
SyntaxFacts.GetAccessibilityAndModifiers(tokens, out var accessibility, out var tmp, out _);
var newTokens = Merge(tokens, AsModifierList(accessibility, modifiers));
return SetModifierTokens(d, newTokens);
});
......@@ -1591,19 +1524,6 @@ private SyntaxNode WithModifiersInternal(SyntaxNode declaration, DeclarationModi
}
}
private static SyntaxTokenList GetModifierTokens(SyntaxNode declaration)
=> declaration switch
{
MemberDeclarationSyntax memberDecl => memberDecl.Modifiers,
ParameterSyntax parameter => parameter.Modifiers,
LocalDeclarationStatementSyntax localDecl => localDecl.Modifiers,
LocalFunctionStatementSyntax localFunc => localFunc.Modifiers,
AccessorDeclarationSyntax accessor => accessor.Modifiers,
VariableDeclarationSyntax varDecl => GetModifierTokens(varDecl.Parent),
VariableDeclaratorSyntax varDecl => GetModifierTokens(varDecl.Parent),
_ => default,
};
private static SyntaxNode SetModifierTokens(SyntaxNode declaration, SyntaxTokenList modifiers)
=> declaration switch
{
......@@ -1696,51 +1616,6 @@ private static SyntaxTokenList AsModifierList(Accessibility accessibility, Decla
return SyntaxFactory.TokenList(list);
}
private static void GetAccessibilityAndModifiers(SyntaxTokenList modifierList, out Accessibility accessibility, out DeclarationModifiers modifiers)
{
accessibility = Accessibility.NotApplicable;
modifiers = DeclarationModifiers.None;
foreach (var token in modifierList)
{
accessibility = (token.Kind(), accessibility) switch
{
(SyntaxKind.PublicKeyword, _) => Accessibility.Public,
(SyntaxKind.PrivateKeyword, Accessibility.Protected) => Accessibility.ProtectedAndInternal,
(SyntaxKind.PrivateKeyword, _) => Accessibility.Private,
(SyntaxKind.InternalKeyword, Accessibility.Protected) => Accessibility.ProtectedOrInternal,
(SyntaxKind.InternalKeyword, _) => Accessibility.Internal,
(SyntaxKind.ProtectedKeyword, Accessibility.Private) => Accessibility.ProtectedAndInternal,
(SyntaxKind.ProtectedKeyword, Accessibility.Internal) => Accessibility.ProtectedOrInternal,
(SyntaxKind.ProtectedKeyword, _) => Accessibility.Protected,
_ => accessibility,
};
modifiers |= token.Kind() switch
{
SyntaxKind.AbstractKeyword => DeclarationModifiers.Abstract,
SyntaxKind.NewKeyword => DeclarationModifiers.New,
SyntaxKind.OverrideKeyword => DeclarationModifiers.Override,
SyntaxKind.VirtualKeyword => DeclarationModifiers.Virtual,
SyntaxKind.StaticKeyword => DeclarationModifiers.Static,
SyntaxKind.AsyncKeyword => DeclarationModifiers.Async,
SyntaxKind.ConstKeyword => DeclarationModifiers.Const,
SyntaxKind.ReadOnlyKeyword => DeclarationModifiers.ReadOnly,
SyntaxKind.SealedKeyword => DeclarationModifiers.Sealed,
SyntaxKind.UnsafeKeyword => DeclarationModifiers.Unsafe,
SyntaxKind.PartialKeyword => DeclarationModifiers.Partial,
SyntaxKind.RefKeyword => DeclarationModifiers.Ref,
SyntaxKind.VolatileKeyword => DeclarationModifiers.Volatile,
SyntaxKind.ExternKeyword => DeclarationModifiers.Extern,
_ => DeclarationModifiers.None,
};
}
}
private static TypeParameterListSyntax AsTypeParameterList(IEnumerable<string> typeParameterNames)
{
var typeParameters = typeParameterNames != null
......@@ -1854,167 +1729,7 @@ public override SyntaxNode WithTypeConstraint(SyntaxNode declaration, string typ
}
public override DeclarationKind GetDeclarationKind(SyntaxNode declaration)
{
switch (declaration.Kind())
{
case SyntaxKind.ClassDeclaration:
return DeclarationKind.Class;
case SyntaxKind.StructDeclaration:
return DeclarationKind.Struct;
case SyntaxKind.InterfaceDeclaration:
return DeclarationKind.Interface;
case SyntaxKind.EnumDeclaration:
return DeclarationKind.Enum;
case SyntaxKind.DelegateDeclaration:
return DeclarationKind.Delegate;
case SyntaxKind.MethodDeclaration:
return DeclarationKind.Method;
case SyntaxKind.OperatorDeclaration:
return DeclarationKind.Operator;
case SyntaxKind.ConversionOperatorDeclaration:
return DeclarationKind.ConversionOperator;
case SyntaxKind.ConstructorDeclaration:
return DeclarationKind.Constructor;
case SyntaxKind.DestructorDeclaration:
return DeclarationKind.Destructor;
case SyntaxKind.PropertyDeclaration:
return DeclarationKind.Property;
case SyntaxKind.IndexerDeclaration:
return DeclarationKind.Indexer;
case SyntaxKind.EventDeclaration:
return DeclarationKind.CustomEvent;
case SyntaxKind.EnumMemberDeclaration:
return DeclarationKind.EnumMember;
case SyntaxKind.CompilationUnit:
return DeclarationKind.CompilationUnit;
case SyntaxKind.NamespaceDeclaration:
return DeclarationKind.Namespace;
case SyntaxKind.UsingDirective:
return DeclarationKind.NamespaceImport;
case SyntaxKind.Parameter:
return DeclarationKind.Parameter;
case SyntaxKind.ParenthesizedLambdaExpression:
case SyntaxKind.SimpleLambdaExpression:
return DeclarationKind.LambdaExpression;
case SyntaxKind.FieldDeclaration:
var fd = (FieldDeclarationSyntax)declaration;
if (fd.Declaration != null && fd.Declaration.Variables.Count == 1)
{
// this node is considered the declaration if it contains only one variable.
return DeclarationKind.Field;
}
else
{
return DeclarationKind.None;
}
case SyntaxKind.EventFieldDeclaration:
var ef = (EventFieldDeclarationSyntax)declaration;
if (ef.Declaration != null && ef.Declaration.Variables.Count == 1)
{
// this node is considered the declaration if it contains only one variable.
return DeclarationKind.Event;
}
else
{
return DeclarationKind.None;
}
case SyntaxKind.LocalDeclarationStatement:
var ld = (LocalDeclarationStatementSyntax)declaration;
if (ld.Declaration != null && ld.Declaration.Variables.Count == 1)
{
// this node is considered the declaration if it contains only one variable.
return DeclarationKind.Variable;
}
else
{
return DeclarationKind.None;
}
case SyntaxKind.VariableDeclaration:
{
var vd = (VariableDeclarationSyntax)declaration;
if (vd.Variables.Count == 1 && vd.Parent == null)
{
// this node is the declaration if it contains only one variable and has no parent.
return DeclarationKind.Variable;
}
else
{
return DeclarationKind.None;
}
}
case SyntaxKind.VariableDeclarator:
{
var vd = declaration.Parent as VariableDeclarationSyntax;
// this node is considered the declaration if it is one among many, or it has no parent
if (vd == null || vd.Variables.Count > 1)
{
if (ParentIsFieldDeclaration(vd))
{
return DeclarationKind.Field;
}
else if (ParentIsEventFieldDeclaration(vd))
{
return DeclarationKind.Event;
}
else
{
return DeclarationKind.Variable;
}
}
break;
}
case SyntaxKind.AttributeList:
var list = (AttributeListSyntax)declaration;
if (list.Attributes.Count == 1)
{
return DeclarationKind.Attribute;
}
break;
case SyntaxKind.Attribute:
if (!(declaration.Parent is AttributeListSyntax parentList) || parentList.Attributes.Count > 1)
{
return DeclarationKind.Attribute;
}
break;
case SyntaxKind.GetAccessorDeclaration:
return DeclarationKind.GetAccessor;
case SyntaxKind.SetAccessorDeclaration:
return DeclarationKind.SetAccessor;
case SyntaxKind.AddAccessorDeclaration:
return DeclarationKind.AddAccessor;
case SyntaxKind.RemoveAccessorDeclaration:
return DeclarationKind.RemoveAccessor;
}
return DeclarationKind.None;
}
private static bool ParentIsFieldDeclaration(SyntaxNode node)
{
return node?.Parent.IsKind(SyntaxKind.FieldDeclaration) ?? false;
}
private static bool ParentIsEventFieldDeclaration(SyntaxNode node)
{
return node?.Parent.IsKind(SyntaxKind.EventFieldDeclaration) ?? false;
}
private static bool ParentIsLocalDeclarationStatement(SyntaxNode node)
{
return node?.Parent.IsKind(SyntaxKind.LocalDeclarationStatement) ?? false;
}
=> SyntaxFacts.GetDeclarationKind(declaration);
public override string GetName(SyntaxNode declaration)
{
......@@ -2295,9 +2010,9 @@ private static SyntaxNode GetFullDeclaration(SyntaxNode declaration)
{
case SyntaxKind.VariableDeclaration:
var vd = (VariableDeclarationSyntax)declaration;
if (ParentIsFieldDeclaration(vd)
|| ParentIsEventFieldDeclaration(vd)
|| ParentIsLocalDeclarationStatement(vd))
if (CSharpSyntaxFacts.ParentIsFieldDeclaration(vd)
|| CSharpSyntaxFacts.ParentIsEventFieldDeclaration(vd)
|| CSharpSyntaxFacts.ParentIsLocalDeclarationStatement(vd))
{
return vd.Parent;
}
......
......@@ -2,8 +2,11 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
#if CODE_STYLE
namespace Microsoft.CodeAnalysis.Internal.Editing
#else
namespace Microsoft.CodeAnalysis.Editing
#endif
{
public enum DeclarationKind
{
......
......@@ -1064,8 +1064,6 @@ public SyntaxNode AddMembers(SyntaxNode declaration, params SyntaxNode[] members
/// </summary>
public abstract SyntaxNode WithAccessibility(SyntaxNode declaration, Accessibility accessibility);
internal abstract bool CanHaveAccessibility(SyntaxNode declaration);
/// <summary>
/// Gets the <see cref="DeclarationModifiers"/> for the declaration.
/// </summary>
......
......@@ -18,6 +18,12 @@
using Microsoft.CodeAnalysis.Text;
using Roslyn.Utilities;
#if CODE_STYLE
using Microsoft.CodeAnalysis.Internal.Editing;
#else
using Microsoft.CodeAnalysis.Editing;
#endif
namespace Microsoft.CodeAnalysis.CSharp.LanguageServices
{
internal class CSharpSyntaxFacts : AbstractSyntaxFacts, ISyntaxFacts
......@@ -1700,5 +1706,299 @@ public void GetPartsOfCastExpression(SyntaxNode node, out SyntaxNode type, out S
public override SyntaxList<SyntaxNode> GetAttributeLists(SyntaxNode node)
=> node.GetAttributeLists();
public override bool CanHaveAccessibility(SyntaxNode declaration)
{
switch (declaration.Kind())
{
case SyntaxKind.ClassDeclaration:
case SyntaxKind.StructDeclaration:
case SyntaxKind.InterfaceDeclaration:
case SyntaxKind.EnumDeclaration:
case SyntaxKind.DelegateDeclaration:
case SyntaxKind.OperatorDeclaration:
case SyntaxKind.ConversionOperatorDeclaration:
case SyntaxKind.FieldDeclaration:
case SyntaxKind.EventFieldDeclaration:
case SyntaxKind.GetAccessorDeclaration:
case SyntaxKind.SetAccessorDeclaration:
case SyntaxKind.AddAccessorDeclaration:
case SyntaxKind.RemoveAccessorDeclaration:
return true;
case SyntaxKind.VariableDeclaration:
case SyntaxKind.VariableDeclarator:
var declarationKind = this.GetDeclarationKind(declaration);
return declarationKind == DeclarationKind.Field || declarationKind == DeclarationKind.Event;
case SyntaxKind.ConstructorDeclaration:
// Static constructor can't have accessibility
return !((ConstructorDeclarationSyntax)declaration).Modifiers.Any(SyntaxKind.StaticKeyword);
case SyntaxKind.PropertyDeclaration:
return ((PropertyDeclarationSyntax)declaration).ExplicitInterfaceSpecifier == null;
case SyntaxKind.IndexerDeclaration:
return ((IndexerDeclarationSyntax)declaration).ExplicitInterfaceSpecifier == null;
case SyntaxKind.MethodDeclaration:
var method = (MethodDeclarationSyntax)declaration;
if (method.ExplicitInterfaceSpecifier != null)
{
// explicit interface methods can't have accessibility.
return false;
}
if (method.Modifiers.Any(SyntaxKind.PartialKeyword))
{
// partial methods can't have accessibility modifiers.
return false;
}
return true;
case SyntaxKind.EventDeclaration:
return ((EventDeclarationSyntax)declaration).ExplicitInterfaceSpecifier == null;
default:
return false;
}
}
public override Accessibility GetAccessibility(SyntaxNode declaration)
{
if (!CanHaveAccessibility(declaration))
{
return Accessibility.NotApplicable;
}
var modifierTokens = GetModifierTokens(declaration);
GetAccessibilityAndModifiers(modifierTokens, out var accessibility, out _, out _);
return accessibility;
}
public override void GetAccessibilityAndModifiers(SyntaxTokenList modifierList, out Accessibility accessibility, out DeclarationModifiers modifiers, out bool isDefault)
{
accessibility = Accessibility.NotApplicable;
modifiers = DeclarationModifiers.None;
isDefault = false;
foreach (var token in modifierList)
{
accessibility = (token.Kind(), accessibility) switch
{
(SyntaxKind.PublicKeyword, _) => Accessibility.Public,
(SyntaxKind.PrivateKeyword, Accessibility.Protected) => Accessibility.ProtectedAndInternal,
(SyntaxKind.PrivateKeyword, _) => Accessibility.Private,
(SyntaxKind.InternalKeyword, Accessibility.Protected) => Accessibility.ProtectedOrInternal,
(SyntaxKind.InternalKeyword, _) => Accessibility.Internal,
(SyntaxKind.ProtectedKeyword, Accessibility.Private) => Accessibility.ProtectedAndInternal,
(SyntaxKind.ProtectedKeyword, Accessibility.Internal) => Accessibility.ProtectedOrInternal,
(SyntaxKind.ProtectedKeyword, _) => Accessibility.Protected,
_ => accessibility,
};
modifiers |= token.Kind() switch
{
SyntaxKind.AbstractKeyword => DeclarationModifiers.Abstract,
SyntaxKind.NewKeyword => DeclarationModifiers.New,
SyntaxKind.OverrideKeyword => DeclarationModifiers.Override,
SyntaxKind.VirtualKeyword => DeclarationModifiers.Virtual,
SyntaxKind.StaticKeyword => DeclarationModifiers.Static,
SyntaxKind.AsyncKeyword => DeclarationModifiers.Async,
SyntaxKind.ConstKeyword => DeclarationModifiers.Const,
SyntaxKind.ReadOnlyKeyword => DeclarationModifiers.ReadOnly,
SyntaxKind.SealedKeyword => DeclarationModifiers.Sealed,
SyntaxKind.UnsafeKeyword => DeclarationModifiers.Unsafe,
SyntaxKind.PartialKeyword => DeclarationModifiers.Partial,
SyntaxKind.RefKeyword => DeclarationModifiers.Ref,
SyntaxKind.VolatileKeyword => DeclarationModifiers.Volatile,
SyntaxKind.ExternKeyword => DeclarationModifiers.Extern,
_ => DeclarationModifiers.None,
};
isDefault |= token.Kind() == SyntaxKind.DefaultKeyword;
}
}
public override SyntaxTokenList GetModifierTokens(SyntaxNode declaration)
=> declaration switch
{
MemberDeclarationSyntax memberDecl => memberDecl.Modifiers,
ParameterSyntax parameter => parameter.Modifiers,
LocalDeclarationStatementSyntax localDecl => localDecl.Modifiers,
LocalFunctionStatementSyntax localFunc => localFunc.Modifiers,
AccessorDeclarationSyntax accessor => accessor.Modifiers,
VariableDeclarationSyntax varDecl => GetModifierTokens(varDecl.Parent),
VariableDeclaratorSyntax varDecl => GetModifierTokens(varDecl.Parent),
_ => default,
};
public override DeclarationKind GetDeclarationKind(SyntaxNode declaration)
{
switch (declaration.Kind())
{
case SyntaxKind.ClassDeclaration:
return DeclarationKind.Class;
case SyntaxKind.StructDeclaration:
return DeclarationKind.Struct;
case SyntaxKind.InterfaceDeclaration:
return DeclarationKind.Interface;
case SyntaxKind.EnumDeclaration:
return DeclarationKind.Enum;
case SyntaxKind.DelegateDeclaration:
return DeclarationKind.Delegate;
case SyntaxKind.MethodDeclaration:
return DeclarationKind.Method;
case SyntaxKind.OperatorDeclaration:
return DeclarationKind.Operator;
case SyntaxKind.ConversionOperatorDeclaration:
return DeclarationKind.ConversionOperator;
case SyntaxKind.ConstructorDeclaration:
return DeclarationKind.Constructor;
case SyntaxKind.DestructorDeclaration:
return DeclarationKind.Destructor;
case SyntaxKind.PropertyDeclaration:
return DeclarationKind.Property;
case SyntaxKind.IndexerDeclaration:
return DeclarationKind.Indexer;
case SyntaxKind.EventDeclaration:
return DeclarationKind.CustomEvent;
case SyntaxKind.EnumMemberDeclaration:
return DeclarationKind.EnumMember;
case SyntaxKind.CompilationUnit:
return DeclarationKind.CompilationUnit;
case SyntaxKind.NamespaceDeclaration:
return DeclarationKind.Namespace;
case SyntaxKind.UsingDirective:
return DeclarationKind.NamespaceImport;
case SyntaxKind.Parameter:
return DeclarationKind.Parameter;
case SyntaxKind.ParenthesizedLambdaExpression:
case SyntaxKind.SimpleLambdaExpression:
return DeclarationKind.LambdaExpression;
case SyntaxKind.FieldDeclaration:
var fd = (FieldDeclarationSyntax)declaration;
if (fd.Declaration != null && fd.Declaration.Variables.Count == 1)
{
// this node is considered the declaration if it contains only one variable.
return DeclarationKind.Field;
}
else
{
return DeclarationKind.None;
}
case SyntaxKind.EventFieldDeclaration:
var ef = (EventFieldDeclarationSyntax)declaration;
if (ef.Declaration != null && ef.Declaration.Variables.Count == 1)
{
// this node is considered the declaration if it contains only one variable.
return DeclarationKind.Event;
}
else
{
return DeclarationKind.None;
}
case SyntaxKind.LocalDeclarationStatement:
var ld = (LocalDeclarationStatementSyntax)declaration;
if (ld.Declaration != null && ld.Declaration.Variables.Count == 1)
{
// this node is considered the declaration if it contains only one variable.
return DeclarationKind.Variable;
}
else
{
return DeclarationKind.None;
}
case SyntaxKind.VariableDeclaration:
{
var vd = (VariableDeclarationSyntax)declaration;
if (vd.Variables.Count == 1 && vd.Parent == null)
{
// this node is the declaration if it contains only one variable and has no parent.
return DeclarationKind.Variable;
}
else
{
return DeclarationKind.None;
}
}
case SyntaxKind.VariableDeclarator:
{
var vd = declaration.Parent as VariableDeclarationSyntax;
// this node is considered the declaration if it is one among many, or it has no parent
if (vd == null || vd.Variables.Count > 1)
{
if (ParentIsFieldDeclaration(vd))
{
return DeclarationKind.Field;
}
else if (ParentIsEventFieldDeclaration(vd))
{
return DeclarationKind.Event;
}
else
{
return DeclarationKind.Variable;
}
}
break;
}
case SyntaxKind.AttributeList:
var list = (AttributeListSyntax)declaration;
if (list.Attributes.Count == 1)
{
return DeclarationKind.Attribute;
}
break;
case SyntaxKind.Attribute:
if (!(declaration.Parent is AttributeListSyntax parentList) || parentList.Attributes.Count > 1)
{
return DeclarationKind.Attribute;
}
break;
case SyntaxKind.GetAccessorDeclaration:
return DeclarationKind.GetAccessor;
case SyntaxKind.SetAccessorDeclaration:
return DeclarationKind.SetAccessor;
case SyntaxKind.AddAccessorDeclaration:
return DeclarationKind.AddAccessor;
case SyntaxKind.RemoveAccessorDeclaration:
return DeclarationKind.RemoveAccessor;
}
return DeclarationKind.None;
}
internal static bool ParentIsFieldDeclaration(SyntaxNode node)
{
return node?.Parent.IsKind(SyntaxKind.FieldDeclaration) ?? false;
}
internal static bool ParentIsEventFieldDeclaration(SyntaxNode node)
{
return node?.Parent.IsKind(SyntaxKind.EventFieldDeclaration) ?? false;
}
internal static bool ParentIsLocalDeclarationStatement(SyntaxNode node)
{
return node?.Parent.IsKind(SyntaxKind.LocalDeclarationStatement) ?? false;
}
}
}
......@@ -14,6 +14,12 @@
using Microsoft.CodeAnalysis.Text;
using Roslyn.Utilities;
#if CODE_STYLE
using Microsoft.CodeAnalysis.Internal.Editing;
#else
using Microsoft.CodeAnalysis.Editing;
#endif
namespace Microsoft.CodeAnalysis.LanguageServices
{
internal abstract class AbstractSyntaxFacts
......@@ -504,5 +510,15 @@ protected int GetStartOfNodeExcludingAttributes(SyntaxNode root, SyntaxNode node
public bool HasIncompleteParentMember(SyntaxNode node)
=> node?.Parent?.RawKind == SyntaxKinds.IncompleteMember;
public abstract bool CanHaveAccessibility(SyntaxNode declaration);
public abstract Accessibility GetAccessibility(SyntaxNode declaration);
public abstract void GetAccessibilityAndModifiers(SyntaxTokenList modifierList, out Accessibility accessibility, out DeclarationModifiers modifiers, out bool isDefault);
public abstract SyntaxTokenList GetModifierTokens(SyntaxNode declaration);
public abstract DeclarationKind GetDeclarationKind(SyntaxNode declaration);
}
}
......@@ -9,6 +9,12 @@
using System.Threading;
using Microsoft.CodeAnalysis.Text;
#if CODE_STYLE
using Microsoft.CodeAnalysis.Internal.Editing;
#else
using Microsoft.CodeAnalysis.Editing;
#endif
namespace Microsoft.CodeAnalysis.LanguageServices
{
internal partial interface ISyntaxFacts
......@@ -417,6 +423,22 @@ internal partial interface ISyntaxFacts
SyntaxToken? GetDeclarationIdentifierIfOverride(SyntaxToken token);
bool SpansPreprocessorDirective(IEnumerable<SyntaxNode> nodes);
bool CanHaveAccessibility(SyntaxNode declaration);
/// <summary>
/// Gets the accessibility of the declaration.
/// </summary>
Accessibility GetAccessibility(SyntaxNode declaration);
public abstract void GetAccessibilityAndModifiers(SyntaxTokenList modifierList, out Accessibility accessibility, out DeclarationModifiers modifiers, out bool isDefault);
public abstract SyntaxTokenList GetModifierTokens(SyntaxNode declaration);
/// <summary>
/// Gets the <see cref="DeclarationKind"/> for the declaration.
/// </summary>
DeclarationKind GetDeclarationKind(SyntaxNode declaration);
}
[Flags]
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册