Exemple #1
0
 public void PublishError(PluginLib.CompileError error)
 {
     IDEView.inst().Dispatcher.Invoke(delegate()
     {
         CompileErrors.Add(error);
     });
 }
        private void HandleAddingDynamicallyCompiledPlugin(AggregateCatalog returnValue, string plugin, CompilerResults compileResult)
        {
            if (compileResult.Errors != null && compileResult.Errors.HasErrors)
            {
                var errors   = new StringBuilder();
                var filename = Path.GetFileName(plugin);
                foreach (CompilerError err in compileResult.Errors)
                {
                    errors.Append(string.Format("\r\n{0}({1},{2}): {3}: {4}",
                                                filename, err.Line, err.Column,
                                                err.ErrorNumber, err.ErrorText));
                }
                CompileErrors.Add("Error loading script " + plugin + "\r\n" + errors.ToString());
            }
            else
            {
                var newCatalog = new AssemblyCatalog(compileResult.CompiledAssembly);


                returnValue.Catalogs.Add(newCatalog);

                //foreach (string assm in mReferenceListExternal)
                //{
                //    Assembly ass = Assembly.LoadFrom(assm);
                //    var assemblies = AppDomain.CurrentDomain.GetAssemblies().Where(a => !a.IsDynamic).Select(a => a.Location);

                //    returnValue.Catalogs.Add(newCatalog);
                //}
            }
        }
