예제 #1
0
        /// <summary>
        /// Compiles the program and save it on the hard drive or returns the build errors.
        /// </summary>
        /// <param name="outputType">Defines the type of assembly to generate.</param>
        /// <param name="outputPath">The full path to the .exe or .dll file to create if the build succeed.</param>
        /// <param name="assemblyName">(optional) Defines the name of the assembly to generate.</param>
        /// <param name="assemblyVersion">(optional) Defines the version of the assembly.</param>
        /// <param name="assemblyCopyright">(optional) Defines the copyright of the assembly.</param>
        /// <param name="releaseMode">(optional) Defines whether the compiler must build in release mode or debug mode.</param>
        /// <returns>Returns the build errors, or null if it succeed.</returns>
        public async Task <AggregateException> Build(BaZicCompilerOutputType outputType, string outputPath, string assemblyName = "", string assemblyVersion = "", string assemblyCopyright = "", bool releaseMode = false)
        {
            var callback = new MarshaledResultSetter <AggregateException>();

            _core.Build(callback, outputType, outputPath, assemblyName, assemblyVersion, assemblyCopyright, releaseMode);
            return(await callback.Task);
        }
예제 #2
0
        /// <summary>
        /// Compiles the program in memory and returns either the generated assembly or the errors.
        /// </summary>
        /// <param name="outputType">Defines the type of assembly to generate</param>
        /// <param name="assemblyName">Defines the name of the assembly to generate.</param>
        /// <param name="assemblyVersion">Defines the version of the assembly.</param>
        /// <param name="assemblyCopyright">Defines the copyright of the assembly.</param>
        /// <param name="releaseMode">Defines whether the compiler must build in release mode or debug mode.</param>
        /// <returns>Returns a <seealso cref="CompilerResult"/>.</returns>
        private CompilerResult Build(BaZicCompilerOutputType outputType, string assemblyName, string assemblyVersion, string assemblyCopyright, bool releaseMode)
        {
            LoadAssemblies();

            if (_releaseModeRuntime == null)
            {
                _releaseModeRuntime = new CompiledProgramRunner(this, Program, _assemblySandbox);
            }

            return(_releaseModeRuntime.Build(outputType, assemblyName, assemblyVersion, assemblyCopyright, releaseMode));
        }
예제 #3
0
        /// <summary>
        /// Compiles the program in memory and save it on the hard drive or returns the build errors.
        /// </summary>
        /// <param name="callback">The cross-AppDomain task proxy.</param>
        /// <param name="outputType">Defines the type of assembly to generate</param>
        /// <param name="outputPath">The full path to the .exe or .dll file to create if the build succeed.</param>
        /// <param name="assemblyName">Defines the name of the assembly to generate.</param>
        /// <param name="assemblyVersion">Defines the version of the assembly.</param>
        /// <param name="assemblyCopyright">Defines the copyright of the assembly.</param>
        /// <param name="releaseMode">Defines whether the compiler must build in release mode or debug mode.</param>
        /// <returns>Returns the build errors, or null if it succeed.</returns>
        internal void Build(MarshaledResultSetter <AggregateException> callback, BaZicCompilerOutputType outputType, string outputPath, string assemblyName, string assemblyVersion, string assemblyCopyright, bool releaseMode)
        {
            Requires.NotNull(_middleware, nameof(_middleware));
            Requires.NotNullOrWhiteSpace(outputPath, nameof(outputPath));

            if (DebugMode)
            {
                throw new UnexpectedException(new Exception(L.BaZic.Runtime.BaZicInterpreter.CannotBuildAfterStartDebug));
            }
            CheckState(BaZicInterpreterState.Ready, BaZicInterpreterState.Stopped, BaZicInterpreterState.StoppedWithError);

            if (ProgramIsOptimized)
            {
                throw new InvalidOperationException(L.BaZic.Runtime.BaZicInterpreter.CannotRunOptimizedProgramInRelease);
            }

            Error = null;
            ChangeState(this, new BaZicInterpreterStateChangeEventArgs(BaZicInterpreterState.Running));

            AggregateException buildErrors = null;
            var currentCulture             = LocalizationHelper.GetCurrentCulture();

            _mainInterpreterTask = Task.Run(() =>
            {
                LocalizationHelper.SetCurrentCulture(currentCulture, false, false);

                var outputFile = new FileInfo(outputPath);
                var directory  = outputFile.Directory;

                if (string.IsNullOrWhiteSpace(outputFile.Extension))
                {
                    if (outputType == BaZicCompilerOutputType.DynamicallyLinkedLibrary)
                    {
                        outputFile = new FileInfo(outputPath + ".dll");
                    }
                    else
                    {
                        outputFile = new FileInfo(outputPath + ".exe");
                    }
                }

                var outputFileName = Path.GetFileNameWithoutExtension(outputPath);
                var outputPdbFile  = new FileInfo(Path.Combine(directory.FullName, outputFileName + ".pdb"));

                using (var compileResult = Build(outputType, assemblyName, assemblyVersion, assemblyCopyright, releaseMode))
                {
                    if (compileResult.BuildErrors != null)
                    {
                        buildErrors = compileResult.BuildErrors;
                        ChangeState(this, new UnexpectedException(buildErrors));
                        return;
                    }

                    try
                    {
                        if (!directory.Exists)
                        {
                            directory.Create();
                        }

                        var assembliesToCopy = _assemblySandbox.GetAssemblies().Where(a => a.CopyToLocal).Concat(Program.Assemblies.Where(a => a.CopyToLocal)).Distinct();
                        foreach (var assembly in assembliesToCopy)
                        {
                            if (File.Exists(assembly.Location))
                            {
                                File.Copy(assembly.Location, Path.Combine(directory.FullName, Path.GetFileName(assembly.Location)));

                                var pdbFilePath = Path.Combine(Directory.GetParent(assembly.Location).FullName, Path.GetFileNameWithoutExtension(assembly.Location) + ".pdb");
                                var xmlFilePath = Path.Combine(Directory.GetParent(assembly.Location).FullName, Path.GetFileNameWithoutExtension(assembly.Location) + ".xml");

                                if (File.Exists(pdbFilePath))
                                {
                                    File.Copy(pdbFilePath, Path.Combine(directory.FullName, Path.GetFileName(pdbFilePath)));
                                }

                                if (File.Exists(xmlFilePath))
                                {
                                    File.Copy(xmlFilePath, Path.Combine(directory.FullName, Path.GetFileName(xmlFilePath)));
                                }
                            }
                        }

                        using (var assemblyFileStream = new FileStream(outputFile.FullName, FileMode.Create))
                            using (var pdbFileStream = new FileStream(outputPdbFile.FullName, FileMode.Create))
                            {
                                compileResult.Assembly.WriteTo(assemblyFileStream);
                                compileResult.Pdb.WriteTo(pdbFileStream);
                            }

                        ChangeState(this, new BaZicInterpreterStateChangeEventArgs(BaZicInterpreterState.Stopped));
                    }
                    catch (Exception exception)
                    {
                        CoreHelper.ReportException(exception);
                        buildErrors = new AggregateException(new List <Exception> {
                            exception
                        });
                        ChangeState(this, new UnexpectedException(exception));
                    }
                }
            });
            _mainInterpreterTask.ContinueWith((task) =>
            {
                callback.SetResult(buildErrors);
            });
        }
