public ScriptResult Execute(string code, string[] scriptArgs, AssemblyReferences references, IEnumerable<string> namespaces, ScriptPackSession scriptPackSession) { Guard.AgainstNullArgument("references", references); Guard.AgainstNullArgument("scriptPackSession", scriptPackSession); references.PathReferences.UnionWith(scriptPackSession.References); SessionState<Evaluator> sessionState; if (!scriptPackSession.State.ContainsKey(SessionKey)) { Logger.Debug("Creating session"); var context = new CompilerContext(new CompilerSettings { AssemblyReferences = references.PathReferences.ToList() }, new ConsoleReportPrinter()); var evaluator = new Evaluator(context); var allNamespaces = namespaces.Union(scriptPackSession.Namespaces).Distinct(); var host = _scriptHostFactory.CreateScriptHost(new ScriptPackManager(scriptPackSession.Contexts), scriptArgs); MonoHost.SetHost((ScriptHost)host); evaluator.ReferenceAssembly(typeof(MonoHost).Assembly); evaluator.InteractiveBaseClass = typeof(MonoHost); sessionState = new SessionState<Evaluator> { References = new AssemblyReferences(references.PathReferences, references.Assemblies), Namespaces = new HashSet<string>(), Session = evaluator }; ImportNamespaces(allNamespaces, sessionState); scriptPackSession.State[SessionKey] = sessionState; } else { Logger.Debug("Reusing existing session"); sessionState = (SessionState<Evaluator>)scriptPackSession.State[SessionKey]; var newReferences = sessionState.References == null ? references : references.Except(sessionState.References); foreach (var reference in newReferences.PathReferences) { Logger.DebugFormat("Adding reference to {0}", reference); sessionState.Session.LoadAssembly(reference); } sessionState.References = new AssemblyReferences(references.PathReferences, references.Assemblies); var newNamespaces = sessionState.Namespaces == null ? namespaces : namespaces.Except(sessionState.Namespaces); ImportNamespaces(newNamespaces, sessionState); } Logger.Debug("Starting execution"); var result = Execute(code, sessionState.Session); Logger.Debug("Finished execution"); return result; }
public ScriptResult Execute(string code, string[] scriptArgs, AssemblyReferences references, IEnumerable<string> namespaces, ScriptPackSession scriptPackSession) { if (scriptPackSession == null) { throw new ArgumentNullException("scriptPackSession"); } if (references == null) { throw new ArgumentNullException("references"); } _log.Debug("Starting to create execution components"); _log.Debug("Creating script host"); var executionReferences = new AssemblyReferences(references.Assemblies, references.Paths); executionReferences.Union(scriptPackSession.References); ScriptResult scriptResult; SessionState<ScriptState> sessionState; var isFirstExecution = !scriptPackSession.State.ContainsKey(SessionKey); if (isFirstExecution) { var host = _scriptHostFactory.CreateScriptHost( new ScriptPackManager(scriptPackSession.Contexts), scriptArgs); ScriptLibraryWrapper.SetHost(host); _log.Debug("Creating session"); var hostType = host.GetType(); ScriptOptions = ScriptOptions.AddReferences(hostType.Assembly); var allNamespaces = namespaces.Union(scriptPackSession.Namespaces).Distinct(); foreach (var reference in executionReferences.Paths) { _log.DebugFormat("Adding reference to {0}", reference); ScriptOptions = ScriptOptions.AddReferences(reference); } foreach (var assembly in executionReferences.Assemblies) { _log.DebugFormat("Adding reference to {0}", assembly.FullName); ScriptOptions = ScriptOptions.AddReferences(assembly); } foreach (var @namespace in allNamespaces) { _log.DebugFormat("Importing namespace {0}", @namespace); ScriptOptions = ScriptOptions.AddNamespaces(@namespace); } sessionState = new SessionState<ScriptState> { References = executionReferences, Namespaces = new HashSet<string>(allNamespaces) }; scriptPackSession.State[SessionKey] = sessionState; scriptResult = Execute(code, host, sessionState); } else { _log.Debug("Reusing existing session"); sessionState = (SessionState<ScriptState>)scriptPackSession.State[SessionKey]; if (sessionState.References == null) { sessionState.References = new AssemblyReferences(); } if (sessionState.Namespaces == null) { sessionState.Namespaces = new HashSet<string>(); } var newReferences = executionReferences.Except(sessionState.References); foreach (var reference in newReferences.Paths) { _log.DebugFormat("Adding reference to {0}", reference); ScriptOptions = ScriptOptions.AddReferences(reference); sessionState.References = sessionState.References.Union(new[] { reference }); } foreach (var assembly in newReferences.Assemblies) { _log.DebugFormat("Adding reference to {0}", assembly.FullName); ScriptOptions = ScriptOptions.AddReferences(assembly); sessionState.References = sessionState.References.Union(new[] { assembly }); } var newNamespaces = namespaces.Except(sessionState.Namespaces); foreach (var @namespace in newNamespaces) { _log.DebugFormat("Importing namespace {0}", @namespace); ScriptOptions = ScriptOptions.AddNamespaces(@namespace); sessionState.Namespaces.Add(@namespace); } if (string.IsNullOrWhiteSpace(code)) { return ScriptResult.Empty; } scriptResult = Execute(code, sessionState.Session, sessionState); } return scriptResult; //todo handle namespace failures //https://github.com/dotnet/roslyn/issues/1012 }
public ScriptResult Execute(string code, string[] scriptArgs, AssemblyReferences references, IEnumerable<string> namespaces, ScriptPackSession scriptPackSession) { references.PathReferences.UnionWith(scriptPackSession.References); SessionState<Evaluator> sessionState; if (!scriptPackSession.State.ContainsKey(SessionKey)) { Logger.Debug("Creating session"); var context = new CompilerContext(new CompilerSettings { AssemblyReferences = references.PathReferences.ToList() }, new ConsoleReportPrinter()); var evaluator = new Evaluator(context); var builder = new StringBuilder(); foreach (var ns in namespaces.Union(scriptPackSession.Namespaces).Distinct()) { builder.AppendLine(string.Format("using {0};", ns)); } evaluator.Compile(builder.ToString()); var parser = new SyntaxParser(); var parseResult = parser.Parse(code); var host = _scriptHostFactory.CreateScriptHost(new ScriptPackManager(scriptPackSession.Contexts), scriptArgs); MonoHost.SetHost((ScriptHost)host); evaluator.ReferenceAssembly(typeof(MonoHost).Assembly); evaluator.InteractiveBaseClass = typeof(MonoHost); if (parseResult.Declarations != null) { evaluator.Compile(parseResult.Declarations); code = null; } if (parseResult.Evaluations != null) { code = parseResult.Evaluations; } sessionState = new SessionState<Evaluator> { References = references, Session = evaluator }; scriptPackSession.State[SessionKey] = sessionState; } else { Logger.Debug("Reusing existing session"); sessionState = (SessionState<Evaluator>)scriptPackSession.State[SessionKey]; var newReferences = sessionState.References == null ? references : references.Except(sessionState.References); foreach (var reference in newReferences.PathReferences) { Logger.DebugFormat("Adding reference to {0}", reference); sessionState.Session.LoadAssembly(reference); } sessionState.References = newReferences; var parser = new SyntaxParser(); var parseResult = parser.Parse(code); if (parseResult.Declarations != null) { var compiledMethod = sessionState.Session.Compile(parseResult.Declarations); return new ScriptResult(); //code = parseResult.Declarations; } //var newUsings = sessionState.References == null || !sessionState.References.Any() ? distinctReferences : distinctReferences.Except(sessionState.References); } Logger.Debug("Starting execution"); try { if (code != null) { object scriptResult; bool resultSet; var result = sessionState.Session.Evaluate(code, out scriptResult, out resultSet); Logger.Debug("Finished execution"); return new ScriptResult { ReturnValue = scriptResult }; } } catch (Exception e) { Logger.Error(e.Message); } return new ScriptResult(); }
public ScriptResult Execute(string code, string[] scriptArgs, AssemblyReferences references, IEnumerable<string> namespaces, ScriptPackSession scriptPackSession) { Guard.AgainstNullArgument("scriptPackSession", scriptPackSession); Guard.AgainstNullArgument("references", references); Logger.Debug("Starting to create execution components"); Logger.Debug("Creating script host"); var executionReferences = new AssemblyReferences(references.PathReferences, references.Assemblies); executionReferences.PathReferences.UnionWith(scriptPackSession.References); SessionState<Session> sessionState; if (!scriptPackSession.State.ContainsKey(SessionKey)) { var host = _scriptHostFactory.CreateScriptHost(new ScriptPackManager(scriptPackSession.Contexts), scriptArgs); Logger.Debug("Creating session"); var hostType = host.GetType(); ScriptEngine.AddReference(hostType.Assembly); var session = ScriptEngine.CreateSession(host, hostType); var allNamespaces = namespaces.Union(scriptPackSession.Namespaces).Distinct(); foreach (var reference in executionReferences.PathReferences) { Logger.DebugFormat("Adding reference to {0}", reference); session.AddReference(reference); } foreach (var assembly in executionReferences.Assemblies) { Logger.DebugFormat("Adding reference to {0}", assembly.FullName); session.AddReference(assembly); } foreach (var @namespace in allNamespaces) { Logger.DebugFormat("Importing namespace {0}", @namespace); session.ImportNamespace(@namespace); } sessionState = new SessionState<Session> { References = executionReferences, Session = session, Namespaces = new HashSet<string>(allNamespaces) }; scriptPackSession.State[SessionKey] = sessionState; } else { Logger.Debug("Reusing existing session"); sessionState = (SessionState<Session>)scriptPackSession.State[SessionKey]; if (sessionState.References == null) { sessionState.References = new AssemblyReferences(); } if (sessionState.Namespaces == null) { sessionState.Namespaces = new HashSet<string>(); } var newReferences = executionReferences.Except(sessionState.References); foreach (var reference in newReferences.PathReferences) { Logger.DebugFormat("Adding reference to {0}", reference); sessionState.Session.AddReference(reference); sessionState.References.PathReferences.Add(reference); } foreach (var assembly in newReferences.Assemblies) { Logger.DebugFormat("Adding reference to {0}", assembly.FullName); sessionState.Session.AddReference(assembly); sessionState.References.Assemblies.Add(assembly); } var newNamespaces = namespaces.Except(sessionState.Namespaces); foreach (var @namespace in newNamespaces) { Logger.DebugFormat("Importing namespace {0}", @namespace); sessionState.Session.ImportNamespace(@namespace); sessionState.Namespaces.Add(@namespace); } } Logger.Debug("Starting execution"); var result = Execute(code, sessionState.Session); Logger.Debug("Finished execution"); return result; }
public ScriptResult Execute(string code, string[] scriptArgs, AssemblyReferences references, IEnumerable<string> namespaces, ScriptPackSession scriptPackSession) { Guard.AgainstNullArgument("scriptPackSession", scriptPackSession); Guard.AgainstNullArgument("references", references); Logger.Debug("Starting to create execution components"); Logger.Debug("Creating script host"); var executionReferences = new AssemblyReferences(references.PathReferences, references.Assemblies); executionReferences.PathReferences.UnionWith(scriptPackSession.References); SessionState<Session> sessionState; var isFirstExecution = !scriptPackSession.State.ContainsKey(SessionKey); if (isFirstExecution) { code = code.DefineTrace(); var host = _scriptHostFactory.CreateScriptHost(new ScriptPackManager(scriptPackSession.Contexts), scriptArgs); Logger.Debug("Creating session"); var hostType = host.GetType(); ScriptEngine.AddReference(hostType.Assembly); var session = ScriptEngine.CreateSession(host, hostType); var allNamespaces = namespaces.Union(scriptPackSession.Namespaces).Distinct(); foreach (var reference in executionReferences.PathReferences) { Logger.DebugFormat("Adding reference to {0}", reference); session.AddReference(reference); } foreach (var assembly in executionReferences.Assemblies) { Logger.DebugFormat("Adding reference to {0}", assembly.FullName); session.AddReference(assembly); } foreach (var @namespace in allNamespaces) { Logger.DebugFormat("Importing namespace {0}", @namespace); session.ImportNamespace(@namespace); } sessionState = new SessionState<Session> { References = executionReferences, Session = session, Namespaces = new HashSet<string>(allNamespaces) }; scriptPackSession.State[SessionKey] = sessionState; } else { Logger.Debug("Reusing existing session"); sessionState = (SessionState<Session>)scriptPackSession.State[SessionKey]; if (sessionState.References == null) { sessionState.References = new AssemblyReferences(); } if (sessionState.Namespaces == null) { sessionState.Namespaces = new HashSet<string>(); } var newReferences = executionReferences.Except(sessionState.References); foreach (var reference in newReferences.PathReferences) { Logger.DebugFormat("Adding reference to {0}", reference); sessionState.Session.AddReference(reference); sessionState.References.PathReferences.Add(reference); } foreach (var assembly in newReferences.Assemblies) { Logger.DebugFormat("Adding reference to {0}", assembly.FullName); sessionState.Session.AddReference(assembly); sessionState.References.Assemblies.Add(assembly); } var newNamespaces = namespaces.Except(sessionState.Namespaces); foreach (var @namespace in newNamespaces) { Logger.DebugFormat("Importing namespace {0}", @namespace); sessionState.Session.ImportNamespace(@namespace); sessionState.Namespaces.Add(@namespace); } } Logger.Debug("Starting execution"); var result = Execute(code, sessionState.Session); if (result.InvalidNamespaces.Any()) { var pendingNamespacesField = sessionState.Session.GetType().GetField("pendingNamespaces", System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic); if (pendingNamespacesField != null) { var pendingNamespacesValue = (ReadOnlyArray<string>)pendingNamespacesField.GetValue(sessionState.Session); //no need to check this for null as ReadOnlyArray is a value type if (pendingNamespacesValue.Any()) { var fixedNamespaces = pendingNamespacesValue.ToList(); foreach (var @namespace in result.InvalidNamespaces) { sessionState.Namespaces.Remove(@namespace); fixedNamespaces.Remove(@namespace); } pendingNamespacesField.SetValue(sessionState.Session, ReadOnlyArray<string>.CreateFrom<string>(fixedNamespaces)); } } } Logger.Debug("Finished execution"); return result; }