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}"); } } }
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); }
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); }