Ejemplo n.º 1
0
        protected virtual Microsoft.CodeAnalysis.SyntaxTree ToSyntaxTree(VSGraphModel graphModel, CompilationOptions options)
        {
            //TODO fix graph name, do not use the asset name
            var className        = graphModel.TypeName;
            var baseClass        = graphModel.Stencil.GetBaseClass().Name;
            var classDeclaration = ClassDeclaration(className)
                                   .WithModifiers(
                TokenList(
                    Token(SyntaxKind.PublicKeyword)));

            if (!String.IsNullOrEmpty(baseClass))
            {
                classDeclaration = classDeclaration.WithBaseList(
                    BaseList(
                        SingletonSeparatedList <BaseTypeSyntax>(
                            SimpleBaseType(
                                IdentifierName(baseClass)))));
            }

            if (graphModel.Stencil.addCreateAssetMenuAttribute)
            {
                classDeclaration = classDeclaration.WithAttributeLists(
                    SingletonList(
                        AttributeList(
                            SingletonSeparatedList(
                                Attribute(
                                    IdentifierName("CreateAssetMenu"))
                                .WithArgumentList(
                                    AttributeArgumentList(
                                        SeparatedList <AttributeArgumentSyntax>(
                                            new SyntaxNodeOrToken[]
                {
                    AttributeArgument(
                        LiteralExpression(
                            SyntaxKind.StringLiteralExpression,
                            Literal(graphModel.Stencil.fileName)))
                    .WithNameEquals(
                        NameEquals(
                            IdentifierName("fileName"))),
                    Token(SyntaxKind.CommaToken),
                    AttributeArgument(
                        LiteralExpression(
                            SyntaxKind.StringLiteralExpression,
                            Literal(graphModel.Stencil.menuName)))
                    .WithNameEquals(
                        NameEquals(
                            IdentifierName("menuName")))
                })))))));
            }

            var allMembers = new List <MemberDeclarationSyntax>();

            m_AllFields = new List <MemberDeclarationSyntax>();
            var allRemainingMembers = new List <MemberDeclarationSyntax>();

            foreach (var fieldDecl in graphModel.GraphVariableModels)
            {
                var fieldSyntaxNode = fieldDecl.DeclareField(this);
                m_AllFields.Add(fieldSyntaxNode);
            }

            var entryPoints = graphModel.GetEntryPoints();

            Dictionary <string, MethodDeclarationSyntax> declaredMethods = new Dictionary <string, MethodDeclarationSyntax>();

            foreach (var stack in entryPoints)
            {
                var entrySyntaxNode = BuildNode(stack);
                foreach (var memberDeclaration in entrySyntaxNode.Cast <MemberDeclarationSyntax>())
                {
                    if (memberDeclaration is MethodDeclarationSyntax methodDeclarationSyntax)
                    {
                        string key = methodDeclarationSyntax.Identifier.ToString();
                        declaredMethods.Add(key, methodDeclarationSyntax);
                    }
                    else
                    {
                        allRemainingMembers.Add(memberDeclaration);
                    }
                }
            }

            allMembers.AddRange(m_AllFields);
            m_AllFields = null;
            allMembers.AddRange(allRemainingMembers);

            if (m_EventRegistrations.Any())
            {
                if (!declaredMethods.TryGetValue("Update", out var method))
                {
                    method = RoslynBuilder.DeclareMethod("Update", AccessibilityFlags.Public, typeof(void))
                             .WithParameterList(
                        ParameterList(
                            SeparatedList(
                                Enumerable.Empty <ParameterSyntax>())))
                             .WithBody(Block());
                }

                BlockSyntax blockSyntax = Block(m_EventRegistrations.Concat(method.Body.Statements));

                method = method.WithBody(blockSyntax);
                declaredMethods["Update"] = method;
            }

            allMembers.AddRange(declaredMethods.Values);

            classDeclaration = classDeclaration.AddMembers(allMembers.ToArray());

            var referencedNamespaces = new[]
            {
                "System",
                "System.Collections",
                "System.Collections.Generic",
                "System.Dynamic",
                "System.Linq",
                "Microsoft.CSharp",
                "UnityEngine",
                "UnityEngine.SceneManagement",
                "UnityEngine.VisualScripting"
            }.Select(namespaceName => UsingDirective(ParseName(namespaceName)));

            var namespaceAliases = new Dictionary <string, string>
            {
                { "UnityEngine.Object", "Object" },
                { "UnityEngine.Random", "Random" },
                { "UnityEngine.Debug", "Debug" },
                { "UnityEngine.SceneManagement.SceneManager", "SceneManager" },
            }.Select(pair =>
                     UsingDirective(ParseName(pair.Key))
                     .WithAlias(NameEquals(
                                    IdentifierName(pair.Value))));

            UsingDirectiveSyntax[] usings = referencedNamespaces.Concat(namespaceAliases).ToArray();

            var compilationUnit = CompilationUnit()
                                  .WithUsings(
                List(usings))
                                  .WithMembers(
                SingletonList <MemberDeclarationSyntax>(classDeclaration)).NormalizeWhitespace();

            return(compilationUnit.SyntaxTree);
        }