/// <param name="cfg">IModeCSharp configuration</param>
        /// <param name="msbuild">Flag of supporting MSBuild properties.</param>
        /// <returns>Prepared list of references</returns>
        protected string[] constructReferences(IModeCSharp cfg, bool msbuild)
        {
            if (cfg.References == null)
            {
                return(new string[] { });
            }

            if (!cfg.SmartReferences)
            {
                return(cfg.References
                       .Where(r => !String.IsNullOrEmpty(r))
                       .Select(r => (msbuild)? cmd.MSBuild.parse(r) : r)
                       .ToArray());
            }

            GAC gac = new GAC();

            return(cfg.References
                   .Where(r => !String.IsNullOrEmpty(r))
                   .Select(r =>
                           gac.getPathToAssembly(
                               (msbuild)? cmd.MSBuild.parse(r) : r,
                               true
                               )
                           )
                   .ToArray());
        }
        /// <summary>
        /// Only compiling user code.
        /// Use the safe compileAndGetType for work with the end-type.
        /// </summary>
        /// <param name="evt">Configured event.</param>
        /// <returns>Compiled user code.</returns>
        protected CompilerResults onlyCompile(ISolutionEvent evt)
        {
            Log.Trace("[Compiler] start new compilation.");

            IModeCSharp cfg     = (IModeCSharp)evt.Mode;
            string      command = cfg.Command;

            if (String.IsNullOrWhiteSpace(command))
            {
                throw new InvalidArgumentException("[Compiler] code is not found. abort;");
            }
            command = parse(evt, command);

            string output = outputCacheFile(evt);

            Log.Debug("[Compiler] output: '{0}' /GenerateInMemory: {1}", output, cfg.GenerateInMemory);

            if (File.Exists(output))
            {
                Log.Trace("[Compiler] clear cache.");
                File.Delete(output);
            }

            CompilerParameters parameters = new CompilerParameters()
            {
                GenerateExecutable    = false,
                GenerateInMemory      = cfg.GenerateInMemory,
                CompilerOptions       = cfg.CompilerOptions,
                TreatWarningsAsErrors = cfg.TreatWarningsAsErrors,
                WarningLevel          = cfg.WarningLevel,

                // use prefix from fileName() to avoid random names if used GenerateInMemory
                OutputAssembly = (!cfg.GenerateInMemory)? output : Path.Combine(Path.GetTempPath(), fileName(evt))
            };

            // Assembly references

            string[] references = constructReferences(cfg, evt.SupportMSBuild);
            Log.Trace("[Compiler] final references: '{0}'", String.Join("; ", references));

            parameters.ReferencedAssemblies.AddRange(references);
            parameters.ReferencedAssemblies.Add(typeof(ISolutionEvent).Assembly.Location); // to support ICommand & ISolutionEvent
            parameters.ReferencedAssemblies.Add(typeof(Bridge.IEvent).Assembly.Location);  // to support Bridge

            // ready to work with provider
            CompilerResults compiled = toBinary(command, parameters, cfg);

            // messages about errors & warnings
            foreach (CompilerError msg in compiled.Errors)
            {
                Log._.NLog.Log((msg.IsWarning)? LogLevel.Warn : LogLevel.Error, "[Compiler] '{0}'", msg.ToString());
            }

            if (compiled.Errors.HasErrors)
            {
                throw new CompilerException("[Compiler] found errors. abort;");
            }

            return(compiled);
        }
        /// <summary>
        /// Recalculate hash for IModeCSharp mode and save in user settings.
        /// </summary>
        /// <param name="mode"></param>
        protected void updateHash(IModeCSharp mode)
        {
            if (mode.CacheData == null)
            {
                mode.CacheData = new UserValue(LinkType.CacheHeader);
            }

            // calculate hash only for objects below

            object[] toHash = new object[]
            {
                mode.Command,
                mode.References,
                mode.OutputPath,
                mode.CompilerOptions,
                mode.TreatWarningsAsErrors,
                mode.WarningLevel,
                mode.FilesMode
            };

            mode.CacheData.Manager.CacheHeader.Hash      = toHash.MD5Hash();
            mode.CacheData.Manager.CacheHeader.Algorithm = HashType.MD5;
            mode.CacheData.Manager.CacheHeader.Updated   = DateTime.Now.ToFileTimeUtc();
            Settings.CfgManager.UserConfig.save();
        }
        /// <summary>
        /// Checks requirement of compiling source code.
        /// </summary>
        /// <param name="evt">Configured event.</param>
        /// <returns>true value if needed compilation, otherwise we can use compiled version from cache.</returns>
        protected bool isRequiresCompilation(ISolutionEvent evt)
        {
            IModeCSharp cfg   = ((IModeCSharp)evt.Mode);
            string      cache = fileName(evt);

            Log.Trace("[Cache] Checks: '{0}','{1}','{2}','{3}'", cfg.GenerateInMemory, cfg.CachingBytecode, evt.Name, cache);
            if (cfg.GenerateInMemory || !cfg.CachingBytecode || String.IsNullOrEmpty(cache))
            {
                return(true);
            }

            if (cfg.CacheData == null)
            {
                Log.Trace("[Cache] hash data is empty.");
                return(true);
            }

            FileInfo f = new FileInfo(outputCacheFile(evt));

            if (!f.Exists)
            {
                Log.Info("[Cache] Binary '{0}' is not found in '{1}'. Compile new.", cache, f.FullName);
                return(true);
            }

            string actual = cfg.CacheData.Manager.CacheHeader.Hash;

            if (!hashEquals(f.FullName, actual))
            {
                Log.Info("[Cache] hash code '{0}' is invalid. Compile new.", actual);
                return(true);
            }

            return(false);
        }
