Free cookie consent management tool by TermsFeed Policy Generator

source: trunk/HeuristicLab.Scripting/3.3/Script.cs @ 17425

Last change on this file since 17425 was 17329, checked in by abeham, 5 years ago

#3037: added ability to exclude assemblies

File size: 5.0 KB
RevLine 
[10506]1#region License Information
2/* HeuristicLab
[17180]3 * Copyright (C) Heuristic and Evolutionary Algorithms Laboratory (HEAL)
[10506]4 *
5 * This file is part of HeuristicLab.
6 *
7 * HeuristicLab is free software: you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation, either version 3 of the License, or
10 * (at your option) any later version.
11 *
12 * HeuristicLab is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
19 */
20#endregion
21
22using System;
[10332]23using System.CodeDom;
24using System.CodeDom.Compiler;
25using System.Collections.Generic;
26using System.Drawing;
27using System.IO;
28using System.Linq;
29using System.Reflection;
30using System.Text;
[17110]31using System.Text.RegularExpressions;
32using HEAL.Attic;
[10332]33using HeuristicLab.Common;
34using HeuristicLab.Common.Resources;
35using HeuristicLab.Core;
36using Microsoft.CSharp;
37
[10506]38namespace HeuristicLab.Scripting {
[16565]39  [StorableType("0FA4F218-E1F5-4C09-9C2F-12B32D4EC373")]
[13218]40  public abstract class Script : NamedItem, IProgrammableItem {
[10332]41    #region Fields & Properties
[17329]42    public static readonly HashSet<string> ExcludedAssemblyFileNames = new HashSet<string> { "IKVM.OpenJDK.ClassLibrary.dll" };
[10332]43    public static new Image StaticItemImage {
44      get { return VSImageLibrary.Script; }
45    }
46
47    [Storable]
48    private string code;
[10857]49    public string Code {
[10332]50      get { return code; }
51      set {
52        if (value == code) return;
53        code = value;
54        OnCodeChanged();
55      }
56    }
57
58    private CompilerErrorCollection compileErrors;
[10857]59    public CompilerErrorCollection CompileErrors {
[10332]60      get { return compileErrors; }
61      private set {
62        compileErrors = value;
63        OnCompileErrorsChanged();
64      }
65    }
66    #endregion
67
68    #region Construction & Initialization
69    [StorableConstructor]
[16565]70    protected Script(StorableConstructorFlag _) : base(_) { }
[10731]71    protected Script(Script original, Cloner cloner)
[10332]72      : base(original, cloner) {
73      code = original.code;
74      if (original.compileErrors != null)
75        compileErrors = new CompilerErrorCollection(original.compileErrors);
76    }
[13218]77    protected Script()
[10857]78      : base("Script", "An empty script.") {
[10332]79    }
[13218]80    protected Script(string code)
[10577]81      : this() {
82      this.code = code;
83    }
[10332]84    #endregion
85
[10731]86    #region Compilation
87    protected virtual CompilerResults DoCompile() {
[10332]88      var parameters = new CompilerParameters {
89        GenerateExecutable = false,
90        GenerateInMemory = true,
[10506]91        IncludeDebugInformation = true,
92        WarningLevel = 4
[10332]93      };
[11657]94
[10332]95      parameters.ReferencedAssemblies.AddRange(
96        GetAssemblies()
97        .Select(a => a.Location)
98        .ToArray());
[11657]99
[13218]100      var codeProvider = new CSharpCodeProvider(
101        new Dictionary<string, string> {
102          { "CompilerVersion", "v4.0"} // support C# 4.0 syntax
103        });
104
105      return codeProvider.CompileAssemblyFromSource(parameters, code);
[10332]106    }
107
[10731]108    public virtual Assembly Compile() {
[10332]109      var results = DoCompile();
110      CompileErrors = results.Errors;
111      if (results.Errors.HasErrors) {
112        var sb = new StringBuilder();
113        foreach (CompilerError error in results.Errors) {
114          sb.Append(error.Line).Append(':')
115            .Append(error.Column).Append(": ")
116            .AppendLine(error.ErrorText);
117        }
[11882]118        throw new CompilationException(string.Format("Compilation of \"{0}\" failed:{1}{2}",
[10731]119          Name, Environment.NewLine, sb.ToString()));
[10332]120      } else {
[10731]121        return results.CompiledAssembly;
[10332]122      }
123    }
124
[10731]125    public virtual IEnumerable<Assembly> GetAssemblies() {
[17110]126      var assemblies = AppDomain.CurrentDomain.GetAssemblies()
[17329]127        .Where(a => !a.IsDynamic && File.Exists(a.Location)
128                 && !ExcludedAssemblyFileNames.Contains(Path.GetFileName(a.Location)))
[17110]129        .GroupBy(x => Regex.Replace(Path.GetFileName(x.Location), @"-[\d.]+\.dll$", ""))
130        .Select(x => x.OrderByDescending(y => y.GetName().Version).First())
131        .ToList();
[10358]132      assemblies.Add(typeof(Microsoft.CSharp.RuntimeBinder.Binder).Assembly); // for dlr functionality
133      return assemblies;
134    }
135
[10731]136    protected virtual CodeCompileUnit CreateCompilationUnit() {
[10401]137      var unit = new CodeSnippetCompileUnit(code);
[10332]138      return unit;
139    }
140    #endregion
141
142    public event EventHandler CodeChanged;
[10731]143    protected virtual void OnCodeChanged() {
[10332]144      var handler = CodeChanged;
145      if (handler != null) handler(this, EventArgs.Empty);
146    }
147
148    public event EventHandler CompileErrorsChanged;
[10731]149    protected virtual void OnCompileErrorsChanged() {
[10332]150      var handler = CompileErrorsChanged;
151      if (handler != null) handler(this, EventArgs.Empty);
152    }
153  }
154}
Note: See TracBrowser for help on using the repository browser.