// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
+using System;
using System.Collections;
using System.IO;
+
using Mono.Cecil;
+using Mono.Cecil.Cil;
namespace Mono.Linker {
AssemblyAction _coreAction;
Hashtable _actions;
string _outputDirectory;
+ Hashtable _parameters;
+ bool _linkSymbols;
AssemblyResolver _resolver;
+ ReaderParameters _readerParameters;
+ ISymbolReaderProvider _symbolReaderProvider;
+ ISymbolWriterProvider _symbolWriterProvider;
+
+ AnnotationStore _annotations;
+
public Pipeline Pipeline {
get { return _pipeline; }
}
+ public AnnotationStore Annotations {
+ get { return _annotations; }
+ }
+
public string OutputDirectory {
get { return _outputDirectory; }
set { _outputDirectory = value; }
set { _coreAction = value; }
}
+ public bool LinkSymbols {
+ get { return _linkSymbols; }
+ set { _linkSymbols = value; }
+ }
+
public IDictionary Actions {
- get {
- if (_actions == null)
- _actions = new Hashtable ();
- return _actions;
- }
+ get { return _actions; }
}
public AssemblyResolver Resolver {
get { return _resolver; }
}
+ public ISymbolReaderProvider SymbolReaderProvider {
+ get { return _symbolReaderProvider; }
+ set { _symbolReaderProvider = value; }
+ }
+
+ public ISymbolWriterProvider SymbolWriterProvider {
+ get { return _symbolWriterProvider; }
+ set { _symbolWriterProvider = value; }
+ }
+
public LinkContext (Pipeline pipeline)
+ : this (pipeline, new AssemblyResolver ())
+ {
+ }
+
+ public LinkContext (Pipeline pipeline, AssemblyResolver resolver)
{
_pipeline = pipeline;
- _resolver = new AssemblyResolver ();
+ _resolver = resolver;
+ _actions = new Hashtable ();
+ _parameters = new Hashtable ();
+ _annotations = new AnnotationStore ();
+ _readerParameters = new ReaderParameters {
+ AssemblyResolver = _resolver,
+ };
}
- public TypeDefinition GetType (string type)
+ public TypeDefinition GetType (string fullName)
{
- int pos = type.IndexOf (",");
- type = type.Replace ("+", "/");
+ int pos = fullName.IndexOf (",");
+ fullName = fullName.Replace ("+", "/");
if (pos == -1) {
- foreach (AssemblyDefinition asm in GetAssemblies ())
- if (asm.MainModule.Types.Contains (type))
- return asm.MainModule.Types [type];
+ foreach (AssemblyDefinition asm in GetAssemblies ()) {
+ var type = asm.MainModule.GetType (fullName);
+ if (type != null)
+ return type;
+ }
return null;
}
- string asmname = type.Substring (pos + 1);
- type = type.Substring (0, pos);
+ string asmname = fullName.Substring (pos + 1);
+ fullName = fullName.Substring (0, pos);
AssemblyDefinition assembly = Resolve (AssemblyNameReference.Parse (asmname));
- return assembly.MainModule.Types [type];
+ return assembly.MainModule.GetType (fullName);
}
public AssemblyDefinition Resolve (string name)
{
if (File.Exists (name)) {
- AssemblyDefinition assembly = AssemblyFactory.GetAssembly (name);
+ AssemblyDefinition assembly = AssemblyDefinition.ReadAssembly (name, _readerParameters);
_resolver.CacheAssembly (assembly);
return assembly;
- } else {
- AssemblyNameReference reference = new AssemblyNameReference ();
- reference.Name = name;
- return Resolve (reference);
}
+
+ return Resolve (new AssemblyNameReference (name, new Version ()));
}
public AssemblyDefinition Resolve (IMetadataScope scope)
{
AssemblyNameReference reference = GetReference (scope);
+ try {
+ AssemblyDefinition assembly = _resolver.Resolve (reference, _readerParameters);
+
+ if (SeenFirstTime (assembly)) {
+ SafeReadSymbols (assembly);
+ SetAction (assembly);
+ }
- AssemblyDefinition assembly = _resolver.Resolve (reference);
+ return assembly;
+ }
+ catch {
+ throw new AssemblyResolutionException (reference);
+ }
+ }
- if (!Annotations.HasAction (assembly))
- SetAction (assembly);
+ bool SeenFirstTime (AssemblyDefinition assembly)
+ {
+ return !_annotations.HasAction (assembly);
+ }
- return assembly;
+ public void SafeReadSymbols (AssemblyDefinition assembly)
+ {
+ if (!_linkSymbols)
+ return;
+
+ if (assembly.MainModule.HasSymbols)
+ return;
+
+ try {
+ if (_symbolReaderProvider != null) {
+ var symbolReader = _symbolReaderProvider.GetSymbolReader (
+ assembly.MainModule,
+ assembly.MainModule.FullyQualifiedName);
+
+ _annotations.AddSymbolReader (assembly, symbolReader);
+ assembly.MainModule.ReadSymbols (symbolReader);
+ } else
+ assembly.MainModule.ReadSymbols ();
+ } catch {}
}
static AssemblyNameReference GetReference (IMetadataScope scope)
else if (IsCore (name))
action = _coreAction;
- Annotations.SetAction (assembly, action);
+ _annotations.SetAction (assembly, action);
}
static bool IsCore (AssemblyNameReference name)
{
- return name.Name == "mscorlib"
- || name.Name == "Accessibility"
- || name.Name.StartsWith ("System")
- || name.Name.StartsWith ("Microsoft");
+ switch (name.Name) {
+ case "mscorlib":
+ case "Accessibility":
+ case "Mono.Security":
+ return true;
+ default:
+ return name.Name.StartsWith ("System")
+ || name.Name.StartsWith ("Microsoft");
+ }
}
public AssemblyDefinition [] GetAssemblies ()
cache.Values.CopyTo (asms, 0);
return asms;
}
+
+ public void SetParameter (string key, string value)
+ {
+ _parameters [key] = value;
+ }
+
+ public bool HasParameter (string key)
+ {
+ return _parameters.Contains (key);
+ }
+
+ public string GetParameter (string key)
+ {
+ return (string) _parameters [key];
+ }
}
}