mirror of https://github.com/icsharpcode/ILSpy.git
27 changed files with 35 additions and 3809 deletions
@ -1,21 +0,0 @@
@@ -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 @@
@@ -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 @@
@@ -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 @@
@@ -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 @@
@@ -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 @@
@@ -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 @@
@@ -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 @@
@@ -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 @@
@@ -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 @@
@@ -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 @@
@@ -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 @@
@@ -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 @@
@@ -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 @@
@@ -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 @@
@@ -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 @@
@@ -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 @@
@@ -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 @@
@@ -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