Free cookie consent management tool by TermsFeed Policy Generator

source: trunk/sources/HeuristicLab.Scripting/3.3/Script.cs @ 13759

Last change on this file since 13759 was 13218, checked in by jkarder, 9 years ago

#2298: applied some of the changes suggested by mkommend in comment:14:ticket:2298

File size: 4.6 KB
Line 
1#region License Information
2/* HeuristicLab
3 * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
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;
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;
31using HeuristicLab.Common;
32using HeuristicLab.Common.Resources;
33using HeuristicLab.Core;
34using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
35using Microsoft.CSharp;
36
37namespace HeuristicLab.Scripting {
38  [StorableClass]
39  public abstract class Script : NamedItem, IProgrammableItem {
40    #region Fields & Properties
41    public static new Image StaticItemImage {
42      get { return VSImageLibrary.Script; }
43    }
44
45    [Storable]
46    private string code;
47    public string Code {
48      get { return code; }
49      set {
50        if (value == code) return;
51        code = value;
52        OnCodeChanged();
53      }
54    }
55
56    private CompilerErrorCollection compileErrors;
57    public CompilerErrorCollection CompileErrors {
58      get { return compileErrors; }
59      private set {
60        compileErrors = value;
61        OnCompileErrorsChanged();
62      }
63    }
64    #endregion
65
66    #region Construction & Initialization
67    [StorableConstructor]
68    protected Script(bool deserializing) : base(deserializing) { }
69    protected Script(Script original, Cloner cloner)
70      : base(original, cloner) {
71      code = original.code;
72      if (original.compileErrors != null)
73        compileErrors = new CompilerErrorCollection(original.compileErrors);
74    }
75    protected Script()
76      : base("Script", "An empty script.") {
77    }
78    protected Script(string code)
79      : this() {
80      this.code = code;
81    }
82    #endregion
83
84    #region Compilation
85    protected virtual CompilerResults DoCompile() {
86      var parameters = new CompilerParameters {
87        GenerateExecutable = false,
88        GenerateInMemory = true,
89        IncludeDebugInformation = true,
90        WarningLevel = 4
91      };
92
93      parameters.ReferencedAssemblies.AddRange(
94        GetAssemblies()
95        .Select(a => a.Location)
96        .ToArray());
97
98      var codeProvider = new CSharpCodeProvider(
99        new Dictionary<string, string> {
100          { "CompilerVersion", "v4.0"} // support C# 4.0 syntax
101        });
102
103      return codeProvider.CompileAssemblyFromSource(parameters, code);
104    }
105
106    public virtual Assembly Compile() {
107      var results = DoCompile();
108      CompileErrors = results.Errors;
109      if (results.Errors.HasErrors) {
110        var sb = new StringBuilder();
111        foreach (CompilerError error in results.Errors) {
112          sb.Append(error.Line).Append(':')
113            .Append(error.Column).Append(": ")
114            .AppendLine(error.ErrorText);
115        }
116        throw new CompilationException(string.Format("Compilation of \"{0}\" failed:{1}{2}",
117          Name, Environment.NewLine, sb.ToString()));
118      } else {
119        return results.CompiledAssembly;
120      }
121    }
122
123    public virtual IEnumerable<Assembly> GetAssemblies() {
124      var assemblies = AppDomain.CurrentDomain.GetAssemblies().Where(a => !a.IsDynamic && File.Exists(a.Location)).ToList();
125      assemblies.Add(typeof(Microsoft.CSharp.RuntimeBinder.Binder).Assembly); // for dlr functionality
126      return assemblies;
127    }
128
129    protected virtual CodeCompileUnit CreateCompilationUnit() {
130      var unit = new CodeSnippetCompileUnit(code);
131      return unit;
132    }
133    #endregion
134
135    public event EventHandler CodeChanged;
136    protected virtual void OnCodeChanged() {
137      var handler = CodeChanged;
138      if (handler != null) handler(this, EventArgs.Empty);
139    }
140
141    public event EventHandler CompileErrorsChanged;
142    protected virtual void OnCompileErrorsChanged() {
143      var handler = CompileErrorsChanged;
144      if (handler != null) handler(this, EventArgs.Empty);
145    }
146  }
147}
Note: See TracBrowser for help on using the repository browser.