Esempio n. 1
0
        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);
        }
 // 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;
 }
Esempio n. 3
0
        /// <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;
        }
        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);
                    }
                }
            }
        }
Esempio n. 5
0
        private static void Factory(OutputWriter writer, SyntaxNode node, bool isConst)
        {
            if (node is ConstructorInitializerSyntax)
                WriteConstructorInitializer.Go(writer, node.As<ConstructorInitializerSyntax>());
            else if (node is CheckedExpressionSyntax)
                WriteChecked.Go(writer, node.As<CheckedExpressionSyntax>());
            else if (node is CheckedStatementSyntax)
                WriteChecked.Go(writer, node.As<CheckedStatementSyntax>());
            else if (node is UnsafeStatementSyntax)
                WriteUnsafeStatement.Go(writer, node.As<UnsafeStatementSyntax>());
            else if (node is InitializerExpressionSyntax)
                WriteInitializer.Go(writer, node.As<InitializerExpressionSyntax>());
            else if (node is GotoStatementSyntax)
                WriteGoto.Go(writer, node.As<GotoStatementSyntax>());
            else if (node is CaseSwitchLabelSyntax)
                WriteLabel.Go(writer, node.As<CaseSwitchLabelSyntax>());
            else if (node is LabeledStatementSyntax)
                WriteLabel.Go(writer, node.As<LabeledStatementSyntax>());
            else if (node is OperatorDeclarationSyntax)
                WriteOperatorDeclaration.Go(writer, node.As<OperatorDeclarationSyntax>());
            else if (node is MethodDeclarationSyntax)
                WriteMethod.Go(writer, node.As<MethodDeclarationSyntax>());
            else if (node is PropertyDeclarationSyntax)
                WriteProperty.Go(writer, node.As<PropertyDeclarationSyntax>());
            else if (node is EventDeclarationSyntax)
                WriteEvent.Go(writer, node.As<EventDeclarationSyntax>());
            else if (node is FieldDeclarationSyntax)
                WriteField.Go(writer, node.As<FieldDeclarationSyntax>());
            else if (node is EventFieldDeclarationSyntax)
                WriteField.Go(writer, node.As<EventFieldDeclarationSyntax>());
            else if (node is ConstructorDeclarationSyntax)
                WriteConstructorBody.Go(writer, node.As<ConstructorDeclarationSyntax>());
            else if (node is ExpressionStatementSyntax)
                WriteStatement(writer, node.As<ExpressionStatementSyntax>());
            else if (node is FixedStatementSyntax)
                WriteFixedStatement(writer, node.As<FixedStatementSyntax>());
            else if (node is LocalDeclarationStatementSyntax)
                WriteLocalDeclaration.Go(writer, node.As<LocalDeclarationStatementSyntax>());
            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));
        }
Esempio n. 6
0
    /// <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;
    }
Esempio n. 7
0
    /// <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;
    }
Esempio n. 8
0
            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);
            }
Esempio n. 9
0
            // Visits all SyntaxNodes.
            public override void Visit(SyntaxNode node)
            {
                // If you need to visit all SyntaxNodes of a particular base type that can never
                // appear directly in a syntax tree then this would be the place to check for that.
                // For example, TypeDeclarationSyntax is a base type for all the type declarations (like 
                // ClassDeclarationSyntax and StructDeclarationSyntax) that can appear in a syntax tree.
                if (node is TypeDeclarationSyntax)
                {
                    Results.AppendLine();
                    Results.Append("Visiting ");
                    Results.Append(node.GetType().Name);
                    Results.Append(" (Kind = ");
                    Results.Append(node.Kind().ToString());
                    Results.Append(")");
                }

                base.Visit(node);
            }
Esempio n. 10
0
    /// <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;
    }
Esempio n. 11
0
        /// <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);
        }
