/* Copyright (C) 2014-2019 de4dot@gmail.com This file is part of dnSpy dnSpy is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. dnSpy is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with dnSpy. If not, see . */ using System; using System.Collections.Generic; using System.Threading; using dnlib.DotNet; namespace dnSpy.Contracts.Decompiler { /// /// Decompilation options /// public class DecompilationContext { const int STRINGBUILDER_POOL_SIZE = 256; /// public CancellationToken CancellationToken { get; set; } /// /// Returns true if the method body has been modified /// public Func IsBodyModified { get; set; } /// /// Disables assembly loading until Dispose() gets called /// public Func? GetDisableAssemblyLoad { get; set; } /// /// true to calculate ILSpans. Used when debugging /// public bool CalculateILSpans { get; set; } /// /// true to decompile method bodies asynchronously. Should not be enabled when decompiling /// to a project since that code already decompiles one type per CPU core. /// Should also not be enabled when only one method body is decompiled since the code won't be faster. /// public bool AsyncMethodBodyDecompilation { get; set; } /// /// Constructor /// public DecompilationContext() { CancellationToken = CancellationToken.None; IsBodyModified = m => false; AsyncMethodBodyDecompilation = true; } /// public IDisposable? DisableAssemblyLoad() => GetDisableAssemblyLoad?.Invoke(); /// /// Gets or creates a cached object /// /// Type /// public T GetOrCreate() where T : class, new() { lock (lockObj) { if (cachedObjs.TryGetValue(typeof(T), out var obj)) return (T)obj; T res = new T(); cachedObjs.Add(typeof(T), res); return res; } } readonly object lockObj = new object(); readonly Dictionary cachedObjs = new Dictionary(); /// /// Gets or creates a cached object /// /// Type /// Creates the object if necessary /// public T GetOrCreate(Func creator) where T : class { lock (lockObj) { if (cachedObjs.TryGetValue(typeof(T), out var obj)) return (T)obj; T res = creator(); cachedObjs.Add(typeof(T), res); return res; } } } }