提交 da4e06fc 编写于 作者: K kayleh

Fix some O(n^2) codepaths to allow faster MetadataAsSource processing of large enums.

AbstractCodeGenerationService.AddMembers was using an O(n^2) algorithm to insert new members.  This change allows bulk inserting members if the AutoInsertionLocation flag is false.  For now, metadata as source only sets AutoInsertionLocation to false for enum symbols which can commonly have thousands of members.

SeparatedSyntaxList.InsertRange was also calling Insert for each node.  It now adds the nodes in a single step. (changeset 1344073)
上级 5ec2e9a8
...@@ -367,19 +367,18 @@ public SeparatedSyntaxList<TNode> InsertRange(int index, IEnumerable<TNode> node ...@@ -367,19 +367,18 @@ public SeparatedSyntaxList<TNode> InsertRange(int index, IEnumerable<TNode> node
} }
} }
var nodesToInsertWithSeparators = new List<SyntaxNodeOrToken>();
foreach (var item in nodes) foreach (var item in nodes)
{ {
if (item != null) if (item != null)
{ {
// if item before insertion point is a node, add a separator // if item before insertion point is a node, add a separator
if (insertionIndex > 0 && nodesWithSeps[insertionIndex - 1].IsNode) if (nodesToInsertWithSeparators.Count > 0 || (insertionIndex > 0 && nodesWithSeps[insertionIndex - 1].IsNode))
{ {
nodesWithSeps = nodesWithSeps.Insert(insertionIndex, item.Green.CreateSeparator<TNode>(item)); // separator nodesToInsertWithSeparators.Add(item.Green.CreateSeparator<TNode>(item));
insertionIndex++;
} }
nodesWithSeps = nodesWithSeps.Insert(insertionIndex, item); nodesToInsertWithSeparators.Add(item);
insertionIndex++;
} }
} }
...@@ -387,10 +386,10 @@ public SeparatedSyntaxList<TNode> InsertRange(int index, IEnumerable<TNode> node ...@@ -387,10 +386,10 @@ public SeparatedSyntaxList<TNode> InsertRange(int index, IEnumerable<TNode> node
if (insertionIndex < nodesWithSeps.Count && nodesWithSeps[insertionIndex].IsNode) if (insertionIndex < nodesWithSeps.Count && nodesWithSeps[insertionIndex].IsNode)
{ {
var node = nodesWithSeps[insertionIndex].AsNode(); var node = nodesWithSeps[insertionIndex].AsNode();
nodesWithSeps = nodesWithSeps.Insert(insertionIndex, node.Green.CreateSeparator<TNode>(node)); // separator nodesToInsertWithSeparators.Add(node.Green.CreateSeparator<TNode>(node)); // separator
} }
return new SeparatedSyntaxList<TNode>(nodesWithSeps); return new SeparatedSyntaxList<TNode>(nodesWithSeps.InsertRange(insertionIndex, nodesToInsertWithSeparators));
} }
private static bool KeepSeparatorWithPreviousNode(SyntaxToken separator) private static bool KeepSeparatorWithPreviousNode(SyntaxToken separator)
......
...@@ -295,7 +295,7 @@ public SyntaxNodeOrTokenList Insert(int index, SyntaxNodeOrToken nodeOrToken) ...@@ -295,7 +295,7 @@ public SyntaxNodeOrTokenList Insert(int index, SyntaxNodeOrToken nodeOrToken)
throw new ArgumentException("nodeOrToken"); throw new ArgumentException("nodeOrToken");
} }
return InsertRange(index, new[] { nodeOrToken }); return InsertRange(index, SpecializedCollections.SingletonEnumerable(nodeOrToken));
} }
/// <summary> /// <summary>
...@@ -315,22 +315,14 @@ public SyntaxNodeOrTokenList InsertRange(int index, IEnumerable<SyntaxNodeOrToke ...@@ -315,22 +315,14 @@ public SyntaxNodeOrTokenList InsertRange(int index, IEnumerable<SyntaxNodeOrToke
throw new ArgumentNullException("nodesAndTokens"); throw new ArgumentNullException("nodesAndTokens");
} }
var items = nodesAndTokens.ToList(); if (nodesAndTokens.IsEmpty())
if (items.Count == 0)
{ {
return this; return this;
} }
var nodes = this.ToList(); var nodes = this.ToList();
nodes.InsertRange(index, nodesAndTokens); nodes.InsertRange(index, nodesAndTokens);
if (nodes.Count == 0) return CreateList(nodes[0].UnderlyingNode, nodes);
{
return this;
}
else
{
return CreateList(nodes[0].UnderlyingNode, nodes);
}
} }
private static SyntaxNodeOrTokenList CreateList(GreenNode creator, List<SyntaxNodeOrToken> items) private static SyntaxNodeOrTokenList CreateList(GreenNode creator, List<SyntaxNodeOrToken> items)
......
...@@ -329,7 +329,7 @@ public static MemberDeclarationSyntax LastOperator(SyntaxList<MemberDeclarationS ...@@ -329,7 +329,7 @@ public static MemberDeclarationSyntax LastOperator(SyntaxList<MemberDeclarationS
return SyntaxFactory.ExplicitInterfaceSpecifier(name); return SyntaxFactory.ExplicitInterfaceSpecifier(name);
} }
public static CodeGenerationDestination GetDestination(TypeDeclarationSyntax destination) public static CodeGenerationDestination GetDestination(SyntaxNode destination)
{ {
if (destination != null) if (destination != null)
{ {
...@@ -337,10 +337,18 @@ public static CodeGenerationDestination GetDestination(TypeDeclarationSyntax des ...@@ -337,10 +337,18 @@ public static CodeGenerationDestination GetDestination(TypeDeclarationSyntax des
{ {
case SyntaxKind.ClassDeclaration: case SyntaxKind.ClassDeclaration:
return CodeGenerationDestination.ClassType; return CodeGenerationDestination.ClassType;
case SyntaxKind.CompilationUnit:
return CodeGenerationDestination.CompilationUnit;
case SyntaxKind.EnumDeclaration:
return CodeGenerationDestination.EnumType;
case SyntaxKind.InterfaceDeclaration: case SyntaxKind.InterfaceDeclaration:
return CodeGenerationDestination.InterfaceType; return CodeGenerationDestination.InterfaceType;
case SyntaxKind.NamespaceDeclaration:
return CodeGenerationDestination.Namespace;
case SyntaxKind.StructDeclaration: case SyntaxKind.StructDeclaration:
return CodeGenerationDestination.StructType; return CodeGenerationDestination.StructType;
default:
return CodeGenerationDestination.Unspecified;
} }
} }
......
...@@ -24,6 +24,11 @@ public CSharpCodeGenerationService(HostLanguageServices languageServices) ...@@ -24,6 +24,11 @@ public CSharpCodeGenerationService(HostLanguageServices languageServices)
{ {
} }
public override CodeGenerationDestination GetDestination(SyntaxNode node)
{
return CSharpCodeGenerationHelpers.GetDestination(node);
}
protected override AbstractImportsAdder CreateImportsAdder( protected override AbstractImportsAdder CreateImportsAdder(
Document document) Document document)
{ {
...@@ -317,6 +322,32 @@ protected override TDeclarationNode AddNamespace<TDeclarationNode>(TDeclarationN ...@@ -317,6 +322,32 @@ protected override TDeclarationNode AddNamespace<TDeclarationNode>(TDeclarationN
return destination; return destination;
} }
protected override TDeclarationNode AddMembers<TDeclarationNode>(TDeclarationNode destination, IEnumerable<SyntaxNode> members)
{
CheckDeclarationNode<EnumDeclarationSyntax, TypeDeclarationSyntax, NamespaceDeclarationSyntax, CompilationUnitSyntax>(destination);
if (destination is EnumDeclarationSyntax)
{
return Cast<TDeclarationNode>(Cast<EnumDeclarationSyntax>(destination)
.AddMembers(members.Cast<EnumMemberDeclarationSyntax>().ToArray()));
}
else if (destination is TypeDeclarationSyntax)
{
return Cast<TDeclarationNode>(Cast<TypeDeclarationSyntax>(destination)
.AddMembers(members.Cast<MemberDeclarationSyntax>().ToArray()));
}
else if (destination is NamespaceDeclarationSyntax)
{
return Cast<TDeclarationNode>(Cast<NamespaceDeclarationSyntax>(destination)
.AddMembers(members.Cast<MemberDeclarationSyntax>().ToArray()));
}
else
{
return Cast<TDeclarationNode>(Cast<CompilationUnitSyntax>(destination)
.AddMembers(members.Cast<MemberDeclarationSyntax>().ToArray()));
}
}
public override TDeclarationNode RemoveAttribute<TDeclarationNode>( public override TDeclarationNode RemoveAttribute<TDeclarationNode>(
TDeclarationNode destination, TDeclarationNode destination,
AttributeData attributeToRemove, AttributeData attributeToRemove,
......
...@@ -66,6 +66,7 @@ public TDeclarationNode AddMembers<TDeclarationNode>(TDeclarationNode destinatio ...@@ -66,6 +66,7 @@ public TDeclarationNode AddMembers<TDeclarationNode>(TDeclarationNode destinatio
protected abstract TDeclarationNode AddProperty<TDeclarationNode>(TDeclarationNode destination, IPropertySymbol property, CodeGenerationOptions options, IList<bool> availableIndices) where TDeclarationNode : SyntaxNode; protected abstract TDeclarationNode AddProperty<TDeclarationNode>(TDeclarationNode destination, IPropertySymbol property, CodeGenerationOptions options, IList<bool> availableIndices) where TDeclarationNode : SyntaxNode;
protected abstract TDeclarationNode AddNamedType<TDeclarationNode>(TDeclarationNode destination, INamedTypeSymbol namedType, CodeGenerationOptions options, IList<bool> availableIndices) where TDeclarationNode : SyntaxNode; protected abstract TDeclarationNode AddNamedType<TDeclarationNode>(TDeclarationNode destination, INamedTypeSymbol namedType, CodeGenerationOptions options, IList<bool> availableIndices) where TDeclarationNode : SyntaxNode;
protected abstract TDeclarationNode AddNamespace<TDeclarationNode>(TDeclarationNode destination, INamespaceSymbol @namespace, CodeGenerationOptions options, IList<bool> availableIndices) where TDeclarationNode : SyntaxNode; protected abstract TDeclarationNode AddNamespace<TDeclarationNode>(TDeclarationNode destination, INamespaceSymbol @namespace, CodeGenerationOptions options, IList<bool> availableIndices) where TDeclarationNode : SyntaxNode;
protected abstract TDeclarationNode AddMembers<TDeclarationNode>(TDeclarationNode destination, IEnumerable<SyntaxNode> members) where TDeclarationNode : SyntaxNode;
public abstract TDeclarationNode AddParameters<TDeclarationNode>(TDeclarationNode destinationMember, IEnumerable<IParameterSymbol> parameters, CodeGenerationOptions options, CancellationToken cancellationToken) where TDeclarationNode : SyntaxNode; public abstract TDeclarationNode AddParameters<TDeclarationNode>(TDeclarationNode destinationMember, IEnumerable<IParameterSymbol> parameters, CodeGenerationOptions options, CancellationToken cancellationToken) where TDeclarationNode : SyntaxNode;
public abstract TDeclarationNode AddAttributes<TDeclarationNode>(TDeclarationNode destination, IEnumerable<AttributeData> attributes, SyntaxToken? target, CodeGenerationOptions options, CancellationToken cancellationToken) where TDeclarationNode : SyntaxNode; public abstract TDeclarationNode AddAttributes<TDeclarationNode>(TDeclarationNode destination, IEnumerable<AttributeData> attributes, SyntaxToken? target, CodeGenerationOptions options, CancellationToken cancellationToken) where TDeclarationNode : SyntaxNode;
...@@ -78,6 +79,7 @@ public TDeclarationNode AddMembers<TDeclarationNode>(TDeclarationNode destinatio ...@@ -78,6 +79,7 @@ public TDeclarationNode AddMembers<TDeclarationNode>(TDeclarationNode destinatio
public abstract TDeclarationNode UpdateDeclarationType<TDeclarationNode>(TDeclarationNode declaration, ITypeSymbol newType, CodeGenerationOptions options, CancellationToken cancellationToken) where TDeclarationNode : SyntaxNode; public abstract TDeclarationNode UpdateDeclarationType<TDeclarationNode>(TDeclarationNode declaration, ITypeSymbol newType, CodeGenerationOptions options, CancellationToken cancellationToken) where TDeclarationNode : SyntaxNode;
public abstract TDeclarationNode UpdateDeclarationMembers<TDeclarationNode>(TDeclarationNode declaration, IList<ISymbol> newMembers, CodeGenerationOptions options = null, CancellationToken cancellationToken = default(CancellationToken)) where TDeclarationNode : SyntaxNode; public abstract TDeclarationNode UpdateDeclarationMembers<TDeclarationNode>(TDeclarationNode declaration, IList<ISymbol> newMembers, CodeGenerationOptions options = null, CancellationToken cancellationToken = default(CancellationToken)) where TDeclarationNode : SyntaxNode;
public abstract CodeGenerationDestination GetDestination(SyntaxNode node);
public abstract SyntaxNode CreateEventDeclaration(IEventSymbol @event, CodeGenerationDestination destination, CodeGenerationOptions options); public abstract SyntaxNode CreateEventDeclaration(IEventSymbol @event, CodeGenerationDestination destination, CodeGenerationOptions options);
public abstract SyntaxNode CreateFieldDeclaration(IFieldSymbol field, CodeGenerationDestination destination, CodeGenerationOptions options); public abstract SyntaxNode CreateFieldDeclaration(IFieldSymbol field, CodeGenerationDestination destination, CodeGenerationOptions options);
public abstract SyntaxNode CreateMethodDeclaration(IMethodSymbol method, CodeGenerationDestination destination, CodeGenerationOptions options); public abstract SyntaxNode CreateMethodDeclaration(IMethodSymbol method, CodeGenerationDestination destination, CodeGenerationOptions options);
...@@ -132,6 +134,24 @@ protected static T Cast<T>(object value) ...@@ -132,6 +134,24 @@ protected static T Cast<T>(object value)
} }
} }
protected static void CheckDeclarationNode<TDeclarationNode1, TDeclarationNode2, TDeclarationNode3, TDeclarationNode4>(SyntaxNode destination)
where TDeclarationNode1 : SyntaxNode
where TDeclarationNode2 : SyntaxNode
where TDeclarationNode3 : SyntaxNode
where TDeclarationNode4 : SyntaxNode
{
if (!(destination is TDeclarationNode1) &&
!(destination is TDeclarationNode2) &&
!(destination is TDeclarationNode3) &&
!(destination is TDeclarationNode4))
{
throw new ArgumentException(
string.Format(WorkspacesResources.InvalidDestinationNode3,
typeof(TDeclarationNode1).Name, typeof(TDeclarationNode2).Name, typeof(TDeclarationNode3).Name, typeof(TDeclarationNode4).Name),
"destination");
}
}
private async Task<Document> GetEditAsync( private async Task<Document> GetEditAsync(
Solution solution, Solution solution,
INamespaceOrTypeSymbol destination, INamespaceOrTypeSymbol destination,
...@@ -189,16 +209,42 @@ protected static T Cast<T>(object value) ...@@ -189,16 +209,42 @@ protected static T Cast<T>(object value)
// not want an explicit declaration. // not want an explicit declaration.
var filteredMembers = membersList.Where(m => !m.IsImplicitlyDeclared); var filteredMembers = membersList.Where(m => !m.IsImplicitlyDeclared);
foreach (var member in filteredMembers) if (options.AutoInsertionLocation)
{
foreach (var member in filteredMembers)
{
currentDestination = member.TypeSwitch(
(IEventSymbol @event) => this.AddEvent(currentDestination, @event, options, availableIndices),
(IFieldSymbol field) => this.AddField(currentDestination, field, options, availableIndices),
(IPropertySymbol property) => this.AddProperty(currentDestination, property, options, availableIndices),
(IMethodSymbol method) => this.AddMethod(currentDestination, method, options, availableIndices),
(INamedTypeSymbol namedType) => this.AddNamedType(currentDestination, namedType, options, availableIndices),
(INamespaceSymbol @namespace) => this.AddNamespace(currentDestination, @namespace, options, availableIndices),
_ => currentDestination);
}
}
else
{ {
currentDestination = member.TypeSwitch( var newMembers = new List<SyntaxNode>();
(IEventSymbol @event) => this.AddEvent(currentDestination, @event, options, availableIndices), var codeGenerationDestination = GetDestination(destination);
(IFieldSymbol field) => this.AddField(currentDestination, field, options, availableIndices), foreach (var member in filteredMembers)
(IPropertySymbol property) => this.AddProperty(currentDestination, property, options, availableIndices), {
(IMethodSymbol method) => this.AddMethod(currentDestination, method, options, availableIndices), var newMember = member.TypeSwitch(
(INamedTypeSymbol namedType) => this.AddNamedType(currentDestination, namedType, options, availableIndices), (IEventSymbol @event) => this.CreateEventDeclaration(@event, codeGenerationDestination, options),
(INamespaceSymbol @namespace) => this.AddNamespace(currentDestination, @namespace, options, availableIndices), (IFieldSymbol field) => this.CreateFieldDeclaration(field, codeGenerationDestination, options),
_ => currentDestination); (IPropertySymbol property) => this.CreatePropertyDeclaration(property, codeGenerationDestination, options),
(IMethodSymbol method) => this.CreateMethodDeclaration(method, codeGenerationDestination, options),
(INamedTypeSymbol namedType) => this.CreateNamedTypeDeclaration(namedType, codeGenerationDestination, options),
(INamespaceSymbol @namespace) => this.CreateNamespaceDeclaration(@namespace, codeGenerationDestination, options),
_ => null);
if (newMember != null)
{
newMembers.Add(newMember);
}
}
currentDestination = this.AddMembers(currentDestination, newMembers);
} }
return currentDestination; return currentDestination;
......
...@@ -13,15 +13,13 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.CodeGeneration ...@@ -13,15 +13,13 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.CodeGeneration
enumMember As IFieldSymbol, enumMember As IFieldSymbol,
options As CodeGenerationOptions) As EnumBlockSyntax options As CodeGenerationOptions) As EnumBlockSyntax
' We never generate the special enum backing field. Dim member = GenerateEnumMemberDeclaration(enumMember, destination, options)
If enumMember.Name = WellKnownMemberNames.EnumBackingFieldName Then If member Is Nothing Then
Return destination Return destination
End If End If
Dim members = New List(Of StatementSyntax)() Dim members = New List(Of StatementSyntax)()
members.AddRange(destination.Members) members.AddRange(destination.Members)
Dim member = GenerateEnumMemberDeclaration(enumMember, destination, options)
members.Add(member) members.Add(member)
Dim leadingTrivia = destination.EndEnumStatement.GetLeadingTrivia() Dim leadingTrivia = destination.EndEnumStatement.GetLeadingTrivia()
...@@ -32,6 +30,11 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.CodeGeneration ...@@ -32,6 +30,11 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.CodeGeneration
Public Function GenerateEnumMemberDeclaration(enumMember As IFieldSymbol, Public Function GenerateEnumMemberDeclaration(enumMember As IFieldSymbol,
enumDeclarationOpt As EnumBlockSyntax, enumDeclarationOpt As EnumBlockSyntax,
options As CodeGenerationOptions) As EnumMemberDeclarationSyntax options As CodeGenerationOptions) As EnumMemberDeclarationSyntax
' We never generate the special enum backing field.
If enumMember.Name = WellKnownMemberNames.EnumBackingFieldName Then
Return Nothing
End If
Dim reusableSyntax = GetReuseableSyntaxNodeForSymbol(Of EnumMemberDeclarationSyntax)(enumMember, options) Dim reusableSyntax = GetReuseableSyntaxNodeForSymbol(Of EnumMemberDeclarationSyntax)(enumMember, options)
If reusableSyntax IsNot Nothing Then If reusableSyntax IsNot Nothing Then
Return reusableSyntax Return reusableSyntax
......
...@@ -236,17 +236,25 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.CodeGeneration ...@@ -236,17 +236,25 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.CodeGeneration
Return declarationList.Count Return declarationList.Count
End Function End Function
Public Function GetDestination(destination As TypeBlockSyntax) As CodeGenerationDestination Public Function GetDestination(destination As SyntaxNode) As CodeGenerationDestination
If destination IsNot Nothing Then If destination IsNot Nothing Then
Select Case destination.VisualBasicKind Select Case destination.VisualBasicKind
Case SyntaxKind.ClassBlock Case SyntaxKind.ClassBlock
Return CodeGenerationDestination.ClassType Return CodeGenerationDestination.ClassType
Case SyntaxKind.CompilationUnit
Return CodeGenerationDestination.CompilationUnit
Case SyntaxKind.EnumBlock
Return CodeGenerationDestination.EnumType
Case SyntaxKind.InterfaceBlock Case SyntaxKind.InterfaceBlock
Return CodeGenerationDestination.InterfaceType Return CodeGenerationDestination.InterfaceType
Case SyntaxKind.ModuleBlock Case SyntaxKind.ModuleBlock
Return CodeGenerationDestination.ModuleType Return CodeGenerationDestination.ModuleType
Case SyntaxKind.NamespaceBlock
Return CodeGenerationDestination.Namespace
Case SyntaxKind.StructureBlock Case SyntaxKind.StructureBlock
Return CodeGenerationDestination.StructType Return CodeGenerationDestination.StructType
Case Else
Return CodeGenerationDestination.Unspecified
End Select End Select
End If End If
......
...@@ -18,6 +18,10 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.CodeGeneration ...@@ -18,6 +18,10 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.CodeGeneration
MyBase.New(provider.GetService(Of ISymbolDeclarationService)()) MyBase.New(provider.GetService(Of ISymbolDeclarationService)())
End Sub End Sub
Public Overloads Overrides Function GetDestination(containerNode As SyntaxNode) As CodeGenerationDestination
Return VisualBasicCodeGenerationHelpers.GetDestination(containerNode)
End Function
Protected Overrides Function CreateImportsAdder(document As Document) As AbstractImportsAdder Protected Overrides Function CreateImportsAdder(document As Document) As AbstractImportsAdder
Return New ImportsStatementsAdder(document) Return New ImportsStatementsAdder(document)
End Function End Function
...@@ -204,6 +208,19 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.CodeGeneration ...@@ -204,6 +208,19 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.CodeGeneration
Return destinationMember Return destinationMember
End Function End Function
Protected Overrides Function AddMembers(Of TDeclarationNode As SyntaxNode)(destination As TDeclarationNode, members As IEnumerable(Of SyntaxNode)) As TDeclarationNode
CheckDeclarationNode(Of EnumBlockSyntax, TypeBlockSyntax, NamespaceBlockSyntax, CompilationUnitSyntax)(destination)
If TypeOf destination Is EnumBlockSyntax Then
Return Cast(Of TDeclarationNode)(Cast(Of EnumBlockSyntax)(destination).AddMembers(members.Cast(Of EnumMemberDeclarationSyntax).ToArray()))
ElseIf TypeOf destination Is TypeBlockSyntax Then
Return Cast(Of TDeclarationNode)(Cast(Of TypeBlockSyntax)(destination).AddMembers(members.Cast(Of StatementSyntax).ToArray()))
ElseIf TypeOf destination Is NamespaceBlockSyntax Then
Return Cast(Of TDeclarationNode)(Cast(Of NamespaceBlockSyntax)(destination).AddMembers(members.Cast(Of StatementSyntax).ToArray()))
Else
Return Cast(Of TDeclarationNode)(Cast(Of CompilationUnitSyntax)(destination).AddMembers(members.Cast(Of StatementSyntax).ToArray()))
End If
End Function
Private Overloads Shared Function AddParametersToMethod(Of TDeclarationNode As SyntaxNode)(methodStatement As MethodBaseSyntax, Private Overloads Shared Function AddParametersToMethod(Of TDeclarationNode As SyntaxNode)(methodStatement As MethodBaseSyntax,
methodBlock As MethodBlockBaseSyntax, methodBlock As MethodBlockBaseSyntax,
parameters As IEnumerable(Of IParameterSymbol), parameters As IEnumerable(Of IParameterSymbol),
......
...@@ -39,6 +39,22 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.Extensions ...@@ -39,6 +39,22 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.Extensions
Throw Contract.Unreachable Throw Contract.Unreachable
End Function End Function
<Extension>
Public Function AddMembers(node As TypeBlockSyntax, ParamArray members As StatementSyntax()) As TypeBlockSyntax
Select Case node.VisualBasicKind
Case SyntaxKind.ModuleBlock
Return DirectCast(node, ModuleBlockSyntax).AddMembers(members)
Case SyntaxKind.InterfaceBlock
Return DirectCast(node, InterfaceBlockSyntax).AddMembers(members)
Case SyntaxKind.StructureBlock
Return DirectCast(node, StructureBlockSyntax).AddMembers(members)
Case SyntaxKind.ClassBlock
Return DirectCast(node, ClassBlockSyntax).AddMembers(members)
End Select
Throw Contract.Unreachable
End Function
<Extension> <Extension>
Public Function WithMembers(node As TypeBlockSyntax, members As SyntaxList(Of StatementSyntax)) As TypeBlockSyntax Public Function WithMembers(node As TypeBlockSyntax, members As SyntaxList(Of StatementSyntax)) As TypeBlockSyntax
Select Case node.VisualBasicKind Select Case node.VisualBasicKind
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册