public IReadOnlyList <IKernelCommand> SplitSubmission(SubmitCode submitCode) { var commands = new List <IKernelCommand>(); var nugetRestoreOnKernels = new HashSet <string>(); var hoistedCommandsIndex = 0; var tree = Parse(submitCode.Code, submitCode.TargetKernelName); var nodes = tree.GetRoot().ChildNodes.ToArray(); var targetKernelName = submitCode.TargetKernelName ?? KernelLanguage; foreach (var node in nodes) { switch (node) { case DirectiveNode directiveNode: var parseResult = directiveNode.GetDirectiveParseResult(); if (parseResult.Errors.Any()) { commands.Clear(); commands.Add( new AnonymousKernelCommand((kernelCommand, context) => { var message = string.Join(Environment.NewLine, parseResult.Errors .Select(e => e.ToString())); context.Fail(message: message); return(Task.CompletedTask); }, parent: submitCode.Parent)); break; } var directiveCommand = new DirectiveCommand( parseResult, submitCode.Parent, directiveNode); if (directiveNode is KernelNameDirectiveNode kernelNameNode) { targetKernelName = kernelNameNode.KernelName; } if (parseResult.CommandResult.Command.Name == "#r") { var value = parseResult.CommandResult.GetArgumentValueOrDefault <PackageReferenceOrFileInfo>("package"); if (value.Value is FileInfo) { AddHoistedCommand( new SubmitCode( directiveNode, submitCode.SubmissionType, submitCode.Parent)); } else { AddHoistedCommand(directiveCommand); nugetRestoreOnKernels.Add(targetKernelName); } } else if (parseResult.CommandResult.Command.Name == "#i") { directiveCommand.TargetKernelName = targetKernelName; AddHoistedCommand(directiveCommand); } else { commands.Add(directiveCommand); } break; case LanguageNode languageNode: commands.Add(new SubmitCode( languageNode, submitCode.SubmissionType, submitCode.Parent)); break; default: throw new ArgumentOutOfRangeException(nameof(node)); } } foreach (var kernelName in nugetRestoreOnKernels) { var findKernel = _kernel.FindKernel(kernelName); if (findKernel is KernelBase kernelBase && kernelBase.SubmissionParser.GetDirectiveParser() is {} parser) { var restore = new DirectiveCommand( parser.Parse("#!nuget-restore"), submitCode.Parent); AddHoistedCommand(restore); } } if (NoSplitWasNeeded(out var originalSubmission)) { return(originalSubmission); } var parent = submitCode.Parent ?? submitCode; foreach (var command in commands.OfType <KernelCommandBase>()) { command.Parent = parent; } return(commands); void AddHoistedCommand(IKernelCommand command) { commands.Insert(hoistedCommandsIndex++, command); } bool NoSplitWasNeeded(out IReadOnlyList <IKernelCommand> splitSubmission) { if (commands.Count == 0) { splitSubmission = new[] { submitCode }; return(true); } if (commands.Count == 1) { if (commands[0] is SubmitCode sc) { if (submitCode.Code.Equals(sc.Code, StringComparison.Ordinal)) { splitSubmission = new[] { submitCode }; return(true); } } } splitSubmission = null; return(false); } }