Esempio n. 5
0
 /// <summary>
 /// To reset cache data.
 /// </summary>
 /// <param name="mode"></param>
 public void cacheReset(IMode mode)
 {
     if (mode.Type == ModeType.CSharp)
     {
         IModeCSharp cfg = (IModeCSharp)mode;
         if (cfg.CacheData != null)
         {
             cfg.CacheData.Manager.reset();
         }
     }
 }
        private string outputCacheFile(ISolutionEvent evt)
        {
            IModeCSharp cfg = (IModeCSharp)evt.Mode;

            string path = (cfg.OutputPath) ?? String.Empty;

            if (evt.SupportMSBuild)
            {
                path = cmd.MSBuild.parse(path);
            }

            return(Path.Combine(BasePathToCache, path, fileName(evt)));
        }
Esempio n. 7
0
        /// <summary>
        /// Prepare data to removing from cache.
        /// </summary>
        /// <param name="mode">Data from used mode.</param>
        public void cacheToRemove(IMode mode)
        {
            if (mode.Type == ModeType.CSharp)
            {
                IModeCSharp cfg = (IModeCSharp)mode;
                if (cfg.CacheData == null)
                {
                    return;
                }

                Settings.CfgUser.toRemoveFromCache(cfg.CacheData);
                cacheUnlink(mode);
            }
        }
        /// <summary>
        /// Compiling user code with getting the result type for next step.
        /// </summary>
        /// <param name="evt">Configured event.</param>
        /// <returns>The Type for work with user code.</returns>
        protected Type compileAndGetType(ISolutionEvent evt)
        {
            IModeCSharp cfg = (IModeCSharp)evt.Mode;

            if (!cfg.GenerateInMemory)
            {
                CompilerResults compiled = onlyCompile(evt);
                return(load(compiled.PathToAssembly, null));
            }
            Log.Trace("Uses memory for getting type.");

            // be careful, this should automatically load assembly with blocking file if not used GenerateInMemory
            // therefore, use this only with GenerateInMemory == true
            return(onlyCompile(evt).CompiledAssembly.GetType(MAIN_CLASS));
        }
        /// <summary>
        /// How to store hash value in assembly.
        /// </summary>
        /// <param name="cfg">IModeCSharp configuration.</param>
        /// <returns>Formatted hash value for assembly.</returns>
        protected virtual string formatHashForAsm(IModeCSharp cfg)
        {
            if (!cfg.CachingBytecode)
            {
                return(String.Empty);
            }

            if (cfg.CacheData == null || String.IsNullOrEmpty(cfg.CacheData.Manager.CacheHeader.Hash))
            {
                updateHash(cfg);
            }

            string hash = cfg.CacheData.Manager.CacheHeader.Hash;

            if (String.IsNullOrEmpty(hash))
            {
                return(String.Empty);
            }
            return(String.Format("[assembly: System.Reflection.AssemblyProduct(\"{0}\")]", hash));
        }