Exemple #3
0
 public void PublishWarning(PluginLib.CompileError error)
 {
     IDEView.inst().Dispatcher.Invoke(delegate()
     {
         CompileErrors.Add(error);
         OnPropertyChanged("CompileErrorCt");
         OnPropertyChanged("CompileWarningCt");
     });
 }
        private void AddPluginsFromDirectory(List <string> pluginsToIgnore, AggregateCatalog returnValue, string plugin)
        {
            try
            {
                bool shouldProcessPlugin = true;
                // GlueView is a special case, so we should skip that
                string pluginToLower = plugin.ToLower().Replace("\\", "/");
                if (pluginToLower.EndsWith("/glueview") || pluginToLower.EndsWith("/glueview/"))
                {
                    shouldProcessPlugin = false;
                }

                if (shouldProcessPlugin)
                {
                    var compileResult = CompilePlugin(plugin);

                    // We had a && false here, so I don't think we use this ignored check, do we?
                    bool isIgnored = pluginsToIgnore != null && pluginsToIgnore.Any(item =>
                                                                                    FileManager.Standardize(item.ToLowerInvariant()) == FileManager.Standardize(plugin.ToLowerInvariant()));

                    if (!isIgnored)
                    {
                        bool wasCompiledFromCSharpCode = compileResult != null;

                        if (wasCompiledFromCSharpCode)
                        {
                            HandleAddingDynamicallyCompiledPlugin(returnValue, plugin, compileResult);
                        }

                        // If nothing was compiled check for any dlls to load
                        else
                        {
                            HandleAddingPreCompiledPluginInDirectory(returnValue, plugin);
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                CompileErrors.Add("Error loading plugin at " + plugin + "\r\n\r\n" + ex);
            }
        }
        private void HandleAddingPreCompiledPluginInDirectory(AggregateCatalog returnValue, string pluginDirectory)
        {
            List <Assembly> assemblies = new List <Assembly>();

            var assembliesFiles = Directory.GetFiles(pluginDirectory, "*.dll");

            foreach (string assemblyName in assembliesFiles)
            {
                try
                {
                    if (IsAssemblyAlreadyReferenced(assemblyName))
                    {
                        string message = $"Warning: {pluginDirectory} - Skipping over assembly {assemblyName} because it is already loaded by a different plugin";

                        CompileOutput.Add(message);
                    }
                    else
                    {
                        var asm = Assembly.LoadFrom(assemblyName);

                        assemblies.Add(asm);
                    }
                }
                catch (Exception ex)
                {
                    CompileErrors.Add(string.Format("Failed to load {0}: {1}", assemblyName, ex.Message));
                }
            }

            AggregateCatalog catalogToMakeSureStuffIsLinked = new AggregateCatalog();

            foreach (var assembly in assemblies)
            {
                var catalog = new AssemblyCatalog(assembly);
                catalogToMakeSureStuffIsLinked.Catalogs.Add(catalog);
            }

            bool failed = false;

            try
            {
                var container = new CompositionContainer(catalogToMakeSureStuffIsLinked);
                container.GetExports <object>();
            }
            catch (Exception e)
            {
                string message = "";
                message += "Error trying to load plugins from directory:     " + pluginDirectory;

                if (e is ReflectionTypeLoadException)
                {
                    foreach (var innerException in (e as ReflectionTypeLoadException).LoaderExceptions)
                    {
                        message += "\r\n" + innerException.ToString();
                    }
                }
                else
                {
                    message += "\r\n" + e.ToString();
                }
                CompileErrors.Add(message);

                failed = true;
            }

            if (!failed)
            {
                foreach (var assemblyCatalog in catalogToMakeSureStuffIsLinked.Catalogs)
                {
                    returnValue.Catalogs.Add(assemblyCatalog);
                }
            }
        }
Exemple #6
0
        public Assembly GetAssembly()
        {
            ImplementInterface();
            CreateConstructor();

            string _source = "//------------------------------------------------------------------------------" + Environment.NewLine +
                             "// <auto-generated>" + Environment.NewLine +
                             "//     Dynamically created source code. Provisionally created as C# syntax, " + Environment.NewLine +
                             "//     because CodeDom is not supported under .NET Core. " + Environment.NewLine +
                             "// </auto-generated>" + Environment.NewLine +
                             "//------------------------------------------------------------------------------" + Environment.NewLine;

            _source += "namespace " + CodeNameSpace + Environment.NewLine;
            _source += "{" + Environment.NewLine;
            _source += "    using System;" + Environment.NewLine;
            _source += "    using Stateless;" + Environment.NewLine;
            _source += "    using Stateless.Graph;" + Environment.NewLine;
            _source += "    using LogFSMShared;" + Environment.NewLine;
            _source += "    using System.Linq;" + Environment.NewLine;

            //_source += "    using System.ComponentModel.Primitives;" + Environment.NewLine;
            _source += "    using System.IO;" + Environment.NewLine;
            _source += "    using System.Collections;" + Environment.NewLine;
            _source += "    using System.Collections.Generic;" + Environment.NewLine;

            _source += "    public class " + ClassName + ": LogFSMShared.LogFSMBase, LogFSMShared.ILogFSM " + Environment.NewLine;
            _source += "    {" + Environment.NewLine;
            _source += "        private Dictionary<int,Stateless.StateMachine<State,Trigger>> machines;" + Environment.NewLine;

            _source += constructorCodeFragment;

            _source += createProcessEventMethodCodeFragment;

            _source += createRulesFunctionCodeFragment;

            _source += createTriggerFunctionCodeFragment;

            _source += enumDefinitionCodeFragment;

            _source += triggerDefinitionCodeFragment;

            _source += "     } " + Environment.NewLine;
            _source += " } " + Environment.NewLine;

            // export generated cs code for inspection
            if (parsedCommandLineArguments.Flags.Contains("EXPORT_GENERATED_SOURCE") || parsedCommandLineArguments.IsDebug)
            {
                using (StreamWriter sourceWriter = new StreamWriter(sourceFileName))
                {
                    sourceWriter.Write(_source);
                }
            }

            Assembly createdAssembly = null;

            var options = new CSharpCompilationOptions(
                OutputKind.DynamicallyLinkedLibrary,
                optimizationLevel: OptimizationLevel.Release,
                allowUnsafe: false);

            var compilation = CSharpCompilation.Create(Path.GetRandomFileName(), options: options);

            SyntaxTree syntaxTree = CSharpSyntaxTree.ParseText(_source);

            compilation = compilation.AddSyntaxTrees(syntaxTree);

            // TODO: Optimize!

            #region Add Rferences

            var assemblyPath = Path.GetDirectoryName(typeof(object).Assembly.Location);
            List <MetadataReference> references = new List <MetadataReference>();

            references.Add(MetadataReference.CreateFromFile(Path.Combine(assemblyPath, "System.Private.CoreLib.dll")));
            references.Add(MetadataReference.CreateFromFile(Path.Combine(assemblyPath, "System.Console.dll")));
            references.Add(MetadataReference.CreateFromFile(Path.Combine(assemblyPath, "System.Runtime.dll")));

            var usings = compilation.SyntaxTrees.Select(tree => tree.GetRoot().DescendantNodes().OfType <UsingDirectiveSyntax>()).SelectMany(s => s).ToArray();

            foreach (var u in usings)
            {
                if (File.Exists(Path.Combine(assemblyPath, u.Name.ToString() + ".dll")))
                {
                    references.Add(MetadataReference.CreateFromFile(Path.Combine(assemblyPath, u.Name.ToString() + ".dll")));
                }
            }

            references.Add(MetadataReference.CreateFromFile(Path.Combine(parsedCommandLineArguments.RuntimePath, "Stateless.dll")));
            references.Add(MetadataReference.CreateFromFile(Assembly.Load("netstandard, Version=2.0.0.0").Location));
            references.Add(MetadataReference.CreateFromFile(Path.Combine(parsedCommandLineArguments.RuntimePath, "LogFSMShared.dll")));

            #endregion

            compilation = compilation.AddReferences(references);

            //compile

            using (var ms = new MemoryStream())
            {
                EmitResult result = compilation.Emit(ms);

                if (!result.Success)
                {
                    IEnumerable <Diagnostic> failures = result.Diagnostics.Where(diagnostic =>
                                                                                 diagnostic.IsWarningAsError ||
                                                                                 diagnostic.Severity == DiagnosticSeverity.Error);

                    foreach (Diagnostic diagnostic in failures)
                    {
                        CompileErrors.Add(diagnostic.Id + ";" + diagnostic.GetMessage() + ";" + diagnostic.Location);
                    }
                }
                else
                {
                    ms.Seek(0, SeekOrigin.Begin);
                    AssemblyLoadContext context = AssemblyLoadContext.Default;
                    createdAssembly = context.LoadFromStream(ms);
                }
            }

            if (HasErrors)
            {
                foreach (string l in CompileErrors)
                {
                    File.AppendAllText(Path.Combine(parsedCommandLineArguments.OutputPath, "logfsmlasterror.txt"), l);
                }
            }

            return(createdAssembly);
        }