예제 #4
0
        /// <summary>
        /// Convert the BaZic program to CSharp code and build it in memory.
        /// </summary>
        /// <param name="outputType">The type of assembly to generate</param>
        /// <param name="assemblyName">Defines the name of the assembly to generate.</param>
        /// <param name="assemblyVersion">Defines the version of the assembly.</param>
        /// <param name="assemblyCopyright">Defines the copyright of the assembly.</param>
        /// <param name="releaseMode">Defines whether the compiler must build in release mode or debug mode.</param>
        /// <returns>Returns the result of the build.</returns>
        internal CompilerResult Build(BaZicCompilerOutputType outputType, string assemblyName, string assemblyVersion, string assemblyCopyright, bool releaseMode)
        {
            if (_baZicInterpreter.Verbose)
            {
                _baZicInterpreter.ChangeState(this, new BaZicInterpreterStateChangeEventArgs(L.BaZic.Runtime.CompiledProgramRunner.GenerationCSharp));
            }

            if (string.IsNullOrWhiteSpace(assemblyName))
            {
                assemblyName = _program.Id.ToString();
            }

            var codeGen    = new CSharpCodeGenerator();
            var csharpCode = codeGen.Generate(_program, assemblyName, assemblyVersion, assemblyCopyright);
            var syntaxTree = CSharpSyntaxTree.ParseText(csharpCode);

            if (_baZicInterpreter.Verbose)
            {
                _baZicInterpreter.ChangeState(this, new BaZicInterpreterStateChangeEventArgs(L.BaZic.Runtime.CompiledProgramRunner.Compiling));
            }

            var outputKind = OutputKind.ConsoleApplication;

            if (outputType == BaZicCompilerOutputType.WindowsApp)
            {
                outputKind = OutputKind.WindowsApplication;
            }
            else if (outputType == BaZicCompilerOutputType.DynamicallyLinkedLibrary)
            {
                outputKind = OutputKind.DynamicallyLinkedLibrary;
            }

            var references = GetAssemblyReferences();
            var options    = new CSharpCompilationOptions(outputKind)
                             .WithAllowUnsafe(true)
                             .WithOptimizationLevel(releaseMode? OptimizationLevel.Release : OptimizationLevel.Debug)
                             .WithPlatform(Platform.AnyCpu);

            var cSharpCompilation = CSharpCompilation.Create(assemblyName, new[] { syntaxTree }, references, options);

            var assemblyStream = new MemoryStream();
            var pdbStream      = new MemoryStream();

            var resources = new List <ResourceDescription>();

            if (_program is BaZicUiProgram uiProgram)
            {
                foreach (var resourceFile in uiProgram.ResourceFilePaths)
                {
                    if (!File.Exists(resourceFile))
                    {
                        return(new CompilerResult
                        {
                            BuildErrors = new AggregateException(new FileNotFoundException("The resource file does not exist", resourceFile))
                        });
                    }

                    resources.Add(new ResourceDescription(Path.GetFileName(resourceFile), () => File.OpenRead(resourceFile), true));
                }
            }

            var result = cSharpCompilation.Emit(peStream: assemblyStream, pdbStream: pdbStream, manifestResources: resources);
            var errors = GetCompilationErrors(result);

            if (errors != null)
            {
                return(new CompilerResult
                {
                    BuildErrors = errors
                });
            }

            assemblyStream.Seek(0, SeekOrigin.Begin);
            pdbStream.Seek(0, SeekOrigin.Begin);

            if (_baZicInterpreter.Verbose)
            {
                _baZicInterpreter.ChangeState(this, new BaZicInterpreterStateChangeEventArgs(L.BaZic.Runtime.CompiledProgramRunner.BuiltSucceed));
            }

            return(new CompilerResult
            {
                Assembly = assemblyStream,
                Pdb = pdbStream
            });
        }