Example #1
0
        protected override Microsoft.CodeAnalysis.SyntaxTree ToSyntaxTree(VSGraphModel graphModel, CompilationOptions compilationOptions)
        {
            var ecsStencil = (EcsStencil)graphModel.Stencil;

            try
            {
                Options = compilationOptions;
                if (!s_TypeManagerInitialized)
                {
                    TypeManager.Initialize(); // avoid NRE in type cache
                    s_TypeManagerInitialized = true;
                }

                return(GenerateSyntaxTree(graphModel, compilationOptions, ecsStencil.UseJobSystem));
            }
            catch (JobSystemNotCompatibleException e)
            {
                if (AllowNoJobsFallback)
                {
                    Debug.LogWarning(e.Message + " - Falling back on main thread execution");
                    var newTranslator = new RoslynEcsTranslator(ecsStencil);
                    return(newTranslator.GenerateSyntaxTree(graphModel, compilationOptions, false));
                }

                throw;
            }
        }
        IEnumerable <StatementSyntax> ConvertNodesToSyntaxList(INodeModel node, IEnumerable <SyntaxNode> blocks,
                                                               CompilationOptions options)
        {
            foreach (var block in blocks)
            {
                switch (block)
                {
                case StatementSyntax statementNode:
                    foreach (var statementSyntax in Instrument(statementNode, node, options))
                    {
                        yield return(statementSyntax);
                    }
                    break;

                case ExpressionSyntax expressionNode:
                    foreach (var statementSyntax in Instrument(ExpressionStatement(expressionNode)
                                                               .WithAdditionalAnnotations(
                                                                   new SyntaxAnnotation(Annotations.VSNodeMetadata, node.Guid.ToString())), node, options))
                    {
                        yield return(statementSyntax);
                    }
                    break;

                default:
                    throw new InvalidOperationException("Expected a statement or expression " +
                                                        $"node, found a {node.GetType()} when building {block}");
                }
            }
        }
Example #3
0
        Microsoft.CodeAnalysis.SyntaxTree GenerateSyntaxTree(VSGraphModel graphModel, CompilationOptions compilationOptions, bool useJobSystem)
        {
            var ecsStencil = (EcsStencil)graphModel.Stencil;

            ecsStencil.ClearComponentDefinitions();

            //TODO fix graph name, do not use the asset name
            var className = graphModel.TypeName;

            TranslationOptions options = TranslationOptions.None;

            if (useJobSystem)
            {
                options |= TranslationOptions.UseJobs;
            }
            if (!compilationOptions.HasFlag(CompilationOptions.LiveEditing))
            {
                options |= TranslationOptions.BurstCompile;
            }

            var rootContext = new RootContext(ecsStencil, className, options);

            context = rootContext;

            List <IFunctionModel> entryPoints = GetEntryPointStacks(graphModel).ToList();

            BuildSpecificStack <PreUpdate>(entryPoints, rootContext);

            foreach (FunctionModel stack in entryPoints.Cast <FunctionModel>().OrderBy(x => x is IOrderedStack orderedStack ? orderedStack.Order : -1))
            {
                if (stack is PreUpdate || stack is PostUpdate)
                {
                    continue;
                }

                IEnumerable <SyntaxNode> entrySyntaxNode = BuildNode(stack);
                foreach (var node in entrySyntaxNode)
                {
                    switch (node)
                    {
                    case null:
                        continue;

                    case StatementSyntax statement:
                        context.AddStatement(statement);
                        break;

                    case MemberDeclarationSyntax member:
                        rootContext.AddMember(member);
                        break;

                    default:
                        Debug.LogError($"Cannot process syntax node type {node.GetType().Name}");
                        break;
                    }
                }
            }

            // TODO: events (see KeyDownEvent)
            // foreach (var statementSyntax in m_EventRegistrations) rootContext.AddStatement(statementSyntax);

            BuildSpecificStack <PostUpdate>(entryPoints, rootContext);

            var referencedNamespaces = new List <string>
            {
                "System",
                "Unity.Burst",
                "Unity.Entities",
                "Unity.Jobs",
                "Unity.Mathematics",
                "Unity.Transforms",
                "Unity.Collections",
                "Microsoft.CSharp",
                "UnityEngine",
            };

            referencedNamespaces = referencedNamespaces.Distinct().ToList();

            var usingList = new List <UsingDirectiveSyntax>();

            foreach (var ns in referencedNamespaces)
            {
                string[] identifiers = ns.Split(".".ToCharArray());

                if (identifiers.Length == 1)
                {
                    usingList.Add(UsingDirective(IdentifierName(identifiers[0])));
                }
                else if (identifiers.Length == 2)
                {
                    usingList.Add(UsingDirective(QualifiedName(IdentifierName(identifiers[0]), IdentifierName(identifiers[1]))));
                }
                else if (identifiers.Length == 3)
                {
                    usingList.Add(UsingDirective(QualifiedName(
                                                     QualifiedName(IdentifierName(identifiers[0]), IdentifierName(identifiers[1])),
                                                     IdentifierName(identifiers[2]))));
                }
            }

            CompilationUnitSyntax compilationUnit = CompilationUnit()
                                                    .WithUsings(
                List(usingList.ToArray()))
                                                    .WithMembers(
                SingletonList <MemberDeclarationSyntax>(rootContext.Build(this, graphModel))).NormalizeWhitespace();

            return(compilationUnit.SyntaxTree);
        }
Example #4
0
 public void Apply(ref Microsoft.CodeAnalysis.SyntaxTree syntaxTree, CompilationOptions options)
 {
     syntaxTree = new InstrumentForInEditorDebugging().Visit(syntaxTree.GetRoot()).SyntaxTree;
     // TODO handle exceptions again: syntaxTree = new ExceptionHandlingInjection().Visit(syntaxTree.GetRoot()).SyntaxTree;
 }
        internal IEnumerable <StatementSyntax> Instrument(StatementSyntax syntaxNode, INodeModel nodeModel, CompilationOptions options)
        {
            // TODO: RecordValue codegen counter instead of counting them after the fact
            if ((options & CompilationOptions.Tracing) != 0)
            {
                int recordedValuesCount = syntaxNode.GetAnnotatedNodes(Annotations.RecordValueKind).Count();

                yield return(InstrumentForInEditorDebugging.BuildLastCallFrameExpression(recordedValuesCount, nodeModel.Guid,
                                                                                         GetRecorderName(),
                                                                                         nodeModel is INodeModelProgress && nodeModel is CoroutineNodeModel coroutineNodeModel
                    ? MemberAccessExpression(
                                                                                             SyntaxKind.SimpleMemberAccessExpression,
                                                                                             IdentifierName(CoroutineParameterName),
                                                                                             IdentifierName(coroutineNodeModel.VariableName))
                    : null));
            }

            yield return(syntaxNode);
        }