Esempio n. 10
0
        /// <summary>
        /// Final step to generate binary.
        /// </summary>
        /// <param name="source">Source code or list of files.</param>
        /// <param name="parameters">Compiler settings.</param>
        /// <param name="cfg">Settings of IModeCSharp.</param>
        /// <returns></returns>
        protected CompilerResults toBinary(string source, CompilerParameters parameters, IModeCSharp cfg)
        {
            string             hash     = formatHashForAsm(cfg);
            CSharpCodeProvider provider = new CSharpCodeProvider();

            if (!cfg.FilesMode)
            {
                return(provider.CompileAssemblyFromSource(parameters, source, hash));
            }

            Log.Trace("[Compiler] use as list of files with source code.");
            if (String.IsNullOrEmpty(hash))
            {
                return(provider.CompileAssemblyFromFile(parameters, filesFromCommand(source).ExtractFiles()));
            }

            using (TempAssemblyInfo f = new TempAssemblyInfo(hash)) {
                return(provider.CompileAssemblyFromFile(parameters, filesFromCommand(String.Format("{0}\n{1}", source, f.FullPath)).ExtractFiles()));
            }
        }
Esempio n. 11
0
        /// <summary>
        /// Recalculate hash for IModeCSharp mode and save in user settings.
        /// </summary>
        /// <param name="mode"></param>
        protected void updateHash(IModeCSharp mode)
        {
            if(mode.CacheData == null) {
                mode.CacheData = new UserValue(LinkType.CacheHeader);
            }

            // calculate hash only for objects below

            object[] toHash = new object[]
            {
                mode.Command,
                mode.References,
                mode.OutputPath,
                mode.CompilerOptions,
                mode.TreatWarningsAsErrors,
                mode.WarningLevel,
                mode.FilesMode
            };

            mode.CacheData.Manager.CacheHeader.Hash         = toHash.MD5Hash();
            mode.CacheData.Manager.CacheHeader.Algorithm    = HashType.MD5;
            mode.CacheData.Manager.CacheHeader.Updated      = DateTime.Now.ToFileTimeUtc();
            Settings.CfgManager.UserConfig.save();
        }
Esempio n. 12
0
        /// <summary>
        /// Final step to generate binary.
        /// </summary>
        /// <param name="source">Source code or list of files.</param>
        /// <param name="parameters">Compiler settings.</param>
        /// <param name="cfg">Settings of IModeCSharp.</param>
        /// <returns></returns>
        protected CompilerResults toBinary(string source, CompilerParameters parameters, IModeCSharp cfg)
        {
            string hash = formatHashForAsm(cfg);
            CSharpCodeProvider provider = new CSharpCodeProvider();

            if(!cfg.FilesMode) {
                return provider.CompileAssemblyFromSource(parameters, source, hash);
            }

            Log.Trace("[Compiler] use as list of files with source code.");
            if(String.IsNullOrEmpty(hash)) {
                return provider.CompileAssemblyFromFile(parameters, extractFiles(filesFromCommand(source)));
            }

            using(TempAssemblyInfo f = new TempAssemblyInfo(hash)) {
                return provider.CompileAssemblyFromFile(parameters, extractFiles(filesFromCommand(String.Format("{0}\n{1}", source, f.FullPath))));
            }
        }
Esempio n. 13
0
        /// <summary>
        /// How to store hash value in assembly.
        /// </summary>
        /// <param name="cfg">IModeCSharp configuration.</param>
        /// <returns>Formatted hash value for assembly.</returns>
        protected virtual string formatHashForAsm(IModeCSharp cfg)
        {
            if(!cfg.CachingBytecode) {
                return String.Empty;
            }

            if(cfg.CacheData == null || String.IsNullOrEmpty(cfg.CacheData.Manager.CacheHeader.Hash)) {
                updateHash(cfg);
            }

            string hash = cfg.CacheData.Manager.CacheHeader.Hash;
            if(String.IsNullOrEmpty(hash)) {
                return String.Empty;
            }
            return String.Format("[assembly: System.Reflection.AssemblyProduct(\"{0}\")]", hash);
        }
Esempio n. 14
0
        /// <param name="cfg">IModeCSharp configuration</param>
        /// <param name="msbuild">Flag of supporting MSBuild properties.</param>
        /// <returns>Prepared list of references</returns>
        protected string[] constructReferences(IModeCSharp cfg, bool msbuild)
        {
            if(cfg.References == null) {
                return new string[] { };
            }

            if(!cfg.SmartReferences)
            {
                return cfg.References
                            .Where(r => !String.IsNullOrEmpty(r))
                            .Select(r => (msbuild)? cmd.MSBuild.parse(r) : r)
                            .ToArray();
            }

            GAC gac = new GAC();
            return cfg.References
                        .Where(r => !String.IsNullOrEmpty(r))
                        .Select(r =>
                                    gac.getPathToAssembly(
                                            (msbuild)? cmd.MSBuild.parse(r) : r,
                                            true
                                    )
                                )
                        .ToArray();
        }