[11700] | 1 | #region License Information
|
---|
| 2 | /* HeuristicLab
|
---|
[17180] | 3 | * Copyright (C) Heuristic and Evolutionary Algorithms Laboratory (HEAL)
|
---|
[11700] | 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 |
|
---|
| 22 | using System;
|
---|
| 23 | using System.Collections.Generic;
|
---|
| 24 | using System.IO;
|
---|
| 25 | using System.Linq;
|
---|
| 26 | using System.Reflection;
|
---|
| 27 | using System.Threading.Tasks;
|
---|
| 28 | using HeuristicLab.Common;
|
---|
| 29 | using ICSharpCode.NRefactory.Documentation;
|
---|
| 30 | using ICSharpCode.NRefactory.TypeSystem;
|
---|
| 31 |
|
---|
| 32 | namespace HeuristicLab.CodeEditor {
|
---|
| 33 | internal class AssemblyLoader {
|
---|
| 34 | private readonly HashSet<IUnresolvedAssembly> assemblySet = new HashSet<IUnresolvedAssembly>();
|
---|
| 35 | private readonly object locker = new object();
|
---|
| 36 |
|
---|
| 37 | public void AddAssembly(Assembly assembly) {
|
---|
| 38 | var assemblies = new[] { assembly };
|
---|
| 39 | OnAssembliesLoading(assemblies);
|
---|
| 40 | var unresolvedAssembly = Load(assembly);
|
---|
| 41 | lock (locker)
|
---|
| 42 | assemblySet.Add(unresolvedAssembly);
|
---|
| 43 | OnInternalAssembliesLoaded(new[] { unresolvedAssembly });
|
---|
| 44 | OnAssembliesLoaded(assemblies);
|
---|
| 45 | }
|
---|
| 46 |
|
---|
| 47 | public void AddAssemblies(IEnumerable<Assembly> assemblies) {
|
---|
| 48 | var a = assemblies.ToArray();
|
---|
| 49 | OnAssembliesLoading(a);
|
---|
| 50 | var ua = new IUnresolvedAssembly[a.Length];
|
---|
| 51 | Parallel.For(0, a.Length, i => ua[i] = Load(a[i]));
|
---|
| 52 |
|
---|
| 53 | lock (locker)
|
---|
| 54 | foreach (var asm in ua)
|
---|
| 55 | assemblySet.Add(asm);
|
---|
| 56 |
|
---|
| 57 | OnInternalAssembliesLoaded(ua);
|
---|
| 58 | OnAssembliesLoaded(a);
|
---|
| 59 | }
|
---|
| 60 |
|
---|
| 61 | public async Task AddAssembliesAsync(IEnumerable<Assembly> assemblies) {
|
---|
| 62 | await Task.Run(() => AddAssemblies(assemblies));
|
---|
| 63 | }
|
---|
| 64 |
|
---|
| 65 | public void RemoveAssembly(Assembly assembly) {
|
---|
| 66 | var assemblies = new[] { assembly };
|
---|
| 67 | OnAssembliesUnloading(assemblies);
|
---|
| 68 | IUnresolvedAssembly unresolvedAssembly;
|
---|
| 69 | lock (locker) {
|
---|
| 70 | unresolvedAssembly = assemblySet.SingleOrDefault(x => x.FullAssemblyName == assembly.FullName);
|
---|
| 71 | assemblySet.Remove(unresolvedAssembly);
|
---|
| 72 | }
|
---|
| 73 | OnInternalAssembliesUnloaded(new[] { unresolvedAssembly });
|
---|
| 74 | OnAssembliesUnloaded(assemblies);
|
---|
| 75 | }
|
---|
| 76 |
|
---|
| 77 | #region Loading Helper
|
---|
| 78 | private IUnresolvedAssembly Load(Assembly assembly) {
|
---|
| 79 | var loader = new CecilLoader {
|
---|
| 80 | DocumentationProvider = GetXmlDocumentation(assembly.Location)
|
---|
| 81 | };
|
---|
| 82 | return loader.LoadAssemblyFile(assembly.Location);
|
---|
| 83 | }
|
---|
| 84 | #endregion
|
---|
| 85 |
|
---|
| 86 | #region XML Documentation Helpers
|
---|
| 87 | private static readonly List<string> xmlDocLookupDirectories = new List<string> {
|
---|
| 88 | Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ProgramFilesX86), @"Reference Assemblies\Microsoft\Framework\.NETFramework\v4.0"),
|
---|
| 89 | System.Runtime.InteropServices.RuntimeEnvironment.GetRuntimeDirectory()
|
---|
| 90 | };
|
---|
| 91 |
|
---|
| 92 | private static IDocumentationProvider GetXmlDocumentation(string assemblyLocation) {
|
---|
| 93 | if (!File.Exists(assemblyLocation)) return null;
|
---|
| 94 |
|
---|
| 95 | string xmlDocFileName = Path.GetFileNameWithoutExtension(assemblyLocation) + ".xml";
|
---|
| 96 |
|
---|
| 97 | foreach (var dir in xmlDocLookupDirectories) {
|
---|
| 98 | string xmlDocFileLocation = Path.Combine(dir, xmlDocFileName);
|
---|
| 99 | if (File.Exists(xmlDocFileLocation)) return new XmlDocumentationProvider(xmlDocFileLocation);
|
---|
| 100 | }
|
---|
| 101 |
|
---|
| 102 | return null;
|
---|
| 103 | }
|
---|
| 104 | #endregion
|
---|
| 105 |
|
---|
| 106 | #region Events
|
---|
| 107 | public event EventHandler<EventArgs<IEnumerable<Assembly>>> AssembliesLoading;
|
---|
| 108 | private void OnAssembliesLoading(IEnumerable<Assembly> args) {
|
---|
| 109 | var handler = AssembliesLoading;
|
---|
| 110 | if (handler != null) handler(this, new EventArgs<IEnumerable<Assembly>>(args));
|
---|
| 111 | }
|
---|
| 112 |
|
---|
| 113 | public event EventHandler<EventArgs<IEnumerable<Assembly>>> AssembliesLoaded;
|
---|
| 114 | private void OnAssembliesLoaded(IEnumerable<Assembly> args) {
|
---|
| 115 | var handler = AssembliesLoaded;
|
---|
| 116 | if (handler != null) handler(this, new EventArgs<IEnumerable<Assembly>>(args));
|
---|
| 117 | }
|
---|
| 118 |
|
---|
| 119 | public event EventHandler<EventArgs<IEnumerable<IUnresolvedAssembly>>> InternalAssembliesLoaded;
|
---|
| 120 | private void OnInternalAssembliesLoaded(IEnumerable<IUnresolvedAssembly> args) {
|
---|
| 121 | var handler = InternalAssembliesLoaded;
|
---|
| 122 | if (handler != null) handler(this, new EventArgs<IEnumerable<IUnresolvedAssembly>>(args));
|
---|
| 123 | }
|
---|
| 124 |
|
---|
| 125 | public event EventHandler<EventArgs<IEnumerable<Assembly>>> AssembliesUnloading;
|
---|
| 126 | private void OnAssembliesUnloading(IEnumerable<Assembly> args) {
|
---|
| 127 | var handler = AssembliesUnloading;
|
---|
| 128 | if (handler != null) handler(this, new EventArgs<IEnumerable<Assembly>>(args));
|
---|
| 129 | }
|
---|
| 130 |
|
---|
| 131 | public event EventHandler<EventArgs<IEnumerable<Assembly>>> AssembliesUnloaded;
|
---|
| 132 | private void OnAssembliesUnloaded(IEnumerable<Assembly> args) {
|
---|
| 133 | var handler = AssembliesUnloaded;
|
---|
| 134 | if (handler != null) handler(this, new EventArgs<IEnumerable<Assembly>>(args));
|
---|
| 135 | }
|
---|
| 136 |
|
---|
| 137 | public event EventHandler<EventArgs<IEnumerable<IUnresolvedAssembly>>> InternalAssembliesUnloaded;
|
---|
| 138 | private void OnInternalAssembliesUnloaded(IEnumerable<IUnresolvedAssembly> args) {
|
---|
| 139 | var handler = InternalAssembliesUnloaded;
|
---|
| 140 | if (handler != null) handler(this, new EventArgs<IEnumerable<IUnresolvedAssembly>>(args));
|
---|
| 141 | }
|
---|
| 142 | #endregion
|
---|
| 143 | }
|
---|
| 144 | }
|
---|