本文整理汇总了C#中Microsoft.CodeAnalysis.SyntaxNode.GetType方法的典型用法代码示例。如果您正苦于以下问题:C# SyntaxNode.GetType方法的具体用法?C# SyntaxNode.GetType怎么用?C# SyntaxNode.GetType使用的例子?那么恭喜您, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在类Microsoft.CodeAnalysis.SyntaxNode
的用法示例。
在下文中一共展示了SyntaxNode.GetType方法的12个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C#代码示例。
示例1: VisitSyntaxNode
protected override void VisitSyntaxNode(SyntaxNode node)
{
Type syntaxNodeType = node.GetType();
MemberInfo[] members = syntaxNodeType.GetMembers(BindingFlags.Public | BindingFlags.DeclaredOnly | BindingFlags.Instance);
GenerateSourceSyntaxNode(syntaxNodeType, node);
base.VisitSyntaxNode(node);
}
示例2: GetIdentifierTokenValueText
// Using reflection to get .Identifier is a hack, but don't know any other way to check for identifiers across all syntax node types - YOLO!
public static string GetIdentifierTokenValueText(SyntaxNode syntaxNode)
{
PropertyInfo identifierProperty = syntaxNode.GetType().GetProperty("Identifier", BindingFlags.Public | BindingFlags.Instance);
if (identifierProperty != null)
{
object identifierToken = identifierProperty.GetValue(syntaxNode);
if (identifierToken != null && identifierToken is SyntaxToken)
{
return ((SyntaxToken)identifierToken).ValueText;
}
}
return null;
}
示例3: SyntaxNode
/// <summary>
/// Converts a C# Roslyn SyntaxNode to its Swift equivilant
/// </summary>
/// <param name="node">Roslyn SyntaxNode representing the C# code to convert</param>
/// <returns>A string with the converted Swift code</returns>
public static string SyntaxNode(SyntaxNode node)
{
if (node == null) return "";
if (node.HasLeadingTrivia)
{
var ignoreNode = node.GetLeadingTrivia()
.Where(trivia =>
trivia.IsKind(SyntaxKind.MultiLineCommentTrivia) ||
trivia.IsKind(SyntaxKind.SingleLineCommentTrivia))
.Any(trivia => trivia.ToString().TrimStart('/', '*').ToLower().Trim() == "ignore");
if (ignoreNode) return "";
}
if (node is BlockSyntax)
{
//Block() takes two arguments, & I don't want to worry about it w/ reflection.
return Block((BlockSyntax)node);
}
/*
* We're gonna search through ConvertToSwift's static methods for one
* with the ParsesType attribute that matches the typeof node.
* If one isn't found we'll just return the C# code
*/
var nodeType = node.GetType();
var methods = typeof(ConvertToSwift).GetMethods();
var matchedMethod =
methods.FirstOrDefault(method => //find method that parses this syntax
method.GetCustomAttributes(true).OfType<ParsesTypeAttribute>()
.Any(attr => attr.ParsesType == nodeType));
if (matchedMethod != null)
{
return matchedMethod.Invoke(new ConvertToSwift(), new[] { node }).ToString();
}
return node + NewLine;
}
示例4: AddNode
private void AddNode(TreeViewItem parentItem, SyntaxNode node)
{
var kind = node.GetKind();
var tag = new SyntaxTag()
{
SyntaxNode = node,
Category = SyntaxCategory.SyntaxNode,
Span = node.Span,
FullSpan = node.FullSpan,
Kind = kind,
ParentItem = parentItem
};
var item = new TreeViewItem()
{
Tag = tag,
IsExpanded = false,
Foreground = Brushes.Blue,
Background = node.ContainsDiagnostics ? Brushes.Pink : Brushes.White,
Header = tag.Kind + " " + node.Span.ToString()
};
if (SyntaxTree != null && node.ContainsDiagnostics)
{
item.ToolTip = string.Empty;
foreach (var diagnostic in SyntaxTree.GetDiagnostics(node))
{
item.ToolTip += diagnostic.ToString() + "\n";
}
item.ToolTip = item.ToolTip.ToString().Trim();
}
item.Selected += new RoutedEventHandler((sender, e) =>
{
_isNavigatingFromTreeToSource = true;
typeTextLabel.Visibility = Visibility.Visible;
kindTextLabel.Visibility = Visibility.Visible;
typeValueLabel.Content = node.GetType().Name;
kindValueLabel.Content = kind;
_propertyGrid.SelectedObject = node;
item.IsExpanded = true;
if (!_isNavigatingFromSourceToTree && SyntaxNodeNavigationToSourceRequested != null)
{
SyntaxNodeNavigationToSourceRequested(node);
}
_isNavigatingFromTreeToSource = false;
e.Handled = true;
});
item.Expanded += new RoutedEventHandler((sender, e) =>
{
if (item.Items.Count == 1 && item.Items[0] == null)
{
// Remove placeholder child and populate real children.
item.Items.RemoveAt(0);
foreach (var child in node.ChildNodesAndTokens())
{
AddNodeOrToken(item, child);
}
}
});
if (parentItem == null)
{
treeView.Items.Clear();
treeView.Items.Add(item);
}
else
{
parentItem.Items.Add(item);
}
if (node.ChildNodesAndTokens().Count > 0)
{
if (IsLazy)
{
// Add placeholder child to indicate that real children need to be populated on expansion.
item.Items.Add(null);
}
else
{
// Recursively populate all descendants.
foreach (var child in node.ChildNodesAndTokens())
{
AddNodeOrToken(item, child);
}
}
}
}
示例5: Factory
//.........这里部分代码省略.........
else if (node is VariableDeclarationSyntax)
WriteVariableDeclaration.Go(writer, node.As<VariableDeclarationSyntax>());
else if (node is BlockSyntax)
WriteBlock(writer, node.As<BlockSyntax>());
else if (node is InvocationExpressionSyntax)
WriteInvocationExpression.Go(writer, node.As<InvocationExpressionSyntax>());
else if (node is LiteralExpressionSyntax)
WriteLiteralExpression.Go(writer, node.As<LiteralExpressionSyntax>(), isConst);
else if (node is IdentifierNameSyntax)
WriteIdentifierName.Go(writer, node.As<IdentifierNameSyntax>());
else if (node is ImplicitArrayCreationExpressionSyntax)
WriteArrayCreationExpression.Go(writer, node.As<ImplicitArrayCreationExpressionSyntax>());
else if (node is ArrayCreationExpressionSyntax)
WriteArrayCreationExpression.Go(writer, node.As<ArrayCreationExpressionSyntax>());
else if (node is MemberAccessExpressionSyntax)
WriteMemberAccessExpression.Go(writer, node.As<MemberAccessExpressionSyntax>());
else if (node is ParenthesizedLambdaExpressionSyntax)
WriteLambdaExpression.Go(writer, node.As<ParenthesizedLambdaExpressionSyntax>());
else if (node is SimpleLambdaExpressionSyntax)
WriteLambdaExpression.Go(writer, node.As<SimpleLambdaExpressionSyntax>());
else if (node is AnonymousMethodExpressionSyntax)
WriteLambdaExpression.Go(writer, node.As<AnonymousMethodExpressionSyntax>());
else if (node is ReturnStatementSyntax)
WriteReturnStatement.Go(writer, node.As<ReturnStatementSyntax>());
else if (node is ObjectCreationExpressionSyntax)
WriteObjectCreationExpression.Go(writer, node.As<ObjectCreationExpressionSyntax>());
else if (node is ElementAccessExpressionSyntax)
WriteElementAccessExpression.Go(writer, node.As<ElementAccessExpressionSyntax>());
else if (node is ForEachStatementSyntax)
WriteForEachStatement.Go(writer, node.As<ForEachStatementSyntax>());
else if (node is IfStatementSyntax)
WriteIfStatement.Go(writer, node.As<IfStatementSyntax>());
else if (node is BinaryExpressionSyntax)
WriteBinaryExpression.Go(writer, node.As<BinaryExpressionSyntax>());
else if (node is AssignmentExpressionSyntax)
WriteAssignmentExpression.Go(writer, node.As<AssignmentExpressionSyntax>());
else if (node is ConditionalExpressionSyntax)
WriteConditionalExpression.Go(writer, node.As<ConditionalExpressionSyntax>());
else if (node is BaseExpressionSyntax)
WriteBaseExpression.Go(writer, node.As<BaseExpressionSyntax>());
else if (node is ThisExpressionSyntax)
WriteThisExpression.Go(writer, node.As<ThisExpressionSyntax>());
else if (node is CastExpressionSyntax)
WriteCastExpression.Go(writer, node.As<CastExpressionSyntax>());
else if (node is ThrowStatementSyntax)
WriteThrowStatement.Go(writer, node.As<ThrowStatementSyntax>());
else if (node is EqualsValueClauseSyntax)
WriteEqualsValueClause.Go(writer, node.As<EqualsValueClauseSyntax>());
else if (node is ForStatementSyntax)
WriteForStatement.Go(writer, node.As<ForStatementSyntax>());
else if (node is WhileStatementSyntax)
WriteWhileStatement.Go(writer, node.As<WhileStatementSyntax>());
else if (node is BreakStatementSyntax)
WriteBreakStatement.Go(writer, node.As<BreakStatementSyntax>());
else if (node is ContinueStatementSyntax)
WriteContinueStatement.Go(writer, node.As<ContinueStatementSyntax>());
else if (node is DoStatementSyntax)
WriteDoStatement.Go(writer, node.As<DoStatementSyntax>());
else if (node is SwitchStatementSyntax)
WriteSwitchStatement.Go(writer, node.As<SwitchStatementSyntax>());
else if (node is TryStatementSyntax)
WriteTryStatement.Go(writer, node.As<TryStatementSyntax>());
else if (node is UsingStatementSyntax)
WriteUsingStatement.Go(writer, node.As<UsingStatementSyntax>());
else if (node is ParenthesizedExpressionSyntax)
WriteParenthesizedExpression.Go(writer, node.As<ParenthesizedExpressionSyntax>());
else if (node is LockStatementSyntax)
WriteLockStatement.Go(writer, node.As<LockStatementSyntax>());
else if (node is TypeOfExpressionSyntax)
WriteTypeOfExpression.Go(writer, node.As<TypeOfExpressionSyntax>());
else if (node is AnonymousObjectCreationExpressionSyntax)
WriteAnonymousObjectCreationExpression.Go(writer, node.As<AnonymousObjectCreationExpressionSyntax>());
else if (node is EmptyStatementSyntax)
return; //ignore empty statements
else if (node is DelegateDeclarationSyntax)
return; //don't write delegates - TypeProcessor converts them to function types directly
else if (node is DefaultExpressionSyntax)
WriteDefaultExpression.Go(writer, node.As<DefaultExpressionSyntax>());
else if (node is GenericNameSyntax)
WriteGenericName.Go(writer, node.As<GenericNameSyntax>());
else if (node is ConversionOperatorDeclarationSyntax)
WriteConversionOperatorDeclaration.Go(writer, node.As<ConversionOperatorDeclarationSyntax>());
else if (node is PrefixUnaryExpressionSyntax)
WriteUnaryExpression.WritePrefix(writer, node.As<PrefixUnaryExpressionSyntax>());
else if (node is PostfixUnaryExpressionSyntax)
WriteUnaryExpression.WritePostfix(writer, node.As<PostfixUnaryExpressionSyntax>());
else if (node is SizeOfExpressionSyntax)
WriteSizeOfExpression.Go(writer, node.As<SizeOfExpressionSyntax>());
else if (node is DestructorDeclarationSyntax)
WriteDestructorBody.WriteDestructor(writer, node.As<DestructorDeclarationSyntax>());
else if (node is IndexerDeclarationSyntax)
WriteIndexer.Go(writer, node.As<IndexerDeclarationSyntax>());
else if (node is StackAllocArrayCreationExpressionSyntax)
WriteStackArrayCreation.Go(writer, node.As<StackAllocArrayCreationExpressionSyntax>());
// writer.Write(node.ToFullString() + "//TODO: StackAlloc not supported yet");
else if (node is YieldStatementSyntax)
WriteYieldStatement.Go(writer, node.As<YieldStatementSyntax>());
else
throw new NotImplementedException(node.GetType().Name + " is not supported. " + Utility.Descriptor(node));
}
示例6: QuotePropertyValues
/// <summary>
/// Inspects the property values of the <paramref name="node"/> object using Reflection and
/// creates API call descriptions for the property values recursively. Properties that are not
/// essential to the shape of the syntax tree (such as Span) are ignored.
/// </summary>
private List<ApiCall> QuotePropertyValues(SyntaxNode node)
{
var result = new List<ApiCall>();
var properties = node.GetType().GetProperties(BindingFlags.Public | BindingFlags.Instance);
// Filter out non-essential properties listed in nonStructuralProperties
result.AddRange(properties
.Where(propertyInfo => !nonStructuralProperties.Contains(propertyInfo.Name))
.Select(propertyInfo => QuotePropertyValue(node, propertyInfo))
.Where(apiCall => apiCall != null));
// HACK: factory methods for the following node types accept back the first "kind" parameter
// that we filter out above. Add an artificial "property value" that can be later used to
// satisfy the first parameter of type SyntaxKind.
if (node is AccessorDeclarationSyntax ||
node is BinaryExpressionSyntax ||
node is ClassOrStructConstraintSyntax ||
node is CheckedExpressionSyntax ||
node is CheckedStatementSyntax ||
node is ConstructorInitializerSyntax ||
node is GotoStatementSyntax ||
node is InitializerExpressionSyntax ||
node is LiteralExpressionSyntax ||
node is MemberAccessExpressionSyntax ||
node is OrderingSyntax ||
node is PostfixUnaryExpressionSyntax ||
node is PrefixUnaryExpressionSyntax ||
node is DocumentationCommentTriviaSyntax ||
node is SwitchLabelSyntax ||
node is YieldStatementSyntax)
{
result.Add(new ApiCall("Kind", "SyntaxKind." + node.Kind().ToString()));
}
return result;
}
示例7: PickFactoryMethodToCreateNode
/// <summary>
/// Uses Reflection to inspect static factory methods on the Roslyn.Compilers.CSharp.Syntax
/// class and pick an overload that creates a node of the same type as the input <paramref
/// name="node"/>
/// </summary>
private MethodInfo PickFactoryMethodToCreateNode(SyntaxNode node)
{
string name = node.GetType().Name;
List<MethodInfo> candidates = null;
if (!factoryMethods.TryGetValue(name, out candidates))
{
throw new NotSupportedException(name + " is not supported");
}
int minParameterCount = candidates.Min(m => m.GetParameters().Length);
// HACK: for LiteralExpression pick the overload with two parameters - the overload with one
// parameter only allows true/false/null literals
if (node is LiteralExpressionSyntax)
{
SyntaxKind kind = ((LiteralExpressionSyntax)node).Kind();
if (kind != SyntaxKind.TrueLiteralExpression &&
kind != SyntaxKind.FalseLiteralExpression &&
kind != SyntaxKind.NullLiteralExpression)
{
minParameterCount = 2;
}
}
MethodInfo factory = null;
if ((node is BaseTypeDeclarationSyntax ||
node is IdentifierNameSyntax))
{
Type desiredParameterType = typeof(string);
factory = candidates.FirstOrDefault(m => m.GetParameters()[0].ParameterType == desiredParameterType);
if (factory != null)
{
return factory;
}
}
factory = candidates.First(m => m.GetParameters().Length == minParameterCount);
return factory;
}
示例8: Visit
public override void Visit(SyntaxNode node)
{
if (node is ExpressionSyntax)
{
var type = SemanticModel.GetTypeInfo((ExpressionSyntax)node).Type;
if (type != null)
{
Results.AppendLine();
Results.Append(node.GetType().Name);
Results.Append(" ");
Results.Append(node.ToString());
Results.Append(" has type ");
Results.Append(type.ToDisplayString());
}
}
base.Visit(node);
}
示例9: PickFactoryMethodToCreateNode
/// <summary>
/// Uses Reflection to inspect static factory methods on the Microsoft.CodeAnalysis.CSharp.SyntaxFactory
/// class and pick an overload that creates a node of the same type as the input <paramref
/// name="node"/>
/// </summary>
private MethodInfo PickFactoryMethodToCreateNode(SyntaxNode node)
{
string name = node.GetType().Name;
List<MethodInfo> candidates = null;
if (!factoryMethods.TryGetValue(name, out candidates))
{
throw new NotSupportedException(name + " is not supported");
}
int minParameterCount = candidates.Min(m => m.GetParameters().Length);
// HACK: for LiteralExpression pick the overload with two parameters - the overload with one
// parameter only allows true/false/null literals
if (node is LiteralExpressionSyntax)
{
SyntaxKind kind = ((LiteralExpressionSyntax)node).Kind();
if (kind != SyntaxKind.TrueLiteralExpression &&
kind != SyntaxKind.FalseLiteralExpression &&
kind != SyntaxKind.NullLiteralExpression)
{
minParameterCount = 2;
}
}
MethodInfo factory = null;
if ((node is BaseTypeDeclarationSyntax ||
node is IdentifierNameSyntax))
{
Type desiredParameterType = typeof(string);
factory = candidates.FirstOrDefault(m => m.GetParameters()[0].ParameterType == desiredParameterType);
if (factory != null)
{
return factory;
}
}
var candidatesWithMinParameterCount = candidates.Where(m => m.GetParameters().Length == minParameterCount).ToArray();
if (minParameterCount == 1 && candidatesWithMinParameterCount.Length > 1)
{
// first see if we have a method that accepts params parameter and return that if found
var paramArray = candidatesWithMinParameterCount.FirstOrDefault(m => m.GetParameters()[0].GetCustomAttribute<ParamArrayAttribute>() != null);
if (paramArray != null)
{
return paramArray;
}
// if there are multiple candidates with one parameter, pick the one that is optional
var firstParameterOptional = candidatesWithMinParameterCount.FirstOrDefault(m => m.GetParameters()[0].IsOptional);
if (firstParameterOptional != null)
{
return firstParameterOptional;
}
}
// otherwise just pick the first one (this is arbitrary)
factory = candidatesWithMinParameterCount[0];
return factory;
}
示例10: TryGetNamespaceDeclarationOfSyntaxNode
/// <summary>
/// Tries to get the namespace declaration for the given syntax
/// node. Returns false if it cannot find a namespace.
/// </summary>
internal bool TryGetNamespaceDeclarationOfSyntaxNode(SyntaxNode syntaxNode,
out NamespaceDeclarationSyntax result)
{
result = null;
if (syntaxNode == null)
{
return false;
}
syntaxNode = syntaxNode.Parent;
if (syntaxNode == null)
{
return false;
}
if (syntaxNode.GetType() == typeof(NamespaceDeclarationSyntax))
{
result = syntaxNode as NamespaceDeclarationSyntax;
return true;
}
return this.TryGetNamespaceDeclarationOfSyntaxNode(syntaxNode, out result);
}
示例11: GenerateSourceSyntaxNode
private void GenerateSourceSyntaxNode(Type type, SyntaxNode node)
{
List<ArgumentSyntax> arguments = new List<ArgumentSyntax>();
List<SyntaxToken> separators = new List<SyntaxToken>();
Type syntaxType = typeof(SyntaxFactory);
string nodeId = identifier.GetId(node);
type = node.GetType();
string createMethodName = GetApiCreateMethod(node.GetType());
MethodInfo[] createMethods = syntaxType.GetMethods();
List<MethodInfo> createMethodList = new List<MethodInfo>(createMethods);
var miq = from m in createMethodList
where m.Name == createMethodName
orderby m.GetParameters().Count() descending
select m;
MethodInfo createMethodInfo = miq.First();
List<ExpressionSyntax> dependentVariableDefinitions = new List<ExpressionSyntax>();
foreach (ParameterInfo parameterInfo in createMethodInfo.GetParameters())
{
string newParameterName = parameterInfo.Name;
newParameterName = new string(new char[] { newParameterName[0] }).ToUpper() + newParameterName.Substring(1);
Type typeSearch = parameterInfo.ParameterType;
//determine if node is derived from type "SyntaxNode"
bool foundSyntaxNode = false;
while (typeSearch != null)
{
if (typeSearch == typeof(SyntaxNode))
{
foundSyntaxNode = true;
}
typeSearch = typeSearch.BaseType;
}
if (foundSyntaxNode)
{
SyntaxNode newNode = (SyntaxNode)type.GetProperty(newParameterName).GetValue(node, null);
if (newNode != null)
{
ExpressionSyntax decl = this.syntaxNodeLocals.Pop();
/*if (decl.Declaration.Type.PlainName != newNode.GetType().Name)
{
throw new ApplicationException("Types do not match when popping SyntaxNode declaration stack.");
}*/
dependentVariableDefinitions.Add(decl);
arguments.Add(CreateArgument(decl, parameterInfo.IsOptional ? parameterInfo.Name : null));
if (parameterInfo.Name == "identifier")
{
if (newNode is SimpleNameSyntax)
{
//friendlyName = ((SimpleNameSyntax)newNode).GetFullText();
}
//parameterInfo.ParameterType.BaseType is NameSyntax
}
}
else
{
arguments.Add(CreateArgument(SyntaxFactory.LiteralExpression(SyntaxKind.NullLiteralExpression), parameterInfo.IsOptional ? parameterInfo.Name : null));
}
}
//TODO: List handling has some repeated code... potential for refactoring
else if (parameterInfo.ParameterType.Name == "SyntaxList`1")
{
IEnumerable syntaxList = (IEnumerable)type.GetProperty(newParameterName).GetValue(node, null);
int count = syntaxList.Cast<SyntaxNode>().Count();
Type[] genericTypes = parameterInfo.ParameterType.GetGenericArguments();
Type genericType = genericTypes[0];
string typeName = string.Format("List<{0}>", genericType.Name);
ExpressionSyntax listDecl = Funcify(nodeId + "_" + parameterInfo.Name, CreateListOfType(count, genericType, genericType, dependentVariableDefinitions, false), SyntaxFactory.ParseTypeName(typeName));
dependentVariableDefinitions.Add(listDecl);
BuildSyntaxNode("pwrap" + parameterInfo.Name, parameterInfo.ParameterType, typeName,
new List<ArgumentSyntax> { CreateArgument(listDecl) },
new List<SyntaxToken>(), null);
ExpressionSyntax decl = this.syntaxNodeLocals.Pop();
dependentVariableDefinitions.Add(decl);
arguments.Add(CreateArgument(decl, parameterInfo.IsOptional ? parameterInfo.Name : null));
}
else if (parameterInfo.ParameterType.Name == "SeparatedSyntaxList`1")
{
IEnumerable syntaxList = (IEnumerable)type.GetProperty(newParameterName).GetValue(node, null);
int count = syntaxList.Cast<SyntaxNode>().Count();
Type[] genericTypes = parameterInfo.ParameterType.GetGenericArguments();
Type genericType = genericTypes[0];
//.........这里部分代码省略.........
示例12: Visit
public override void Visit(SyntaxNode node)
{
var padding = node.Ancestors().Count();
var prepend = node.ChildNodes().Any() ? "[-]" : "[.]";
var nodetype = node.GetType().FullName;
if (nodetype.StartsWith(prefix)) nodetype = nodetype.Substring(prefix.Length);
var line = new string(' ', padding) + prepend + " " + nodetype;
Console.WriteLine(line);
//var decl = node as ClassDeclarationSyntax;
//if (decl != null && decl.BaseList != null)
//{
// Console.Write(new string(' ', padding + 4) + decl.Identifier);
// foreach (var n in decl.BaseList.Types.OfType<IdentifierNameSyntax>())
// {
// Console.Write(" " + n.Identifier);
// }
// Console.WriteLine();
//}
var attr = node as AttributeSyntax;
if (attr != null)
{
Console.WriteLine(new string(' ', padding + 4) + "> " + attr.Name);
foreach (var arg in attr.ArgumentList.Arguments)
{
var expr = arg.Expression as LiteralExpressionSyntax;
//Console.WriteLine(new string(' ', padding + 4) + "> " + arg.NameColon + " " + arg.NameEquals);
Console.WriteLine(new string(' ', padding + 4) + "> " + (expr == null ? null : expr.Token.Value));
}
}
var attr2 = node as IdentifierNameSyntax;
if (attr2 != null)
{
Console.WriteLine(new string(' ', padding + 4) + "T " + attr2.Identifier.GetType());
Console.WriteLine(new string(' ', padding + 4) + "V " + attr2.Identifier);
}
var x = node as TypeSyntax;
if (x != null)
{
var xtype = x.GetType().FullName;
if (xtype.StartsWith(prefix)) xtype = nodetype.Substring(prefix.Length);
Console.WriteLine(new string(' ', padding + 4) + "> " + xtype);
}
base.Visit(node);
}