mirror of https://github.com/icsharpcode/ILSpy.git
27 changed files with 35 additions and 3809 deletions
@ -1,21 +0,0 @@ |
|||||||
using System; |
|
||||||
using System.Collections.Generic; |
|
||||||
using System.Linq; |
|
||||||
using System.Text; |
|
||||||
using System.Threading.Tasks; |
|
||||||
using ICSharpCode.Decompiler.TypeSystem; |
|
||||||
using ICSharpCode.Decompiler.TypeSystem.Implementation; |
|
||||||
|
|
||||||
namespace ICSharpCode.Decompiler.Tests.TypeSystem |
|
||||||
{ |
|
||||||
public static class TypeSystemHelper |
|
||||||
{ |
|
||||||
public static ICompilation CreateCompilation(params IUnresolvedTypeDefinition[] unresolvedTypeDefinitions) |
|
||||||
{ |
|
||||||
var unresolvedAsm = new DefaultUnresolvedAssembly("dummy"); |
|
||||||
foreach (var typeDef in unresolvedTypeDefinitions) |
|
||||||
unresolvedAsm.AddTypeDefinition(typeDef); |
|
||||||
return new SimpleCompilation(unresolvedAsm, TypeSystemLoaderTests.Mscorlib, TypeSystemLoaderTests.SystemCore); |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
@ -1,65 +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.Util; |
|
||||||
|
|
||||||
namespace ICSharpCode.Decompiler.TypeSystem.Implementation |
|
||||||
{ |
|
||||||
public class DefaultResolvedEvent : AbstractResolvedMember, IEvent |
|
||||||
{ |
|
||||||
protected new readonly IUnresolvedEvent unresolved; |
|
||||||
IMethod addAccessor; |
|
||||||
IMethod removeAccessor; |
|
||||||
IMethod invokeAccessor; |
|
||||||
|
|
||||||
public DefaultResolvedEvent(IUnresolvedEvent unresolved, ITypeResolveContext parentContext) |
|
||||||
: base(unresolved, parentContext) |
|
||||||
{ |
|
||||||
this.unresolved = unresolved; |
|
||||||
} |
|
||||||
|
|
||||||
public bool CanAdd { |
|
||||||
get { return unresolved.CanAdd; } |
|
||||||
} |
|
||||||
|
|
||||||
public bool CanRemove { |
|
||||||
get { return unresolved.CanRemove; } |
|
||||||
} |
|
||||||
|
|
||||||
public bool CanInvoke { |
|
||||||
get { return unresolved.CanInvoke; } |
|
||||||
} |
|
||||||
|
|
||||||
public IMethod AddAccessor { |
|
||||||
get { return GetAccessor(ref addAccessor, unresolved.AddAccessor); } |
|
||||||
} |
|
||||||
|
|
||||||
public IMethod RemoveAccessor { |
|
||||||
get { return GetAccessor(ref removeAccessor, unresolved.RemoveAccessor); } |
|
||||||
} |
|
||||||
|
|
||||||
public IMethod InvokeAccessor { |
|
||||||
get { return GetAccessor(ref invokeAccessor, unresolved.InvokeAccessor); } |
|
||||||
} |
|
||||||
|
|
||||||
public override IMember Specialize(TypeParameterSubstitution substitution) |
|
||||||
{ |
|
||||||
return SpecializedEvent.Create(this, substitution); |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
@ -1,78 +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; |
|
||||||
using ICSharpCode.Decompiler.Util; |
|
||||||
|
|
||||||
namespace ICSharpCode.Decompiler.TypeSystem.Implementation |
|
||||||
{ |
|
||||||
public class DefaultResolvedField : AbstractResolvedMember, IField |
|
||||||
{ |
|
||||||
volatile ResolveResult constantValue; |
|
||||||
|
|
||||||
public DefaultResolvedField(IUnresolvedField unresolved, ITypeResolveContext parentContext) |
|
||||||
: base(unresolved, parentContext) |
|
||||||
{ |
|
||||||
} |
|
||||||
|
|
||||||
public bool IsReadOnly { |
|
||||||
get { return ((IUnresolvedField)unresolved).IsReadOnly; } |
|
||||||
} |
|
||||||
|
|
||||||
public bool IsVolatile { |
|
||||||
get { return ((IUnresolvedField)unresolved).IsVolatile; } |
|
||||||
} |
|
||||||
|
|
||||||
IType IVariable.Type { |
|
||||||
get { return this.ReturnType; } |
|
||||||
} |
|
||||||
|
|
||||||
public bool IsConst { |
|
||||||
get { return ((IUnresolvedField)unresolved).IsConst; } |
|
||||||
} |
|
||||||
|
|
||||||
public bool IsFixed { |
|
||||||
get { return ((IUnresolvedField)unresolved).IsFixed; } |
|
||||||
} |
|
||||||
|
|
||||||
public object ConstantValue { |
|
||||||
get { |
|
||||||
ResolveResult rr = this.constantValue; |
|
||||||
if (rr == null) { |
|
||||||
using (var busyLock = BusyManager.Enter(this)) { |
|
||||||
if (!busyLock.Success) |
|
||||||
return null; |
|
||||||
|
|
||||||
IConstantValue unresolvedCV = ((IUnresolvedField)unresolved).ConstantValue; |
|
||||||
if (unresolvedCV != null) |
|
||||||
rr = unresolvedCV.Resolve(context); |
|
||||||
else |
|
||||||
rr = ErrorResolveResult.UnknownError; |
|
||||||
this.constantValue = rr; |
|
||||||
} |
|
||||||
} |
|
||||||
return rr.ConstantValue; |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
public override IMember Specialize(TypeParameterSubstitution substitution) |
|
||||||
{ |
|
||||||
return SpecializedField.Create(this, substitution); |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
@ -1,288 +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 System.Text; |
|
||||||
using ICSharpCode.Decompiler.Util; |
|
||||||
|
|
||||||
namespace ICSharpCode.Decompiler.TypeSystem.Implementation |
|
||||||
{ |
|
||||||
/// <summary>
|
|
||||||
/// Default implementation of <see cref="IMethod"/> that resolves an unresolved method.
|
|
||||||
/// </summary>
|
|
||||||
public class DefaultResolvedMethod : AbstractResolvedMember, IMethod |
|
||||||
{ |
|
||||||
IUnresolvedMethod[] parts; |
|
||||||
|
|
||||||
public DefaultResolvedMethod(DefaultUnresolvedMethod unresolved, ITypeResolveContext parentContext) |
|
||||||
: this(unresolved, parentContext, unresolved.IsExtensionMethod) |
|
||||||
{ |
|
||||||
} |
|
||||||
|
|
||||||
public DefaultResolvedMethod(IUnresolvedMethod unresolved, ITypeResolveContext parentContext, bool isExtensionMethod) |
|
||||||
: base(unresolved, parentContext) |
|
||||||
{ |
|
||||||
this.Parameters = unresolved.Parameters.CreateResolvedParameters(context); |
|
||||||
this.ReturnTypeAttributes = unresolved.ReturnTypeAttributes.CreateResolvedAttributes(parentContext); |
|
||||||
this.TypeParameters = unresolved.TypeParameters.CreateResolvedTypeParameters(context); |
|
||||||
this.IsExtensionMethod = isExtensionMethod; |
|
||||||
} |
|
||||||
|
|
||||||
class ListOfLists<T> : IList<T>, IReadOnlyList<T> |
|
||||||
{ |
|
||||||
List<IReadOnlyList<T>> lists =new List<IReadOnlyList<T>> (); |
|
||||||
|
|
||||||
public void AddList(IReadOnlyList<T> list) |
|
||||||
{ |
|
||||||
lists.Add (list); |
|
||||||
} |
|
||||||
|
|
||||||
#region IEnumerable implementation
|
|
||||||
System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() |
|
||||||
{ |
|
||||||
return GetEnumerator(); |
|
||||||
} |
|
||||||
#endregion
|
|
||||||
|
|
||||||
#region IEnumerable implementation
|
|
||||||
public IEnumerator<T> GetEnumerator () |
|
||||||
{ |
|
||||||
for (int i = 0; i < this.Count; i++) { |
|
||||||
yield return this[i]; |
|
||||||
} |
|
||||||
} |
|
||||||
#endregion
|
|
||||||
|
|
||||||
#region ICollection implementation
|
|
||||||
public void Add (T item) |
|
||||||
{ |
|
||||||
throw new NotSupportedException(); |
|
||||||
} |
|
||||||
|
|
||||||
public void Clear () |
|
||||||
{ |
|
||||||
throw new NotSupportedException(); |
|
||||||
} |
|
||||||
|
|
||||||
public bool Contains (T item) |
|
||||||
{ |
|
||||||
var comparer = EqualityComparer<T>.Default; |
|
||||||
for (int i = 0; i < this.Count; i++) { |
|
||||||
if (comparer.Equals(this[i], item)) |
|
||||||
return true; |
|
||||||
} |
|
||||||
return false; |
|
||||||
} |
|
||||||
|
|
||||||
public void CopyTo (T[] array, int arrayIndex) |
|
||||||
{ |
|
||||||
for (int i = 0; i < Count; i++) { |
|
||||||
array[arrayIndex + i] = this[i]; |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
public bool Remove (T item) |
|
||||||
{ |
|
||||||
throw new NotSupportedException(); |
|
||||||
} |
|
||||||
|
|
||||||
public int Count { |
|
||||||
get { |
|
||||||
return lists.Sum (l => l.Count); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
public bool IsReadOnly { |
|
||||||
get { |
|
||||||
return true; |
|
||||||
} |
|
||||||
} |
|
||||||
#endregion
|
|
||||||
|
|
||||||
#region IList implementation
|
|
||||||
public int IndexOf (T item) |
|
||||||
{ |
|
||||||
var comparer = EqualityComparer<T>.Default; |
|
||||||
for (int i = 0; i < this.Count; i++) { |
|
||||||
if (comparer.Equals(this[i], item)) |
|
||||||
return i; |
|
||||||
} |
|
||||||
return -1; |
|
||||||
} |
|
||||||
|
|
||||||
public void Insert (int index, T item) |
|
||||||
{ |
|
||||||
throw new NotSupportedException(); |
|
||||||
} |
|
||||||
|
|
||||||
public void RemoveAt (int index) |
|
||||||
{ |
|
||||||
throw new NotSupportedException(); |
|
||||||
} |
|
||||||
|
|
||||||
public T this[int index] { |
|
||||||
get { |
|
||||||
foreach (var list in lists){ |
|
||||||
if (index < list.Count) |
|
||||||
return list[index]; |
|
||||||
index -= list.Count; |
|
||||||
} |
|
||||||
throw new IndexOutOfRangeException (); |
|
||||||
} |
|
||||||
set { |
|
||||||
throw new NotSupportedException(); |
|
||||||
} |
|
||||||
} |
|
||||||
#endregion
|
|
||||||
} |
|
||||||
|
|
||||||
public static DefaultResolvedMethod CreateFromMultipleParts(IUnresolvedMethod[] parts, ITypeResolveContext[] contexts, bool isExtensionMethod) |
|
||||||
{ |
|
||||||
DefaultResolvedMethod method = new DefaultResolvedMethod(parts[0], contexts[0], isExtensionMethod); |
|
||||||
method.parts = parts; |
|
||||||
if (parts.Length > 1) { |
|
||||||
var attrs = new ListOfLists <IAttribute>(); |
|
||||||
attrs.AddList (method.Attributes); |
|
||||||
for (int i = 1; i < parts.Length; i++) { |
|
||||||
attrs.AddList (parts[i].Attributes.CreateResolvedAttributes(contexts[i])); |
|
||||||
} |
|
||||||
method.Attributes = attrs; |
|
||||||
} |
|
||||||
return method; |
|
||||||
} |
|
||||||
|
|
||||||
public IReadOnlyList<IParameter> Parameters { get; private set; } |
|
||||||
public IReadOnlyList<IAttribute> ReturnTypeAttributes { get; private set; } |
|
||||||
IEnumerable<IAttribute> IMethod.GetReturnTypeAttributes() => ReturnTypeAttributes; |
|
||||||
public IReadOnlyList<ITypeParameter> TypeParameters { get; private set; } |
|
||||||
|
|
||||||
public IReadOnlyList<IType> TypeArguments { |
|
||||||
get { |
|
||||||
return TypeParameters; |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
public bool IsExtensionMethod { get; private set; } |
|
||||||
|
|
||||||
public IReadOnlyList<IUnresolvedMethod> Parts { |
|
||||||
get { |
|
||||||
return parts ?? new IUnresolvedMethod[] { (IUnresolvedMethod)unresolved }; |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
public bool IsConstructor { |
|
||||||
get { return ((IUnresolvedMethod)unresolved).IsConstructor; } |
|
||||||
} |
|
||||||
|
|
||||||
public bool IsDestructor { |
|
||||||
get { return ((IUnresolvedMethod)unresolved).IsDestructor; } |
|
||||||
} |
|
||||||
|
|
||||||
public bool IsOperator { |
|
||||||
get { return ((IUnresolvedMethod)unresolved).IsOperator; } |
|
||||||
} |
|
||||||
|
|
||||||
public bool HasBody { |
|
||||||
get { return ((IUnresolvedMethod)unresolved).HasBody; } |
|
||||||
} |
|
||||||
|
|
||||||
public bool IsAccessor { |
|
||||||
get { return ((IUnresolvedMethod)unresolved).AccessorOwner != null; } |
|
||||||
} |
|
||||||
|
|
||||||
IMethod IMethod.ReducedFrom { |
|
||||||
get { return null; } |
|
||||||
} |
|
||||||
|
|
||||||
public virtual IMember AccessorOwner { |
|
||||||
get { |
|
||||||
var reference = ((IUnresolvedMethod)unresolved).AccessorOwner; |
|
||||||
if (reference != null) |
|
||||||
return reference.Resolve(context); |
|
||||||
else |
|
||||||
return null; |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
public override IMember Specialize(TypeParameterSubstitution substitution) |
|
||||||
{ |
|
||||||
return SpecializedMethod.Create(this, substitution); |
|
||||||
} |
|
||||||
|
|
||||||
IMethod IMethod.Specialize(TypeParameterSubstitution substitution) |
|
||||||
{ |
|
||||||
return SpecializedMethod.Create(this, substitution); |
|
||||||
} |
|
||||||
|
|
||||||
public override string ToString() |
|
||||||
{ |
|
||||||
StringBuilder b = new StringBuilder("["); |
|
||||||
b.Append(this.SymbolKind); |
|
||||||
b.Append(' '); |
|
||||||
if (this.DeclaringType != null) { |
|
||||||
b.Append(this.DeclaringType.ReflectionName); |
|
||||||
b.Append('.'); |
|
||||||
} |
|
||||||
b.Append(this.Name); |
|
||||||
if (this.TypeParameters.Count > 0) { |
|
||||||
b.Append("``"); |
|
||||||
b.Append(this.TypeParameters.Count); |
|
||||||
} |
|
||||||
b.Append('('); |
|
||||||
for (int i = 0; i < this.Parameters.Count; i++) { |
|
||||||
if (i > 0) b.Append(", "); |
|
||||||
b.Append(this.Parameters[i].ToString()); |
|
||||||
} |
|
||||||
b.Append("):"); |
|
||||||
b.Append(this.ReturnType.ReflectionName); |
|
||||||
b.Append(']'); |
|
||||||
return b.ToString(); |
|
||||||
} |
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets a dummy constructor for the specified compilation.
|
|
||||||
/// </summary>
|
|
||||||
/// <returns>
|
|
||||||
/// A public instance constructor with IsSynthetic=true and no declaring type.
|
|
||||||
/// </returns>
|
|
||||||
/// <seealso cref="DefaultUnresolvedMethod.DummyConstructor"/>
|
|
||||||
public static IMethod GetDummyConstructor(ICompilation compilation) |
|
||||||
{ |
|
||||||
var dummyConstructor = DefaultUnresolvedMethod.DummyConstructor; |
|
||||||
// Reuse the same IMethod instance for all dummy constructors
|
|
||||||
// so that two occurrences of 'new T()' refer to the same constructor.
|
|
||||||
return (IMethod)compilation.CacheManager.GetOrAddShared( |
|
||||||
dummyConstructor, _ => dummyConstructor.CreateResolved(compilation.TypeResolveContext)); |
|
||||||
} |
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets a dummy constructor for the specified type.
|
|
||||||
/// </summary>
|
|
||||||
/// <returns>
|
|
||||||
/// A public instance constructor with IsSynthetic=true and the specified declaring type.
|
|
||||||
/// </returns>
|
|
||||||
/// <seealso cref="DefaultUnresolvedMethod.DummyConstructor"/>
|
|
||||||
public static IMethod GetDummyConstructor(ICompilation compilation, IType declaringType) |
|
||||||
{ |
|
||||||
var resolvedCtor = GetDummyConstructor(compilation); |
|
||||||
return new SpecializedMethod(resolvedCtor, TypeParameterSubstitution.Identity) { DeclaringType = declaringType }; |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
@ -1,92 +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 |
|
||||||
{ |
|
||||||
public class DefaultResolvedProperty : AbstractResolvedMember, IProperty |
|
||||||
{ |
|
||||||
protected new readonly IUnresolvedProperty unresolved; |
|
||||||
readonly IReadOnlyList<IParameter> parameters; |
|
||||||
IMethod getter; |
|
||||||
IMethod setter; |
|
||||||
const Accessibility InvalidAccessibility = (Accessibility)0xff; |
|
||||||
volatile Accessibility cachedAccessiblity = InvalidAccessibility; |
|
||||||
|
|
||||||
public DefaultResolvedProperty(IUnresolvedProperty unresolved, ITypeResolveContext parentContext) |
|
||||||
: base(unresolved, parentContext) |
|
||||||
{ |
|
||||||
this.unresolved = unresolved; |
|
||||||
this.parameters = unresolved.Parameters.CreateResolvedParameters(context); |
|
||||||
} |
|
||||||
|
|
||||||
public IReadOnlyList<IParameter> Parameters { |
|
||||||
get { return parameters; } |
|
||||||
} |
|
||||||
|
|
||||||
public override Accessibility Accessibility { |
|
||||||
get { |
|
||||||
var acc = cachedAccessiblity; |
|
||||||
if (acc == InvalidAccessibility) |
|
||||||
return cachedAccessiblity = ComputeAccessibility(); |
|
||||||
else |
|
||||||
return acc; |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
Accessibility ComputeAccessibility() |
|
||||||
{ |
|
||||||
var baseAcc = base.Accessibility; |
|
||||||
if (IsOverride && !(CanGet && CanSet)) { |
|
||||||
foreach (var baseMember in InheritanceHelper.GetBaseMembers(this, false)) { |
|
||||||
if (!baseMember.IsOverride) |
|
||||||
return baseMember.Accessibility; |
|
||||||
} |
|
||||||
} |
|
||||||
return baseAcc; |
|
||||||
} |
|
||||||
|
|
||||||
public bool CanGet { |
|
||||||
get { return unresolved.CanGet; } |
|
||||||
} |
|
||||||
|
|
||||||
public bool CanSet { |
|
||||||
get { return unresolved.CanSet; } |
|
||||||
} |
|
||||||
|
|
||||||
public IMethod Getter { |
|
||||||
get { return GetAccessor(ref getter, unresolved.Getter); } |
|
||||||
} |
|
||||||
|
|
||||||
public IMethod Setter { |
|
||||||
get { return GetAccessor(ref setter, unresolved.Setter); } |
|
||||||
} |
|
||||||
|
|
||||||
public bool IsIndexer { |
|
||||||
get { return unresolved.IsIndexer; } |
|
||||||
} |
|
||||||
|
|
||||||
public override IMember Specialize(TypeParameterSubstitution substitution) |
|
||||||
{ |
|
||||||
return SpecializedProperty.Create(this, substitution); |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
@ -1,810 +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>
|
|
||||||
/// Default implementation of <see cref="ITypeDefinition"/>.
|
|
||||||
/// </summary>
|
|
||||||
public class DefaultResolvedTypeDefinition : ITypeDefinition |
|
||||||
{ |
|
||||||
readonly ITypeResolveContext parentContext; |
|
||||||
readonly IUnresolvedTypeDefinition[] parts; |
|
||||||
Accessibility accessibility = Accessibility.Internal; |
|
||||||
bool isAbstract, isSealed, isShadowing; |
|
||||||
|
|
||||||
public DefaultResolvedTypeDefinition(ITypeResolveContext parentContext, params IUnresolvedTypeDefinition[] parts) |
|
||||||
{ |
|
||||||
if (parentContext == null || parentContext.CurrentAssembly == null) |
|
||||||
throw new ArgumentException("Parent context does not specify any assembly", "parentContext"); |
|
||||||
if (parts == null || parts.Length == 0) |
|
||||||
throw new ArgumentException("No parts were specified", "parts"); |
|
||||||
this.parentContext = parentContext; |
|
||||||
this.parts = parts; |
|
||||||
|
|
||||||
foreach (IUnresolvedTypeDefinition part in parts) { |
|
||||||
isAbstract |= part.IsAbstract; |
|
||||||
isSealed |= part.IsSealed; |
|
||||||
isShadowing |= part.IsShadowing; |
|
||||||
|
|
||||||
// internal is the default, so use another part's accessibility until we find a non-internal accessibility
|
|
||||||
if (accessibility == Accessibility.Internal) |
|
||||||
accessibility = part.Accessibility; |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
IReadOnlyList<ITypeParameter> typeParameters; |
|
||||||
|
|
||||||
public IReadOnlyList<ITypeParameter> TypeParameters { |
|
||||||
get { |
|
||||||
var result = LazyInit.VolatileRead(ref this.typeParameters); |
|
||||||
if (result != null) { |
|
||||||
return result; |
|
||||||
} |
|
||||||
ITypeResolveContext contextForTypeParameters = parts[0].CreateResolveContext(parentContext); |
|
||||||
contextForTypeParameters = contextForTypeParameters.WithCurrentTypeDefinition(this); |
|
||||||
if (parentContext.CurrentTypeDefinition == null || parentContext.CurrentTypeDefinition.TypeParameterCount == 0) { |
|
||||||
result = parts[0].TypeParameters.CreateResolvedTypeParameters(contextForTypeParameters); |
|
||||||
} else { |
|
||||||
// This is a nested class inside a generic class; copy type parameters from outer class if we can:
|
|
||||||
var outerClass = parentContext.CurrentTypeDefinition; |
|
||||||
ITypeParameter[] typeParameters = new ITypeParameter[parts[0].TypeParameters.Count]; |
|
||||||
for (int i = 0; i < typeParameters.Length; i++) { |
|
||||||
var unresolvedTP = parts[0].TypeParameters[i]; |
|
||||||
if (i < outerClass.TypeParameterCount && outerClass.TypeParameters[i].Name == unresolvedTP.Name) |
|
||||||
typeParameters[i] = outerClass.TypeParameters[i]; |
|
||||||
else |
|
||||||
typeParameters[i] = unresolvedTP.CreateResolvedTypeParameter(contextForTypeParameters); |
|
||||||
} |
|
||||||
result = typeParameters; |
|
||||||
} |
|
||||||
return LazyInit.GetOrSet(ref this.typeParameters, result); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
IReadOnlyList<IAttribute> attributes; |
|
||||||
|
|
||||||
public IReadOnlyList<IAttribute> Attributes { |
|
||||||
get { |
|
||||||
var result = LazyInit.VolatileRead(ref this.attributes); |
|
||||||
if (result != null) { |
|
||||||
return result; |
|
||||||
} |
|
||||||
var newResult = new List<IAttribute>(); |
|
||||||
var context = parentContext.WithCurrentTypeDefinition(this); |
|
||||||
foreach (IUnresolvedTypeDefinition part in parts) { |
|
||||||
ITypeResolveContext parentContextForPart = part.CreateResolveContext(context); |
|
||||||
foreach (var attr in part.Attributes) { |
|
||||||
newResult.Add(attr.CreateResolvedAttribute(parentContextForPart)); |
|
||||||
} |
|
||||||
} |
|
||||||
if (newResult.Count == 0) |
|
||||||
result = EmptyList<IAttribute>.Instance; |
|
||||||
else |
|
||||||
result = newResult; |
|
||||||
return LazyInit.GetOrSet(ref this.attributes, result); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
public IEnumerable<IAttribute> GetAttributes() => Attributes; |
|
||||||
|
|
||||||
public System.Reflection.Metadata.EntityHandle MetadataToken => parts[0].MetadataToken; |
|
||||||
|
|
||||||
public SymbolKind SymbolKind { |
|
||||||
get { return parts[0].SymbolKind; } |
|
||||||
} |
|
||||||
|
|
||||||
public virtual TypeKind Kind { |
|
||||||
get { return parts[0].Kind; } |
|
||||||
} |
|
||||||
|
|
||||||
#region NestedTypes
|
|
||||||
IReadOnlyList<ITypeDefinition> nestedTypes; |
|
||||||
|
|
||||||
public IReadOnlyList<ITypeDefinition> NestedTypes { |
|
||||||
get { |
|
||||||
IReadOnlyList<ITypeDefinition> result = LazyInit.VolatileRead(ref this.nestedTypes); |
|
||||||
if (result != null) { |
|
||||||
return result; |
|
||||||
} else { |
|
||||||
result = ( |
|
||||||
from part in parts |
|
||||||
from nestedTypeRef in part.NestedTypes |
|
||||||
group nestedTypeRef by new { nestedTypeRef.Name, nestedTypeRef.TypeParameters.Count } into g |
|
||||||
select new DefaultResolvedTypeDefinition(new SimpleTypeResolveContext(this), g.ToArray()) |
|
||||||
).ToList<ITypeDefinition>(); |
|
||||||
return LazyInit.GetOrSet(ref this.nestedTypes, result); |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
#endregion
|
|
||||||
|
|
||||||
#region Members
|
|
||||||
sealed class MemberList : IReadOnlyList<IMember> |
|
||||||
{ |
|
||||||
internal readonly ITypeResolveContext[] contextPerMember; |
|
||||||
internal readonly IUnresolvedMember[] unresolvedMembers; |
|
||||||
internal readonly IMember[] resolvedMembers; |
|
||||||
internal readonly int NonPartialMemberCount; |
|
||||||
|
|
||||||
public MemberList(List<ITypeResolveContext> contextPerMember, List<IUnresolvedMember> unresolvedNonPartialMembers, List<PartialMethodInfo> partialMethodInfos) |
|
||||||
{ |
|
||||||
this.NonPartialMemberCount = unresolvedNonPartialMembers.Count; |
|
||||||
this.contextPerMember = contextPerMember.ToArray(); |
|
||||||
this.unresolvedMembers = unresolvedNonPartialMembers.ToArray(); |
|
||||||
if (partialMethodInfos == null) { |
|
||||||
this.resolvedMembers = new IMember[unresolvedNonPartialMembers.Count]; |
|
||||||
} else { |
|
||||||
this.resolvedMembers = new IMember[unresolvedNonPartialMembers.Count + partialMethodInfos.Count]; |
|
||||||
for (int i = 0; i < partialMethodInfos.Count; i++) { |
|
||||||
var info = partialMethodInfos[i]; |
|
||||||
int memberIndex = NonPartialMemberCount + i; |
|
||||||
resolvedMembers[memberIndex] = DefaultResolvedMethod.CreateFromMultipleParts( |
|
||||||
info.Parts.ToArray(), info.Contexts.ToArray (), false); |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
public IMember this[int index] { |
|
||||||
get { |
|
||||||
IMember output = LazyInit.VolatileRead(ref resolvedMembers[index]); |
|
||||||
if (output != null) { |
|
||||||
return output; |
|
||||||
} |
|
||||||
return LazyInit.GetOrSet(ref resolvedMembers[index], unresolvedMembers[index].CreateResolved(contextPerMember[index])); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
public int Count { |
|
||||||
get { return resolvedMembers.Length; } |
|
||||||
} |
|
||||||
|
|
||||||
public int IndexOf(IMember item) |
|
||||||
{ |
|
||||||
for (int i = 0; i < this.Count; i++) { |
|
||||||
if (this[i].Equals(item)) |
|
||||||
return i; |
|
||||||
} |
|
||||||
return -1; |
|
||||||
} |
|
||||||
|
|
||||||
public IEnumerator<IMember> GetEnumerator() |
|
||||||
{ |
|
||||||
for (int i = 0; i < this.Count; i++) { |
|
||||||
yield return this[i]; |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() |
|
||||||
{ |
|
||||||
return GetEnumerator(); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
sealed class PartialMethodInfo |
|
||||||
{ |
|
||||||
public readonly string Name; |
|
||||||
public readonly int TypeParameterCount; |
|
||||||
public readonly IReadOnlyList<IParameter> Parameters; |
|
||||||
public readonly List<IUnresolvedMethod> Parts = new List<IUnresolvedMethod>(); |
|
||||||
public readonly List<ITypeResolveContext> Contexts = new List<ITypeResolveContext>(); |
|
||||||
|
|
||||||
public PartialMethodInfo(IUnresolvedMethod method, ITypeResolveContext context) |
|
||||||
{ |
|
||||||
this.Name = method.Name; |
|
||||||
this.TypeParameterCount = method.TypeParameters.Count; |
|
||||||
this.Parameters = method.Parameters.CreateResolvedParameters(context); |
|
||||||
this.Parts.Add(method); |
|
||||||
this.Contexts.Add (context); |
|
||||||
} |
|
||||||
|
|
||||||
public void AddPart(IUnresolvedMethod method, ITypeResolveContext context) |
|
||||||
{ |
|
||||||
if (method.HasBody) { |
|
||||||
// make the implementation the primary part
|
|
||||||
this.Parts.Insert(0, method); |
|
||||||
this.Contexts.Insert (0, context); |
|
||||||
} else { |
|
||||||
this.Parts.Add(method); |
|
||||||
this.Contexts.Add (context); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
public bool IsSameSignature(PartialMethodInfo other, StringComparer nameComparer) |
|
||||||
{ |
|
||||||
return nameComparer.Equals(this.Name, other.Name) |
|
||||||
&& this.TypeParameterCount == other.TypeParameterCount |
|
||||||
&& ParameterListComparer.Instance.Equals(this.Parameters, other.Parameters); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
MemberList memberList; |
|
||||||
|
|
||||||
MemberList GetMemberList() |
|
||||||
{ |
|
||||||
var result = LazyInit.VolatileRead(ref this.memberList); |
|
||||||
if (result != null) { |
|
||||||
return result; |
|
||||||
} |
|
||||||
List<IUnresolvedMember> unresolvedMembers = new List<IUnresolvedMember>(); |
|
||||||
List<ITypeResolveContext> contextPerMember = new List<ITypeResolveContext>(); |
|
||||||
List<PartialMethodInfo> partialMethodInfos = null; |
|
||||||
bool addDefaultConstructorIfRequired = false; |
|
||||||
foreach (IUnresolvedTypeDefinition part in parts) { |
|
||||||
ITypeResolveContext parentContextForPart = part.CreateResolveContext(parentContext); |
|
||||||
ITypeResolveContext contextForPart = parentContextForPart.WithCurrentTypeDefinition(this); |
|
||||||
foreach (var member in part.Members) { |
|
||||||
IUnresolvedMethod method = member as IUnresolvedMethod; |
|
||||||
if (method != null && method.IsPartial) { |
|
||||||
// Merge partial method declaration and implementation
|
|
||||||
if (partialMethodInfos == null) |
|
||||||
partialMethodInfos = new List<PartialMethodInfo>(); |
|
||||||
PartialMethodInfo newInfo = new PartialMethodInfo(method, contextForPart); |
|
||||||
PartialMethodInfo existingInfo = null; |
|
||||||
foreach (var info in partialMethodInfos) { |
|
||||||
if (newInfo.IsSameSignature(info, Compilation.NameComparer)) { |
|
||||||
existingInfo = info; |
|
||||||
break; |
|
||||||
} |
|
||||||
} |
|
||||||
if (existingInfo != null) { |
|
||||||
// Add the unresolved method to the PartialMethodInfo:
|
|
||||||
existingInfo.AddPart(method, contextForPart); |
|
||||||
} else { |
|
||||||
partialMethodInfos.Add(newInfo); |
|
||||||
} |
|
||||||
} else { |
|
||||||
unresolvedMembers.Add(member); |
|
||||||
contextPerMember.Add(contextForPart); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
addDefaultConstructorIfRequired |= part.AddDefaultConstructorIfRequired; |
|
||||||
} |
|
||||||
if (addDefaultConstructorIfRequired) { |
|
||||||
TypeKind kind = this.Kind; |
|
||||||
if (kind == TypeKind.Class && !this.IsStatic && !unresolvedMembers.Any(m => m.SymbolKind == SymbolKind.Constructor && !m.IsStatic) |
|
||||||
|| kind == TypeKind.Enum || kind == TypeKind.Struct) |
|
||||||
{ |
|
||||||
contextPerMember.Add(parts[0].CreateResolveContext(parentContext).WithCurrentTypeDefinition(this)); |
|
||||||
unresolvedMembers.Add(DefaultUnresolvedMethod.CreateDefaultConstructor(parts[0])); |
|
||||||
} |
|
||||||
} |
|
||||||
result = new MemberList(contextPerMember, unresolvedMembers, partialMethodInfos); |
|
||||||
return LazyInit.GetOrSet(ref this.memberList, result); |
|
||||||
} |
|
||||||
|
|
||||||
public IReadOnlyList<IMember> Members { |
|
||||||
get { return GetMemberList(); } |
|
||||||
} |
|
||||||
|
|
||||||
public IEnumerable<IField> Fields { |
|
||||||
get { |
|
||||||
var members = GetMemberList(); |
|
||||||
for (int i = 0; i < members.unresolvedMembers.Length; i++) { |
|
||||||
if (members.unresolvedMembers[i].SymbolKind == SymbolKind.Field) |
|
||||||
yield return (IField)members[i]; |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
public IEnumerable<IMethod> Methods { |
|
||||||
get { |
|
||||||
var members = GetMemberList(); |
|
||||||
for (int i = 0; i < members.unresolvedMembers.Length; i++) { |
|
||||||
if (members.unresolvedMembers[i] is IUnresolvedMethod) |
|
||||||
yield return (IMethod)members[i]; |
|
||||||
} |
|
||||||
for (int i = members.unresolvedMembers.Length; i < members.Count; i++) { |
|
||||||
yield return (IMethod)members[i]; |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
public IEnumerable<IProperty> Properties { |
|
||||||
get { |
|
||||||
var members = GetMemberList(); |
|
||||||
for (int i = 0; i < members.unresolvedMembers.Length; i++) { |
|
||||||
switch (members.unresolvedMembers[i].SymbolKind) { |
|
||||||
case SymbolKind.Property: |
|
||||||
case SymbolKind.Indexer: |
|
||||||
yield return (IProperty)members[i]; |
|
||||||
break; |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
public IEnumerable<IEvent> Events { |
|
||||||
get { |
|
||||||
var members = GetMemberList(); |
|
||||||
for (int i = 0; i < members.unresolvedMembers.Length; i++) { |
|
||||||
if (members.unresolvedMembers[i].SymbolKind == SymbolKind.Event) |
|
||||||
yield return (IEvent)members[i]; |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
#endregion
|
|
||||||
|
|
||||||
volatile KnownTypeCode knownTypeCode = (KnownTypeCode)(-1); |
|
||||||
|
|
||||||
public KnownTypeCode KnownTypeCode { |
|
||||||
get { |
|
||||||
KnownTypeCode result = this.knownTypeCode; |
|
||||||
if (result == (KnownTypeCode)(-1)) { |
|
||||||
result = KnownTypeCode.None; |
|
||||||
ICompilation compilation = this.Compilation; |
|
||||||
for (int i = 0; i < KnownTypeReference.KnownTypeCodeCount; i++) { |
|
||||||
if (compilation.FindType((KnownTypeCode)i) == this) { |
|
||||||
result = (KnownTypeCode)i; |
|
||||||
break; |
|
||||||
} |
|
||||||
} |
|
||||||
this.knownTypeCode = result; |
|
||||||
} |
|
||||||
return result; |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
volatile IType enumUnderlyingType; |
|
||||||
|
|
||||||
public IType EnumUnderlyingType { |
|
||||||
get { |
|
||||||
IType result = this.enumUnderlyingType; |
|
||||||
if (result == null) { |
|
||||||
if (this.Kind == TypeKind.Enum) { |
|
||||||
result = CalculateEnumUnderlyingType(); |
|
||||||
} else { |
|
||||||
result = SpecialType.UnknownType; |
|
||||||
} |
|
||||||
this.enumUnderlyingType = result; |
|
||||||
} |
|
||||||
return result; |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
IType CalculateEnumUnderlyingType() |
|
||||||
{ |
|
||||||
foreach (var part in parts) { |
|
||||||
var context = part.CreateResolveContext(parentContext).WithCurrentTypeDefinition(this); |
|
||||||
foreach (var baseTypeRef in part.BaseTypes) { |
|
||||||
IType type = baseTypeRef.Resolve(context); |
|
||||||
if (type.Kind != TypeKind.Unknown) |
|
||||||
return type; |
|
||||||
} |
|
||||||
} |
|
||||||
return this.Compilation.FindType(KnownTypeCode.Int32); |
|
||||||
} |
|
||||||
|
|
||||||
volatile byte hasExtensionMethods; // 0 = unknown, 1 = true, 2 = false
|
|
||||||
|
|
||||||
public bool HasExtensionMethods { |
|
||||||
get { |
|
||||||
byte val = this.hasExtensionMethods; |
|
||||||
if (val == 0) { |
|
||||||
if (CalculateHasExtensionMethods()) |
|
||||||
val = 1; |
|
||||||
else |
|
||||||
val = 2; |
|
||||||
this.hasExtensionMethods = val; |
|
||||||
} |
|
||||||
return val == 1; |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
bool CalculateHasExtensionMethods() |
|
||||||
{ |
|
||||||
bool noExtensionMethods = true; |
|
||||||
foreach (var part in parts) { |
|
||||||
// Return true if any part has extension methods
|
|
||||||
if (part.HasExtensionMethods == true) |
|
||||||
return true; |
|
||||||
if (part.HasExtensionMethods == null) |
|
||||||
noExtensionMethods = false; |
|
||||||
} |
|
||||||
// Return false if all parts are known to have no extension methods
|
|
||||||
if (noExtensionMethods) |
|
||||||
return false; |
|
||||||
// If unsure, look at the resolved methods.
|
|
||||||
return Methods.Any(m => m.IsExtensionMethod); |
|
||||||
} |
|
||||||
|
|
||||||
public bool IsPartial { |
|
||||||
get { return parts.Length > 1 || parts[0].IsPartial; } |
|
||||||
} |
|
||||||
|
|
||||||
public bool? IsReferenceType { |
|
||||||
get { |
|
||||||
switch (this.Kind) { |
|
||||||
case TypeKind.Class: |
|
||||||
case TypeKind.Interface: |
|
||||||
case TypeKind.Delegate: |
|
||||||
return true; |
|
||||||
case TypeKind.Struct: |
|
||||||
case TypeKind.Enum: |
|
||||||
case TypeKind.Void: |
|
||||||
return false; |
|
||||||
default: |
|
||||||
throw new InvalidOperationException("Invalid value for TypeKind"); |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
public int TypeParameterCount { |
|
||||||
get { return parts[0].TypeParameters.Count; } |
|
||||||
} |
|
||||||
|
|
||||||
public IReadOnlyList<IType> TypeArguments => TypeParameters; |
|
||||||
|
|
||||||
#region DirectBaseTypes
|
|
||||||
IList<IType> directBaseTypes; |
|
||||||
|
|
||||||
public IEnumerable<IType> DirectBaseTypes { |
|
||||||
get { |
|
||||||
IList<IType> result = LazyInit.VolatileRead(ref this.directBaseTypes); |
|
||||||
if (result != null) { |
|
||||||
return result; |
|
||||||
} |
|
||||||
using (var busyLock = BusyManager.Enter(this)) { |
|
||||||
if (busyLock.Success) { |
|
||||||
result = CalculateDirectBaseTypes(); |
|
||||||
return LazyInit.GetOrSet(ref this.directBaseTypes, result); |
|
||||||
} else { |
|
||||||
// This can happen for "class Test : $Test.Base$ { public class Base {} }"
|
|
||||||
// and also for the valid code
|
|
||||||
// "class Test : Base<Test.Inner> { public class Inner {} }"
|
|
||||||
|
|
||||||
// Don't cache the error!
|
|
||||||
return EmptyList<IType>.Instance; |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
IList<IType> CalculateDirectBaseTypes() |
|
||||||
{ |
|
||||||
List<IType> result = new List<IType>(); |
|
||||||
bool hasNonInterface = false; |
|
||||||
if (this.Kind != TypeKind.Enum) { |
|
||||||
foreach (var part in parts) { |
|
||||||
var context = part.CreateResolveContext(parentContext).WithCurrentTypeDefinition(this); |
|
||||||
foreach (var baseTypeRef in part.BaseTypes) { |
|
||||||
IType baseType = baseTypeRef.Resolve(context); |
|
||||||
if (!(baseType.Kind == TypeKind.Unknown || result.Contains(baseType))) { |
|
||||||
result.Add(baseType); |
|
||||||
if (baseType.Kind != TypeKind.Interface) |
|
||||||
hasNonInterface = true; |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
if (!hasNonInterface && !(this.Name == "Object" && this.Namespace == "System" && this.TypeParameterCount == 0)) { |
|
||||||
KnownTypeCode primitiveBaseType; |
|
||||||
switch (this.Kind) { |
|
||||||
case TypeKind.Enum: |
|
||||||
primitiveBaseType = KnownTypeCode.Enum; |
|
||||||
break; |
|
||||||
case TypeKind.Struct: |
|
||||||
case TypeKind.Void: |
|
||||||
primitiveBaseType = KnownTypeCode.ValueType; |
|
||||||
break; |
|
||||||
case TypeKind.Delegate: |
|
||||||
primitiveBaseType = KnownTypeCode.Delegate; |
|
||||||
break; |
|
||||||
default: |
|
||||||
primitiveBaseType = KnownTypeCode.Object; |
|
||||||
break; |
|
||||||
} |
|
||||||
IType t = parentContext.Compilation.FindType(primitiveBaseType); |
|
||||||
if (t.Kind != TypeKind.Unknown) |
|
||||||
result.Add(t); |
|
||||||
} |
|
||||||
return result; |
|
||||||
} |
|
||||||
#endregion
|
|
||||||
|
|
||||||
public string FullName { |
|
||||||
get { return parts[0].FullName; } |
|
||||||
} |
|
||||||
|
|
||||||
public string Name { |
|
||||||
get { return parts[0].Name; } |
|
||||||
} |
|
||||||
|
|
||||||
public string ReflectionName { |
|
||||||
get { return parts[0].ReflectionName; } |
|
||||||
} |
|
||||||
|
|
||||||
public string Namespace { |
|
||||||
get { return parts[0].Namespace; } |
|
||||||
} |
|
||||||
|
|
||||||
public FullTypeName FullTypeName { |
|
||||||
get { return parts[0].FullTypeName; } |
|
||||||
} |
|
||||||
|
|
||||||
public ITypeDefinition DeclaringTypeDefinition { |
|
||||||
get { return parentContext.CurrentTypeDefinition; } |
|
||||||
} |
|
||||||
|
|
||||||
public IType DeclaringType { |
|
||||||
get { return parentContext.CurrentTypeDefinition; } |
|
||||||
} |
|
||||||
|
|
||||||
public IAssembly ParentAssembly { |
|
||||||
get { return parentContext.CurrentAssembly; } |
|
||||||
} |
|
||||||
|
|
||||||
public ICompilation Compilation { |
|
||||||
get { return parentContext.Compilation; } |
|
||||||
} |
|
||||||
|
|
||||||
#region Modifiers
|
|
||||||
public bool IsStatic { get { return isAbstract && isSealed; } } |
|
||||||
public bool IsAbstract { get { return isAbstract; } } |
|
||||||
public bool IsSealed { get { return isSealed; } } |
|
||||||
public bool IsShadowing { get { return isShadowing; } } |
|
||||||
|
|
||||||
public Accessibility Accessibility { |
|
||||||
get { return accessibility; } |
|
||||||
} |
|
||||||
#endregion
|
|
||||||
|
|
||||||
ITypeDefinition IType.GetDefinition() |
|
||||||
{ |
|
||||||
return this; |
|
||||||
} |
|
||||||
|
|
||||||
IType IType.AcceptVisitor(TypeVisitor visitor) |
|
||||||
{ |
|
||||||
return visitor.VisitTypeDefinition(this); |
|
||||||
} |
|
||||||
|
|
||||||
IType IType.VisitChildren(TypeVisitor visitor) |
|
||||||
{ |
|
||||||
return this; |
|
||||||
} |
|
||||||
|
|
||||||
public IEnumerable<IType> GetNestedTypes(Predicate<ITypeDefinition> filter = null, GetMemberOptions options = GetMemberOptions.None) |
|
||||||
{ |
|
||||||
const GetMemberOptions opt = GetMemberOptions.IgnoreInheritedMembers | GetMemberOptions.ReturnMemberDefinitions; |
|
||||||
if ((options & opt) == opt) { |
|
||||||
if (filter == null) |
|
||||||
return this.NestedTypes; |
|
||||||
else |
|
||||||
return GetNestedTypesImpl(filter); |
|
||||||
} else { |
|
||||||
return GetMembersHelper.GetNestedTypes(this, filter, options); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
IEnumerable<IType> GetNestedTypesImpl(Predicate<ITypeDefinition> filter) |
|
||||||
{ |
|
||||||
foreach (var nestedType in this.NestedTypes) { |
|
||||||
if (filter(nestedType)) |
|
||||||
yield return nestedType; |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
public IEnumerable<IType> GetNestedTypes(IReadOnlyList<IType> typeArguments, Predicate<ITypeDefinition> filter = null, GetMemberOptions options = GetMemberOptions.None) |
|
||||||
{ |
|
||||||
return GetMembersHelper.GetNestedTypes(this, typeArguments, filter, options); |
|
||||||
} |
|
||||||
|
|
||||||
#region GetMembers()
|
|
||||||
IEnumerable<IMember> GetFilteredMembers(Predicate<IMember> filter) |
|
||||||
{ |
|
||||||
foreach (var member in GetMemberList()) { |
|
||||||
if (filter == null || filter(member)) { |
|
||||||
yield return member; |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
IEnumerable<IMethod> GetFilteredMethods(Predicate<IMethod> filter) |
|
||||||
{ |
|
||||||
foreach (var member in GetMemberList().OfType<IMethod>()) { |
|
||||||
if (filter == null || filter(member)) { |
|
||||||
yield return member; |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
IEnumerable<TResolved> GetFilteredNonMethods<TUnresolved, TResolved>(Predicate<TResolved> filter) where TUnresolved : class, IUnresolvedMember where TResolved : class, IMember |
|
||||||
{ |
|
||||||
var members = GetMemberList(); |
|
||||||
for (int i = 0; i < members.unresolvedMembers.Length; i++) { |
|
||||||
if (members.unresolvedMembers[i] is TUnresolved && members[i] is TResolved member) { |
|
||||||
if (filter == null || filter(member)) |
|
||||||
yield return member; |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
public virtual IEnumerable<IMethod> GetMethods(Predicate<IMethod> filter = null, GetMemberOptions options = GetMemberOptions.None) |
|
||||||
{ |
|
||||||
if ((options & GetMemberOptions.IgnoreInheritedMembers) == GetMemberOptions.IgnoreInheritedMembers) { |
|
||||||
return GetFilteredMethods(ExtensionMethods.And(m => !m.IsConstructor, filter)); |
|
||||||
} else { |
|
||||||
return GetMembersHelper.GetMethods(this, filter, options); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
public virtual IEnumerable<IMethod> GetMethods(IReadOnlyList<IType> typeArguments, Predicate<IMethod> filter = null, GetMemberOptions options = GetMemberOptions.None) |
|
||||||
{ |
|
||||||
return GetMembersHelper.GetMethods(this, typeArguments, filter, options); |
|
||||||
} |
|
||||||
|
|
||||||
public virtual IEnumerable<IMethod> GetConstructors(Predicate<IMethod> filter = null, GetMemberOptions options = GetMemberOptions.IgnoreInheritedMembers) |
|
||||||
{ |
|
||||||
if (ComHelper.IsComImport(this)) { |
|
||||||
IType coClass = ComHelper.GetCoClass(this); |
|
||||||
using (var busyLock = BusyManager.Enter(this)) { |
|
||||||
if (busyLock.Success) { |
|
||||||
return coClass.GetConstructors(filter, options) |
|
||||||
.Select(m => new SpecializedMethod(m, m.Substitution) { DeclaringType = this }); |
|
||||||
} |
|
||||||
} |
|
||||||
return EmptyList<IMethod>.Instance; |
|
||||||
} |
|
||||||
if ((options & GetMemberOptions.IgnoreInheritedMembers) == GetMemberOptions.IgnoreInheritedMembers) { |
|
||||||
return GetFilteredMethods(ExtensionMethods.And(m => m.IsConstructor && !m.IsStatic, filter)); |
|
||||||
} else { |
|
||||||
return GetMembersHelper.GetConstructors(this, filter, options); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
public virtual IEnumerable<IProperty> GetProperties(Predicate<IProperty> filter = null, GetMemberOptions options = GetMemberOptions.None) |
|
||||||
{ |
|
||||||
if ((options & GetMemberOptions.IgnoreInheritedMembers) == GetMemberOptions.IgnoreInheritedMembers) { |
|
||||||
return GetFilteredNonMethods<IUnresolvedProperty, IProperty>(filter); |
|
||||||
} else { |
|
||||||
return GetMembersHelper.GetProperties(this, filter, options); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
public virtual IEnumerable<IField> GetFields(Predicate<IField> filter = null, GetMemberOptions options = GetMemberOptions.None) |
|
||||||
{ |
|
||||||
if ((options & GetMemberOptions.IgnoreInheritedMembers) == GetMemberOptions.IgnoreInheritedMembers) { |
|
||||||
return GetFilteredNonMethods<IUnresolvedField, IField>(filter); |
|
||||||
} else { |
|
||||||
return GetMembersHelper.GetFields(this, filter, options); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
public virtual IEnumerable<IEvent> GetEvents(Predicate<IEvent> filter = null, GetMemberOptions options = GetMemberOptions.None) |
|
||||||
{ |
|
||||||
if ((options & GetMemberOptions.IgnoreInheritedMembers) == GetMemberOptions.IgnoreInheritedMembers) { |
|
||||||
return GetFilteredNonMethods<IUnresolvedEvent, IEvent>(filter); |
|
||||||
} else { |
|
||||||
return GetMembersHelper.GetEvents(this, filter, options); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
public virtual IEnumerable<IMember> GetMembers(Predicate<IMember> filter = null, GetMemberOptions options = GetMemberOptions.None) |
|
||||||
{ |
|
||||||
if ((options & GetMemberOptions.IgnoreInheritedMembers) == GetMemberOptions.IgnoreInheritedMembers) { |
|
||||||
return GetFilteredMembers(filter); |
|
||||||
} else { |
|
||||||
return GetMembersHelper.GetMembers(this, filter, options); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
public virtual IEnumerable<IMethod> GetAccessors(Predicate<IMethod> filter = null, GetMemberOptions options = GetMemberOptions.None) |
|
||||||
{ |
|
||||||
if ((options & GetMemberOptions.IgnoreInheritedMembers) == GetMemberOptions.IgnoreInheritedMembers) { |
|
||||||
return GetFilteredAccessors(filter); |
|
||||||
} else { |
|
||||||
return GetMembersHelper.GetAccessors(this, filter, options); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
IEnumerable<IMethod> GetFilteredAccessors(Predicate<IMethod> filter) |
|
||||||
{ |
|
||||||
var members = GetMemberList(); |
|
||||||
for (int i = 0; i < members.unresolvedMembers.Length; i++) { |
|
||||||
IUnresolvedMember unresolved = members.unresolvedMembers[i]; |
|
||||||
var unresolvedProperty = unresolved as IUnresolvedProperty; |
|
||||||
var unresolvedEvent = unresolved as IUnresolvedEvent; |
|
||||||
if (unresolvedProperty != null) { |
|
||||||
var prop = (IProperty)members[i]; |
|
||||||
if (unresolvedProperty.CanGet && (filter == null || filter(prop.Getter))) |
|
||||||
yield return prop.Getter; |
|
||||||
if (unresolvedProperty.CanSet && (filter == null || filter(prop.Setter))) |
|
||||||
yield return prop.Setter; |
|
||||||
} else if (unresolvedEvent != null) { |
|
||||||
var ev = (IEvent)members[i]; |
|
||||||
if (unresolvedEvent.CanAdd && (filter == null || filter(ev.AddAccessor))) |
|
||||||
yield return ev.AddAccessor; |
|
||||||
if (unresolvedEvent.CanRemove && (filter == null || filter(ev.RemoveAccessor))) |
|
||||||
yield return ev.RemoveAccessor; |
|
||||||
if (unresolvedEvent.CanInvoke && (filter == null || filter(ev.InvokeAccessor))) |
|
||||||
yield return ev.InvokeAccessor; |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
#endregion
|
|
||||||
|
|
||||||
#region GetInterfaceImplementation
|
|
||||||
public IMember GetInterfaceImplementation(IMember interfaceMember) |
|
||||||
{ |
|
||||||
return GetInterfaceImplementation(new[] { interfaceMember })[0]; |
|
||||||
} |
|
||||||
|
|
||||||
public IReadOnlyList<IMember> GetInterfaceImplementation(IReadOnlyList<IMember> interfaceMembers) |
|
||||||
{ |
|
||||||
// TODO: review the subtle rules for interface reimplementation,
|
|
||||||
// write tests and fix this method.
|
|
||||||
// Also virtual/override is going to be tricky -
|
|
||||||
// I think we'll need to consider the 'virtual' method first for
|
|
||||||
// reimplemenatation purposes, but then actually return the 'override'
|
|
||||||
// (as that's the method that ends up getting called)
|
|
||||||
|
|
||||||
interfaceMembers = interfaceMembers.ToList(); // avoid evaluating more than once
|
|
||||||
|
|
||||||
var result = new IMember[interfaceMembers.Count]; |
|
||||||
var signatureToIndexDict = new MultiDictionary<IMember, int>(SignatureComparer.Ordinal); |
|
||||||
for (int i = 0; i < interfaceMembers.Count; i++) { |
|
||||||
signatureToIndexDict.Add(interfaceMembers[i], i); |
|
||||||
} |
|
||||||
foreach (var member in GetMembers(m => !m.IsExplicitInterfaceImplementation)) { |
|
||||||
foreach (int interfaceMemberIndex in signatureToIndexDict[member]) { |
|
||||||
result[interfaceMemberIndex] = member; |
|
||||||
} |
|
||||||
} |
|
||||||
foreach (var explicitImpl in GetMembers(m => m.IsExplicitInterfaceImplementation)) { |
|
||||||
/*foreach (var interfaceMember in explicitImpl.ImplementedInterfaceMembers) { |
|
||||||
foreach (int potentialMatchingIndex in signatureToIndexDict[interfaceMember]) { |
|
||||||
if (interfaceMember.Equals(interfaceMembers[potentialMatchingIndex])) { |
|
||||||
result[potentialMatchingIndex] = explicitImpl; |
|
||||||
} |
|
||||||
} |
|
||||||
}*/ |
|
||||||
// not adjusted to TS changes; but this is dead code and about to be deleted
|
|
||||||
throw new NotImplementedException(); |
|
||||||
} |
|
||||||
return result; |
|
||||||
} |
|
||||||
#endregion
|
|
||||||
|
|
||||||
public TypeParameterSubstitution GetSubstitution() |
|
||||||
{ |
|
||||||
return TypeParameterSubstitution.Identity; |
|
||||||
} |
|
||||||
|
|
||||||
public TypeParameterSubstitution GetSubstitution(IReadOnlyList<IType> methodTypeArguments) |
|
||||||
{ |
|
||||||
return TypeParameterSubstitution.Identity; |
|
||||||
} |
|
||||||
|
|
||||||
public bool Equals(IType other) |
|
||||||
{ |
|
||||||
return this == other; |
|
||||||
} |
|
||||||
|
|
||||||
public override string ToString() |
|
||||||
{ |
|
||||||
return this.ReflectionName; |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
@ -1,581 +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.Concurrent; |
|
||||||
using System.Collections.Generic; |
|
||||||
using System.Diagnostics; |
|
||||||
using System.Linq; |
|
||||||
using System.Threading; |
|
||||||
using ICSharpCode.Decompiler.Semantics; |
|
||||||
using ICSharpCode.Decompiler.Util; |
|
||||||
|
|
||||||
namespace ICSharpCode.Decompiler.TypeSystem.Implementation |
|
||||||
{ |
|
||||||
/// <summary>
|
|
||||||
/// Default implementation for <see cref="IUnresolvedAssembly"/>.
|
|
||||||
/// </summary>
|
|
||||||
[Serializable] |
|
||||||
public class DefaultUnresolvedAssembly : AbstractFreezable, IUnresolvedAssembly |
|
||||||
{ |
|
||||||
string assemblyName; |
|
||||||
string fullAssemblyName; |
|
||||||
IList<IUnresolvedAttribute> assemblyAttributes; |
|
||||||
IList<IUnresolvedAttribute> moduleAttributes; |
|
||||||
Dictionary<TopLevelTypeName, IUnresolvedTypeDefinition> typeDefinitions = new Dictionary<TopLevelTypeName, IUnresolvedTypeDefinition>(TopLevelTypeNameComparer.Ordinal); |
|
||||||
Dictionary<TopLevelTypeName, ITypeReference> typeForwarders = new Dictionary<TopLevelTypeName, ITypeReference>(TopLevelTypeNameComparer.Ordinal); |
|
||||||
|
|
||||||
protected override void FreezeInternal() |
|
||||||
{ |
|
||||||
base.FreezeInternal(); |
|
||||||
assemblyAttributes = FreezableHelper.FreezeListAndElements(assemblyAttributes); |
|
||||||
moduleAttributes = FreezableHelper.FreezeListAndElements(moduleAttributes); |
|
||||||
foreach (var type in typeDefinitions.Values) { |
|
||||||
FreezableHelper.Freeze(type); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Creates a new unresolved assembly.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="assemblyName">Full assembly name</param>
|
|
||||||
public DefaultUnresolvedAssembly(string assemblyName) |
|
||||||
{ |
|
||||||
if (assemblyName == null) |
|
||||||
throw new ArgumentNullException("assemblyName"); |
|
||||||
this.fullAssemblyName = assemblyName; |
|
||||||
int pos = assemblyName != null ? assemblyName.IndexOf(',') : -1; |
|
||||||
this.assemblyName = pos < 0 ? assemblyName : assemblyName.Substring(0, pos); |
|
||||||
this.assemblyAttributes = new List<IUnresolvedAttribute>(); |
|
||||||
this.moduleAttributes = new List<IUnresolvedAttribute>(); |
|
||||||
} |
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets/Sets the short assembly name.
|
|
||||||
/// </summary>
|
|
||||||
/// <remarks>
|
|
||||||
/// This class handles the short and the full name independently;
|
|
||||||
/// if you change the short name, you should also change the full name.
|
|
||||||
/// </remarks>
|
|
||||||
public string AssemblyName { |
|
||||||
get { return assemblyName; } |
|
||||||
set { |
|
||||||
if (value == null) |
|
||||||
throw new ArgumentNullException("value"); |
|
||||||
FreezableHelper.ThrowIfFrozen(this); |
|
||||||
assemblyName = value; |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets/Sets the full assembly name.
|
|
||||||
/// </summary>
|
|
||||||
/// <remarks>
|
|
||||||
/// This class handles the short and the full name independently;
|
|
||||||
/// if you change the full name, you should also change the short name.
|
|
||||||
/// </remarks>
|
|
||||||
public string FullAssemblyName { |
|
||||||
get { return fullAssemblyName; } |
|
||||||
set { |
|
||||||
if (value == null) |
|
||||||
throw new ArgumentNullException("value"); |
|
||||||
FreezableHelper.ThrowIfFrozen(this); |
|
||||||
fullAssemblyName = value; |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
public IList<IUnresolvedAttribute> AssemblyAttributes { |
|
||||||
get { return assemblyAttributes; } |
|
||||||
} |
|
||||||
|
|
||||||
IEnumerable<IUnresolvedAttribute> IUnresolvedAssembly.AssemblyAttributes { |
|
||||||
get { return assemblyAttributes; } |
|
||||||
} |
|
||||||
|
|
||||||
public IList<IUnresolvedAttribute> ModuleAttributes { |
|
||||||
get { return moduleAttributes; } |
|
||||||
} |
|
||||||
|
|
||||||
IEnumerable<IUnresolvedAttribute> IUnresolvedAssembly.ModuleAttributes { |
|
||||||
get { return moduleAttributes; } |
|
||||||
} |
|
||||||
|
|
||||||
public IEnumerable<IUnresolvedTypeDefinition> TopLevelTypeDefinitions { |
|
||||||
get { return typeDefinitions.Values; } |
|
||||||
} |
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Adds a new top-level type definition to this assembly.
|
|
||||||
/// </summary>
|
|
||||||
/// <remarks>DefaultUnresolvedAssembly does not support partial classes.
|
|
||||||
/// Adding more than one part of a type will cause an ArgumentException.</remarks>
|
|
||||||
public void AddTypeDefinition(IUnresolvedTypeDefinition typeDefinition) |
|
||||||
{ |
|
||||||
if (typeDefinition == null) |
|
||||||
throw new ArgumentNullException("typeDefinition"); |
|
||||||
if (typeDefinition.DeclaringTypeDefinition != null) |
|
||||||
throw new ArgumentException("Cannot add nested types."); |
|
||||||
FreezableHelper.ThrowIfFrozen(this); |
|
||||||
var key = new TopLevelTypeName(typeDefinition.Namespace, typeDefinition.Name, typeDefinition.TypeParameters.Count); |
|
||||||
typeDefinitions.Add(key, typeDefinition); |
|
||||||
} |
|
||||||
|
|
||||||
static readonly ITypeReference typeForwardedToAttributeTypeRef = typeof(System.Runtime.CompilerServices.TypeForwardedToAttribute).ToTypeReference(); |
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Adds a type forwarder.
|
|
||||||
/// This adds both an assembly attribute and an internal forwarder entry, which will be used
|
|
||||||
/// by the resolved assembly to provide the forwarded types.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="typeName">The name of the type.</param>
|
|
||||||
/// <param name="referencedType">The reference used to look up the type in the target assembly.</param>
|
|
||||||
public void AddTypeForwarder(TopLevelTypeName typeName, ITypeReference referencedType) |
|
||||||
{ |
|
||||||
if (referencedType == null) |
|
||||||
throw new ArgumentNullException("referencedType"); |
|
||||||
FreezableHelper.ThrowIfFrozen(this); |
|
||||||
var attribute = new DefaultUnresolvedAttribute(typeForwardedToAttributeTypeRef, new[] { KnownTypeReference.Get(KnownTypeCode.Type) }); |
|
||||||
attribute.PositionalArguments.Add(new TypeOfConstantValue(referencedType)); |
|
||||||
assemblyAttributes.Add(attribute); |
|
||||||
|
|
||||||
typeForwarders[typeName] = referencedType; |
|
||||||
} |
|
||||||
|
|
||||||
[Serializable] |
|
||||||
sealed class TypeOfConstantValue : IConstantValue |
|
||||||
{ |
|
||||||
readonly ITypeReference typeRef; |
|
||||||
|
|
||||||
public TypeOfConstantValue(ITypeReference typeRef) |
|
||||||
{ |
|
||||||
this.typeRef = typeRef; |
|
||||||
} |
|
||||||
|
|
||||||
public ResolveResult Resolve(ITypeResolveContext context) |
|
||||||
{ |
|
||||||
return new TypeOfResolveResult(context.Compilation.FindType(KnownTypeCode.Type), typeRef.Resolve(context)); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
public IUnresolvedTypeDefinition GetTypeDefinition(string ns, string name, int typeParameterCount) |
|
||||||
{ |
|
||||||
var key = new TopLevelTypeName(ns ?? string.Empty, name, typeParameterCount); |
|
||||||
IUnresolvedTypeDefinition td; |
|
||||||
if (typeDefinitions.TryGetValue(key, out td)) |
|
||||||
return td; |
|
||||||
else |
|
||||||
return null; |
|
||||||
} |
|
||||||
|
|
||||||
public IAssembly Resolve(ITypeResolveContext context) |
|
||||||
{ |
|
||||||
if (context == null) |
|
||||||
throw new ArgumentNullException("context"); |
|
||||||
Freeze(); |
|
||||||
var cache = context.Compilation.CacheManager; |
|
||||||
IAssembly asm = (IAssembly)cache.GetShared(this); |
|
||||||
if (asm != null) { |
|
||||||
return asm; |
|
||||||
} else { |
|
||||||
asm = new DefaultResolvedAssembly(context.Compilation, this); |
|
||||||
return (IAssembly)cache.GetOrAddShared(this, asm); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
public override string ToString() |
|
||||||
{ |
|
||||||
return "[" + GetType().Name + " " + assemblyName + "]"; |
|
||||||
} |
|
||||||
|
|
||||||
//[NonSerialized]
|
|
||||||
//List<Dictionary<TopLevelTypeName, IUnresolvedTypeDefinition>> cachedTypeDictionariesPerNameComparer;
|
|
||||||
|
|
||||||
Dictionary<TopLevelTypeName, IUnresolvedTypeDefinition> GetTypeDictionary(StringComparer nameComparer) |
|
||||||
{ |
|
||||||
Debug.Assert(IsFrozen); |
|
||||||
if (nameComparer == StringComparer.Ordinal) |
|
||||||
return typeDefinitions; |
|
||||||
else |
|
||||||
throw new NotImplementedException(); |
|
||||||
} |
|
||||||
|
|
||||||
#region UnresolvedNamespace
|
|
||||||
sealed class UnresolvedNamespace |
|
||||||
{ |
|
||||||
internal readonly string FullName; |
|
||||||
internal readonly string Name; |
|
||||||
internal readonly List<UnresolvedNamespace> Children = new List<UnresolvedNamespace>(); |
|
||||||
|
|
||||||
public UnresolvedNamespace(string fullName, string name) |
|
||||||
{ |
|
||||||
this.FullName = fullName; |
|
||||||
this.Name = name; |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
[NonSerialized] |
|
||||||
List<KeyValuePair<StringComparer, UnresolvedNamespace>> unresolvedNamespacesPerNameComparer; |
|
||||||
|
|
||||||
UnresolvedNamespace GetUnresolvedRootNamespace(StringComparer nameComparer) |
|
||||||
{ |
|
||||||
Debug.Assert(IsFrozen); |
|
||||||
LazyInitializer.EnsureInitialized(ref unresolvedNamespacesPerNameComparer); |
|
||||||
lock (unresolvedNamespacesPerNameComparer) { |
|
||||||
foreach (var pair in unresolvedNamespacesPerNameComparer) { |
|
||||||
if (pair.Key == nameComparer) |
|
||||||
return pair.Value; |
|
||||||
} |
|
||||||
var root = new UnresolvedNamespace(string.Empty, string.Empty); |
|
||||||
var dict = new Dictionary<string, UnresolvedNamespace>(nameComparer); |
|
||||||
dict.Add(root.FullName, root); |
|
||||||
foreach (var typeName in typeDefinitions.Keys) { |
|
||||||
GetOrAddNamespace(dict, typeName.Namespace); |
|
||||||
} |
|
||||||
unresolvedNamespacesPerNameComparer.Add(new KeyValuePair<StringComparer, UnresolvedNamespace>(nameComparer, root)); |
|
||||||
return root; |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
static UnresolvedNamespace GetOrAddNamespace(Dictionary<string, UnresolvedNamespace> dict, string fullName) |
|
||||||
{ |
|
||||||
UnresolvedNamespace ns; |
|
||||||
if (dict.TryGetValue(fullName, out ns)) |
|
||||||
return ns; |
|
||||||
int pos = fullName.LastIndexOf('.'); |
|
||||||
UnresolvedNamespace parent; |
|
||||||
string name; |
|
||||||
if (pos < 0) { |
|
||||||
parent = dict[string.Empty]; // root
|
|
||||||
name = fullName; |
|
||||||
} else { |
|
||||||
parent = GetOrAddNamespace(dict, fullName.Substring(0, pos)); |
|
||||||
name = fullName.Substring(pos + 1); |
|
||||||
} |
|
||||||
ns = new UnresolvedNamespace(fullName, name); |
|
||||||
parent.Children.Add(ns); |
|
||||||
dict.Add(fullName, ns); |
|
||||||
return ns; |
|
||||||
} |
|
||||||
#endregion
|
|
||||||
|
|
||||||
IUnresolvedTypeDefinition[] allTypesByMetadata; |
|
||||||
|
|
||||||
IUnresolvedTypeDefinition[] BuildMetadataLookup() |
|
||||||
{ |
|
||||||
Debug.Assert(IsFrozen); |
|
||||||
int maxRowId = 0; |
|
||||||
foreach (var td in this.GetAllTypeDefinitions()) { |
|
||||||
var token = td.MetadataToken; |
|
||||||
int rowId = System.Reflection.Metadata.Ecma335.MetadataTokens.GetRowNumber(token); |
|
||||||
if (token.Kind == System.Reflection.Metadata.HandleKind.TypeDefinition && rowId > maxRowId) { |
|
||||||
maxRowId = rowId; |
|
||||||
} |
|
||||||
} |
|
||||||
var lookup = new IUnresolvedTypeDefinition[maxRowId + 1]; |
|
||||||
foreach (var td in this.GetAllTypeDefinitions()) { |
|
||||||
var token = td.MetadataToken; |
|
||||||
if (token.Kind == System.Reflection.Metadata.HandleKind.TypeDefinition) { |
|
||||||
int rowId = System.Reflection.Metadata.Ecma335.MetadataTokens.GetRowNumber(token); |
|
||||||
lookup[rowId] = td; |
|
||||||
} |
|
||||||
} |
|
||||||
return lookup; |
|
||||||
} |
|
||||||
|
|
||||||
internal IUnresolvedTypeDefinition GetTypeDefByToken(System.Reflection.Metadata.TypeDefinitionHandle token) |
|
||||||
{ |
|
||||||
var lookup = LazyInit.VolatileRead(ref allTypesByMetadata); |
|
||||||
if (lookup == null) { |
|
||||||
lookup = LazyInit.GetOrSet(ref allTypesByMetadata, BuildMetadataLookup()); |
|
||||||
} |
|
||||||
int rid = System.Reflection.Metadata.Ecma335.MetadataTokens.GetRowNumber(token); |
|
||||||
if (rid < lookup.Length) |
|
||||||
return lookup[rid]; |
|
||||||
else |
|
||||||
return null; |
|
||||||
} |
|
||||||
|
|
||||||
sealed class DefaultResolvedAssembly : IAssembly |
|
||||||
{ |
|
||||||
readonly DefaultUnresolvedAssembly unresolvedAssembly; |
|
||||||
readonly ICompilation compilation; |
|
||||||
readonly ITypeResolveContext context; |
|
||||||
readonly Dictionary<TopLevelTypeName, IUnresolvedTypeDefinition> unresolvedTypeDict; |
|
||||||
readonly ConcurrentDictionary<IUnresolvedTypeDefinition, ITypeDefinition> typeDict = new ConcurrentDictionary<IUnresolvedTypeDefinition, ITypeDefinition>(); |
|
||||||
readonly INamespace rootNamespace; |
|
||||||
|
|
||||||
public DefaultResolvedAssembly(ICompilation compilation, DefaultUnresolvedAssembly unresolved) |
|
||||||
{ |
|
||||||
this.compilation = compilation; |
|
||||||
this.unresolvedAssembly = unresolved; |
|
||||||
this.unresolvedTypeDict = unresolved.GetTypeDictionary(compilation.NameComparer); |
|
||||||
this.rootNamespace = new NS(this, unresolved.GetUnresolvedRootNamespace(compilation.NameComparer), null); |
|
||||||
this.context = new SimpleTypeResolveContext(this); |
|
||||||
this.AssemblyAttributes = unresolved.AssemblyAttributes.CreateResolvedAttributes(context); |
|
||||||
this.ModuleAttributes = unresolved.ModuleAttributes.CreateResolvedAttributes(context); |
|
||||||
} |
|
||||||
|
|
||||||
public Metadata.PEFile PEFile => null; |
|
||||||
|
|
||||||
public IUnresolvedAssembly UnresolvedAssembly { |
|
||||||
get { return unresolvedAssembly; } |
|
||||||
} |
|
||||||
|
|
||||||
public bool IsMainAssembly { |
|
||||||
get { return this.Compilation.MainAssembly == this; } |
|
||||||
} |
|
||||||
|
|
||||||
public string AssemblyName { |
|
||||||
get { return unresolvedAssembly.AssemblyName; } |
|
||||||
} |
|
||||||
|
|
||||||
public string FullAssemblyName { |
|
||||||
get { return unresolvedAssembly.FullAssemblyName; } |
|
||||||
} |
|
||||||
|
|
||||||
public IReadOnlyList<IAttribute> AssemblyAttributes { get; private set; } |
|
||||||
public IReadOnlyList<IAttribute> ModuleAttributes { get; private set; } |
|
||||||
|
|
||||||
public INamespace RootNamespace { |
|
||||||
get { return rootNamespace; } |
|
||||||
} |
|
||||||
|
|
||||||
public ICompilation Compilation { |
|
||||||
get { return compilation; } |
|
||||||
} |
|
||||||
|
|
||||||
public bool InternalsVisibleTo(IAssembly assembly) |
|
||||||
{ |
|
||||||
if (this == assembly) |
|
||||||
return true; |
|
||||||
foreach (string shortName in GetInternalsVisibleTo()) { |
|
||||||
if (assembly.AssemblyName == shortName) |
|
||||||
return true; |
|
||||||
} |
|
||||||
return false; |
|
||||||
} |
|
||||||
|
|
||||||
volatile string[] internalsVisibleTo; |
|
||||||
|
|
||||||
string[] GetInternalsVisibleTo() |
|
||||||
{ |
|
||||||
var result = this.internalsVisibleTo; |
|
||||||
if (result != null) { |
|
||||||
return result; |
|
||||||
} else { |
|
||||||
using (var busyLock = BusyManager.Enter(this)) { |
|
||||||
Debug.Assert(busyLock.Success); |
|
||||||
if (!busyLock.Success) { |
|
||||||
return new string[0]; |
|
||||||
} |
|
||||||
internalsVisibleTo = ( |
|
||||||
from attr in this.AssemblyAttributes |
|
||||||
where attr.AttributeType.Name == "InternalsVisibleToAttribute" |
|
||||||
&& attr.AttributeType.Namespace == "System.Runtime.CompilerServices" |
|
||||||
&& attr.FixedArguments.Length == 1 |
|
||||||
select GetShortName(attr.FixedArguments.Single().Value as string) |
|
||||||
).ToArray(); |
|
||||||
} |
|
||||||
return internalsVisibleTo; |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
static string GetShortName(string fullAssemblyName) |
|
||||||
{ |
|
||||||
if (fullAssemblyName == null) |
|
||||||
return null; |
|
||||||
int pos = fullAssemblyName.IndexOf(','); |
|
||||||
if (pos < 0) |
|
||||||
return fullAssemblyName; |
|
||||||
else |
|
||||||
return fullAssemblyName.Substring(0, pos); |
|
||||||
} |
|
||||||
|
|
||||||
public ITypeDefinition GetTypeDefinition(TopLevelTypeName topLevelTypeName) |
|
||||||
{ |
|
||||||
IUnresolvedTypeDefinition td; |
|
||||||
ITypeReference typeRef; |
|
||||||
if (unresolvedAssembly.typeDefinitions.TryGetValue(topLevelTypeName, out td)) |
|
||||||
return GetTypeDefinition(td); |
|
||||||
if (unresolvedAssembly.typeForwarders.TryGetValue(topLevelTypeName, out typeRef)) { |
|
||||||
// Protect against cyclic type forwarders:
|
|
||||||
using (var busyLock = BusyManager.Enter(typeRef)) { |
|
||||||
if (busyLock.Success) |
|
||||||
return typeRef.Resolve(compilation.TypeResolveContext).GetDefinition(); |
|
||||||
} |
|
||||||
} |
|
||||||
return null; |
|
||||||
} |
|
||||||
|
|
||||||
ITypeDefinition GetTypeDefinition(IUnresolvedTypeDefinition unresolved) |
|
||||||
{ |
|
||||||
return typeDict.GetOrAdd(unresolved, t => CreateTypeDefinition(t)); |
|
||||||
} |
|
||||||
|
|
||||||
ITypeDefinition CreateTypeDefinition(IUnresolvedTypeDefinition unresolved) |
|
||||||
{ |
|
||||||
if (unresolved.DeclaringTypeDefinition != null) { |
|
||||||
ITypeDefinition declaringType = GetTypeDefinition(unresolved.DeclaringTypeDefinition); |
|
||||||
return new DefaultResolvedTypeDefinition(context.WithCurrentTypeDefinition(declaringType), unresolved); |
|
||||||
} else if (unresolved.Name == "Void" && unresolved.Namespace == "System" && unresolved.TypeParameters.Count == 0) { |
|
||||||
return new VoidTypeDefinition(context, unresolved); |
|
||||||
} else { |
|
||||||
return new DefaultResolvedTypeDefinition(context, unresolved); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
public IEnumerable<ITypeDefinition> TopLevelTypeDefinitions { |
|
||||||
get { |
|
||||||
return unresolvedAssembly.TopLevelTypeDefinitions.Select(t => GetTypeDefinition(t)); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
public IEnumerable<ITypeDefinition> TypeDefinitions { |
|
||||||
get { |
|
||||||
return TreeTraversal.PreOrder(TopLevelTypeDefinitions, td => td.NestedTypes); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
public ITypeDefinition ResolveTypeDefToken(System.Reflection.Metadata.TypeDefinitionHandle token) |
|
||||||
{ |
|
||||||
var td = unresolvedAssembly.GetTypeDefByToken(token); |
|
||||||
if (td != null) |
|
||||||
return GetPotentiallyNestedTypeDefinition(td); |
|
||||||
return null; |
|
||||||
} |
|
||||||
|
|
||||||
ITypeDefinition GetPotentiallyNestedTypeDefinition(IUnresolvedTypeDefinition unresolved) |
|
||||||
{ |
|
||||||
var outerUnresolvedType = unresolved.DeclaringTypeDefinition; |
|
||||||
if (outerUnresolvedType == null) { |
|
||||||
// GetTypeDefinition() may only be called for top-level types
|
|
||||||
return GetTypeDefinition(unresolved); |
|
||||||
} |
|
||||||
var outerType = GetPotentiallyNestedTypeDefinition(outerUnresolvedType); |
|
||||||
if (outerType == null) |
|
||||||
return null; |
|
||||||
foreach (var nestedType in outerType.NestedTypes) { |
|
||||||
if (nestedType.MetadataToken == unresolved.MetadataToken) |
|
||||||
return nestedType; |
|
||||||
} |
|
||||||
return null; |
|
||||||
} |
|
||||||
|
|
||||||
public override string ToString() |
|
||||||
{ |
|
||||||
return "[DefaultResolvedAssembly " + AssemblyName + "]"; |
|
||||||
} |
|
||||||
|
|
||||||
IEnumerable<IAttribute> IAssembly.GetAssemblyAttributes() |
|
||||||
{ |
|
||||||
throw new NotImplementedException(); |
|
||||||
} |
|
||||||
|
|
||||||
IEnumerable<IAttribute> IAssembly.GetModuleAttributes() |
|
||||||
{ |
|
||||||
throw new NotImplementedException(); |
|
||||||
} |
|
||||||
|
|
||||||
sealed class NS : INamespace |
|
||||||
{ |
|
||||||
readonly DefaultResolvedAssembly assembly; |
|
||||||
readonly UnresolvedNamespace ns; |
|
||||||
readonly INamespace parentNamespace; |
|
||||||
readonly IReadOnlyList<NS> childNamespaces; |
|
||||||
IEnumerable<ITypeDefinition> types; |
|
||||||
|
|
||||||
public NS(DefaultResolvedAssembly assembly, UnresolvedNamespace ns, INamespace parentNamespace) |
|
||||||
{ |
|
||||||
this.assembly = assembly; |
|
||||||
this.ns = ns; |
|
||||||
this.parentNamespace = parentNamespace; |
|
||||||
this.childNamespaces = new ProjectedList<NS, UnresolvedNamespace, NS>( |
|
||||||
this, ns.Children, (self, c) => new NS(self.assembly, c, self)); |
|
||||||
} |
|
||||||
|
|
||||||
string INamespace.ExternAlias { |
|
||||||
get { return null; } |
|
||||||
} |
|
||||||
|
|
||||||
string INamespace.FullName { |
|
||||||
get { return ns.FullName; } |
|
||||||
} |
|
||||||
|
|
||||||
SymbolKind ISymbol.SymbolKind { |
|
||||||
get { return SymbolKind.Namespace; } |
|
||||||
} |
|
||||||
|
|
||||||
public string Name { |
|
||||||
get { return ns.Name; } |
|
||||||
} |
|
||||||
|
|
||||||
INamespace INamespace.ParentNamespace { |
|
||||||
get { return parentNamespace; } |
|
||||||
} |
|
||||||
|
|
||||||
IEnumerable<IAssembly> INamespace.ContributingAssemblies { |
|
||||||
get { return new [] { assembly }; } |
|
||||||
} |
|
||||||
|
|
||||||
IEnumerable<INamespace> INamespace.ChildNamespaces { |
|
||||||
get { return childNamespaces; } |
|
||||||
} |
|
||||||
|
|
||||||
INamespace INamespace.GetChildNamespace(string name) |
|
||||||
{ |
|
||||||
var nameComparer = assembly.compilation.NameComparer; |
|
||||||
for (int i = 0; i < childNamespaces.Count; i++) { |
|
||||||
if (nameComparer.Equals(name, ns.Children[i].Name)) |
|
||||||
return childNamespaces[i]; |
|
||||||
} |
|
||||||
return null; |
|
||||||
} |
|
||||||
|
|
||||||
ICompilation ICompilationProvider.Compilation { |
|
||||||
get { return assembly.compilation; } |
|
||||||
} |
|
||||||
|
|
||||||
IEnumerable<ITypeDefinition> INamespace.Types { |
|
||||||
get { |
|
||||||
var result = LazyInit.VolatileRead(ref this.types); |
|
||||||
if (result != null) { |
|
||||||
return result; |
|
||||||
} else { |
|
||||||
var hashSet = new HashSet<ITypeDefinition>(); |
|
||||||
foreach (IUnresolvedTypeDefinition typeDef in assembly.UnresolvedAssembly.TopLevelTypeDefinitions) { |
|
||||||
if (typeDef.Namespace == ns.FullName) |
|
||||||
hashSet.Add(assembly.GetTypeDefinition(typeDef)); |
|
||||||
} |
|
||||||
return LazyInit.GetOrSet(ref this.types, hashSet.ToArray()); |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
ITypeDefinition INamespace.GetTypeDefinition(string name, int typeParameterCount) |
|
||||||
{ |
|
||||||
var key = new TopLevelTypeName(ns.FullName, name, typeParameterCount); |
|
||||||
IUnresolvedTypeDefinition unresolvedTypeDef; |
|
||||||
if (assembly.unresolvedTypeDict.TryGetValue(key, out unresolvedTypeDef)) |
|
||||||
return assembly.GetTypeDefinition(unresolvedTypeDef); |
|
||||||
else |
|
||||||
return null; |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
@ -1,257 +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.Collections.Immutable; |
|
||||||
using System.Reflection.Metadata; |
|
||||||
using ICSharpCode.Decompiler.Semantics; |
|
||||||
using ICSharpCode.Decompiler.Util; |
|
||||||
|
|
||||||
namespace ICSharpCode.Decompiler.TypeSystem.Implementation |
|
||||||
{ |
|
||||||
/// <summary>
|
|
||||||
/// Default implementation of <see cref="IUnresolvedAttribute"/>.
|
|
||||||
/// </summary>
|
|
||||||
[Serializable] |
|
||||||
public sealed class DefaultUnresolvedAttribute : AbstractFreezable, IUnresolvedAttribute, IFreezable, ISupportsInterning |
|
||||||
{ |
|
||||||
ITypeReference attributeType; |
|
||||||
IList<ITypeReference> constructorParameterTypes; |
|
||||||
IList<IConstantValue> positionalArguments; |
|
||||||
IList<KeyValuePair<IMemberReference, IConstantValue>> namedArguments; |
|
||||||
|
|
||||||
public DefaultUnresolvedAttribute(ITypeReference attributeType) |
|
||||||
{ |
|
||||||
if (attributeType == null) |
|
||||||
throw new ArgumentNullException("attributeType"); |
|
||||||
this.attributeType = attributeType; |
|
||||||
} |
|
||||||
|
|
||||||
public DefaultUnresolvedAttribute(ITypeReference attributeType, IEnumerable<ITypeReference> constructorParameterTypes) |
|
||||||
{ |
|
||||||
if (attributeType == null) |
|
||||||
throw new ArgumentNullException("attributeType"); |
|
||||||
this.attributeType = attributeType; |
|
||||||
this.ConstructorParameterTypes.AddRange(constructorParameterTypes); |
|
||||||
} |
|
||||||
|
|
||||||
protected override void FreezeInternal() |
|
||||||
{ |
|
||||||
base.FreezeInternal(); |
|
||||||
constructorParameterTypes = FreezableHelper.FreezeList(constructorParameterTypes); |
|
||||||
positionalArguments = FreezableHelper.FreezeListAndElements(positionalArguments); |
|
||||||
namedArguments = FreezableHelper.FreezeList(namedArguments); |
|
||||||
foreach (var pair in namedArguments) { |
|
||||||
FreezableHelper.Freeze(pair.Key); |
|
||||||
FreezableHelper.Freeze(pair.Value); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
public ITypeReference AttributeType { |
|
||||||
get { return attributeType; } |
|
||||||
} |
|
||||||
|
|
||||||
public IList<ITypeReference> ConstructorParameterTypes { |
|
||||||
get { |
|
||||||
if (constructorParameterTypes == null) |
|
||||||
constructorParameterTypes = new List<ITypeReference>(); |
|
||||||
return constructorParameterTypes; |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
public IList<IConstantValue> PositionalArguments { |
|
||||||
get { |
|
||||||
if (positionalArguments == null) |
|
||||||
positionalArguments = new List<IConstantValue>(); |
|
||||||
return positionalArguments; |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
public IList<KeyValuePair<IMemberReference, IConstantValue>> NamedArguments { |
|
||||||
get { |
|
||||||
if (namedArguments == null) |
|
||||||
namedArguments = new List<KeyValuePair<IMemberReference, IConstantValue>>(); |
|
||||||
return namedArguments; |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
public void AddNamedFieldArgument(string fieldName, IConstantValue value) |
|
||||||
{ |
|
||||||
this.NamedArguments.Add(new KeyValuePair<IMemberReference, IConstantValue>( |
|
||||||
new DefaultMemberReference(SymbolKind.Field, attributeType, fieldName), |
|
||||||
value |
|
||||||
)); |
|
||||||
} |
|
||||||
|
|
||||||
public void AddNamedPropertyArgument(string propertyName, IConstantValue value) |
|
||||||
{ |
|
||||||
this.NamedArguments.Add(new KeyValuePair<IMemberReference, IConstantValue>( |
|
||||||
new DefaultMemberReference(SymbolKind.Property, attributeType, propertyName), |
|
||||||
value |
|
||||||
)); |
|
||||||
} |
|
||||||
|
|
||||||
public IAttribute CreateResolvedAttribute(ITypeResolveContext context) |
|
||||||
{ |
|
||||||
return new DefaultResolvedAttribute(this, context); |
|
||||||
} |
|
||||||
|
|
||||||
int ISupportsInterning.GetHashCodeForInterning() |
|
||||||
{ |
|
||||||
int hash = attributeType.GetHashCode() ^ constructorParameterTypes.GetHashCode(); |
|
||||||
unchecked { |
|
||||||
if (constructorParameterTypes != null) { |
|
||||||
foreach (var type in constructorParameterTypes) { |
|
||||||
hash *= 27; |
|
||||||
hash += type.GetHashCode(); |
|
||||||
} |
|
||||||
} |
|
||||||
if (positionalArguments != null) { |
|
||||||
foreach (var arg in positionalArguments) { |
|
||||||
hash *= 31; |
|
||||||
hash += arg.GetHashCode(); |
|
||||||
} |
|
||||||
} |
|
||||||
if (namedArguments != null) { |
|
||||||
foreach (var pair in namedArguments) { |
|
||||||
hash *= 71; |
|
||||||
hash += pair.Key.GetHashCode() + pair.Value.GetHashCode() * 73; |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
return hash; |
|
||||||
} |
|
||||||
|
|
||||||
bool ISupportsInterning.EqualsForInterning(ISupportsInterning other) |
|
||||||
{ |
|
||||||
DefaultUnresolvedAttribute o = other as DefaultUnresolvedAttribute; |
|
||||||
return o != null && attributeType == o.attributeType |
|
||||||
&& ListEquals(constructorParameterTypes, o.constructorParameterTypes) |
|
||||||
&& ListEquals(positionalArguments, o.positionalArguments) |
|
||||||
&& ListEquals(namedArguments ?? EmptyList<KeyValuePair<IMemberReference, IConstantValue>>.Instance, |
|
||||||
o.namedArguments ?? EmptyList<KeyValuePair<IMemberReference, IConstantValue>>.Instance); |
|
||||||
} |
|
||||||
|
|
||||||
static bool ListEquals<T>(IList<T> list1, IList<T> list2) where T : class |
|
||||||
{ |
|
||||||
if (list1 == null) |
|
||||||
list1 = EmptyList<T>.Instance; |
|
||||||
if (list2 == null) |
|
||||||
list2 = EmptyList<T>.Instance; |
|
||||||
if (list1 == list2) |
|
||||||
return true; |
|
||||||
if (list1.Count != list2.Count) |
|
||||||
return false; |
|
||||||
for (int i = 0; i < list1.Count; i++) { |
|
||||||
if (list1[i] != list2[i]) |
|
||||||
return false; |
|
||||||
} |
|
||||||
return true; |
|
||||||
} |
|
||||||
|
|
||||||
static bool ListEquals(IList<KeyValuePair<IMemberReference, IConstantValue>> list1, IList<KeyValuePair<IMemberReference, IConstantValue>> list2) |
|
||||||
{ |
|
||||||
if (list1 == list2) |
|
||||||
return true; |
|
||||||
if (list1.Count != list2.Count) |
|
||||||
return false; |
|
||||||
for (int i = 0; i < list1.Count; i++) { |
|
||||||
var a = list1[i]; |
|
||||||
var b = list2[i]; |
|
||||||
if (!(a.Key == b.Key && a.Value == b.Value)) |
|
||||||
return false; |
|
||||||
} |
|
||||||
return true; |
|
||||||
} |
|
||||||
|
|
||||||
sealed class DefaultResolvedAttribute : IAttribute, ICompilationProvider |
|
||||||
{ |
|
||||||
readonly DefaultUnresolvedAttribute unresolved; |
|
||||||
readonly ITypeResolveContext context; |
|
||||||
readonly IType attributeType; |
|
||||||
readonly IReadOnlyList<ResolveResult> positionalArguments; |
|
||||||
|
|
||||||
// cannot use ProjectedList because KeyValuePair is value type
|
|
||||||
//IReadOnlyList<KeyValuePair<IMember, ResolveResult>> namedArguments;
|
|
||||||
|
|
||||||
IMethod constructor; |
|
||||||
volatile bool constructorResolved; |
|
||||||
|
|
||||||
public DefaultResolvedAttribute(DefaultUnresolvedAttribute unresolved, ITypeResolveContext context) |
|
||||||
{ |
|
||||||
this.unresolved = unresolved; |
|
||||||
this.context = context; |
|
||||||
|
|
||||||
this.attributeType = unresolved.AttributeType.Resolve(context); |
|
||||||
this.positionalArguments = unresolved.PositionalArguments.Resolve(context); |
|
||||||
} |
|
||||||
|
|
||||||
public IType AttributeType { |
|
||||||
get { return attributeType; } |
|
||||||
} |
|
||||||
|
|
||||||
public IMethod Constructor { |
|
||||||
get { |
|
||||||
if (!constructorResolved) { |
|
||||||
constructor = ResolveConstructor(); |
|
||||||
constructorResolved = true; |
|
||||||
} |
|
||||||
return constructor; |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
IMethod ResolveConstructor() |
|
||||||
{ |
|
||||||
var parameterTypes = unresolved.ConstructorParameterTypes.Resolve(context); |
|
||||||
foreach (var ctor in attributeType.GetConstructors(m => m.Parameters.Count == parameterTypes.Count)) { |
|
||||||
bool ok = true; |
|
||||||
for (int i = 0; i < parameterTypes.Count; i++) { |
|
||||||
if (!ctor.Parameters[i].Type.Equals(parameterTypes[i])) { |
|
||||||
ok = false; |
|
||||||
break; |
|
||||||
} |
|
||||||
} |
|
||||||
if (ok) |
|
||||||
return ctor; |
|
||||||
} |
|
||||||
return null; |
|
||||||
} |
|
||||||
|
|
||||||
public ICompilation Compilation { |
|
||||||
get { return context.Compilation; } |
|
||||||
} |
|
||||||
|
|
||||||
IType IAttribute.AttributeType => throw new NotImplementedException(); |
|
||||||
|
|
||||||
IMethod IAttribute.Constructor => throw new NotImplementedException(); |
|
||||||
|
|
||||||
ImmutableArray<CustomAttributeTypedArgument<IType>> IAttribute.FixedArguments => throw new NotImplementedException(); |
|
||||||
|
|
||||||
ImmutableArray<CustomAttributeNamedArgument<IType>> IAttribute.NamedArguments => throw new NotImplementedException(); |
|
||||||
|
|
||||||
public override string ToString() |
|
||||||
{ |
|
||||||
if (positionalArguments.Count == 0) |
|
||||||
return "[" + attributeType.ToString() + "]"; |
|
||||||
else |
|
||||||
return "[" + attributeType.ToString() + "(...)]"; |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
@ -1,97 +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>
|
|
||||||
/// Default implementation of <see cref="IUnresolvedEvent"/>.
|
|
||||||
/// </summary>
|
|
||||||
[Serializable] |
|
||||||
public class DefaultUnresolvedEvent : AbstractUnresolvedMember, IUnresolvedEvent |
|
||||||
{ |
|
||||||
IUnresolvedMethod addAccessor, removeAccessor, invokeAccessor; |
|
||||||
|
|
||||||
protected override void FreezeInternal() |
|
||||||
{ |
|
||||||
base.FreezeInternal(); |
|
||||||
FreezableHelper.Freeze(addAccessor); |
|
||||||
FreezableHelper.Freeze(removeAccessor); |
|
||||||
FreezableHelper.Freeze(invokeAccessor); |
|
||||||
} |
|
||||||
|
|
||||||
public DefaultUnresolvedEvent() |
|
||||||
{ |
|
||||||
this.SymbolKind = SymbolKind.Event; |
|
||||||
} |
|
||||||
|
|
||||||
public DefaultUnresolvedEvent(IUnresolvedTypeDefinition declaringType, string name) |
|
||||||
{ |
|
||||||
this.SymbolKind = SymbolKind.Event; |
|
||||||
this.DeclaringTypeDefinition = declaringType; |
|
||||||
this.Name = name; |
|
||||||
} |
|
||||||
|
|
||||||
public bool CanAdd { |
|
||||||
get { return addAccessor != null; } |
|
||||||
} |
|
||||||
|
|
||||||
public bool CanRemove { |
|
||||||
get { return removeAccessor != null; } |
|
||||||
} |
|
||||||
|
|
||||||
public bool CanInvoke { |
|
||||||
get { return invokeAccessor != null; } |
|
||||||
} |
|
||||||
|
|
||||||
public IUnresolvedMethod AddAccessor { |
|
||||||
get { return addAccessor; } |
|
||||||
set { |
|
||||||
ThrowIfFrozen(); |
|
||||||
addAccessor = value; |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
public IUnresolvedMethod RemoveAccessor { |
|
||||||
get { return removeAccessor; } |
|
||||||
set { |
|
||||||
ThrowIfFrozen(); |
|
||||||
removeAccessor = value; |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
public IUnresolvedMethod InvokeAccessor { |
|
||||||
get { return invokeAccessor; } |
|
||||||
set { |
|
||||||
ThrowIfFrozen(); |
|
||||||
invokeAccessor = value; |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
public override IMember CreateResolved(ITypeResolveContext context) |
|
||||||
{ |
|
||||||
return new DefaultResolvedEvent(this, context); |
|
||||||
} |
|
||||||
|
|
||||||
IEvent IUnresolvedEvent.Resolve(ITypeResolveContext context) |
|
||||||
{ |
|
||||||
return (IEvent)Resolve(context); |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
@ -1,95 +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>
|
|
||||||
/// Default implementation of <see cref="IUnresolvedField"/>.
|
|
||||||
/// </summary>
|
|
||||||
[Serializable] |
|
||||||
public class DefaultUnresolvedField : AbstractUnresolvedMember, IUnresolvedField |
|
||||||
{ |
|
||||||
IConstantValue constantValue; |
|
||||||
|
|
||||||
protected override void FreezeInternal() |
|
||||||
{ |
|
||||||
FreezableHelper.Freeze(constantValue); |
|
||||||
base.FreezeInternal(); |
|
||||||
} |
|
||||||
|
|
||||||
public DefaultUnresolvedField() |
|
||||||
{ |
|
||||||
this.SymbolKind = SymbolKind.Field; |
|
||||||
} |
|
||||||
|
|
||||||
public DefaultUnresolvedField(IUnresolvedTypeDefinition declaringType, string name) |
|
||||||
{ |
|
||||||
this.SymbolKind = SymbolKind.Field; |
|
||||||
this.DeclaringTypeDefinition = declaringType; |
|
||||||
this.Name = name; |
|
||||||
} |
|
||||||
|
|
||||||
public bool IsConst { |
|
||||||
get { return constantValue != null && !IsFixed; } |
|
||||||
} |
|
||||||
|
|
||||||
public bool IsReadOnly { |
|
||||||
get { return flags[FlagFieldIsReadOnly]; } |
|
||||||
set { |
|
||||||
ThrowIfFrozen(); |
|
||||||
flags[FlagFieldIsReadOnly] = value; |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
public bool IsVolatile { |
|
||||||
get { return flags[FlagFieldIsVolatile]; } |
|
||||||
set { |
|
||||||
ThrowIfFrozen(); |
|
||||||
flags[FlagFieldIsVolatile] = value; |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
public bool IsFixed { |
|
||||||
get { return flags[FlagFieldIsFixedSize]; } |
|
||||||
set { |
|
||||||
ThrowIfFrozen(); |
|
||||||
flags[FlagFieldIsFixedSize] = value; |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
public IConstantValue ConstantValue { |
|
||||||
get { return constantValue; } |
|
||||||
set { |
|
||||||
ThrowIfFrozen(); |
|
||||||
constantValue = value; |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
public override IMember CreateResolved(ITypeResolveContext context) |
|
||||||
{ |
|
||||||
return new DefaultResolvedField(this, context); |
|
||||||
} |
|
||||||
|
|
||||||
IField IUnresolvedField.Resolve(ITypeResolveContext context) |
|
||||||
{ |
|
||||||
return (IField)Resolve(context); |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
@ -1,254 +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 System.Text; |
|
||||||
|
|
||||||
namespace ICSharpCode.Decompiler.TypeSystem.Implementation |
|
||||||
{ |
|
||||||
/// <summary>
|
|
||||||
/// Default implementation of <see cref="IUnresolvedMethod" /> interface.
|
|
||||||
/// </summary>
|
|
||||||
[Serializable] |
|
||||||
public class DefaultUnresolvedMethod : AbstractUnresolvedMember, IUnresolvedMethod |
|
||||||
{ |
|
||||||
IList<IUnresolvedAttribute> returnTypeAttributes; |
|
||||||
IList<IUnresolvedTypeParameter> typeParameters; |
|
||||||
IList<IUnresolvedParameter> parameters; |
|
||||||
IUnresolvedMember accessorOwner; |
|
||||||
|
|
||||||
protected override void FreezeInternal() |
|
||||||
{ |
|
||||||
returnTypeAttributes = FreezableHelper.FreezeListAndElements(returnTypeAttributes); |
|
||||||
typeParameters = FreezableHelper.FreezeListAndElements(typeParameters); |
|
||||||
parameters = FreezableHelper.FreezeListAndElements(parameters); |
|
||||||
base.FreezeInternal(); |
|
||||||
} |
|
||||||
|
|
||||||
public override object Clone() |
|
||||||
{ |
|
||||||
var copy = (DefaultUnresolvedMethod)base.Clone(); |
|
||||||
if (returnTypeAttributes != null) |
|
||||||
copy.returnTypeAttributes = new List<IUnresolvedAttribute>(returnTypeAttributes); |
|
||||||
if (typeParameters != null) |
|
||||||
copy.typeParameters = new List<IUnresolvedTypeParameter>(typeParameters); |
|
||||||
if (parameters != null) |
|
||||||
copy.parameters = new List<IUnresolvedParameter>(parameters); |
|
||||||
return copy; |
|
||||||
} |
|
||||||
|
|
||||||
public override void ApplyInterningProvider(InterningProvider provider) |
|
||||||
{ |
|
||||||
base.ApplyInterningProvider(provider); |
|
||||||
if (provider != null) { |
|
||||||
returnTypeAttributes = provider.InternList(returnTypeAttributes); |
|
||||||
typeParameters = provider.InternList(typeParameters); |
|
||||||
parameters = provider.InternList(parameters); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
public DefaultUnresolvedMethod() |
|
||||||
{ |
|
||||||
this.SymbolKind = SymbolKind.Method; |
|
||||||
} |
|
||||||
|
|
||||||
public DefaultUnresolvedMethod(IUnresolvedTypeDefinition declaringType, string name) |
|
||||||
{ |
|
||||||
this.SymbolKind = SymbolKind.Method; |
|
||||||
this.DeclaringTypeDefinition = declaringType; |
|
||||||
this.Name = name; |
|
||||||
} |
|
||||||
|
|
||||||
public IList<IUnresolvedAttribute> ReturnTypeAttributes { |
|
||||||
get { |
|
||||||
if (returnTypeAttributes == null) |
|
||||||
returnTypeAttributes = new List<IUnresolvedAttribute>(); |
|
||||||
return returnTypeAttributes; |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
public IList<IUnresolvedTypeParameter> TypeParameters { |
|
||||||
get { |
|
||||||
if (typeParameters == null) |
|
||||||
typeParameters = new List<IUnresolvedTypeParameter>(); |
|
||||||
return typeParameters; |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
public bool IsExtensionMethod { |
|
||||||
get { return flags[FlagExtensionMethod]; } |
|
||||||
set { |
|
||||||
ThrowIfFrozen(); |
|
||||||
flags[FlagExtensionMethod] = value; |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
public bool IsConstructor { |
|
||||||
get { return this.SymbolKind == SymbolKind.Constructor; } |
|
||||||
} |
|
||||||
|
|
||||||
public bool IsDestructor { |
|
||||||
get { return this.SymbolKind == SymbolKind.Destructor; } |
|
||||||
} |
|
||||||
|
|
||||||
public bool IsOperator { |
|
||||||
get { return this.SymbolKind == SymbolKind.Operator; } |
|
||||||
} |
|
||||||
|
|
||||||
public bool IsPartial { |
|
||||||
get { return flags[FlagPartialMethod]; } |
|
||||||
set { |
|
||||||
ThrowIfFrozen(); |
|
||||||
flags[FlagPartialMethod] = value; |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
public bool IsAsync { |
|
||||||
get { return flags[FlagAsyncMethod]; } |
|
||||||
set { |
|
||||||
ThrowIfFrozen(); |
|
||||||
flags[FlagAsyncMethod] = value; |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
public bool HasBody { |
|
||||||
get { return flags[FlagHasBody]; } |
|
||||||
set { |
|
||||||
ThrowIfFrozen(); |
|
||||||
flags[FlagHasBody] = value; |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
public IList<IUnresolvedParameter> Parameters { |
|
||||||
get { |
|
||||||
if (parameters == null) |
|
||||||
parameters = new List<IUnresolvedParameter>(); |
|
||||||
return parameters; |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
public IUnresolvedMember AccessorOwner { |
|
||||||
get { return accessorOwner; } |
|
||||||
set { |
|
||||||
ThrowIfFrozen(); |
|
||||||
accessorOwner = value; |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
public override string ToString() |
|
||||||
{ |
|
||||||
StringBuilder b = new StringBuilder("["); |
|
||||||
b.Append(SymbolKind.ToString()); |
|
||||||
b.Append(' '); |
|
||||||
if (DeclaringTypeDefinition != null) { |
|
||||||
b.Append(DeclaringTypeDefinition.Name); |
|
||||||
b.Append('.'); |
|
||||||
} |
|
||||||
b.Append(Name); |
|
||||||
b.Append('('); |
|
||||||
b.Append(string.Join(", ", this.Parameters)); |
|
||||||
b.Append("):"); |
|
||||||
b.Append(ReturnType.ToString()); |
|
||||||
b.Append(']'); |
|
||||||
return b.ToString(); |
|
||||||
} |
|
||||||
|
|
||||||
public override IMember CreateResolved(ITypeResolveContext context) |
|
||||||
{ |
|
||||||
return new DefaultResolvedMethod(this, context); |
|
||||||
} |
|
||||||
|
|
||||||
public override IMember Resolve(ITypeResolveContext context) |
|
||||||
{ |
|
||||||
if (accessorOwner != null) { |
|
||||||
var owner = accessorOwner.Resolve(context); |
|
||||||
if (owner != null) { |
|
||||||
IProperty p = owner as IProperty; |
|
||||||
if (p != null) { |
|
||||||
if (p.CanGet && p.Getter.Name == this.Name) |
|
||||||
return p.Getter; |
|
||||||
if (p.CanSet && p.Setter.Name == this.Name) |
|
||||||
return p.Setter; |
|
||||||
} |
|
||||||
IEvent e = owner as IEvent; |
|
||||||
if (e != null) { |
|
||||||
if (e.CanAdd && e.AddAccessor.Name == this.Name) |
|
||||||
return e.AddAccessor; |
|
||||||
if (e.CanRemove && e.RemoveAccessor.Name == this.Name) |
|
||||||
return e.RemoveAccessor; |
|
||||||
if (e.CanInvoke && e.InvokeAccessor.Name == this.Name) |
|
||||||
return e.InvokeAccessor; |
|
||||||
} |
|
||||||
} |
|
||||||
return null; |
|
||||||
} |
|
||||||
|
|
||||||
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, |
|
||||||
this.TypeParameters.Select(tp => tp.Name).ToList(), |
|
||||||
this.Parameters.Select(p => p.Type).ToList()); |
|
||||||
} |
|
||||||
|
|
||||||
IMethod IUnresolvedMethod.Resolve(ITypeResolveContext context) |
|
||||||
{ |
|
||||||
return (IMethod)Resolve(context); |
|
||||||
} |
|
||||||
|
|
||||||
public static DefaultUnresolvedMethod CreateDefaultConstructor(IUnresolvedTypeDefinition typeDefinition) |
|
||||||
{ |
|
||||||
if (typeDefinition == null) |
|
||||||
throw new ArgumentNullException("typeDefinition"); |
|
||||||
return new DefaultUnresolvedMethod(typeDefinition, ".ctor") { |
|
||||||
SymbolKind = SymbolKind.Constructor, |
|
||||||
Accessibility = typeDefinition.IsAbstract ? Accessibility.Protected : Accessibility.Public, |
|
||||||
HasBody = true, |
|
||||||
MetadataToken = System.Reflection.Metadata.Ecma335.MetadataTokens.MethodDefinitionHandle(0), // initialize with properly typed nil token, to avoid InvalidCastExceptions
|
|
||||||
ReturnType = KnownTypeReference.Get(KnownTypeCode.Void) |
|
||||||
}; |
|
||||||
} |
|
||||||
|
|
||||||
static readonly IUnresolvedMethod dummyConstructor = CreateDummyConstructor(); |
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Returns a dummy constructor instance:
|
|
||||||
/// </summary>
|
|
||||||
/// <returns>
|
|
||||||
/// A public instance constructor with IsSynthetic=true and no declaring type.
|
|
||||||
/// </returns>
|
|
||||||
public static IUnresolvedMethod DummyConstructor { |
|
||||||
get { return dummyConstructor; } |
|
||||||
} |
|
||||||
|
|
||||||
static IUnresolvedMethod CreateDummyConstructor() |
|
||||||
{ |
|
||||||
var m = new DefaultUnresolvedMethod { |
|
||||||
SymbolKind = SymbolKind.Constructor, |
|
||||||
Name = ".ctor", |
|
||||||
Accessibility = Accessibility.Public, |
|
||||||
ReturnType = KnownTypeReference.Get(KnownTypeCode.Void) |
|
||||||
}; |
|
||||||
m.Freeze(); |
|
||||||
return m; |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
@ -1,258 +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 System.Text; |
|
||||||
using ICSharpCode.Decompiler.Semantics; |
|
||||||
using ICSharpCode.Decompiler.Util; |
|
||||||
|
|
||||||
namespace ICSharpCode.Decompiler.TypeSystem.Implementation |
|
||||||
{ |
|
||||||
/// <summary>
|
|
||||||
/// Default implementation for IUnresolvedParameter.
|
|
||||||
/// </summary>
|
|
||||||
[Serializable] |
|
||||||
public sealed class DefaultUnresolvedParameter : IUnresolvedParameter, IFreezable, ISupportsInterning |
|
||||||
{ |
|
||||||
string name = string.Empty; |
|
||||||
ITypeReference type = SpecialType.UnknownType; |
|
||||||
IList<IUnresolvedAttribute> attributes; |
|
||||||
IConstantValue defaultValue; |
|
||||||
byte flags; |
|
||||||
|
|
||||||
public DefaultUnresolvedParameter() |
|
||||||
{ |
|
||||||
} |
|
||||||
|
|
||||||
public DefaultUnresolvedParameter(ITypeReference type, string name) |
|
||||||
{ |
|
||||||
if (type == null) |
|
||||||
throw new ArgumentNullException("type"); |
|
||||||
if (name == null) |
|
||||||
throw new ArgumentNullException("name"); |
|
||||||
this.type = type; |
|
||||||
this.name = name; |
|
||||||
} |
|
||||||
|
|
||||||
void FreezeInternal() |
|
||||||
{ |
|
||||||
attributes = FreezableHelper.FreezeListAndElements(attributes); |
|
||||||
FreezableHelper.Freeze(defaultValue); |
|
||||||
} |
|
||||||
|
|
||||||
public string Name { |
|
||||||
get { return name; } |
|
||||||
set { |
|
||||||
if (value == null) |
|
||||||
throw new ArgumentNullException("value"); |
|
||||||
FreezableHelper.ThrowIfFrozen(this); |
|
||||||
name = value; |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
public ITypeReference Type { |
|
||||||
get { return type; } |
|
||||||
set { |
|
||||||
if (value == null) |
|
||||||
throw new ArgumentNullException("value"); |
|
||||||
FreezableHelper.ThrowIfFrozen(this); |
|
||||||
type = value; |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
public IList<IUnresolvedAttribute> Attributes { |
|
||||||
get { |
|
||||||
if (attributes == null) |
|
||||||
attributes = new List<IUnresolvedAttribute>(); |
|
||||||
return attributes; |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
public IConstantValue DefaultValue { |
|
||||||
get { return defaultValue; } |
|
||||||
set { |
|
||||||
FreezableHelper.ThrowIfFrozen(this); |
|
||||||
defaultValue = value; |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
bool HasFlag(byte flag) |
|
||||||
{ |
|
||||||
return (this.flags & flag) != 0; |
|
||||||
} |
|
||||||
void SetFlag(byte flag, bool value) |
|
||||||
{ |
|
||||||
FreezableHelper.ThrowIfFrozen(this); |
|
||||||
if (value) |
|
||||||
this.flags |= flag; |
|
||||||
else |
|
||||||
this.flags &= unchecked((byte)~flag); |
|
||||||
} |
|
||||||
|
|
||||||
public bool IsFrozen { |
|
||||||
get { return HasFlag(1); } |
|
||||||
} |
|
||||||
|
|
||||||
public void Freeze() |
|
||||||
{ |
|
||||||
if (!this.IsFrozen) { |
|
||||||
FreezeInternal(); |
|
||||||
this.flags |= 1; |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
public bool IsRef { |
|
||||||
get { return HasFlag(2); } |
|
||||||
set { SetFlag(2, value); } |
|
||||||
} |
|
||||||
|
|
||||||
public bool IsOut { |
|
||||||
get { return HasFlag(4); } |
|
||||||
set { SetFlag(4, value); } |
|
||||||
} |
|
||||||
|
|
||||||
public bool IsParams { |
|
||||||
get { return HasFlag(8); } |
|
||||||
set { SetFlag(8, value); } |
|
||||||
} |
|
||||||
|
|
||||||
public bool IsOptional { |
|
||||||
get { return this.DefaultValue != null; } |
|
||||||
} |
|
||||||
|
|
||||||
int ISupportsInterning.GetHashCodeForInterning() |
|
||||||
{ |
|
||||||
unchecked { |
|
||||||
int hashCode = 1919191 ^ (flags & ~1); |
|
||||||
hashCode *= 31; |
|
||||||
hashCode += type.GetHashCode(); |
|
||||||
hashCode *= 31; |
|
||||||
hashCode += name.GetHashCode(); |
|
||||||
if (attributes != null) { |
|
||||||
foreach (var attr in attributes) |
|
||||||
hashCode ^= attr.GetHashCode (); |
|
||||||
} |
|
||||||
if (defaultValue != null) |
|
||||||
hashCode ^= defaultValue.GetHashCode (); |
|
||||||
return hashCode; |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
bool ISupportsInterning.EqualsForInterning(ISupportsInterning other) |
|
||||||
{ |
|
||||||
// compare everything except for the IsFrozen flag
|
|
||||||
DefaultUnresolvedParameter p = other as DefaultUnresolvedParameter; |
|
||||||
return p != null && type == p.type && name == p.name && |
|
||||||
defaultValue == p.defaultValue && (flags & ~1) == (p.flags & ~1) && ListEquals(attributes, p.attributes); |
|
||||||
} |
|
||||||
|
|
||||||
static bool ListEquals(IList<IUnresolvedAttribute> list1, IList<IUnresolvedAttribute> list2) |
|
||||||
{ |
|
||||||
return (list1 ?? EmptyList<IUnresolvedAttribute>.Instance).SequenceEqual(list2 ?? EmptyList<IUnresolvedAttribute>.Instance); |
|
||||||
} |
|
||||||
|
|
||||||
public override string ToString() |
|
||||||
{ |
|
||||||
StringBuilder b = new StringBuilder(); |
|
||||||
if (IsRef) |
|
||||||
b.Append("ref "); |
|
||||||
if (IsOut) |
|
||||||
b.Append("out "); |
|
||||||
if (IsParams) |
|
||||||
b.Append("params "); |
|
||||||
b.Append(name); |
|
||||||
b.Append(':'); |
|
||||||
b.Append(type.ToString()); |
|
||||||
if (defaultValue != null) { |
|
||||||
b.Append(" = "); |
|
||||||
b.Append(defaultValue.ToString()); |
|
||||||
} |
|
||||||
return b.ToString(); |
|
||||||
} |
|
||||||
|
|
||||||
static bool IsOptionalAttribute (IType attributeType) |
|
||||||
{ |
|
||||||
return attributeType.Name == "OptionalAttribute" && attributeType.Namespace == "System.Runtime.InteropServices"; |
|
||||||
} |
|
||||||
|
|
||||||
public IParameter CreateResolvedParameter(ITypeResolveContext context) |
|
||||||
{ |
|
||||||
Freeze(); |
|
||||||
if (defaultValue != null) { |
|
||||||
return new ResolvedParameterWithDefaultValue(defaultValue, context) { |
|
||||||
Type = type.Resolve(context), |
|
||||||
Name = name, |
|
||||||
Attributes = attributes.CreateResolvedAttributes(context), |
|
||||||
IsRef = this.IsRef, |
|
||||||
IsOut = this.IsOut, |
|
||||||
IsParams = this.IsParams |
|
||||||
}; |
|
||||||
} else { |
|
||||||
var owner = context.CurrentMember as IParameterizedMember; |
|
||||||
var resolvedAttributes = attributes.CreateResolvedAttributes (context); |
|
||||||
bool isOptional = resolvedAttributes != null && resolvedAttributes.Any (a => IsOptionalAttribute (a.AttributeType)); |
|
||||||
return new DefaultParameter (type.Resolve (context), name, owner, |
|
||||||
resolvedAttributes, IsRef, IsOut, IsParams, isOptional); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
sealed class ResolvedParameterWithDefaultValue : IParameter |
|
||||||
{ |
|
||||||
readonly IConstantValue defaultValue; |
|
||||||
readonly ITypeResolveContext context; |
|
||||||
|
|
||||||
public ResolvedParameterWithDefaultValue(IConstantValue defaultValue, ITypeResolveContext context) |
|
||||||
{ |
|
||||||
this.defaultValue = defaultValue; |
|
||||||
this.context = context; |
|
||||||
} |
|
||||||
|
|
||||||
SymbolKind ISymbol.SymbolKind { get { return SymbolKind.Parameter; } } |
|
||||||
public IParameterizedMember Owner { get { return context.CurrentMember as IParameterizedMember; } } |
|
||||||
public IType Type { get; internal set; } |
|
||||||
public string Name { get; internal set; } |
|
||||||
public IReadOnlyList<IAttribute> Attributes { get; internal set; } |
|
||||||
public IEnumerable<IAttribute> GetAttributes() => Attributes; |
|
||||||
public bool IsRef { get; internal set; } |
|
||||||
public bool IsOut { get; internal set; } |
|
||||||
public bool IsParams { get; internal set; } |
|
||||||
public bool IsOptional { get { return true; } } |
|
||||||
bool IVariable.IsConst { get { return false; } } |
|
||||||
|
|
||||||
ResolveResult resolvedDefaultValue; |
|
||||||
|
|
||||||
public object ConstantValue { |
|
||||||
get { |
|
||||||
ResolveResult rr = LazyInit.VolatileRead(ref this.resolvedDefaultValue); |
|
||||||
if (rr == null) { |
|
||||||
rr = defaultValue.Resolve(context); |
|
||||||
LazyInit.GetOrSet(ref this.resolvedDefaultValue, rr); |
|
||||||
} |
|
||||||
return rr.ConstantValue; |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
public override string ToString() |
|
||||||
{ |
|
||||||
return DefaultParameter.ToString(this); |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
@ -1,124 +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; |
|
||||||
|
|
||||||
namespace ICSharpCode.Decompiler.TypeSystem.Implementation |
|
||||||
{ |
|
||||||
/// <summary>
|
|
||||||
/// Default implementation of <see cref="IUnresolvedProperty"/>.
|
|
||||||
/// </summary>
|
|
||||||
[Serializable] |
|
||||||
public class DefaultUnresolvedProperty : AbstractUnresolvedMember, IUnresolvedProperty |
|
||||||
{ |
|
||||||
IUnresolvedMethod getter, setter; |
|
||||||
IList<IUnresolvedParameter> parameters; |
|
||||||
|
|
||||||
protected override void FreezeInternal() |
|
||||||
{ |
|
||||||
parameters = FreezableHelper.FreezeListAndElements(parameters); |
|
||||||
FreezableHelper.Freeze(getter); |
|
||||||
FreezableHelper.Freeze(setter); |
|
||||||
base.FreezeInternal(); |
|
||||||
} |
|
||||||
|
|
||||||
public override object Clone() |
|
||||||
{ |
|
||||||
var copy = (DefaultUnresolvedProperty)base.Clone(); |
|
||||||
if (parameters != null) |
|
||||||
copy.parameters = new List<IUnresolvedParameter>(parameters); |
|
||||||
return copy; |
|
||||||
} |
|
||||||
|
|
||||||
public override void ApplyInterningProvider(InterningProvider provider) |
|
||||||
{ |
|
||||||
base.ApplyInterningProvider(provider); |
|
||||||
parameters = provider.InternList(parameters); |
|
||||||
} |
|
||||||
|
|
||||||
public DefaultUnresolvedProperty() |
|
||||||
{ |
|
||||||
this.SymbolKind = SymbolKind.Property; |
|
||||||
} |
|
||||||
|
|
||||||
public DefaultUnresolvedProperty(IUnresolvedTypeDefinition declaringType, string name) |
|
||||||
{ |
|
||||||
this.SymbolKind = SymbolKind.Property; |
|
||||||
this.DeclaringTypeDefinition = declaringType; |
|
||||||
this.Name = name; |
|
||||||
} |
|
||||||
|
|
||||||
public bool IsIndexer { |
|
||||||
get { return this.SymbolKind == SymbolKind.Indexer; } |
|
||||||
} |
|
||||||
|
|
||||||
public IList<IUnresolvedParameter> Parameters { |
|
||||||
get { |
|
||||||
if (parameters == null) |
|
||||||
parameters = new List<IUnresolvedParameter>(); |
|
||||||
return parameters; |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
public bool CanGet { |
|
||||||
get { return getter != null; } |
|
||||||
} |
|
||||||
|
|
||||||
public bool CanSet { |
|
||||||
get { return setter != null; } |
|
||||||
} |
|
||||||
|
|
||||||
public IUnresolvedMethod Getter { |
|
||||||
get { return getter; } |
|
||||||
set { |
|
||||||
ThrowIfFrozen(); |
|
||||||
getter = value; |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
public IUnresolvedMethod Setter { |
|
||||||
get { return setter; } |
|
||||||
set { |
|
||||||
ThrowIfFrozen(); |
|
||||||
setter = value; |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
public override IMember CreateResolved(ITypeResolveContext context) |
|
||||||
{ |
|
||||||
return new DefaultResolvedProperty(this, context); |
|
||||||
} |
|
||||||
|
|
||||||
public override 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, |
|
||||||
parameterTypeReferences: this.Parameters.Select(p => p.Type).ToList()); |
|
||||||
} |
|
||||||
|
|
||||||
IProperty IUnresolvedProperty.Resolve(ITypeResolveContext context) |
|
||||||
{ |
|
||||||
return (IProperty)Resolve(context); |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
@ -1,238 +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; |
|
||||||
|
|
||||||
namespace ICSharpCode.Decompiler.TypeSystem.Implementation |
|
||||||
{ |
|
||||||
/// <summary>
|
|
||||||
/// Represents an unresolved type definition.
|
|
||||||
/// </summary>
|
|
||||||
[Serializable] |
|
||||||
public class DefaultUnresolvedTypeDefinition : AbstractUnresolvedEntity, IUnresolvedTypeDefinition |
|
||||||
{ |
|
||||||
TypeKind kind = TypeKind.Class; |
|
||||||
string namespaceName; |
|
||||||
IList<ITypeReference> baseTypes; |
|
||||||
IList<IUnresolvedTypeParameter> typeParameters; |
|
||||||
IList<IUnresolvedTypeDefinition> nestedTypes; |
|
||||||
IList<IUnresolvedMember> members; |
|
||||||
|
|
||||||
public DefaultUnresolvedTypeDefinition() |
|
||||||
{ |
|
||||||
this.SymbolKind = SymbolKind.TypeDefinition; |
|
||||||
} |
|
||||||
|
|
||||||
public DefaultUnresolvedTypeDefinition(string fullName) |
|
||||||
{ |
|
||||||
string namespaceName; |
|
||||||
string name; |
|
||||||
int idx = fullName.LastIndexOf ('.'); |
|
||||||
if (idx > 0) { |
|
||||||
namespaceName = fullName.Substring (0, idx); |
|
||||||
name = fullName.Substring (idx + 1); |
|
||||||
} else { |
|
||||||
namespaceName = ""; |
|
||||||
name = fullName; |
|
||||||
} |
|
||||||
|
|
||||||
this.SymbolKind = SymbolKind.TypeDefinition; |
|
||||||
this.namespaceName = namespaceName; |
|
||||||
this.Name = name; |
|
||||||
} |
|
||||||
|
|
||||||
public DefaultUnresolvedTypeDefinition(string namespaceName, string name) |
|
||||||
{ |
|
||||||
this.SymbolKind = SymbolKind.TypeDefinition; |
|
||||||
this.namespaceName = namespaceName; |
|
||||||
this.Name = name; |
|
||||||
} |
|
||||||
|
|
||||||
public DefaultUnresolvedTypeDefinition(IUnresolvedTypeDefinition declaringTypeDefinition, string name) |
|
||||||
{ |
|
||||||
this.SymbolKind = SymbolKind.TypeDefinition; |
|
||||||
this.DeclaringTypeDefinition = declaringTypeDefinition; |
|
||||||
this.namespaceName = declaringTypeDefinition.Namespace; |
|
||||||
this.Name = name; |
|
||||||
} |
|
||||||
|
|
||||||
protected override void FreezeInternal() |
|
||||||
{ |
|
||||||
base.FreezeInternal(); |
|
||||||
baseTypes = FreezableHelper.FreezeList(baseTypes); |
|
||||||
typeParameters = FreezableHelper.FreezeListAndElements(typeParameters); |
|
||||||
nestedTypes = FreezableHelper.FreezeListAndElements(nestedTypes); |
|
||||||
members = FreezableHelper.FreezeListAndElements(members); |
|
||||||
} |
|
||||||
|
|
||||||
public override object Clone() |
|
||||||
{ |
|
||||||
var copy = (DefaultUnresolvedTypeDefinition)base.Clone(); |
|
||||||
if (baseTypes != null) |
|
||||||
copy.baseTypes = new List<ITypeReference>(baseTypes); |
|
||||||
if (typeParameters != null) |
|
||||||
copy.typeParameters = new List<IUnresolvedTypeParameter>(typeParameters); |
|
||||||
if (nestedTypes != null) |
|
||||||
copy.nestedTypes = new List<IUnresolvedTypeDefinition>(nestedTypes); |
|
||||||
if (members != null) |
|
||||||
copy.members = new List<IUnresolvedMember>(members); |
|
||||||
return copy; |
|
||||||
} |
|
||||||
|
|
||||||
public TypeKind Kind { |
|
||||||
get { return kind; } |
|
||||||
set { |
|
||||||
ThrowIfFrozen(); |
|
||||||
kind = value; |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
public bool AddDefaultConstructorIfRequired { |
|
||||||
get { return flags[FlagAddDefaultConstructorIfRequired]; } |
|
||||||
set { |
|
||||||
ThrowIfFrozen(); |
|
||||||
flags[FlagAddDefaultConstructorIfRequired] = value; |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
public bool? HasExtensionMethods { |
|
||||||
get { |
|
||||||
if (flags[FlagHasExtensionMethods]) |
|
||||||
return true; |
|
||||||
else if (flags[FlagHasNoExtensionMethods]) |
|
||||||
return false; |
|
||||||
else |
|
||||||
return null; |
|
||||||
} |
|
||||||
set { |
|
||||||
ThrowIfFrozen(); |
|
||||||
flags[FlagHasExtensionMethods] = (value == true); |
|
||||||
flags[FlagHasNoExtensionMethods] = (value == false); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
public bool IsPartial { |
|
||||||
get { return flags[FlagPartialTypeDefinition]; } |
|
||||||
set { |
|
||||||
ThrowIfFrozen(); |
|
||||||
flags[FlagPartialTypeDefinition] = value; |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
public override string Namespace { |
|
||||||
get { return namespaceName; } |
|
||||||
set { |
|
||||||
if (value == null) |
|
||||||
throw new ArgumentNullException("value"); |
|
||||||
ThrowIfFrozen(); |
|
||||||
namespaceName = value; |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
public override string ReflectionName { |
|
||||||
get { |
|
||||||
return this.FullTypeName.ReflectionName; |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
public FullTypeName FullTypeName { |
|
||||||
get { |
|
||||||
IUnresolvedTypeDefinition declaringTypeDef = this.DeclaringTypeDefinition; |
|
||||||
if (declaringTypeDef != null) { |
|
||||||
return declaringTypeDef.FullTypeName.NestedType(this.Name, this.TypeParameters.Count - declaringTypeDef.TypeParameters.Count); |
|
||||||
} else { |
|
||||||
return new TopLevelTypeName(namespaceName, this.Name, this.TypeParameters.Count); |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
public IList<ITypeReference> BaseTypes { |
|
||||||
get { |
|
||||||
if (baseTypes == null) |
|
||||||
baseTypes = new List<ITypeReference>(); |
|
||||||
return baseTypes; |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
public IList<IUnresolvedTypeParameter> TypeParameters { |
|
||||||
get { |
|
||||||
if (typeParameters == null) |
|
||||||
typeParameters = new List<IUnresolvedTypeParameter>(); |
|
||||||
return typeParameters; |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
public IList<IUnresolvedTypeDefinition> NestedTypes { |
|
||||||
get { |
|
||||||
if (nestedTypes == null) |
|
||||||
nestedTypes = new List<IUnresolvedTypeDefinition>(); |
|
||||||
return nestedTypes; |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
public IList<IUnresolvedMember> Members { |
|
||||||
get { |
|
||||||
if (members == null) |
|
||||||
members = new List<IUnresolvedMember>(); |
|
||||||
return members; |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
public IEnumerable<IUnresolvedMethod> Methods { |
|
||||||
get { |
|
||||||
return Members.OfType<IUnresolvedMethod> (); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
public IEnumerable<IUnresolvedProperty> Properties { |
|
||||||
get { |
|
||||||
return Members.OfType<IUnresolvedProperty> (); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
public IEnumerable<IUnresolvedField> Fields { |
|
||||||
get { |
|
||||||
return Members.OfType<IUnresolvedField> (); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
public IEnumerable<IUnresolvedEvent> Events { |
|
||||||
get { |
|
||||||
return Members.OfType<IUnresolvedEvent> (); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
|
|
||||||
public IType Resolve(ITypeResolveContext context) |
|
||||||
{ |
|
||||||
if (context == null) |
|
||||||
throw new ArgumentNullException("context"); |
|
||||||
if (context.CurrentAssembly == null) |
|
||||||
throw new ArgumentException("An ITypeDefinition cannot be resolved in a context without a current assembly."); |
|
||||||
return context.CurrentAssembly.GetTypeDefinition(this.FullTypeName) |
|
||||||
?? (IType)new UnknownType(this.Namespace, this.Name, this.TypeParameters.Count); |
|
||||||
} |
|
||||||
|
|
||||||
public virtual ITypeResolveContext CreateResolveContext(ITypeResolveContext parentContext) |
|
||||||
{ |
|
||||||
return parentContext; |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
@ -1,184 +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.Globalization; |
|
||||||
using ICSharpCode.Decompiler.Util; |
|
||||||
|
|
||||||
namespace ICSharpCode.Decompiler.TypeSystem.Implementation |
|
||||||
{ |
|
||||||
/// <summary>
|
|
||||||
/// Default implementation of <see cref="IUnresolvedTypeParameter"/>.
|
|
||||||
/// </summary>
|
|
||||||
[Serializable] |
|
||||||
public class DefaultUnresolvedTypeParameter : IUnresolvedTypeParameter, IFreezable |
|
||||||
{ |
|
||||||
readonly int index; |
|
||||||
IList<IUnresolvedAttribute> attributes; |
|
||||||
IList<ITypeReference> constraints; |
|
||||||
string name; |
|
||||||
|
|
||||||
SymbolKind ownerType; |
|
||||||
VarianceModifier variance; |
|
||||||
BitVector16 flags; |
|
||||||
const ushort FlagFrozen = 0x0001; |
|
||||||
const ushort FlagReferenceTypeConstraint = 0x0002; |
|
||||||
const ushort FlagValueTypeConstraint = 0x0004; |
|
||||||
const ushort FlagDefaultConstructorConstraint = 0x0008; |
|
||||||
|
|
||||||
public void Freeze() |
|
||||||
{ |
|
||||||
if (!flags[FlagFrozen]) { |
|
||||||
FreezeInternal(); |
|
||||||
flags[FlagFrozen] = true; |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
protected virtual void FreezeInternal() |
|
||||||
{ |
|
||||||
attributes = FreezableHelper.FreezeListAndElements(attributes); |
|
||||||
constraints = FreezableHelper.FreezeList(constraints); |
|
||||||
} |
|
||||||
|
|
||||||
public DefaultUnresolvedTypeParameter(SymbolKind ownerType, int index, string name = null) |
|
||||||
{ |
|
||||||
this.ownerType = ownerType; |
|
||||||
this.index = index; |
|
||||||
this.name = name ?? ((ownerType == SymbolKind.Method ? "!!" : "!") + index.ToString(CultureInfo.InvariantCulture)); |
|
||||||
} |
|
||||||
|
|
||||||
public SymbolKind OwnerType { |
|
||||||
get { return ownerType; } |
|
||||||
} |
|
||||||
|
|
||||||
public int Index { |
|
||||||
get { return index; } |
|
||||||
} |
|
||||||
|
|
||||||
public bool IsFrozen { |
|
||||||
get { return flags[FlagFrozen]; } |
|
||||||
} |
|
||||||
|
|
||||||
public string Name { |
|
||||||
get { return name; } |
|
||||||
set { |
|
||||||
FreezableHelper.ThrowIfFrozen(this); |
|
||||||
name = value; |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
string INamedElement.FullName { |
|
||||||
get { return name; } |
|
||||||
} |
|
||||||
|
|
||||||
string INamedElement.Namespace { |
|
||||||
get { return string.Empty; } |
|
||||||
} |
|
||||||
|
|
||||||
string INamedElement.ReflectionName { |
|
||||||
get { |
|
||||||
if (ownerType == SymbolKind.Method) |
|
||||||
return "``" + index.ToString(CultureInfo.InvariantCulture); |
|
||||||
else |
|
||||||
return "`" + index.ToString(CultureInfo.InvariantCulture); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
public IList<IUnresolvedAttribute> Attributes { |
|
||||||
get { |
|
||||||
if (attributes == null) |
|
||||||
attributes = new List<IUnresolvedAttribute>(); |
|
||||||
return attributes; |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
public IList<ITypeReference> Constraints { |
|
||||||
get { |
|
||||||
if (constraints == null) |
|
||||||
constraints = new List<ITypeReference>(); |
|
||||||
return constraints; |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
public VarianceModifier Variance { |
|
||||||
get { return variance; } |
|
||||||
set { |
|
||||||
FreezableHelper.ThrowIfFrozen(this); |
|
||||||
variance = value; |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
public bool HasDefaultConstructorConstraint { |
|
||||||
get { return flags[FlagDefaultConstructorConstraint]; } |
|
||||||
set { |
|
||||||
FreezableHelper.ThrowIfFrozen(this); |
|
||||||
flags[FlagDefaultConstructorConstraint] = value; |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
public bool HasReferenceTypeConstraint { |
|
||||||
get { return flags[FlagReferenceTypeConstraint]; } |
|
||||||
set { |
|
||||||
FreezableHelper.ThrowIfFrozen(this); |
|
||||||
flags[FlagReferenceTypeConstraint] = value; |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
public bool HasValueTypeConstraint { |
|
||||||
get { return flags[FlagValueTypeConstraint]; } |
|
||||||
set { |
|
||||||
FreezableHelper.ThrowIfFrozen(this); |
|
||||||
flags[FlagValueTypeConstraint] = value; |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
/// <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"); |
|
||||||
FreezableHelper.ThrowIfFrozen(this); |
|
||||||
name = provider.Intern(name); |
|
||||||
attributes = provider.InternList(attributes); |
|
||||||
constraints = provider.InternList(constraints); |
|
||||||
} |
|
||||||
|
|
||||||
public virtual ITypeParameter CreateResolvedTypeParameter(ITypeResolveContext context) |
|
||||||
{ |
|
||||||
IEntity owner = null; |
|
||||||
if (this.OwnerType == SymbolKind.Method) { |
|
||||||
owner = context.CurrentMember as IMethod; |
|
||||||
} else if (this.OwnerType == SymbolKind.TypeDefinition) { |
|
||||||
owner = context.CurrentTypeDefinition; |
|
||||||
} |
|
||||||
if (owner == null) |
|
||||||
throw new InvalidOperationException("Could not determine the type parameter's owner."); |
|
||||||
return new DefaultTypeParameter( |
|
||||||
owner, index, name, variance, |
|
||||||
this.Attributes.CreateResolvedAttributes(context), |
|
||||||
this.HasValueTypeConstraint, this.HasReferenceTypeConstraint, this.HasDefaultConstructorConstraint, this.Constraints.Resolve(context) |
|
||||||
); |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
@ -1,160 +0,0 @@ |
|||||||
//
|
|
||||||
// ResolvedAttributeBlob.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 System.Collections.Immutable; |
|
||||||
using System.Diagnostics; |
|
||||||
using System.Reflection.Metadata; |
|
||||||
using System.Threading; |
|
||||||
using ICSharpCode.Decompiler.Semantics; |
|
||||||
using ICSharpCode.Decompiler.Util; |
|
||||||
|
|
||||||
namespace ICSharpCode.Decompiler.TypeSystem.Implementation |
|
||||||
{ |
|
||||||
sealed class CecilResolvedAttribute : IAttribute |
|
||||||
{ |
|
||||||
readonly ITypeResolveContext context; |
|
||||||
readonly byte[] blob; |
|
||||||
readonly IList<ITypeReference> ctorParameterTypes; |
|
||||||
readonly IType attributeType; |
|
||||||
|
|
||||||
IMethod constructor; |
|
||||||
volatile bool constructorResolved; |
|
||||||
|
|
||||||
IReadOnlyList<ResolveResult> positionalArguments; |
|
||||||
IReadOnlyList<KeyValuePair<IMember, ResolveResult>> namedArguments; |
|
||||||
|
|
||||||
public CecilResolvedAttribute(ITypeResolveContext context, UnresolvedAttributeBlob unresolved) |
|
||||||
{ |
|
||||||
this.context = context; |
|
||||||
this.blob = unresolved.blob; |
|
||||||
this.ctorParameterTypes = unresolved.ctorParameterTypes; |
|
||||||
this.attributeType = unresolved.attributeType.Resolve(context); |
|
||||||
} |
|
||||||
|
|
||||||
public CecilResolvedAttribute(ITypeResolveContext context, IType attributeType) |
|
||||||
{ |
|
||||||
this.context = context; |
|
||||||
this.attributeType = attributeType; |
|
||||||
this.ctorParameterTypes = EmptyList<ITypeReference>.Instance; |
|
||||||
} |
|
||||||
|
|
||||||
public IType AttributeType { |
|
||||||
get { return attributeType; } |
|
||||||
} |
|
||||||
|
|
||||||
public IMethod Constructor { |
|
||||||
get { |
|
||||||
if (!constructorResolved) { |
|
||||||
constructor = ResolveConstructor(); |
|
||||||
constructorResolved = true; |
|
||||||
} |
|
||||||
return constructor; |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
IType IAttribute.AttributeType => throw new NotImplementedException(); |
|
||||||
|
|
||||||
IMethod IAttribute.Constructor => throw new NotImplementedException(); |
|
||||||
|
|
||||||
ImmutableArray<CustomAttributeTypedArgument<IType>> IAttribute.FixedArguments => throw new NotImplementedException(); |
|
||||||
|
|
||||||
ImmutableArray<CustomAttributeNamedArgument<IType>> IAttribute.NamedArguments => throw new NotImplementedException(); |
|
||||||
|
|
||||||
IMethod ResolveConstructor() |
|
||||||
{ |
|
||||||
var parameterTypes = ctorParameterTypes.Resolve(context); |
|
||||||
foreach (var ctor in attributeType.GetConstructors(m => m.Parameters.Count == parameterTypes.Count)) { |
|
||||||
bool ok = true; |
|
||||||
for (int i = 0; i < parameterTypes.Count; i++) { |
|
||||||
if (!ctor.Parameters[i].Type.Equals(parameterTypes[i])) { |
|
||||||
ok = false; |
|
||||||
break; |
|
||||||
} |
|
||||||
} |
|
||||||
if (ok) |
|
||||||
return ctor; |
|
||||||
} |
|
||||||
return null; |
|
||||||
} |
|
||||||
|
|
||||||
public override string ToString() |
|
||||||
{ |
|
||||||
return "[" + attributeType.ToString() + "(...)]"; |
|
||||||
} |
|
||||||
|
|
||||||
void DecodeBlob() |
|
||||||
{ |
|
||||||
var positionalArguments = new List<ResolveResult>(); |
|
||||||
var namedArguments = new List<KeyValuePair<IMember, ResolveResult>>(); |
|
||||||
DecodeBlob(positionalArguments, namedArguments); |
|
||||||
Interlocked.CompareExchange(ref this.positionalArguments, positionalArguments, null); |
|
||||||
Interlocked.CompareExchange(ref this.namedArguments, namedArguments, null); |
|
||||||
} |
|
||||||
|
|
||||||
void DecodeBlob(List<ResolveResult> positionalArguments, List<KeyValuePair<IMember, ResolveResult>> namedArguments) |
|
||||||
{ |
|
||||||
if (blob == null) |
|
||||||
return; |
|
||||||
BlobReader reader = new BlobReader(blob, context.CurrentAssembly); |
|
||||||
if (reader.ReadUInt16() != 0x0001) { |
|
||||||
Debug.WriteLine("Unknown blob prolog"); |
|
||||||
return; |
|
||||||
} |
|
||||||
foreach (var ctorParameter in ctorParameterTypes.Resolve(context)) { |
|
||||||
ResolveResult arg; |
|
||||||
bool isError; |
|
||||||
try { |
|
||||||
arg = reader.ReadFixedArg (ctorParameter); |
|
||||||
positionalArguments.Add(arg); |
|
||||||
isError = arg.IsError; |
|
||||||
} catch (Exception ex) { |
|
||||||
Debug.WriteLine("Crash during blob decoding: " + ex); |
|
||||||
isError = true; |
|
||||||
} |
|
||||||
if (isError) { |
|
||||||
// After a decoding error, we must stop decoding the blob because
|
|
||||||
// we might have read too few bytes due to the error.
|
|
||||||
// Just fill up the remaining arguments with ErrorResolveResult:
|
|
||||||
while (positionalArguments.Count < ctorParameterTypes.Count) |
|
||||||
positionalArguments.Add(ErrorResolveResult.UnknownError); |
|
||||||
return; |
|
||||||
} |
|
||||||
} |
|
||||||
try { |
|
||||||
ushort numNamed = reader.ReadUInt16(); |
|
||||||
for (int i = 0; i < numNamed; i++) { |
|
||||||
var namedArg = reader.ReadNamedArg(attributeType); |
|
||||||
if (namedArg.Key != null) |
|
||||||
namedArguments.Add(namedArg); |
|
||||||
} |
|
||||||
} catch (Exception ex) { |
|
||||||
Debug.WriteLine("Crash during blob decoding: " + ex); |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
@ -1,74 +0,0 @@ |
|||||||
//
|
|
||||||
// UnresolvedAttributeBlob.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; |
|
||||||
|
|
||||||
namespace ICSharpCode.Decompiler.TypeSystem.Implementation |
|
||||||
{ |
|
||||||
/// <summary>
|
|
||||||
/// <c>IUnresolvedAttribute</c> implementation that loads the arguments from a binary blob.
|
|
||||||
/// </summary>
|
|
||||||
[Serializable] |
|
||||||
public sealed class UnresolvedAttributeBlob : IUnresolvedAttribute, ISupportsInterning |
|
||||||
{ |
|
||||||
internal readonly ITypeReference attributeType; |
|
||||||
internal readonly IList<ITypeReference> ctorParameterTypes; |
|
||||||
internal readonly byte[] blob; |
|
||||||
|
|
||||||
public UnresolvedAttributeBlob(ITypeReference attributeType, IList<ITypeReference> ctorParameterTypes, byte[] blob) |
|
||||||
{ |
|
||||||
if (attributeType == null) |
|
||||||
throw new ArgumentNullException("attributeType"); |
|
||||||
if (ctorParameterTypes == null) |
|
||||||
throw new ArgumentNullException("ctorParameterTypes"); |
|
||||||
if (blob == null) |
|
||||||
throw new ArgumentNullException("blob"); |
|
||||||
this.attributeType = attributeType; |
|
||||||
this.ctorParameterTypes = ctorParameterTypes; |
|
||||||
this.blob = blob; |
|
||||||
} |
|
||||||
|
|
||||||
public IAttribute CreateResolvedAttribute(ITypeResolveContext context) |
|
||||||
{ |
|
||||||
if (context.CurrentAssembly == null) |
|
||||||
throw new InvalidOperationException("Cannot resolve CecilUnresolvedAttribute without a parent assembly"); |
|
||||||
return new CecilResolvedAttribute(context, this); |
|
||||||
} |
|
||||||
|
|
||||||
int ISupportsInterning.GetHashCodeForInterning() |
|
||||||
{ |
|
||||||
return attributeType.GetHashCode() ^ ctorParameterTypes.GetHashCode() ^ BlobReader.GetBlobHashCode(blob); |
|
||||||
} |
|
||||||
|
|
||||||
bool ISupportsInterning.EqualsForInterning(ISupportsInterning other) |
|
||||||
{ |
|
||||||
UnresolvedAttributeBlob o = other as UnresolvedAttributeBlob; |
|
||||||
return o != null && attributeType == o.attributeType && ctorParameterTypes == o.ctorParameterTypes |
|
||||||
&& BlobReader.BlobEquals(blob, o.blob); |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
@ -1,74 +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>
|
|
||||||
/// Special type definition for 'void'.
|
|
||||||
/// </summary>
|
|
||||||
public class VoidTypeDefinition : DefaultResolvedTypeDefinition |
|
||||||
{ |
|
||||||
public VoidTypeDefinition(ITypeResolveContext parentContext, params IUnresolvedTypeDefinition[] parts) |
|
||||||
: base(parentContext, parts) |
|
||||||
{ |
|
||||||
} |
|
||||||
|
|
||||||
public override TypeKind Kind { |
|
||||||
get { return TypeKind.Void; } |
|
||||||
} |
|
||||||
|
|
||||||
public override IEnumerable<IMethod> GetConstructors(Predicate<IMethod> filter, GetMemberOptions options) |
|
||||||
{ |
|
||||||
return EmptyList<IMethod>.Instance; |
|
||||||
} |
|
||||||
|
|
||||||
public override IEnumerable<IEvent> GetEvents(Predicate<IEvent> filter, GetMemberOptions options) |
|
||||||
{ |
|
||||||
return EmptyList<IEvent>.Instance; |
|
||||||
} |
|
||||||
|
|
||||||
public override IEnumerable<IField> GetFields(Predicate<IField> filter, GetMemberOptions options) |
|
||||||
{ |
|
||||||
return EmptyList<IField>.Instance; |
|
||||||
} |
|
||||||
|
|
||||||
public override IEnumerable<IMethod> GetMethods(Predicate<IMethod> filter, GetMemberOptions options) |
|
||||||
{ |
|
||||||
return EmptyList<IMethod>.Instance; |
|
||||||
} |
|
||||||
|
|
||||||
public override IEnumerable<IMethod> GetMethods(IReadOnlyList<IType> typeArguments, Predicate<IMethod> filter, GetMemberOptions options) |
|
||||||
{ |
|
||||||
return EmptyList<IMethod>.Instance; |
|
||||||
} |
|
||||||
|
|
||||||
public override IEnumerable<IProperty> GetProperties(Predicate<IProperty> filter, GetMemberOptions options) |
|
||||||
{ |
|
||||||
return EmptyList<IProperty>.Instance; |
|
||||||
} |
|
||||||
|
|
||||||
public override IEnumerable<IMember> GetMembers(Predicate<IMember> filter, GetMemberOptions options) |
|
||||||
{ |
|
||||||
return EmptyList<IMember>.Instance; |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
Loading…
Reference in new issue