public override void GenerateCode(VisualScriptCompilerContext context) { var arguments = new List <SyntaxNodeOrToken>(); var memberCallProcessed = false; var invocationTarget = MethodName; for (int index = 0; index < Slots.Count; index++) { var slot = Slots[index]; if (slot.Direction == SlotDirection.Input && slot.Kind == SlotKind.Value) { var argument = context.GenerateExpression(slot); if (IsMemberCall && !memberCallProcessed) { // this parameter (non-static or extension method) memberCallProcessed = true; invocationTarget = argument.ToFullString() + "." + invocationTarget; continue; } if (arguments.Count > 0) { arguments.Add(Token(SyntaxKind.CommaToken)); } arguments.Add(Argument(argument)); } } var expression = InvocationExpression(ParseExpression(invocationTarget), ArgumentList(SeparatedList <ArgumentSyntax>(arguments))); var statement = (StatementSyntax)ExpressionStatement(expression); // Only store return variable if somebody is using it if (ReturnSlot != null && context.FindOutputLinks(ReturnSlot).Any()) { var localVariableName = context.GenerateLocalVariableName(); // Store return value in a local variable statement = LocalDeclarationStatement( VariableDeclaration( IdentifierName("var")) .WithVariables( SingletonSeparatedList <VariableDeclaratorSyntax>( VariableDeclarator( Identifier(localVariableName)) .WithInitializer( EqualsValueClause(expression))))); context.RegisterLocalVariable(ReturnSlot, localVariableName); } context.AddStatement(statement); }
public override void GenerateCode(VisualScriptCompilerContext context) { // Create local variable that will store the item var itemVariableName = context.GenerateLocalVariableName("item"); context.RegisterLocalVariable(ItemSlot, itemVariableName); // Switch to "continue" instead of "return" in case there is no next node var wasInsideLoop = context.IsInsideLoop; context.IsInsideLoop = true; var innerBlockStatements = context.ProcessInnerLoop(LoopSlot); context.IsInsideLoop = wasInsideLoop; context.AddStatement(ForEachStatement(IdentifierName("var"), itemVariableName, context.GenerateExpression(CollectionSlot), Block(innerBlockStatements))); }
public override void GenerateCode(VisualScriptCompilerContext context) { var blockStatement = ParseStatement($"{{ {Code} }}"); // Forward diagnostics to log foreach (var diagnostic in blockStatement.GetDiagnostics()) { LogMessageType logType; switch (diagnostic.Severity) { case DiagnosticSeverity.Info: logType = LogMessageType.Info; break; case DiagnosticSeverity.Warning: logType = LogMessageType.Warning; break; case DiagnosticSeverity.Error: logType = LogMessageType.Error; break; default: throw new ArgumentOutOfRangeException(); } context.Log.Log(new LogMessage(nameof(CustomCodeBlock), logType, diagnostic.GetMessage())); } var block = blockStatement as BlockSyntax; if (block != null) { RoslynHelper.CreateCompilationUnitFromBlock(ref block); foreach (var slot in Slots.Where(x => x.Kind == SlotKind.Value)) { var symbolsToReplace = block.DescendantNodes() .OfType <IdentifierNameSyntax>() .Where(x => x.Identifier.Text == slot.Name) .Where(x => { // We can never be on the right side of a member access var memberAccess = (x.Parent as MemberAccessExpressionSyntax); return(memberAccess == null || memberAccess.Expression == x); }) .ToArray(); if (slot.Direction == SlotDirection.Input) { // Input // Find expression var expression = context.GenerateExpression(slot); block = block.ReplaceNodes(symbolsToReplace, (x1, x2) => expression); } else { // Output // Replace every reference of slot.Name into generated slotName var slotName = context.GenerateLocalVariableName(slot.Name); block = block.ReplaceNodes(symbolsToReplace, (x1, x2) => x1.WithIdentifier(Identifier(slotName))); // Register a local var with generated name context.RegisterLocalVariable(slot, slotName); } } foreach (var statement in block.Statements) { context.AddStatement(statement); } } }