mirror of https://github.com/icsharpcode/ILSpy.git
24 changed files with 0 additions and 2062 deletions
@ -1,36 +0,0 @@
@@ -1,36 +0,0 @@
|
||||
// Copyright (c) 2010-2013 AlphaSierraPapa for the SharpDevelop Team
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy of this
|
||||
// software and associated documentation files (the "Software"), to deal in the Software
|
||||
// without restriction, including without limitation the rights to use, copy, modify, merge,
|
||||
// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons
|
||||
// to whom the Software is furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in all copies or
|
||||
// substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
|
||||
// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
|
||||
// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE
|
||||
// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
|
||||
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
// DEALINGS IN THE SOFTWARE.
|
||||
|
||||
using ICSharpCode.Decompiler.Semantics; |
||||
|
||||
namespace ICSharpCode.Decompiler.TypeSystem |
||||
{ |
||||
/// <summary>
|
||||
/// Represents an unresolved constant value.
|
||||
/// </summary>
|
||||
public interface IConstantValue |
||||
{ |
||||
/// <summary>
|
||||
/// Resolves the value of this constant.
|
||||
/// </summary>
|
||||
/// <param name="context">Context where the constant value will be used.</param>
|
||||
/// <returns>Resolve result representing the constant value.
|
||||
/// This method never returns null; in case of errors, an ErrorResolveResult will be returned.</returns>
|
||||
ResolveResult Resolve(ITypeResolveContext context); |
||||
} |
||||
} |
@ -1,85 +0,0 @@
@@ -1,85 +0,0 @@
|
||||
// Copyright (c) 2010-2013 AlphaSierraPapa for the SharpDevelop Team
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy of this
|
||||
// software and associated documentation files (the "Software"), to deal in the Software
|
||||
// without restriction, including without limitation the rights to use, copy, modify, merge,
|
||||
// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons
|
||||
// to whom the Software is furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in all copies or
|
||||
// substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
|
||||
// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
|
||||
// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE
|
||||
// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
|
||||
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
// DEALINGS IN THE SOFTWARE.
|
||||
|
||||
using System; |
||||
using System.Collections.Generic; |
||||
|
||||
namespace ICSharpCode.Decompiler.TypeSystem.Implementation |
||||
{ |
||||
/// <summary>
|
||||
/// Implementation of <see cref="IEntity"/> that resolves an unresolved entity.
|
||||
/// </summary>
|
||||
public abstract class AbstractResolvedEntity : IEntity |
||||
{ |
||||
protected readonly IUnresolvedEntity unresolved; |
||||
protected readonly ITypeResolveContext parentContext; |
||||
|
||||
protected AbstractResolvedEntity(IUnresolvedEntity unresolved, ITypeResolveContext parentContext) |
||||
{ |
||||
if (unresolved == null) |
||||
throw new ArgumentNullException("unresolved"); |
||||
if (parentContext == null) |
||||
throw new ArgumentNullException("parentContext"); |
||||
this.unresolved = unresolved; |
||||
this.parentContext = parentContext; |
||||
this.Attributes = unresolved.Attributes.CreateResolvedAttributes(parentContext); |
||||
} |
||||
|
||||
public System.Reflection.Metadata.EntityHandle MetadataToken => unresolved.MetadataToken; |
||||
|
||||
public SymbolKind SymbolKind { |
||||
get { return unresolved.SymbolKind; } |
||||
} |
||||
|
||||
public ITypeDefinition DeclaringTypeDefinition { |
||||
get { return parentContext.CurrentTypeDefinition; } |
||||
} |
||||
|
||||
public virtual IType DeclaringType { |
||||
get { return parentContext.CurrentTypeDefinition; } |
||||
} |
||||
|
||||
public IAssembly ParentAssembly { |
||||
get { return parentContext.CurrentAssembly; } |
||||
} |
||||
|
||||
public IReadOnlyList<IAttribute> Attributes { get; protected set; } |
||||
IEnumerable<IAttribute> IEntity.GetAttributes() => Attributes; |
||||
|
||||
public bool IsStatic { get { return unresolved.IsStatic; } } |
||||
public bool IsAbstract { get { return unresolved.IsAbstract; } } |
||||
public bool IsSealed { get { return unresolved.IsSealed; } } |
||||
public bool IsShadowing { get { return unresolved.IsShadowing; } } |
||||
|
||||
public ICompilation Compilation { |
||||
get { return parentContext.Compilation; } |
||||
} |
||||
|
||||
public string FullName { get { return unresolved.FullName; } } |
||||
public string Name { get { return unresolved.Name; } } |
||||
public string ReflectionName { get { return unresolved.ReflectionName; } } |
||||
public string Namespace { get { return unresolved.Namespace; } } |
||||
|
||||
public virtual Accessibility Accessibility { get { return unresolved.Accessibility; } } |
||||
|
||||
public override string ToString() |
||||
{ |
||||
return "[" + this.SymbolKind.ToString() + " " + this.ReflectionName + "]"; |
||||
} |
||||
} |
||||
} |
@ -1,138 +0,0 @@
@@ -1,138 +0,0 @@
|
||||
// Copyright (c) 2010-2013 AlphaSierraPapa for the SharpDevelop Team
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy of this
|
||||
// software and associated documentation files (the "Software"), to deal in the Software
|
||||
// without restriction, including without limitation the rights to use, copy, modify, merge,
|
||||
// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons
|
||||
// to whom the Software is furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in all copies or
|
||||
// substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
|
||||
// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
|
||||
// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE
|
||||
// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
|
||||
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
// DEALINGS IN THE SOFTWARE.
|
||||
|
||||
using System.Collections.Generic; |
||||
using System.Linq; |
||||
using ICSharpCode.Decompiler.Util; |
||||
|
||||
namespace ICSharpCode.Decompiler.TypeSystem.Implementation |
||||
{ |
||||
/// <summary>
|
||||
/// Implementation of <see cref="IMember"/> that resolves an unresolved member.
|
||||
/// </summary>
|
||||
public abstract class AbstractResolvedMember : AbstractResolvedEntity, IMember |
||||
{ |
||||
protected new readonly IUnresolvedMember unresolved; |
||||
protected readonly ITypeResolveContext context; |
||||
volatile IType returnType; |
||||
IReadOnlyList<IMember> implementedInterfaceMembers; |
||||
|
||||
protected AbstractResolvedMember(IUnresolvedMember unresolved, ITypeResolveContext parentContext) |
||||
: base(unresolved, parentContext) |
||||
{ |
||||
this.unresolved = unresolved; |
||||
this.context = parentContext.WithCurrentMember(this); |
||||
} |
||||
|
||||
IMember IMember.MemberDefinition { |
||||
get { return this; } |
||||
} |
||||
|
||||
public IType ReturnType { |
||||
get { |
||||
return this.returnType ?? (this.returnType = unresolved.ReturnType.Resolve(context)); |
||||
} |
||||
} |
||||
|
||||
public IUnresolvedMember UnresolvedMember { |
||||
get { return unresolved; } |
||||
} |
||||
|
||||
public IEnumerable<IMember> ExplicitlyImplementedInterfaceMembers { |
||||
get { |
||||
IReadOnlyList<IMember> result = LazyInit.VolatileRead(ref this.implementedInterfaceMembers); |
||||
if (result != null) { |
||||
return result; |
||||
} else { |
||||
return LazyInit.GetOrSet(ref implementedInterfaceMembers, FindImplementedInterfaceMembers()); |
||||
} |
||||
} |
||||
} |
||||
|
||||
IReadOnlyList<IMember> FindImplementedInterfaceMembers() |
||||
{ |
||||
if (unresolved.IsExplicitInterfaceImplementation) { |
||||
List<IMember> result = new List<IMember>(); |
||||
foreach (var memberReference in unresolved.ExplicitInterfaceImplementations) { |
||||
IMember member = memberReference.Resolve(context); |
||||
if (member != null) |
||||
result.Add(member); |
||||
} |
||||
return result.ToArray(); |
||||
} else if (unresolved.IsStatic || unresolved.Accessibility != Accessibility.Public || DeclaringTypeDefinition == null || DeclaringTypeDefinition.Kind == TypeKind.Interface) { |
||||
return EmptyList<IMember>.Instance; |
||||
} else { |
||||
// TODO: implement interface member mappings correctly
|
||||
var result = InheritanceHelper.GetBaseMembers(this, true) |
||||
.Where(m => m.DeclaringTypeDefinition != null && m.DeclaringTypeDefinition.Kind == TypeKind.Interface) |
||||
.ToArray(); |
||||
|
||||
IEnumerable<IMember> otherMembers = DeclaringTypeDefinition.Members; |
||||
if (SymbolKind == SymbolKind.Accessor) |
||||
otherMembers = DeclaringTypeDefinition.GetAccessors(options: GetMemberOptions.IgnoreInheritedMembers); |
||||
result = result.Where(item => !otherMembers.Any(m => m.IsExplicitInterfaceImplementation && m.ExplicitlyImplementedInterfaceMembers.Contains(item))).ToArray(); |
||||
|
||||
return result; |
||||
} |
||||
} |
||||
|
||||
public bool IsExplicitInterfaceImplementation { |
||||
get { return unresolved.IsExplicitInterfaceImplementation; } |
||||
} |
||||
|
||||
public bool IsVirtual { |
||||
get { return unresolved.IsVirtual; } |
||||
} |
||||
|
||||
public bool IsOverride { |
||||
get { return unresolved.IsOverride; } |
||||
} |
||||
|
||||
public bool IsOverridable { |
||||
get { return unresolved.IsOverridable; } |
||||
} |
||||
|
||||
public TypeParameterSubstitution Substitution { |
||||
get { return TypeParameterSubstitution.Identity; } |
||||
} |
||||
|
||||
public virtual bool Equals(IMember obj, TypeVisitor typeNormalization) |
||||
{ |
||||
return Equals(obj); |
||||
} |
||||
|
||||
public abstract IMember Specialize(TypeParameterSubstitution substitution); |
||||
|
||||
internal IMethod GetAccessor(ref IMethod accessorField, IUnresolvedMethod unresolvedAccessor) |
||||
{ |
||||
if (unresolvedAccessor == null) |
||||
return null; |
||||
IMethod result = LazyInit.VolatileRead(ref accessorField); |
||||
if (result != null) { |
||||
return result; |
||||
} else { |
||||
return LazyInit.GetOrSet(ref accessorField, CreateResolvedAccessor(unresolvedAccessor)); |
||||
} |
||||
} |
||||
|
||||
protected virtual IMethod CreateResolvedAccessor(IUnresolvedMethod unresolvedAccessor) |
||||
{ |
||||
return (IMethod)unresolvedAccessor.CreateResolved(context); |
||||
} |
||||
} |
||||
} |
@ -1,252 +0,0 @@
@@ -1,252 +0,0 @@
|
||||
// Copyright (c) 2010-2013 AlphaSierraPapa for the SharpDevelop Team
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy of this
|
||||
// software and associated documentation files (the "Software"), to deal in the Software
|
||||
// without restriction, including without limitation the rights to use, copy, modify, merge,
|
||||
// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons
|
||||
// to whom the Software is furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in all copies or
|
||||
// substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
|
||||
// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
|
||||
// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE
|
||||
// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
|
||||
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
// DEALINGS IN THE SOFTWARE.
|
||||
|
||||
using System; |
||||
using System.Collections.Generic; |
||||
using System.Text; |
||||
using ICSharpCode.Decompiler.Util; |
||||
|
||||
namespace ICSharpCode.Decompiler.TypeSystem.Implementation |
||||
{ |
||||
/// <summary>
|
||||
/// Base class for <see cref="IUnresolvedEntity"/> implementations.
|
||||
/// </summary>
|
||||
[Serializable] |
||||
public abstract class AbstractUnresolvedEntity : IUnresolvedEntity, IFreezable |
||||
{ |
||||
// possible optimizations to reduce the memory usage of AbstractUnresolvedEntity:
|
||||
// - store regions in more compact form (e.g. assume both file names are identical; use ushort for columns)
|
||||
|
||||
IUnresolvedTypeDefinition declaringTypeDefinition; |
||||
|
||||
string name = string.Empty; |
||||
IList<IUnresolvedAttribute> attributes; |
||||
System.Reflection.Metadata.EntityHandle metadataToken; |
||||
|
||||
// 1 byte per enum + 2 bytes for flags
|
||||
SymbolKind symbolKind; |
||||
Accessibility accessibility; |
||||
internal BitVector16 flags; |
||||
|
||||
// flags for AbstractUnresolvedEntity:
|
||||
internal const ushort FlagFrozen = 0x0001; |
||||
internal const ushort FlagSealed = 0x0002; |
||||
internal const ushort FlagAbstract = 0x0004; |
||||
internal const ushort FlagShadowing = 0x0008; |
||||
//internal const ushort FlagSynthetic = 0x0010;
|
||||
internal const ushort FlagStatic = 0x0020; |
||||
// flags for DefaultUnresolvedTypeDefinition/LazyCecilTypeDefinition
|
||||
internal const ushort FlagAddDefaultConstructorIfRequired = 0x0040; |
||||
internal const ushort FlagHasExtensionMethods = 0x0080; |
||||
internal const ushort FlagHasNoExtensionMethods = 0x0100; |
||||
internal const ushort FlagPartialTypeDefinition = 0x0200; |
||||
// flags for AbstractUnresolvedMember:
|
||||
internal const ushort FlagExplicitInterfaceImplementation = 0x0040; |
||||
internal const ushort FlagVirtual = 0x0080; |
||||
internal const ushort FlagOverride = 0x0100; |
||||
// flags for DefaultField:
|
||||
internal const ushort FlagFieldIsReadOnly = 0x1000; |
||||
internal const ushort FlagFieldIsVolatile = 0x2000; |
||||
internal const ushort FlagFieldIsFixedSize = 0x4000; |
||||
// flags for DefaultMethod:
|
||||
internal const ushort FlagExtensionMethod = 0x1000; |
||||
internal const ushort FlagPartialMethod = 0x2000; |
||||
internal const ushort FlagHasBody = 0x4000; |
||||
internal const ushort FlagAsyncMethod = 0x8000; |
||||
|
||||
public bool IsFrozen { |
||||
get { return flags[FlagFrozen]; } |
||||
} |
||||
|
||||
public void Freeze() |
||||
{ |
||||
if (!flags[FlagFrozen]) { |
||||
FreezeInternal(); |
||||
flags[FlagFrozen] = true; |
||||
} |
||||
} |
||||
|
||||
protected virtual void FreezeInternal() |
||||
{ |
||||
attributes = FreezableHelper.FreezeListAndElements(attributes); |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Uses the specified interning provider to intern
|
||||
/// strings and lists in this entity.
|
||||
/// This method does not test arbitrary objects to see if they implement ISupportsInterning;
|
||||
/// instead we assume that those are interned immediately when they are created (before they are added to this entity).
|
||||
/// </summary>
|
||||
public virtual void ApplyInterningProvider(InterningProvider provider) |
||||
{ |
||||
if (provider == null) |
||||
throw new ArgumentNullException("provider"); |
||||
ThrowIfFrozen(); |
||||
name = provider.Intern(name); |
||||
attributes = provider.InternList(attributes); |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Creates a shallow clone of this entity.
|
||||
/// Collections (e.g. a type's member list) will be cloned as well, but the elements
|
||||
/// of said list will not be.
|
||||
/// If this instance is frozen, the clone will be unfrozen.
|
||||
/// </summary>
|
||||
public virtual object Clone() |
||||
{ |
||||
var copy = (AbstractUnresolvedEntity)MemberwiseClone(); |
||||
copy.flags[FlagFrozen] = false; |
||||
if (attributes != null) |
||||
copy.attributes = new List<IUnresolvedAttribute>(attributes); |
||||
return copy; |
||||
} |
||||
|
||||
protected void ThrowIfFrozen() |
||||
{ |
||||
FreezableHelper.ThrowIfFrozen(this); |
||||
} |
||||
|
||||
public System.Reflection.Metadata.EntityHandle MetadataToken { |
||||
get { return metadataToken; } |
||||
set { |
||||
ThrowIfFrozen(); |
||||
metadataToken = value; |
||||
} |
||||
} |
||||
|
||||
public SymbolKind SymbolKind { |
||||
get { return symbolKind; } |
||||
set { |
||||
ThrowIfFrozen(); |
||||
symbolKind = value; |
||||
} |
||||
} |
||||
|
||||
public IUnresolvedTypeDefinition DeclaringTypeDefinition { |
||||
get { return declaringTypeDefinition; } |
||||
set { |
||||
ThrowIfFrozen(); |
||||
declaringTypeDefinition = value; |
||||
} |
||||
} |
||||
|
||||
public IList<IUnresolvedAttribute> Attributes { |
||||
get { |
||||
if (attributes == null) |
||||
attributes = new List<IUnresolvedAttribute>(); |
||||
return attributes; |
||||
} |
||||
} |
||||
|
||||
public string Name { |
||||
get { return name; } |
||||
set { |
||||
if (value == null) |
||||
throw new ArgumentNullException("value"); |
||||
ThrowIfFrozen(); |
||||
name = value; |
||||
} |
||||
} |
||||
|
||||
public virtual string FullName { |
||||
get { |
||||
if (declaringTypeDefinition != null) |
||||
return declaringTypeDefinition.FullName + "." + name; |
||||
else if (!string.IsNullOrEmpty(this.Namespace)) |
||||
return this.Namespace + "." + name; |
||||
else |
||||
return name; |
||||
} |
||||
} |
||||
|
||||
public virtual string Namespace { |
||||
get { |
||||
if (declaringTypeDefinition != null) |
||||
return declaringTypeDefinition.Namespace; |
||||
else |
||||
return string.Empty; |
||||
} |
||||
set { |
||||
throw new NotSupportedException(); |
||||
} |
||||
} |
||||
|
||||
public virtual string ReflectionName { |
||||
get { |
||||
if (declaringTypeDefinition != null) |
||||
return declaringTypeDefinition.ReflectionName + "." + name; |
||||
else |
||||
return name; |
||||
} |
||||
} |
||||
|
||||
public Accessibility Accessibility { |
||||
get { return accessibility; } |
||||
set { |
||||
ThrowIfFrozen(); |
||||
accessibility = value; |
||||
} |
||||
} |
||||
|
||||
public bool IsStatic { |
||||
get { return flags[FlagStatic]; } |
||||
set { |
||||
ThrowIfFrozen(); |
||||
flags[FlagStatic] = value; |
||||
} |
||||
} |
||||
|
||||
public bool IsAbstract { |
||||
get { return flags[FlagAbstract]; } |
||||
set { |
||||
ThrowIfFrozen(); |
||||
flags[FlagAbstract] = value; |
||||
} |
||||
} |
||||
|
||||
public bool IsSealed { |
||||
get { return flags[FlagSealed]; } |
||||
set { |
||||
ThrowIfFrozen(); |
||||
flags[FlagSealed] = value; |
||||
} |
||||
} |
||||
|
||||
public bool IsShadowing { |
||||
get { return flags[FlagShadowing]; } |
||||
set { |
||||
ThrowIfFrozen(); |
||||
flags[FlagShadowing] = value; |
||||
} |
||||
} |
||||
|
||||
public override string ToString() |
||||
{ |
||||
StringBuilder b = new StringBuilder("["); |
||||
b.Append(GetType().Name); |
||||
b.Append(' '); |
||||
if (this.DeclaringTypeDefinition != null) { |
||||
b.Append(this.DeclaringTypeDefinition.Name); |
||||
b.Append('.'); |
||||
} |
||||
b.Append(this.Name); |
||||
b.Append(']'); |
||||
return b.ToString(); |
||||
} |
||||
} |
||||
} |
@ -1,268 +0,0 @@
@@ -1,268 +0,0 @@
|
||||
// Copyright (c) 2010-2013 AlphaSierraPapa for the SharpDevelop Team
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy of this
|
||||
// software and associated documentation files (the "Software"), to deal in the Software
|
||||
// without restriction, including without limitation the rights to use, copy, modify, merge,
|
||||
// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons
|
||||
// to whom the Software is furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in all copies or
|
||||
// substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
|
||||
// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
|
||||
// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE
|
||||
// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
|
||||
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
// DEALINGS IN THE SOFTWARE.
|
||||
|
||||
using System; |
||||
using System.Collections.Generic; |
||||
using System.Linq; |
||||
using ICSharpCode.Decompiler.Util; |
||||
|
||||
namespace ICSharpCode.Decompiler.TypeSystem.Implementation |
||||
{ |
||||
/// <summary>
|
||||
/// Base class for <see cref="IUnresolvedMember"/> implementations.
|
||||
/// </summary>
|
||||
[Serializable] |
||||
public abstract class AbstractUnresolvedMember : AbstractUnresolvedEntity, IUnresolvedMember |
||||
{ |
||||
ITypeReference returnType = SpecialType.UnknownType; |
||||
IList<IMemberReference> interfaceImplementations; |
||||
|
||||
public override void ApplyInterningProvider(InterningProvider provider) |
||||
{ |
||||
base.ApplyInterningProvider(provider); |
||||
interfaceImplementations = provider.InternList(interfaceImplementations); |
||||
} |
||||
|
||||
protected override void FreezeInternal() |
||||
{ |
||||
base.FreezeInternal(); |
||||
interfaceImplementations = FreezableHelper.FreezeList(interfaceImplementations); |
||||
} |
||||
|
||||
public override object Clone() |
||||
{ |
||||
var copy = (AbstractUnresolvedMember)base.Clone(); |
||||
if (interfaceImplementations != null) |
||||
copy.interfaceImplementations = new List<IMemberReference>(interfaceImplementations); |
||||
return copy; |
||||
} |
||||
|
||||
/* |
||||
[Serializable] |
||||
internal new class RareFields : AbstractUnresolvedEntity.RareFields |
||||
{ |
||||
internal IList<IMemberReference> interfaceImplementations; |
||||
|
||||
public override void ApplyInterningProvider(IInterningProvider provider) |
||||
{ |
||||
base.ApplyInterningProvider(provider); |
||||
interfaceImplementations = provider.InternList(interfaceImplementations); |
||||
} |
||||
|
||||
protected internal override void FreezeInternal() |
||||
{ |
||||
interfaceImplementations = FreezableHelper.FreezeListAndElements(interfaceImplementations); |
||||
base.FreezeInternal(); |
||||
} |
||||
|
||||
override Clone(){} |
||||
} |
||||
|
||||
internal override AbstractUnresolvedEntity.RareFields WriteRareFields() |
||||
{ |
||||
ThrowIfFrozen(); |
||||
if (rareFields == null) rareFields = new RareFields(); |
||||
return rareFields; |
||||
}*/ |
||||
|
||||
public ITypeReference ReturnType { |
||||
get { return returnType; } |
||||
set { |
||||
if (value == null) |
||||
throw new ArgumentNullException("value"); |
||||
ThrowIfFrozen(); |
||||
returnType = value; |
||||
} |
||||
} |
||||
|
||||
public bool IsExplicitInterfaceImplementation { |
||||
get { return flags[FlagExplicitInterfaceImplementation]; } |
||||
set { |
||||
ThrowIfFrozen(); |
||||
flags[FlagExplicitInterfaceImplementation] = value; |
||||
} |
||||
} |
||||
|
||||
public IList<IMemberReference> ExplicitInterfaceImplementations { |
||||
get { |
||||
/* |
||||
RareFields rareFields = (RareFields)this.rareFields; |
||||
if (rareFields == null || rareFields.interfaceImplementations == null) { |
||||
rareFields = (RareFields)WriteRareFields(); |
||||
return rareFields.interfaceImplementations = new List<IMemberReference>(); |
||||
} |
||||
return rareFields.interfaceImplementations; |
||||
*/ |
||||
if (interfaceImplementations == null) |
||||
interfaceImplementations = new List<IMemberReference>(); |
||||
return interfaceImplementations; |
||||
} |
||||
} |
||||
|
||||
public bool IsVirtual { |
||||
get { return flags[FlagVirtual]; } |
||||
set { |
||||
ThrowIfFrozen(); |
||||
flags[FlagVirtual] = value; |
||||
} |
||||
} |
||||
|
||||
public bool IsOverride { |
||||
get { return flags[FlagOverride]; } |
||||
set { |
||||
ThrowIfFrozen(); |
||||
flags[FlagOverride] = value; |
||||
} |
||||
} |
||||
|
||||
public bool IsOverridable { |
||||
get { |
||||
// override or virtual or abstract but not sealed
|
||||
return (flags.Data & (FlagOverride | FlagVirtual | FlagAbstract)) != 0 && !this.IsSealed; |
||||
} |
||||
} |
||||
|
||||
ITypeReference IMemberReference.DeclaringTypeReference { |
||||
get { return this.DeclaringTypeDefinition; } |
||||
} |
||||
|
||||
#region Resolve
|
||||
public abstract IMember CreateResolved(ITypeResolveContext context); |
||||
|
||||
public virtual IMember Resolve(ITypeResolveContext context) |
||||
{ |
||||
ITypeReference interfaceTypeReference = null; |
||||
if (this.IsExplicitInterfaceImplementation && this.ExplicitInterfaceImplementations.Count == 1) |
||||
interfaceTypeReference = this.ExplicitInterfaceImplementations[0].DeclaringTypeReference; |
||||
return Resolve(ExtendContextForType(context, this.DeclaringTypeDefinition), this.SymbolKind, this.Name, interfaceTypeReference); |
||||
} |
||||
|
||||
protected static ITypeResolveContext ExtendContextForType(ITypeResolveContext assemblyContext, IUnresolvedTypeDefinition typeDef) |
||||
{ |
||||
if (typeDef == null) |
||||
return assemblyContext; |
||||
ITypeResolveContext parentContext; |
||||
if (typeDef.DeclaringTypeDefinition != null) |
||||
parentContext = ExtendContextForType(assemblyContext, typeDef.DeclaringTypeDefinition); |
||||
else |
||||
parentContext = assemblyContext; |
||||
ITypeDefinition resolvedTypeDef = typeDef.Resolve(assemblyContext).GetDefinition(); |
||||
return typeDef.CreateResolveContext(parentContext).WithCurrentTypeDefinition(resolvedTypeDef); |
||||
} |
||||
|
||||
public static IMember Resolve(ITypeResolveContext context, |
||||
SymbolKind symbolKind, |
||||
string name, |
||||
ITypeReference explicitInterfaceTypeReference = null, |
||||
IList<string> typeParameterNames = null, |
||||
IList<ITypeReference> parameterTypeReferences = null) |
||||
{ |
||||
if (context.CurrentTypeDefinition == null) |
||||
return null; |
||||
if (parameterTypeReferences == null) |
||||
parameterTypeReferences = EmptyList<ITypeReference>.Instance; |
||||
if (typeParameterNames == null || typeParameterNames.Count == 0) { |
||||
// non-generic member
|
||||
// In this case, we can simply resolve the parameter types in the given context
|
||||
var parameterTypes = parameterTypeReferences.Resolve(context); |
||||
if (explicitInterfaceTypeReference == null) { |
||||
foreach (IMember member in context.CurrentTypeDefinition.Members) { |
||||
if (member.IsExplicitInterfaceImplementation) |
||||
continue; |
||||
if (IsNonGenericMatch(member, symbolKind, name, parameterTypes)) |
||||
return member; |
||||
} |
||||
} else { |
||||
IType explicitInterfaceType = explicitInterfaceTypeReference.Resolve(context); |
||||
foreach (IMember member in context.CurrentTypeDefinition.Members) { |
||||
if (!member.IsExplicitInterfaceImplementation) |
||||
continue; |
||||
var interfaceMembers = member.ExplicitlyImplementedInterfaceMembers.ToList(); |
||||
if (interfaceMembers.Count != 1) |
||||
continue; |
||||
if (IsNonGenericMatch(member, symbolKind, name, parameterTypes)) { |
||||
if (explicitInterfaceType.Equals(interfaceMembers[0].DeclaringType)) |
||||
return member; |
||||
} |
||||
} |
||||
} |
||||
} else { |
||||
// generic member
|
||||
// In this case, we must specify the correct context for resolving the parameter types
|
||||
foreach (IMethod method in context.CurrentTypeDefinition.Methods) { |
||||
if (method.SymbolKind != symbolKind) |
||||
continue; |
||||
if (method.Name != name) |
||||
continue; |
||||
if (method.Parameters.Count != parameterTypeReferences.Count) |
||||
continue; |
||||
// Compare type parameter count and names:
|
||||
if (!typeParameterNames.SequenceEqual(method.TypeParameters.Select(tp => tp.Name))) |
||||
continue; |
||||
// Once we know the type parameter names are fitting, we can resolve the
|
||||
// type references in the context of the method:
|
||||
var contextForMethod = context.WithCurrentMember(method); |
||||
var parameterTypes = parameterTypeReferences.Resolve(contextForMethod); |
||||
if (!IsParameterTypeMatch(method, parameterTypes)) |
||||
continue; |
||||
if (explicitInterfaceTypeReference == null) { |
||||
if (!method.IsExplicitInterfaceImplementation) |
||||
return method; |
||||
} else if (method.IsExplicitInterfaceImplementation && method.ExplicitlyImplementedInterfaceMembers.Count() == 1) { |
||||
IType explicitInterfaceType = explicitInterfaceTypeReference.Resolve(contextForMethod); |
||||
if (explicitInterfaceType.Equals(method.ExplicitlyImplementedInterfaceMembers.First().DeclaringType)) |
||||
return method; |
||||
} |
||||
} |
||||
} |
||||
return null; |
||||
} |
||||
|
||||
static bool IsNonGenericMatch(IMember member, SymbolKind symbolKind, string name, IReadOnlyList<IType> parameterTypes) |
||||
{ |
||||
if (member.SymbolKind != symbolKind) |
||||
return false; |
||||
if (member.Name != name) |
||||
return false; |
||||
IMethod method = member as IMethod; |
||||
if (method != null && method.TypeParameters.Count > 0) |
||||
return false; |
||||
return IsParameterTypeMatch(member, parameterTypes); |
||||
} |
||||
|
||||
static bool IsParameterTypeMatch(IMember member, IReadOnlyList<IType> parameterTypes) |
||||
{ |
||||
IParameterizedMember parameterizedMember = member as IParameterizedMember; |
||||
if (parameterizedMember == null) { |
||||
return parameterTypes.Count == 0; |
||||
} else if (parameterTypes.Count == parameterizedMember.Parameters.Count) { |
||||
for (int i = 0; i < parameterTypes.Count; i++) { |
||||
IType type1 = parameterTypes[i]; |
||||
IType type2 = parameterizedMember.Parameters[i].Type; |
||||
if (!type1.Equals(type2)) { |
||||
return false; |
||||
} |
||||
} |
||||
return true; |
||||
} else { |
||||
return false; |
||||
} |
||||
} |
||||
#endregion
|
||||
} |
||||
} |
@ -1,51 +0,0 @@
@@ -1,51 +0,0 @@
|
||||
// Copyright (c) 2010-2013 AlphaSierraPapa for the SharpDevelop Team
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy of this
|
||||
// software and associated documentation files (the "Software"), to deal in the Software
|
||||
// without restriction, including without limitation the rights to use, copy, modify, merge,
|
||||
// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons
|
||||
// to whom the Software is furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in all copies or
|
||||
// substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
|
||||
// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
|
||||
// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE
|
||||
// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
|
||||
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
// DEALINGS IN THE SOFTWARE.
|
||||
|
||||
using System; |
||||
|
||||
namespace ICSharpCode.Decompiler.TypeSystem.Implementation |
||||
{ |
||||
/// <summary>
|
||||
/// Given a reference to an accessor, returns the accessor's owner.
|
||||
/// </summary>
|
||||
[Serializable] |
||||
sealed class AccessorOwnerMemberReference : IMemberReference |
||||
{ |
||||
readonly IMemberReference accessorReference; |
||||
|
||||
public AccessorOwnerMemberReference(IMemberReference accessorReference) |
||||
{ |
||||
if (accessorReference == null) |
||||
throw new ArgumentNullException("accessorReference"); |
||||
this.accessorReference = accessorReference; |
||||
} |
||||
|
||||
public ITypeReference DeclaringTypeReference { |
||||
get { return accessorReference.DeclaringTypeReference; } |
||||
} |
||||
|
||||
public IMember Resolve(ITypeResolveContext context) |
||||
{ |
||||
IMethod method = accessorReference.Resolve(context) as IMethod; |
||||
if (method != null) |
||||
return method.AccessorOwner; |
||||
else |
||||
return null; |
||||
} |
||||
} |
||||
} |
@ -1,399 +0,0 @@
@@ -1,399 +0,0 @@
|
||||
//
|
||||
// BlobReader.cs
|
||||
//
|
||||
// Author:
|
||||
// Daniel Grunwald <daniel@danielgrunwald.de>
|
||||
//
|
||||
// Copyright (c) 2010-2013 AlphaSierraPapa for the SharpDevelop Team
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
|
||||
using System; |
||||
using System.Collections.Generic; |
||||
using ICSharpCode.Decompiler.Semantics; |
||||
|
||||
namespace ICSharpCode.Decompiler.TypeSystem.Implementation |
||||
{ |
||||
sealed class BlobReader |
||||
{ |
||||
internal static int GetBlobHashCode(byte[] blob) |
||||
{ |
||||
unchecked { |
||||
int hash = 0; |
||||
foreach (byte b in blob) { |
||||
hash *= 257; |
||||
hash += b; |
||||
} |
||||
return hash; |
||||
} |
||||
} |
||||
|
||||
internal static bool BlobEquals(byte[] a, byte[] b) |
||||
{ |
||||
if (a.Length != b.Length) |
||||
return false; |
||||
for (int i = 0; i < a.Length; i++) { |
||||
if (a[i] != b[i]) |
||||
return false; |
||||
} |
||||
return true; |
||||
} |
||||
|
||||
byte[] buffer; |
||||
int position; |
||||
readonly IAssembly currentResolvedAssembly; |
||||
|
||||
public BlobReader(byte[] buffer, IAssembly currentResolvedAssembly) |
||||
{ |
||||
if (buffer == null) |
||||
throw new ArgumentNullException("buffer"); |
||||
this.buffer = buffer; |
||||
this.currentResolvedAssembly = currentResolvedAssembly; |
||||
} |
||||
|
||||
public byte ReadByte() |
||||
{ |
||||
return buffer[position++]; |
||||
} |
||||
|
||||
public sbyte ReadSByte() |
||||
{ |
||||
unchecked { |
||||
return(sbyte) ReadByte(); |
||||
} |
||||
} |
||||
|
||||
public byte[] ReadBytes(int length) |
||||
{ |
||||
var bytes = new byte[length]; |
||||
Buffer.BlockCopy(buffer, position, bytes, 0, length); |
||||
position += length; |
||||
return bytes; |
||||
} |
||||
|
||||
public ushort ReadUInt16() |
||||
{ |
||||
unchecked { |
||||
ushort value =(ushort)(buffer[position] |
||||
|(buffer[position + 1] << 8)); |
||||
position += 2; |
||||
return value; |
||||
} |
||||
} |
||||
|
||||
public short ReadInt16() |
||||
{ |
||||
unchecked { |
||||
return(short) ReadUInt16(); |
||||
} |
||||
} |
||||
|
||||
public uint ReadUInt32() |
||||
{ |
||||
unchecked { |
||||
uint value =(uint)(buffer[position] |
||||
|(buffer[position + 1] << 8) |
||||
|(buffer[position + 2] << 16) |
||||
|(buffer[position + 3] << 24)); |
||||
position += 4; |
||||
return value; |
||||
} |
||||
} |
||||
|
||||
public int ReadInt32() |
||||
{ |
||||
unchecked { |
||||
return(int) ReadUInt32(); |
||||
} |
||||
} |
||||
|
||||
public ulong ReadUInt64() |
||||
{ |
||||
unchecked { |
||||
uint low = ReadUInt32(); |
||||
uint high = ReadUInt32(); |
||||
|
||||
return(((ulong) high) << 32) | low; |
||||
} |
||||
} |
||||
|
||||
public long ReadInt64() |
||||
{ |
||||
unchecked { |
||||
return(long) ReadUInt64(); |
||||
} |
||||
} |
||||
|
||||
public uint ReadCompressedUInt32() |
||||
{ |
||||
unchecked { |
||||
byte first = ReadByte(); |
||||
if((first & 0x80) == 0) |
||||
return first; |
||||
|
||||
if((first & 0x40) == 0) |
||||
return((uint)(first & ~0x80) << 8) |
||||
| ReadByte(); |
||||
|
||||
return((uint)(first & ~0xc0) << 24) |
||||
|(uint) ReadByte() << 16 |
||||
|(uint) ReadByte() << 8 |
||||
| ReadByte(); |
||||
} |
||||
} |
||||
|
||||
public float ReadSingle() |
||||
{ |
||||
unchecked { |
||||
if(!BitConverter.IsLittleEndian) { |
||||
var bytes = ReadBytes(4); |
||||
Array.Reverse(bytes); |
||||
return BitConverter.ToSingle(bytes, 0); |
||||
} |
||||
|
||||
float value = BitConverter.ToSingle(buffer, position); |
||||
position += 4; |
||||
return value; |
||||
} |
||||
} |
||||
|
||||
public double ReadDouble() |
||||
{ |
||||
unchecked { |
||||
if(!BitConverter.IsLittleEndian) { |
||||
var bytes = ReadBytes(8); |
||||
Array.Reverse(bytes); |
||||
return BitConverter.ToDouble(bytes, 0); |
||||
} |
||||
|
||||
double value = BitConverter.ToDouble(buffer, position); |
||||
position += 8; |
||||
return value; |
||||
} |
||||
} |
||||
|
||||
public ResolveResult ReadFixedArg(IType argType) |
||||
{ |
||||
if (argType.Kind == TypeKind.Array) { |
||||
if (((ArrayType)argType).Dimensions != 1) { |
||||
// Only single-dimensional arrays are supported
|
||||
return ErrorResolveResult.UnknownError; |
||||
} |
||||
IType elementType = ((ArrayType)argType).ElementType; |
||||
uint numElem = ReadUInt32(); |
||||
if (numElem == 0xffffffff) { |
||||
// null reference
|
||||
return new ConstantResolveResult(argType, null); |
||||
} else { |
||||
ResolveResult[] elements = new ResolveResult[numElem]; |
||||
for (int i = 0; i < elements.Length; i++) { |
||||
elements[i] = ReadElem(elementType); |
||||
// Stop decoding when encountering an error:
|
||||
if (elements[i].IsError) |
||||
return ErrorResolveResult.UnknownError; |
||||
} |
||||
IType int32 = currentResolvedAssembly.Compilation.FindType(KnownTypeCode.Int32); |
||||
ResolveResult[] sizeArgs = { new ConstantResolveResult(int32, elements.Length) }; |
||||
return new ArrayCreateResolveResult(argType, sizeArgs, elements); |
||||
} |
||||
} else { |
||||
return ReadElem(argType); |
||||
} |
||||
} |
||||
|
||||
public ResolveResult ReadElem(IType elementType) |
||||
{ |
||||
ITypeDefinition underlyingType; |
||||
if (elementType.Kind == TypeKind.Enum) { |
||||
underlyingType = elementType.GetDefinition().EnumUnderlyingType.GetDefinition(); |
||||
} else { |
||||
underlyingType = elementType.GetDefinition(); |
||||
} |
||||
if (underlyingType == null) |
||||
return ErrorResolveResult.UnknownError; |
||||
KnownTypeCode typeCode = underlyingType.KnownTypeCode; |
||||
if (typeCode == KnownTypeCode.Object) { |
||||
// boxed value type
|
||||
IType boxedTyped = ReadCustomAttributeFieldOrPropType(); |
||||
ResolveResult elem = ReadFixedArg(boxedTyped); |
||||
if (elem.IsCompileTimeConstant && elem.ConstantValue == null) |
||||
return new ConstantResolveResult(elementType, null); |
||||
else |
||||
return new ConversionResolveResult(elementType, elem, Conversion.BoxingConversion); |
||||
} else if (typeCode == KnownTypeCode.Type) { |
||||
var type = ReadType(); |
||||
if (type != null) { |
||||
return new TypeOfResolveResult(underlyingType, type); |
||||
} else { |
||||
return new ConstantResolveResult(underlyingType, null); |
||||
} |
||||
} else { |
||||
return new ConstantResolveResult(elementType, ReadElemValue(typeCode)); |
||||
} |
||||
} |
||||
|
||||
object ReadElemValue(KnownTypeCode typeCode) |
||||
{ |
||||
switch (typeCode) { |
||||
case KnownTypeCode.Boolean: |
||||
return ReadByte() != 0; |
||||
case KnownTypeCode.Char: |
||||
return (char)ReadUInt16(); |
||||
case KnownTypeCode.SByte: |
||||
return ReadSByte(); |
||||
case KnownTypeCode.Byte: |
||||
return ReadByte(); |
||||
case KnownTypeCode.Int16: |
||||
return ReadInt16(); |
||||
case KnownTypeCode.UInt16: |
||||
return ReadUInt16(); |
||||
case KnownTypeCode.Int32: |
||||
return ReadInt32(); |
||||
case KnownTypeCode.UInt32: |
||||
return ReadUInt32(); |
||||
case KnownTypeCode.Int64: |
||||
return ReadInt64(); |
||||
case KnownTypeCode.UInt64: |
||||
return ReadUInt64(); |
||||
case KnownTypeCode.Single: |
||||
return ReadSingle(); |
||||
case KnownTypeCode.Double: |
||||
return ReadDouble(); |
||||
case KnownTypeCode.String: |
||||
return ReadSerString(); |
||||
default: |
||||
throw new NotSupportedException(); |
||||
} |
||||
} |
||||
|
||||
public string ReadSerString () |
||||
{ |
||||
if (buffer [position] == 0xff) { |
||||
position++; |
||||
return null; |
||||
} |
||||
|
||||
int length = (int) ReadCompressedUInt32(); |
||||
if (length == 0) |
||||
return string.Empty; |
||||
|
||||
string @string = System.Text.Encoding.UTF8.GetString( |
||||
buffer, position, |
||||
buffer [position + length - 1] == 0 ? length - 1 : length); |
||||
|
||||
position += length; |
||||
return @string; |
||||
} |
||||
|
||||
public KeyValuePair<IMember, ResolveResult> ReadNamedArg(IType attributeType) |
||||
{ |
||||
SymbolKind memberType; |
||||
var b = ReadByte(); |
||||
switch (b) { |
||||
case 0x53: |
||||
memberType = SymbolKind.Field; |
||||
break; |
||||
case 0x54: |
||||
memberType = SymbolKind.Property; |
||||
break; |
||||
default: |
||||
throw new NotSupportedException(string.Format("Custom member type 0x{0:x} is not supported.", b)); |
||||
} |
||||
IType type = ReadCustomAttributeFieldOrPropType(); |
||||
string name = ReadSerString(); |
||||
ResolveResult val = ReadFixedArg(type); |
||||
IMember member = null; |
||||
// Use last matching member, as GetMembers() returns members from base types first.
|
||||
foreach (IMember m in attributeType.GetMembers(m => m.SymbolKind == memberType && m.Name == name)) { |
||||
if (m.ReturnType.Equals(type)) |
||||
member = m; |
||||
} |
||||
return new KeyValuePair<IMember, ResolveResult>(member, val); |
||||
} |
||||
|
||||
IType ReadCustomAttributeFieldOrPropType() |
||||
{ |
||||
ICompilation compilation = currentResolvedAssembly.Compilation; |
||||
var b = ReadByte(); |
||||
switch (b) { |
||||
case 0x02: |
||||
return compilation.FindType(KnownTypeCode.Boolean); |
||||
case 0x03: |
||||
return compilation.FindType(KnownTypeCode.Char); |
||||
case 0x04: |
||||
return compilation.FindType(KnownTypeCode.SByte); |
||||
case 0x05: |
||||
return compilation.FindType(KnownTypeCode.Byte); |
||||
case 0x06: |
||||
return compilation.FindType(KnownTypeCode.Int16); |
||||
case 0x07: |
||||
return compilation.FindType(KnownTypeCode.UInt16); |
||||
case 0x08: |
||||
return compilation.FindType(KnownTypeCode.Int32); |
||||
case 0x09: |
||||
return compilation.FindType(KnownTypeCode.UInt32); |
||||
case 0x0a: |
||||
return compilation.FindType(KnownTypeCode.Int64); |
||||
case 0x0b: |
||||
return compilation.FindType(KnownTypeCode.UInt64); |
||||
case 0x0c: |
||||
return compilation.FindType(KnownTypeCode.Single); |
||||
case 0x0d: |
||||
return compilation.FindType(KnownTypeCode.Double); |
||||
case 0x0e: |
||||
return compilation.FindType(KnownTypeCode.String); |
||||
case 0x1d: |
||||
return new ArrayType(compilation, ReadCustomAttributeFieldOrPropType()); |
||||
case 0x50: |
||||
return compilation.FindType(KnownTypeCode.Type); |
||||
case 0x51: // boxed value type
|
||||
return compilation.FindType(KnownTypeCode.Object); |
||||
case 0x55: // enum
|
||||
var type = ReadType(); |
||||
if (type == null) { |
||||
throw new NotSupportedException("Enum type should not be null."); |
||||
} |
||||
return type; |
||||
default: |
||||
throw new NotSupportedException(string.Format("Custom attribute type 0x{0:x} is not supported.", b)); |
||||
} |
||||
} |
||||
|
||||
IType ReadType() |
||||
{ |
||||
string typeName = ReadSerString(); |
||||
if (typeName == null) { |
||||
return null; |
||||
} |
||||
ITypeReference typeReference = ReflectionHelper.ParseReflectionName(typeName); |
||||
IType typeInCurrentAssembly = typeReference.Resolve(new SimpleTypeResolveContext(currentResolvedAssembly)); |
||||
if (typeInCurrentAssembly.Kind != TypeKind.Unknown) |
||||
return typeInCurrentAssembly; |
||||
|
||||
// look for the type in mscorlib
|
||||
ITypeDefinition systemObject = currentResolvedAssembly.Compilation.FindType(KnownTypeCode.Object).GetDefinition(); |
||||
if (systemObject != null) { |
||||
return typeReference.Resolve(new SimpleTypeResolveContext(systemObject.ParentAssembly)); |
||||
} else { |
||||
// couldn't find corlib - return the unknown IType for the current assembly
|
||||
return typeInCurrentAssembly; |
||||
} |
||||
} |
||||
} |
||||
} |
@ -1,115 +0,0 @@
@@ -1,115 +0,0 @@
|
||||
// Copyright (c) 2010-2013 AlphaSierraPapa for the SharpDevelop Team
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy of this
|
||||
// software and associated documentation files (the "Software"), to deal in the Software
|
||||
// without restriction, including without limitation the rights to use, copy, modify, merge,
|
||||
// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons
|
||||
// to whom the Software is furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in all copies or
|
||||
// substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
|
||||
// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
|
||||
// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE
|
||||
// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
|
||||
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
// DEALINGS IN THE SOFTWARE.
|
||||
|
||||
using System; |
||||
using System.Collections.Generic; |
||||
using ICSharpCode.Decompiler.Util; |
||||
|
||||
namespace ICSharpCode.Decompiler.TypeSystem.Implementation |
||||
{ |
||||
/// <summary>
|
||||
/// References an entity by its type and name.
|
||||
/// This class can be used to refer to all members except for constructors and explicit interface implementations.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Resolving a DefaultMemberReference requires a context that provides enough information for resolving the declaring type reference
|
||||
/// and the parameter types references.
|
||||
/// </remarks>
|
||||
[Serializable] |
||||
public sealed class DefaultMemberReference : IMemberReference, ISupportsInterning |
||||
{ |
||||
readonly SymbolKind symbolKind; |
||||
readonly ITypeReference typeReference; |
||||
readonly string name; |
||||
readonly int typeParameterCount; |
||||
readonly IList<ITypeReference> parameterTypes; |
||||
|
||||
public DefaultMemberReference(SymbolKind symbolKind, ITypeReference typeReference, string name, int typeParameterCount = 0, IList<ITypeReference> parameterTypes = null) |
||||
{ |
||||
if (typeReference == null) |
||||
throw new ArgumentNullException("typeReference"); |
||||
if (name == null) |
||||
throw new ArgumentNullException("name"); |
||||
if (typeParameterCount != 0 && symbolKind != SymbolKind.Method) |
||||
throw new ArgumentException("Type parameter count > 0 is only supported for methods."); |
||||
this.symbolKind = symbolKind; |
||||
this.typeReference = typeReference; |
||||
this.name = name; |
||||
this.typeParameterCount = typeParameterCount; |
||||
this.parameterTypes = parameterTypes ?? EmptyList<ITypeReference>.Instance; |
||||
} |
||||
|
||||
public ITypeReference DeclaringTypeReference { |
||||
get { return typeReference; } |
||||
} |
||||
|
||||
static readonly NormalizeTypeVisitor normalizeTypeVisitor = new NormalizeTypeVisitor(); |
||||
|
||||
public IMember Resolve(ITypeResolveContext context) |
||||
{ |
||||
IType type = typeReference.Resolve(context); |
||||
IEnumerable<IMember> members; |
||||
if (symbolKind == SymbolKind.Accessor) { |
||||
members = type.GetAccessors( |
||||
m => m.Name == name && !m.IsExplicitInterfaceImplementation, |
||||
GetMemberOptions.IgnoreInheritedMembers); |
||||
} else if (symbolKind == SymbolKind.Method) { |
||||
members = type.GetMethods( |
||||
m => m.Name == name && m.SymbolKind == SymbolKind.Method |
||||
&& m.TypeParameters.Count == typeParameterCount && !m.IsExplicitInterfaceImplementation, |
||||
GetMemberOptions.IgnoreInheritedMembers); |
||||
} else { |
||||
members = type.GetMembers( |
||||
m => m.Name == name && m.SymbolKind == symbolKind && !m.IsExplicitInterfaceImplementation, |
||||
GetMemberOptions.IgnoreInheritedMembers); |
||||
} |
||||
var resolvedParameterTypes = parameterTypes.Resolve(context); |
||||
foreach (IMember member in members) { |
||||
IParameterizedMember parameterizedMember = member as IParameterizedMember; |
||||
if (parameterizedMember == null) { |
||||
if (parameterTypes.Count == 0) |
||||
return member; |
||||
} else if (parameterTypes.Count == parameterizedMember.Parameters.Count) { |
||||
bool signatureMatches = true; |
||||
for (int i = 0; i < parameterTypes.Count; i++) { |
||||
IType type1 = resolvedParameterTypes[i].AcceptVisitor(normalizeTypeVisitor); |
||||
IType type2 = parameterizedMember.Parameters[i].Type.AcceptVisitor(normalizeTypeVisitor); |
||||
if (!type1.Equals(type2)) { |
||||
signatureMatches = false; |
||||
break; |
||||
} |
||||
} |
||||
if (signatureMatches) |
||||
return member; |
||||
} |
||||
} |
||||
return null; |
||||
} |
||||
|
||||
int ISupportsInterning.GetHashCodeForInterning() |
||||
{ |
||||
return (int)symbolKind ^ typeReference.GetHashCode() ^ name.GetHashCode() ^ parameterTypes.GetHashCode(); |
||||
} |
||||
|
||||
bool ISupportsInterning.EqualsForInterning(ISupportsInterning other) |
||||
{ |
||||
DefaultMemberReference o = other as DefaultMemberReference; |
||||
return o != null && symbolKind == o.symbolKind && typeReference == o.typeReference && name == o.name && parameterTypes == o.parameterTypes; |
||||
} |
||||
} |
||||
} |
@ -1,69 +0,0 @@
@@ -1,69 +0,0 @@
|
||||
// Copyright (c) 2010-2013 AlphaSierraPapa for the SharpDevelop Team
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy of this
|
||||
// software and associated documentation files (the "Software"), to deal in the Software
|
||||
// without restriction, including without limitation the rights to use, copy, modify, merge,
|
||||
// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons
|
||||
// to whom the Software is furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in all copies or
|
||||
// substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
|
||||
// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
|
||||
// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE
|
||||
// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
|
||||
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
// DEALINGS IN THE SOFTWARE.
|
||||
|
||||
using System; |
||||
using ICSharpCode.Decompiler.Semantics; |
||||
|
||||
namespace ICSharpCode.Decompiler.TypeSystem.Implementation |
||||
{ |
||||
/// <summary>
|
||||
/// A simple constant value that is independent of the resolve context.
|
||||
/// </summary>
|
||||
[Serializable] |
||||
public sealed class SimpleConstantValue : IConstantValue, ISupportsInterning |
||||
{ |
||||
readonly ITypeReference type; |
||||
readonly object value; |
||||
|
||||
public SimpleConstantValue(ITypeReference type, object value) |
||||
{ |
||||
if (type == null) |
||||
throw new ArgumentNullException("type"); |
||||
this.type = type; |
||||
this.value = value; |
||||
} |
||||
|
||||
public ResolveResult Resolve(ITypeResolveContext context) |
||||
{ |
||||
return new ConstantResolveResult(type.Resolve(context), value); |
||||
} |
||||
|
||||
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Globalization", "CA1308:NormalizeStringsToUppercase", |
||||
Justification = "The C# keyword is lower case")] |
||||
public override string ToString() |
||||
{ |
||||
if (value == null) |
||||
return "null"; |
||||
else if (value is bool) |
||||
return value.ToString().ToLowerInvariant(); |
||||
else |
||||
return value.ToString(); |
||||
} |
||||
|
||||
int ISupportsInterning.GetHashCodeForInterning() |
||||
{ |
||||
return type.GetHashCode() ^ (value != null ? value.GetHashCode() : 0); |
||||
} |
||||
|
||||
bool ISupportsInterning.EqualsForInterning(ISupportsInterning other) |
||||
{ |
||||
SimpleConstantValue scv = other as SimpleConstantValue; |
||||
return scv != null && type == scv.type && value == scv.value; |
||||
} |
||||
} |
||||
} |
@ -1,140 +0,0 @@
@@ -1,140 +0,0 @@
|
||||
// Copyright (c) 2010-2013 AlphaSierraPapa for the SharpDevelop Team
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy of this
|
||||
// software and associated documentation files (the "Software"), to deal in the Software
|
||||
// without restriction, including without limitation the rights to use, copy, modify, merge,
|
||||
// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons
|
||||
// to whom the Software is furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in all copies or
|
||||
// substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
|
||||
// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
|
||||
// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE
|
||||
// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
|
||||
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
// DEALINGS IN THE SOFTWARE.
|
||||
|
||||
using System.Collections; |
||||
using System.Collections.Generic; |
||||
using System.Collections.ObjectModel; |
||||
using System.Runtime.CompilerServices; |
||||
using ICSharpCode.Decompiler.Util; |
||||
|
||||
namespace ICSharpCode.Decompiler.TypeSystem.Implementation |
||||
{ |
||||
/// <summary>
|
||||
/// Simple interning provider.
|
||||
/// </summary>
|
||||
public sealed class SimpleInterningProvider : InterningProvider |
||||
{ |
||||
sealed class InterningComparer : IEqualityComparer<ISupportsInterning> |
||||
{ |
||||
public bool Equals(ISupportsInterning x, ISupportsInterning y) |
||||
{ |
||||
return x.EqualsForInterning(y); |
||||
} |
||||
|
||||
public int GetHashCode(ISupportsInterning obj) |
||||
{ |
||||
return obj.GetHashCodeForInterning(); |
||||
} |
||||
} |
||||
|
||||
sealed class ListComparer : IEqualityComparer<IEnumerable> |
||||
{ |
||||
public bool Equals(IEnumerable a, IEnumerable b) |
||||
{ |
||||
if (a.GetType() != b.GetType()) |
||||
return false; |
||||
IEnumerator e1 = a.GetEnumerator(); |
||||
IEnumerator e2 = b.GetEnumerator(); |
||||
while (e1.MoveNext()) { |
||||
// e1 has more elements than e2; or elements are different
|
||||
if (!e2.MoveNext() || e1.Current != e2.Current) |
||||
return false; |
||||
} |
||||
if (e2.MoveNext()) // e2 has more elements than e1
|
||||
return false; |
||||
// No need to dispose e1/e2: non-generic IEnumerator doesn't implement IDisposable,
|
||||
// and the underlying enumerator will likely be a List<T>.Enumerator which has an empty Dispose() method.
|
||||
return true; |
||||
} |
||||
|
||||
public int GetHashCode(IEnumerable obj) |
||||
{ |
||||
int hashCode = obj.GetType().GetHashCode(); |
||||
unchecked { |
||||
foreach (object o in obj) { |
||||
hashCode *= 27; |
||||
hashCode += RuntimeHelpers.GetHashCode(o); |
||||
} |
||||
} |
||||
return hashCode; |
||||
} |
||||
} |
||||
|
||||
Dictionary<object, object> byValueDict = new Dictionary<object, object>(); |
||||
Dictionary<ISupportsInterning, ISupportsInterning> supportsInternDict = new Dictionary<ISupportsInterning, ISupportsInterning>(new InterningComparer()); |
||||
Dictionary<IEnumerable, IEnumerable> listDict = new Dictionary<IEnumerable, IEnumerable>(new ListComparer()); |
||||
|
||||
public override ISupportsInterning Intern(ISupportsInterning obj) |
||||
{ |
||||
if (obj == null) |
||||
return null; |
||||
|
||||
// ensure objects are frozen when we put them into the dictionary
|
||||
// note that Freeze may change the hash code of the object
|
||||
FreezableHelper.Freeze(obj); |
||||
|
||||
ISupportsInterning output; |
||||
if (supportsInternDict.TryGetValue(obj, out output)) { |
||||
return output; |
||||
} else { |
||||
supportsInternDict.Add(obj, obj); |
||||
return obj; |
||||
} |
||||
} |
||||
|
||||
public override string Intern(string text) |
||||
{ |
||||
if (text == null) |
||||
return null; |
||||
|
||||
object output; |
||||
if (byValueDict.TryGetValue(text, out output)) |
||||
return (string)output; |
||||
else |
||||
return text; |
||||
} |
||||
|
||||
public override object InternValue(object obj) |
||||
{ |
||||
if (obj == null) |
||||
return null; |
||||
|
||||
object output; |
||||
if (byValueDict.TryGetValue(obj, out output)) |
||||
return output; |
||||
else |
||||
return obj; |
||||
} |
||||
|
||||
public override IList<T> InternList<T>(IList<T> list) |
||||
{ |
||||
if (list == null) |
||||
return null; |
||||
if (list.Count == 0) |
||||
return EmptyList<T>.Instance; |
||||
if (!list.IsReadOnly) |
||||
list = new ReadOnlyCollection<T>(list); |
||||
IEnumerable output; |
||||
if (listDict.TryGetValue(list, out output)) |
||||
list = (IList<T>)output; |
||||
else |
||||
listDict.Add(list, list); |
||||
return list; |
||||
} |
||||
} |
||||
} |
Loading…
Reference in new issue