Esempio n. 12
0
        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];

                    ExpressionSyntax listDecl = Funcify(nodeId + "_" + parameterInfo.Name, CreateListOfType(count, typeof(SyntaxNodeOrToken), genericType, dependentVariableDefinitions, true), SyntaxFactory.ParseTypeName("List<SyntaxNodeOrToken>"));

                    dependentVariableDefinitions.Add(listDecl);

                    BuildSyntaxNode(nodeId, parameterInfo.ParameterType, string.Format("SeparatedList<{0}>", genericType.Name),
                        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 == typeof(SyntaxToken))
                {
                    SyntaxToken tokenValue = (SyntaxToken)type.GetProperty(newParameterName).GetValue(node, null);
                    ExpressionSyntax tokenExpr = CreateToken(parameterInfo.Name, tokenValue);
                    arguments.Add(CreateArgument(tokenExpr, parameterInfo.IsOptional ? parameterInfo.Name : null));
                }
                else if (parameterInfo.ParameterType == typeof(SyntaxTokenList))
                {
                    SyntaxTokenList syntaxTokenList = (SyntaxTokenList)type.GetProperty(newParameterName).GetValue(node, null);
                    int count = syntaxTokenList.Count;
                    List<SyntaxNodeOrToken> listInitExpressionList = new List<SyntaxNodeOrToken>();

                    for (int i = 0; i < count; i++)
                    {
                        ExpressionSyntax expressionSyntax = CreateToken(parameterInfo.Name, syntaxTokenList[i]);
                        listInitExpressionList.Add(expressionSyntax);
                        if (i + 1 < count)
                        {
                            listInitExpressionList.Add(SyntaxFactory.Literal(",", ","));
                        }
                    }

                    string typeName = string.Format("List<{0}>", typeof(SyntaxToken).ToString());

                    ExpressionSyntax listDecl = Funcify(nodeId + "_" + parameterInfo.Name, CreateListOfType(typeof(SyntaxToken), listInitExpressionList), SyntaxFactory.ParseTypeName(typeName));
                    dependentVariableDefinitions.Add(listDecl);

                    BuildSyntaxNode(nodeId, parameterInfo.ParameterType, "TokenList",
                        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 == typeof(SyntaxKind))
                {
                    arguments.Add(CreateArgument(SyntaxFactory.MemberAccessExpression(SyntaxKind.SimpleMemberAccessExpression,
                        SyntaxFactory.IdentifierName("SyntaxKind"), name: SyntaxFactory.IdentifierName(Enum.GetName(typeof(SyntaxKind), node.Kind()))),
                        parameterInfo.IsOptional ? parameterInfo.Name : null));
                }
                else
                {
                    throw new ApplicationException("Unknown parameter to SyntaxNode creator.");
                    //System.Object value = type.GetProperty(newParameterName, BindingFlags.FlattenHierarchy | BindingFlags.Public | BindingFlags.Instance).GetValue(node, null);
                    //arguments.Add(CreateArgument(SyntaxFactory.LiteralExpression(SyntaxKind.StringLiteralExpression, SyntaxFactory.Literal("asdf", (string)value)), parameterInfo.IsOptional ? parameterInfo.Name : null));
                }

                //if (!(parameterInfo.ParameterType == typeof(LiteralExpressionSyntax)) && !(parameterInfo.ParameterType == typeof(SyntaxTokenList)))
                {
                    separators.Add(SyntaxFactory.Literal(",", ","));
                }
            }

            separators.RemoveAt(separators.Count - 1);
            BuildSyntaxNode(nodeId, type, GetApiCreateMethod(type), arguments, separators, dependentVariableDefinitions);
        }
        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);
        }
 public override void Visit(SyntaxNode node)
 {
     var padding = node.Ancestors().Count();
     var prepend = node.ChildNodes().Any() ? "[-]" : "[.]";
     var line = new string(' ', padding) + prepend + " " + node.GetType().ToString();
     Console.WriteLine(line);
     base.Visit(node);
 }