Example #1
0
        private static LNode CompileTimeMacro(string macroName, LNode node, IMacroContext context, bool alsoRuntime, bool wantPreprocess = true)
        {
            if (node.ArgCount != 1 || !node[0].Calls(S.Braces))
            {
                context.Error(node.Target, "{0} should have a single argument: a braced block.", macroName);
                return(null);
            }

            LNodeList code = node[0].Args;

            if (wantPreprocess)
            {
                if (context.Ancestors.Take(context.Ancestors.Count - 1).Any(
                        n => n.Name.IsOneOf(S.Class, S.Struct, S.Enum, S.Namespace) ||
                        n.Name.IsOneOf(S.Constructor, S.Fn, S.Property, S.Var)))
                {
                    context.Error(node.Target, "{0} is designed for use only at the top level of the file. It will be executed as though it is at the top level: any outer scopes will be ignored.", macroName);
                }

                code = context.PreProcess(code);
            }

            WriteHeaderCommentInSessionLog(node, context.Sink);

            // Remove namespace blocks (not supported by Roslyn scripting)
            LNode namespaceBlock     = null;
            var   codeSansNamespaces = code.RecursiveReplace(RemoveNamespaces);

            LNodeList?RemoveNamespaces(LNode n)
            {
                if (EcsValidators.SpaceDefinitionKind(n, out _, out _, out LNode body) == S.Namespace)
                {
                    namespaceBlock = n;
                    return(body.Args.RecursiveReplace(RemoveNamespaces));
                }
                return(null);
            }

            if (namespaceBlock != null && wantPreprocess)
            {
                context.Warning(namespaceBlock, "The C# scripting engine does not support namespaces. They will be ignored when running at compile time.");
            }

            RunCSharpCodeWithRoslyn(node, codeSansNamespaces, context);

            _roslynSessionLog?.Flush();
            return(alsoRuntime ? F.Splice(code) : F.Splice());
        }