15 changed files with 368 additions and 118 deletions
@ -0,0 +1,183 @@ |
|||||||
|
// Copyright (c) 2010 AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
|
||||||
|
// This code is distributed under MIT X11 license (for details please see \doc\license.txt)
|
||||||
|
|
||||||
|
using System; |
||||||
|
using System.Collections.Generic; |
||||||
|
using System.Diagnostics.Contracts; |
||||||
|
|
||||||
|
using ICSharpCode.NRefactory.TypeSystem.Implementation; |
||||||
|
using Mono.Cecil; |
||||||
|
|
||||||
|
namespace ICSharpCode.NRefactory.TypeSystem |
||||||
|
{ |
||||||
|
/// <summary>
|
||||||
|
/// Project content that represents an already compiled assembly.
|
||||||
|
/// </summary>
|
||||||
|
public class CecilProjectContent : IProjectContent |
||||||
|
{ |
||||||
|
IList<IAttribute> assemblyAttributes; |
||||||
|
|
||||||
|
#region Constructor
|
||||||
|
public CecilProjectContent(AssemblyDefinition assemblyDefinition) |
||||||
|
{ |
||||||
|
this.assemblyAttributes = ReadAttributes(assemblyDefinition, this); |
||||||
|
} |
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region IProjectContent implementation
|
||||||
|
public IList<IAttribute> AssemblyAttributes { |
||||||
|
get { return assemblyAttributes; } |
||||||
|
} |
||||||
|
|
||||||
|
public ITypeDefinition GetClass(string fullTypeName, int typeParameterCount, StringComparer nameComparer) |
||||||
|
{ |
||||||
|
throw new NotImplementedException(); |
||||||
|
} |
||||||
|
|
||||||
|
public ISynchronizedTypeResolveContext Synchronize() |
||||||
|
{ |
||||||
|
// CecilProjectContent is immutable, so we don't need to synchronize
|
||||||
|
return new DummySynchronizedTypeResolveContext(this); |
||||||
|
} |
||||||
|
|
||||||
|
sealed class DummySynchronizedTypeResolveContext : ProxyTypeResolveContext, ISynchronizedTypeResolveContext |
||||||
|
{ |
||||||
|
public DummySynchronizedTypeResolveContext(ITypeResolveContext context) : base(context) |
||||||
|
{ |
||||||
|
} |
||||||
|
|
||||||
|
public void Dispose() |
||||||
|
{ |
||||||
|
} |
||||||
|
} |
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Load Assembly From Disk
|
||||||
|
public static CecilProjectContent LoadAssembly(string fileName) |
||||||
|
{ |
||||||
|
if (fileName == null) |
||||||
|
throw new ArgumentNullException("fileName"); |
||||||
|
AssemblyDefinition asm = AssemblyDefinition.ReadAssembly(fileName, new ReaderParameters { AssemblyResolver = new DummyAssemblyResolver() }); |
||||||
|
return new CecilProjectContent(asm); |
||||||
|
} |
||||||
|
|
||||||
|
// used to prevent Cecil from loading referenced assemblies
|
||||||
|
sealed class DummyAssemblyResolver : IAssemblyResolver |
||||||
|
{ |
||||||
|
public AssemblyDefinition Resolve(AssemblyNameReference name) |
||||||
|
{ |
||||||
|
return null; |
||||||
|
} |
||||||
|
|
||||||
|
public AssemblyDefinition Resolve(string fullName) |
||||||
|
{ |
||||||
|
return null; |
||||||
|
} |
||||||
|
} |
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Read Type Reference
|
||||||
|
public static ITypeReference ReadTypeReference(TypeReference attributeType, ITypeResolveContext earlyBindContext) |
||||||
|
{ |
||||||
|
throw new NotImplementedException(); |
||||||
|
} |
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Read Attributes
|
||||||
|
public static IList<IAttribute> ReadAttributes(ICustomAttributeProvider attributeProvider, ITypeResolveContext earlyBindContext) |
||||||
|
{ |
||||||
|
Contract.Ensures(Contract.Result<IList<IAttribute>>() != null); |
||||||
|
if (attributeProvider == null || !attributeProvider.HasCustomAttributes) |
||||||
|
return EmptyList<IAttribute>.Instance; |
||||||
|
var cecilAttributes = attributeProvider.CustomAttributes; |
||||||
|
IAttribute[] attributes = new IAttribute[cecilAttributes.Count]; |
||||||
|
for (int i = 0; i < attributes.Length; i++) { |
||||||
|
attributes[i] = new CecilAttribute(cecilAttributes[i], earlyBindContext); |
||||||
|
} |
||||||
|
return Array.AsReadOnly(attributes); |
||||||
|
} |
||||||
|
|
||||||
|
sealed class CecilAttribute : Immutable, IAttribute |
||||||
|
{ |
||||||
|
ITypeReference attributeType; |
||||||
|
volatile CustomAttribute ca; |
||||||
|
ITypeResolveContext earlyBindContext; |
||||||
|
IList<IConstantValue> positionalArguments; |
||||||
|
IList<KeyValuePair<string, IConstantValue>> namedArguments; |
||||||
|
|
||||||
|
public CecilAttribute(CustomAttribute ca, ITypeResolveContext earlyBindContext) |
||||||
|
{ |
||||||
|
this.attributeType = ReadTypeReference(ca.AttributeType, earlyBindContext); |
||||||
|
this.ca = ca; |
||||||
|
this.earlyBindContext = earlyBindContext; |
||||||
|
} |
||||||
|
|
||||||
|
public DomRegion Region { |
||||||
|
get { return DomRegion.Empty; } |
||||||
|
} |
||||||
|
|
||||||
|
public ITypeReference AttributeType { |
||||||
|
get { return attributeType; } |
||||||
|
} |
||||||
|
|
||||||
|
public IList<IConstantValue> PositionalArguments { |
||||||
|
get { |
||||||
|
EnsureArguments(); |
||||||
|
return positionalArguments; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
public IList<KeyValuePair<string, IConstantValue>> NamedArguments { |
||||||
|
get { |
||||||
|
EnsureArguments(); |
||||||
|
return namedArguments; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
void EnsureArguments() |
||||||
|
{ |
||||||
|
CustomAttribute ca = this.ca; |
||||||
|
if (ca != null) { |
||||||
|
try { |
||||||
|
if (ca.HasConstructorArguments) { |
||||||
|
var posArgs = new List<IConstantValue>(); |
||||||
|
foreach (var arg in ca.ConstructorArguments) { |
||||||
|
posArgs.Add(ReadConstantValue(arg, earlyBindContext)); |
||||||
|
} |
||||||
|
this.positionalArguments = posArgs.AsReadOnly(); |
||||||
|
} else { |
||||||
|
this.positionalArguments = EmptyList<IConstantValue>.Instance; |
||||||
|
} |
||||||
|
} catch (InvalidOperationException) { |
||||||
|
this.positionalArguments = EmptyList<IConstantValue>.Instance; |
||||||
|
} |
||||||
|
try { |
||||||
|
if (ca.HasFields || ca.HasProperties) { |
||||||
|
var namedArgs = new List<KeyValuePair<string, IConstantValue>>(); |
||||||
|
foreach (var arg in ca.Fields) { |
||||||
|
namedArgs.Add(new KeyValuePair<string, IConstantValue>(arg.Name, ReadConstantValue(arg.Argument, earlyBindContext))); |
||||||
|
} |
||||||
|
foreach (var arg in ca.Properties) { |
||||||
|
namedArgs.Add(new KeyValuePair<string, IConstantValue>(arg.Name, ReadConstantValue(arg.Argument, earlyBindContext))); |
||||||
|
} |
||||||
|
this.namedArguments = namedArgs.AsReadOnly(); |
||||||
|
} else { |
||||||
|
this.namedArguments = EmptyList<KeyValuePair<string, IConstantValue>>.Instance; |
||||||
|
} |
||||||
|
} catch (InvalidOperationException) { |
||||||
|
this.namedArguments = EmptyList<KeyValuePair<string, IConstantValue>>.Instance; |
||||||
|
} |
||||||
|
this.ca = null; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Read Constant Value
|
||||||
|
public static IConstantValue ReadConstantValue(CustomAttributeArgument arg, ITypeResolveContext earlyBindContext) |
||||||
|
{ |
||||||
|
throw new NotImplementedException(); |
||||||
|
} |
||||||
|
#endregion
|
||||||
|
} |
||||||
|
} |
||||||
@ -0,0 +1,24 @@ |
|||||||
|
// Copyright (c) 2010 AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
|
||||||
|
// This code is distributed under MIT X11 license (for details please see \doc\license.txt)
|
||||||
|
|
||||||
|
using System; |
||||||
|
using System.Collections.Generic; |
||||||
|
using System.Diagnostics.Contracts; |
||||||
|
|
||||||
|
namespace ICSharpCode.NRefactory.TypeSystem |
||||||
|
{ |
||||||
|
/// <summary>
|
||||||
|
/// Context representing the set of assemblies in which a type is being searched.
|
||||||
|
/// Guarantees that the list of types available in the context is not changed until Dispose() is called.
|
||||||
|
/// The Dispose() method must be called from the same thread that create the
|
||||||
|
/// <c>ISynchronizedTypeResolveContext</c>.
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks>
|
||||||
|
/// A simple implementation might enter a ReaderWriterLock when the synchronized context
|
||||||
|
/// is created, and releases the lock when Dispose() is called.
|
||||||
|
/// However, implementations based on immutable data structures are also possible.
|
||||||
|
/// </remarks>
|
||||||
|
public interface ISynchronizedTypeResolveContext : ITypeResolveContext, IDisposable |
||||||
|
{ |
||||||
|
} |
||||||
|
} |
||||||
@ -0,0 +1,36 @@ |
|||||||
|
// <file>
|
||||||
|
// <copyright see="prj:///doc/copyright.txt"/>
|
||||||
|
// <license see="prj:///doc/license.txt"/>
|
||||||
|
// <author name="Daniel Grunwald"/>
|
||||||
|
// <version>$Revision$</version>
|
||||||
|
// </file>
|
||||||
|
using System; |
||||||
|
|
||||||
|
namespace ICSharpCode.NRefactory.TypeSystem.Implementation |
||||||
|
{ |
||||||
|
/// <summary>
|
||||||
|
/// Proxy that forwards calls to another TypeResolveContext.
|
||||||
|
/// Useful as base class for decorators.
|
||||||
|
/// </summary>
|
||||||
|
public class ProxyTypeResolveContext : ITypeResolveContext |
||||||
|
{ |
||||||
|
ITypeResolveContext target; |
||||||
|
|
||||||
|
public ProxyTypeResolveContext(ITypeResolveContext target) |
||||||
|
{ |
||||||
|
if (target == null) |
||||||
|
throw new ArgumentNullException("target"); |
||||||
|
this.target = target; |
||||||
|
} |
||||||
|
|
||||||
|
public virtual ITypeDefinition GetClass(string fullTypeName, int typeParameterCount, StringComparer nameComparer) |
||||||
|
{ |
||||||
|
return target.GetClass(fullTypeName, typeParameterCount, nameComparer); |
||||||
|
} |
||||||
|
|
||||||
|
public virtual ISynchronizedTypeResolveContext Synchronize() |
||||||
|
{ |
||||||
|
return target.Synchronize(); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
@ -1,24 +0,0 @@ |
|||||||
// Copyright (c) 2010 AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
|
|
||||||
// This code is distributed under MIT X11 license (for details please see \doc\license.txt)
|
|
||||||
|
|
||||||
using System; |
|
||||||
using System.Diagnostics.Contracts; |
|
||||||
|
|
||||||
namespace ICSharpCode.NRefactory.TypeSystem |
|
||||||
{ |
|
||||||
/// <summary>
|
|
||||||
/// Describes the properties of a language.
|
|
||||||
/// </summary>
|
|
||||||
public class LanguageProperties |
|
||||||
{ |
|
||||||
// TODO: is this class actually useful? consider removing it
|
|
||||||
|
|
||||||
public virtual StringComparer NameComparer { |
|
||||||
get { |
|
||||||
Contract.Ensures(Contract.Result<StringComparer>() != null); |
|
||||||
Contract.Assume(StringComparer.Ordinal != null); |
|
||||||
return StringComparer.Ordinal; |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
@ -0,0 +1,7 @@ |
|||||||
|
Overview of the NRefactory library: |
||||||
|
|
||||||
|
ICSharpCode.NRefactory.TypeSystem: |
||||||
|
Contains a language-independent representation of the .NET type system. |
||||||
|
|
||||||
|
ICSharpCode.NRefactory.TypeSystem.Implementation: |
||||||
|
Contains base classes that help implementing the type system interfaces. |
||||||
Loading…
Reference in new issue