Browse Source

Use IReadOnlyList<T> instead of IList<T> in the resolved type system.

pull/1087/head
Daniel Grunwald 7 years ago
parent
commit
4d00c65608
  1. 8
      ICSharpCode.Decompiler.Tests/Semantics/OverloadResolutionTests.cs
  2. 6
      ICSharpCode.Decompiler/CSharp/ExpressionBuilder.cs
  3. 50
      ICSharpCode.Decompiler/CSharp/Resolver/CSharpOperators.cs
  4. 20
      ICSharpCode.Decompiler/CSharp/Resolver/CSharpResolver.cs
  5. 4
      ICSharpCode.Decompiler/CSharp/Resolver/LambdaResolveResult.cs
  6. 8
      ICSharpCode.Decompiler/CSharp/Resolver/MemberLookup.cs
  7. 10
      ICSharpCode.Decompiler/CSharp/Resolver/MethodGroupResolveResult.cs
  8. 12
      ICSharpCode.Decompiler/CSharp/Resolver/OverloadResolution.cs
  9. 18
      ICSharpCode.Decompiler/CSharp/Resolver/ReducedExtensionMethod.cs
  10. 14
      ICSharpCode.Decompiler/CSharp/Resolver/TypeInference.cs
  11. 14
      ICSharpCode.Decompiler/CSharp/Syntax/TypeSystemAstBuilder.cs
  12. 2
      ICSharpCode.Decompiler/CSharp/TypeSystem/MemberTypeOrNamespaceReference.cs
  13. 2
      ICSharpCode.Decompiler/CSharp/TypeSystem/MethodTypeParameterWithInheritedConstraints.cs
  14. 4
      ICSharpCode.Decompiler/IL/Instructions/ILFunction.cs
  15. 4
      ICSharpCode.Decompiler/NRExtensions.cs
  16. 2
      ICSharpCode.Decompiler/TypeSystem/AnonymousType.cs
  17. 2
      ICSharpCode.Decompiler/TypeSystem/ArrayType.cs
  18. 6
      ICSharpCode.Decompiler/TypeSystem/DecompilerTypeSystem.cs
  19. 8
      ICSharpCode.Decompiler/TypeSystem/IAssembly.cs
  20. 4
      ICSharpCode.Decompiler/TypeSystem/IEntity.cs
  21. 4
      ICSharpCode.Decompiler/TypeSystem/IMember.cs
  22. 20
      ICSharpCode.Decompiler/TypeSystem/IMethod.cs
  23. 4
      ICSharpCode.Decompiler/TypeSystem/IParameter.cs
  24. 2
      ICSharpCode.Decompiler/TypeSystem/IParameterizedMember.cs
  25. 15
      ICSharpCode.Decompiler/TypeSystem/IType.cs
  26. 14
      ICSharpCode.Decompiler/TypeSystem/ITypeDefinition.cs
  27. 6
      ICSharpCode.Decompiler/TypeSystem/ITypeParameter.cs
  28. 2
      ICSharpCode.Decompiler/TypeSystem/Implementation/AbstractResolvedEntity.cs
  29. 10
      ICSharpCode.Decompiler/TypeSystem/Implementation/AbstractResolvedMember.cs
  30. 34
      ICSharpCode.Decompiler/TypeSystem/Implementation/AbstractResolvedTypeParameter.cs
  31. 16
      ICSharpCode.Decompiler/TypeSystem/Implementation/AbstractType.cs
  32. 4
      ICSharpCode.Decompiler/TypeSystem/Implementation/AbstractUnresolvedMember.cs
  33. 7
      ICSharpCode.Decompiler/TypeSystem/Implementation/DefaultParameter.cs
  34. 20
      ICSharpCode.Decompiler/TypeSystem/Implementation/DefaultResolvedMethod.cs
  35. 4
      ICSharpCode.Decompiler/TypeSystem/Implementation/DefaultResolvedProperty.cs
  36. 97
      ICSharpCode.Decompiler/TypeSystem/Implementation/DefaultResolvedTypeDefinition.cs
  37. 10
      ICSharpCode.Decompiler/TypeSystem/Implementation/DefaultResolvedTypeParameter.cs
  38. 4
      ICSharpCode.Decompiler/TypeSystem/Implementation/DefaultUnresolvedAssembly.cs
  39. 2
      ICSharpCode.Decompiler/TypeSystem/Implementation/DefaultUnresolvedParameter.cs
  40. 4
      ICSharpCode.Decompiler/TypeSystem/Implementation/DummyTypeParameter.cs
  41. 8
      ICSharpCode.Decompiler/TypeSystem/Implementation/GetMembersHelper.cs
  42. 16
      ICSharpCode.Decompiler/TypeSystem/Implementation/SpecializedMember.cs
  43. 12
      ICSharpCode.Decompiler/TypeSystem/Implementation/SpecializedMethod.cs
  44. 2
      ICSharpCode.Decompiler/TypeSystem/Implementation/VoidTypeDefinition.cs
  45. 2
      ICSharpCode.Decompiler/TypeSystem/IntersectionType.cs
  46. 6
      ICSharpCode.Decompiler/TypeSystem/ParameterListComparer.cs
  47. 8
      ICSharpCode.Decompiler/TypeSystem/ParameterizedType.cs
  48. 16
      ICSharpCode.Decompiler/TypeSystem/TypeParameterSubstitution.cs
  49. 8
      ICSharpCode.Decompiler/TypeSystem/TypeSystemExtensions.cs
  50. 18
      ICSharpCode.Decompiler/TypeSystem/VarArgInstanceMethod.cs
  51. 57
      ICSharpCode.Decompiler/Util/CollectionExtensions.cs
  52. 4
      ICSharpCode.Decompiler/Util/ProjectedList.cs

8
ICSharpCode.Decompiler.Tests/Semantics/OverloadResolutionTests.cs

@ -206,15 +206,15 @@ namespace ICSharpCode.Decompiler.Tests.Semantics
/// </summary> /// </summary>
class MockLambda : LambdaResolveResult class MockLambda : LambdaResolveResult
{ {
IType inferredReturnType; readonly IType inferredReturnType;
List<IParameter> parameters = new List<IParameter>(); internal readonly List<IParameter> parameters = new List<IParameter>();
public MockLambda(IType returnType) public MockLambda(IType returnType)
{ {
this.inferredReturnType = returnType; this.inferredReturnType = returnType;
} }
public override IList<IParameter> Parameters { public override IReadOnlyList<IParameter> Parameters {
get { return parameters; } get { return parameters; }
} }
@ -312,7 +312,7 @@ namespace ICSharpCode.Decompiler.Tests.Semantics
var container = compilation.FindType(typeof(BetterFunctionMemberIsNotTransitiveTestCase)).GetDefinition(); var container = compilation.FindType(typeof(BetterFunctionMemberIsNotTransitiveTestCase)).GetDefinition();
var args = new ResolveResult[] { var args = new ResolveResult[] {
new MockLambda(compilation.FindType(KnownTypeCode.String)) { Parameters = { new DefaultParameter(SpecialType.UnknownType, "arg") } } new MockLambda(compilation.FindType(KnownTypeCode.String)) { parameters = { new DefaultParameter(SpecialType.UnknownType, "arg") } }
}; };
OverloadResolution r = new OverloadResolution(compilation, args); OverloadResolution r = new OverloadResolution(compilation, args);

6
ICSharpCode.Decompiler/CSharp/ExpressionBuilder.cs

@ -1493,7 +1493,7 @@ namespace ICSharpCode.Decompiler.CSharp
return SpecialType.UnknownType; return SpecialType.UnknownType;
} }
IEnumerable<ParameterDeclaration> MakeParameters(IList<IParameter> parameters, ILFunction function) IEnumerable<ParameterDeclaration> MakeParameters(IReadOnlyList<IParameter> parameters, ILFunction function)
{ {
var variables = function.Variables.Where(v => v.Kind == VariableKind.Parameter).ToDictionary(v => v.Index); var variables = function.Variables.Where(v => v.Kind == VariableKind.Parameter).ToDictionary(v => v.Index);
int i = 0; int i = 0;
@ -1915,7 +1915,7 @@ namespace ICSharpCode.Decompiler.CSharp
return new AssignmentExpression(target, value); return new AssignmentExpression(target, value);
} }
Expression MakeInitializerElements(List<ILInstruction> values, IList<IParameter> parameters) Expression MakeInitializerElements(List<ILInstruction> values, IReadOnlyList<IParameter> parameters)
{ {
if (values.Count == 1) { if (values.Count == 1) {
return Translate(values[0], typeHint: parameters[0].Type).ConvertTo(parameters[0].Type, this); return Translate(values[0], typeHint: parameters[0].Type).ConvertTo(parameters[0].Type, this);
@ -1979,7 +1979,7 @@ namespace ICSharpCode.Decompiler.CSharp
} else { } else {
typeExpression = ConvertType(type); typeExpression = ConvertType(type);
if (typeExpression is ComposedType compType && compType.ArraySpecifiers.Count > 0) { if (typeExpression is ComposedType compType && compType.ArraySpecifiers.Count > 0) {
additionalSpecifiers = compType.ArraySpecifiers.SelectArray(a => (ArraySpecifier)a.Clone()); additionalSpecifiers = compType.ArraySpecifiers.Select(a => (ArraySpecifier)a.Clone()).ToArray();
compType.ArraySpecifiers.Clear(); compType.ArraySpecifiers.Clear();
} else { } else {
additionalSpecifiers = NoSpecifiers; additionalSpecifiers = NoSpecifiers;

50
ICSharpCode.Decompiler/CSharp/Resolver/CSharpOperators.cs

@ -94,14 +94,14 @@ namespace ICSharpCode.Decompiler.CSharp.Resolver
internal class OperatorMethod : IParameterizedMember internal class OperatorMethod : IParameterizedMember
{ {
readonly ICompilation compilation; readonly ICompilation compilation;
readonly IList<IParameter> parameters = new List<IParameter>(); internal readonly List<IParameter> parameters = new List<IParameter>();
protected OperatorMethod(ICompilation compilation) protected OperatorMethod(ICompilation compilation)
{ {
this.compilation = compilation; this.compilation = compilation;
} }
public IList<IParameter> Parameters { public IReadOnlyList<IParameter> Parameters {
get { return parameters; } get { return parameters; }
} }
@ -131,8 +131,8 @@ namespace ICSharpCode.Decompiler.CSharp.Resolver
IUnresolvedMember IMember.UnresolvedMember { IUnresolvedMember IMember.UnresolvedMember {
get { return null; } get { return null; }
} }
IList<IMember> IMember.ImplementedInterfaceMembers { IReadOnlyList<IMember> IMember.ImplementedInterfaceMembers {
get { return EmptyList<IMember>.Instance; } get { return EmptyList<IMember>.Instance; }
} }
@ -159,8 +159,8 @@ namespace ICSharpCode.Decompiler.CSharp.Resolver
DomRegion IEntity.BodyRegion { DomRegion IEntity.BodyRegion {
get { return DomRegion.Empty; } get { return DomRegion.Empty; }
} }
IList<IAttribute> IEntity.Attributes { IReadOnlyList<IAttribute> IEntity.Attributes {
get { return EmptyList<IAttribute>.Instance; } get { return EmptyList<IAttribute>.Instance; }
} }
@ -298,7 +298,7 @@ namespace ICSharpCode.Decompiler.CSharp.Resolver
{ {
TypeCode typeCode = Type.GetTypeCode(typeof(T)); TypeCode typeCode = Type.GetTypeCode(typeof(T));
this.ReturnType = operators.compilation.FindType(typeCode); this.ReturnType = operators.compilation.FindType(typeCode);
this.Parameters.Add(operators.MakeParameter(typeCode)); parameters.Add(operators.MakeParameter(typeCode));
this.func = func; this.func = func;
} }
@ -327,10 +327,10 @@ namespace ICSharpCode.Decompiler.CSharp.Resolver
{ {
this.baseMethod = baseMethod; this.baseMethod = baseMethod;
this.ReturnType = NullableType.Create(baseMethod.Compilation, baseMethod.ReturnType); this.ReturnType = NullableType.Create(baseMethod.Compilation, baseMethod.ReturnType);
this.Parameters.Add(operators.MakeNullableParameter(baseMethod.Parameters[0])); parameters.Add(operators.MakeNullableParameter(baseMethod.Parameters[0]));
} }
public IList<IParameter> NonLiftedParameters => baseMethod.Parameters; public IReadOnlyList<IParameter> NonLiftedParameters => baseMethod.Parameters;
public IType NonLiftedReturnType => baseMethod.ReturnType; public IType NonLiftedReturnType => baseMethod.ReturnType;
} }
#endregion #endregion
@ -459,8 +459,8 @@ namespace ICSharpCode.Decompiler.CSharp.Resolver
{ {
TypeCode t1 = Type.GetTypeCode(typeof(T1)); TypeCode t1 = Type.GetTypeCode(typeof(T1));
this.ReturnType = operators.compilation.FindType(t1); this.ReturnType = operators.compilation.FindType(t1);
this.Parameters.Add(operators.MakeParameter(t1)); parameters.Add(operators.MakeParameter(t1));
this.Parameters.Add(operators.MakeParameter(Type.GetTypeCode(typeof(T2)))); parameters.Add(operators.MakeParameter(Type.GetTypeCode(typeof(T2))));
this.checkedFunc = checkedFunc; this.checkedFunc = checkedFunc;
this.uncheckedFunc = uncheckedFunc; this.uncheckedFunc = uncheckedFunc;
} }
@ -493,11 +493,11 @@ namespace ICSharpCode.Decompiler.CSharp.Resolver
{ {
this.baseMethod = baseMethod; this.baseMethod = baseMethod;
this.ReturnType = NullableType.Create(operators.compilation, baseMethod.ReturnType); this.ReturnType = NullableType.Create(operators.compilation, baseMethod.ReturnType);
this.Parameters.Add(operators.MakeNullableParameter(baseMethod.Parameters[0])); parameters.Add(operators.MakeNullableParameter(baseMethod.Parameters[0]));
this.Parameters.Add(operators.MakeNullableParameter(baseMethod.Parameters[1])); parameters.Add(operators.MakeNullableParameter(baseMethod.Parameters[1]));
} }
public IList<IParameter> NonLiftedParameters => baseMethod.Parameters; public IReadOnlyList<IParameter> NonLiftedParameters => baseMethod.Parameters;
public IType NonLiftedReturnType => baseMethod.ReturnType; public IType NonLiftedReturnType => baseMethod.ReturnType;
} }
#endregion #endregion
@ -605,8 +605,8 @@ namespace ICSharpCode.Decompiler.CSharp.Resolver
{ {
this.canEvaluateAtCompileTime = p1 == TypeCode.String && p2 == TypeCode.String; this.canEvaluateAtCompileTime = p1 == TypeCode.String && p2 == TypeCode.String;
this.ReturnType = operators.compilation.FindType(KnownTypeCode.String); this.ReturnType = operators.compilation.FindType(KnownTypeCode.String);
this.Parameters.Add(operators.MakeParameter(p1)); parameters.Add(operators.MakeParameter(p1));
this.Parameters.Add(operators.MakeParameter(p2)); parameters.Add(operators.MakeParameter(p2));
} }
public override bool CanEvaluateAtCompileTime { public override bool CanEvaluateAtCompileTime {
@ -691,8 +691,8 @@ namespace ICSharpCode.Decompiler.CSharp.Resolver
this.Negate = negate; this.Negate = negate;
this.Type = type; this.Type = type;
this.ReturnType = operators.compilation.FindType(KnownTypeCode.Boolean); this.ReturnType = operators.compilation.FindType(KnownTypeCode.Boolean);
this.Parameters.Add(operators.MakeParameter(type)); parameters.Add(operators.MakeParameter(type));
this.Parameters.Add(operators.MakeParameter(type)); parameters.Add(operators.MakeParameter(type));
} }
public override bool CanEvaluateAtCompileTime { public override bool CanEvaluateAtCompileTime {
@ -737,8 +737,8 @@ namespace ICSharpCode.Decompiler.CSharp.Resolver
this.baseMethod = baseMethod; this.baseMethod = baseMethod;
this.ReturnType = baseMethod.ReturnType; this.ReturnType = baseMethod.ReturnType;
IParameter p = operators.MakeNullableParameter(baseMethod.Parameters[0]); IParameter p = operators.MakeNullableParameter(baseMethod.Parameters[0]);
this.Parameters.Add(p); parameters.Add(p);
this.Parameters.Add(p); parameters.Add(p);
} }
public override bool CanEvaluateAtCompileTime { public override bool CanEvaluateAtCompileTime {
@ -750,7 +750,7 @@ namespace ICSharpCode.Decompiler.CSharp.Resolver
return baseMethod.Invoke(resolver, lhs, rhs); return baseMethod.Invoke(resolver, lhs, rhs);
} }
public IList<IParameter> NonLiftedParameters => baseMethod.Parameters; public IReadOnlyList<IParameter> NonLiftedParameters => baseMethod.Parameters;
public IType NonLiftedReturnType => baseMethod.ReturnType; public IType NonLiftedReturnType => baseMethod.ReturnType;
} }
@ -835,8 +835,8 @@ namespace ICSharpCode.Decompiler.CSharp.Resolver
: base(operators.compilation) : base(operators.compilation)
{ {
this.ReturnType = operators.compilation.FindType(KnownTypeCode.Boolean); this.ReturnType = operators.compilation.FindType(KnownTypeCode.Boolean);
this.Parameters.Add(operators.MakeParameter(Type.GetTypeCode(typeof(T1)))); parameters.Add(operators.MakeParameter(Type.GetTypeCode(typeof(T1))));
this.Parameters.Add(operators.MakeParameter(Type.GetTypeCode(typeof(T2)))); parameters.Add(operators.MakeParameter(Type.GetTypeCode(typeof(T2))));
this.func = func; this.func = func;
} }
@ -1080,7 +1080,7 @@ namespace ICSharpCode.Decompiler.CSharp.Resolver
this.ReturnType = nonLiftedMethod.ReturnType.AcceptVisitor(substitution); this.ReturnType = nonLiftedMethod.ReturnType.AcceptVisitor(substitution);
} }
public IList<IParameter> NonLiftedParameters => nonLiftedOperator.Parameters; public IReadOnlyList<IParameter> NonLiftedParameters => nonLiftedOperator.Parameters;
public IType NonLiftedReturnType => nonLiftedOperator.ReturnType; public IType NonLiftedReturnType => nonLiftedOperator.ReturnType;
public override bool Equals(object obj) public override bool Equals(object obj)
@ -1136,6 +1136,6 @@ namespace ICSharpCode.Decompiler.CSharp.Resolver
public interface ILiftedOperator : IParameterizedMember public interface ILiftedOperator : IParameterizedMember
{ {
IType NonLiftedReturnType { get; } IType NonLiftedReturnType { get; }
IList<IParameter> NonLiftedParameters { get; } IReadOnlyList<IParameter> NonLiftedParameters { get; }
} }
} }

20
ICSharpCode.Decompiler/CSharp/Resolver/CSharpResolver.cs

@ -908,7 +908,7 @@ namespace ICSharpCode.Decompiler.CSharp.Resolver
{ {
return new CSharpOperators.BinaryOperatorMethod(compilation) { return new CSharpOperators.BinaryOperatorMethod(compilation) {
ReturnType = resultType, ReturnType = resultType,
Parameters = { parameters = {
new DefaultParameter(inputType1, string.Empty), new DefaultParameter(inputType1, string.Empty),
new DefaultParameter(inputType2, string.Empty) new DefaultParameter(inputType2, string.Empty)
} }
@ -1295,7 +1295,7 @@ namespace ICSharpCode.Decompiler.CSharp.Resolver
#endregion #endregion
#region ResolveSimpleName #region ResolveSimpleName
public ResolveResult ResolveSimpleName(string identifier, IList<IType> typeArguments, bool isInvocationTarget = false) public ResolveResult ResolveSimpleName(string identifier, IReadOnlyList<IType> typeArguments, bool isInvocationTarget = false)
{ {
// C# 4.0 spec: §7.6.2 Simple Names // C# 4.0 spec: §7.6.2 Simple Names
@ -1304,7 +1304,7 @@ namespace ICSharpCode.Decompiler.CSharp.Resolver
isInvocationTarget ? NameLookupMode.InvocationTarget : NameLookupMode.Expression); isInvocationTarget ? NameLookupMode.InvocationTarget : NameLookupMode.Expression);
} }
public ResolveResult LookupSimpleNameOrTypeName(string identifier, IList<IType> typeArguments, NameLookupMode lookupMode) public ResolveResult LookupSimpleNameOrTypeName(string identifier, IReadOnlyList<IType> typeArguments, NameLookupMode lookupMode)
{ {
// C# 4.0 spec: §3.8 Namespace and type names; §7.6.2 Simple Names // C# 4.0 spec: §3.8 Namespace and type names; §7.6.2 Simple Names
@ -1416,7 +1416,7 @@ namespace ICSharpCode.Decompiler.CSharp.Resolver
return trr != null && trr.Type.Equals (rr.Type); return trr != null && trr.Type.Equals (rr.Type);
} }
ResolveResult LookInCurrentType(string identifier, IList<IType> typeArguments, NameLookupMode lookupMode, bool parameterizeResultType) ResolveResult LookInCurrentType(string identifier, IReadOnlyList<IType> typeArguments, NameLookupMode lookupMode, bool parameterizeResultType)
{ {
int k = typeArguments.Count; int k = typeArguments.Count;
MemberLookup lookup = CreateMemberLookup(lookupMode); MemberLookup lookup = CreateMemberLookup(lookupMode);
@ -1451,7 +1451,7 @@ namespace ICSharpCode.Decompiler.CSharp.Resolver
return null; return null;
} }
ResolveResult LookInCurrentUsingScope(string identifier, IList<IType> typeArguments, bool isInUsingDeclaration, bool parameterizeResultType) ResolveResult LookInCurrentUsingScope(string identifier, IReadOnlyList<IType> typeArguments, bool isInUsingDeclaration, bool parameterizeResultType)
{ {
// look in current namespace definitions // look in current namespace definitions
ResolvedUsingScope currentUsingScope = this.CurrentUsingScope; ResolvedUsingScope currentUsingScope = this.CurrentUsingScope;
@ -1500,7 +1500,7 @@ namespace ICSharpCode.Decompiler.CSharp.Resolver
return null; return null;
} }
ResolveResult LookInUsingScopeNamespace(ResolvedUsingScope usingScope, INamespace n, string identifier, IList<IType> typeArguments, bool parameterizeResultType) ResolveResult LookInUsingScopeNamespace(ResolvedUsingScope usingScope, INamespace n, string identifier, IReadOnlyList<IType> typeArguments, bool parameterizeResultType)
{ {
if (n == null) if (n == null)
return null; return null;
@ -1569,7 +1569,7 @@ namespace ICSharpCode.Decompiler.CSharp.Resolver
#endregion #endregion
#region ResolveMemberAccess #region ResolveMemberAccess
public ResolveResult ResolveMemberAccess(ResolveResult target, string identifier, IList<IType> typeArguments, NameLookupMode lookupMode = NameLookupMode.Expression) public ResolveResult ResolveMemberAccess(ResolveResult target, string identifier, IReadOnlyList<IType> typeArguments, NameLookupMode lookupMode = NameLookupMode.Expression)
{ {
// C# 4.0 spec: §7.6.4 // C# 4.0 spec: §7.6.4
@ -1622,7 +1622,7 @@ namespace ICSharpCode.Decompiler.CSharp.Resolver
return result; return result;
} }
ResolveResult ResolveMemberAccessOnNamespace(NamespaceResolveResult nrr, string identifier, IList<IType> typeArguments, bool parameterizeResultType) ResolveResult ResolveMemberAccessOnNamespace(NamespaceResolveResult nrr, string identifier, IReadOnlyList<IType> typeArguments, bool parameterizeResultType)
{ {
if (typeArguments.Count == 0) { if (typeArguments.Count == 0) {
INamespace childNamespace = nrr.Namespace.GetChildNamespace(identifier); INamespace childNamespace = nrr.Namespace.GetChildNamespace(identifier);
@ -1693,7 +1693,7 @@ namespace ICSharpCode.Decompiler.CSharp.Resolver
/// new List { all extensions from SomeExtensions } /// new List { all extensions from SomeExtensions }
/// } /// }
/// </remarks> /// </remarks>
public List<List<IMethod>> GetExtensionMethods(string name = null, IList<IType> typeArguments = null) public List<List<IMethod>> GetExtensionMethods(string name = null, IReadOnlyList<IType> typeArguments = null)
{ {
return GetExtensionMethods(null, name, typeArguments); return GetExtensionMethods(null, name, typeArguments);
} }
@ -1722,7 +1722,7 @@ namespace ICSharpCode.Decompiler.CSharp.Resolver
/// new List { all extensions from SomeExtensions } /// new List { all extensions from SomeExtensions }
/// } /// }
/// </remarks> /// </remarks>
public List<List<IMethod>> GetExtensionMethods(IType targetType, string name = null, IList<IType> typeArguments = null, bool substituteInferredTypes = false) public List<List<IMethod>> GetExtensionMethods(IType targetType, string name = null, IReadOnlyList<IType> typeArguments = null, bool substituteInferredTypes = false)
{ {
var lookup = CreateMemberLookup(); var lookup = CreateMemberLookup();
List<List<IMethod>> extensionMethodGroups = new List<List<IMethod>>(); List<List<IMethod>> extensionMethodGroups = new List<List<IMethod>>();

4
ICSharpCode.Decompiler/CSharp/Resolver/LambdaResolveResult.cs

@ -69,7 +69,7 @@ namespace ICSharpCode.Decompiler.CSharp.Resolver
/// <summary> /// <summary>
/// Gets the list of parameters. /// Gets the list of parameters.
/// </summary> /// </summary>
public abstract IList<IParameter> Parameters { get; } public abstract IReadOnlyList<IParameter> Parameters { get; }
/// <summary> /// <summary>
/// Gets the return type of the lambda. /// Gets the return type of the lambda.
@ -132,7 +132,7 @@ namespace ICSharpCode.Decompiler.CSharp.Resolver
public override bool IsImplicitlyTyped { get; } public override bool IsImplicitlyTyped { get; }
public override bool IsAsync => function.IsAsync; public override bool IsAsync => function.IsAsync;
public override IList<IParameter> Parameters => function.Parameters; public override IReadOnlyList<IParameter> Parameters => function.Parameters;
public override IType ReturnType => function.ReturnType; public override IType ReturnType => function.ReturnType;
public override ResolveResult Body { get; } public override ResolveResult Body { get; }

8
ICSharpCode.Decompiler/CSharp/Resolver/MemberLookup.cs

@ -273,7 +273,7 @@ namespace ICSharpCode.Decompiler.CSharp.Resolver
#endregion #endregion
#region LookupType #region LookupType
public ResolveResult LookupType(IType declaringType, string name, IList<IType> typeArguments, bool parameterizeResultType = true) public ResolveResult LookupType(IType declaringType, string name, IReadOnlyList<IType> typeArguments, bool parameterizeResultType = true)
{ {
if (declaringType == null) if (declaringType == null)
throw new ArgumentNullException("declaringType"); throw new ArgumentNullException("declaringType");
@ -332,7 +332,7 @@ namespace ICSharpCode.Decompiler.CSharp.Resolver
/// <summary> /// <summary>
/// Performs a member lookup. /// Performs a member lookup.
/// </summary> /// </summary>
public ResolveResult Lookup(ResolveResult targetResolveResult, string name, IList<IType> typeArguments, bool isInvocation) public ResolveResult Lookup(ResolveResult targetResolveResult, string name, IReadOnlyList<IType> typeArguments, bool isInvocation)
{ {
if (targetResolveResult == null) if (targetResolveResult == null)
throw new ArgumentNullException("targetResolveResult"); throw new ArgumentNullException("targetResolveResult");
@ -410,7 +410,7 @@ namespace ICSharpCode.Decompiler.CSharp.Resolver
/// <summary> /// <summary>
/// Looks up the indexers on the target type. /// Looks up the indexers on the target type.
/// </summary> /// </summary>
public IList<MethodListWithDeclaringType> LookupIndexers(ResolveResult targetResolveResult) public IReadOnlyList<MethodListWithDeclaringType> LookupIndexers(ResolveResult targetResolveResult)
{ {
if (targetResolveResult == null) if (targetResolveResult == null)
throw new ArgumentNullException("targetResolveResult"); throw new ArgumentNullException("targetResolveResult");
@ -634,7 +634,7 @@ namespace ICSharpCode.Decompiler.CSharp.Resolver
#endregion #endregion
#region CreateResult #region CreateResult
ResolveResult CreateResult(ResolveResult targetResolveResult, List<LookupGroup> lookupGroups, string name, IList<IType> typeArguments) ResolveResult CreateResult(ResolveResult targetResolveResult, List<LookupGroup> lookupGroups, string name, IReadOnlyList<IType> typeArguments)
{ {
// Remove all hidden groups // Remove all hidden groups
lookupGroups.RemoveAll(g => g.AllHidden); lookupGroups.RemoveAll(g => g.AllHidden);

10
ICSharpCode.Decompiler/CSharp/Resolver/MethodGroupResolveResult.cs

@ -76,12 +76,14 @@ namespace ICSharpCode.Decompiler.CSharp.Resolver
/// </summary> /// </summary>
public class MethodGroupResolveResult : ResolveResult public class MethodGroupResolveResult : ResolveResult
{ {
readonly IList<MethodListWithDeclaringType> methodLists; readonly IReadOnlyList<MethodListWithDeclaringType> methodLists;
readonly IList<IType> typeArguments; readonly IReadOnlyList<IType> typeArguments;
readonly ResolveResult targetResult; readonly ResolveResult targetResult;
readonly string methodName; readonly string methodName;
public MethodGroupResolveResult(ResolveResult targetResult, string methodName, IList<MethodListWithDeclaringType> methods, IList<IType> typeArguments) : base(SpecialType.UnknownType) public MethodGroupResolveResult(ResolveResult targetResult, string methodName,
IReadOnlyList<MethodListWithDeclaringType> methods, IReadOnlyList<IType> typeArguments)
: base(SpecialType.UnknownType)
{ {
if (methods == null) if (methods == null)
throw new ArgumentNullException("methods"); throw new ArgumentNullException("methods");
@ -132,7 +134,7 @@ namespace ICSharpCode.Decompiler.CSharp.Resolver
/// <summary> /// <summary>
/// Gets the type arguments that were explicitly provided. /// Gets the type arguments that were explicitly provided.
/// </summary> /// </summary>
public IList<IType> TypeArguments { public IReadOnlyList<IType> TypeArguments {
get { return typeArguments; } get { return typeArguments; }
} }

12
ICSharpCode.Decompiler/CSharp/Resolver/OverloadResolution.cs

@ -62,12 +62,12 @@ namespace ICSharpCode.Decompiler.CSharp.Resolver
/// <summary> /// <summary>
/// Gets the original member parameters (before any substitution!) /// Gets the original member parameters (before any substitution!)
/// </summary> /// </summary>
public readonly IList<IParameter> Parameters; public readonly IReadOnlyList<IParameter> Parameters;
/// <summary> /// <summary>
/// Gets the original method type parameters (before any substitution!) /// Gets the original method type parameters (before any substitution!)
/// </summary> /// </summary>
public readonly IList<ITypeParameter> TypeParameters; public readonly IReadOnlyList<ITypeParameter> TypeParameters;
/// <summary> /// <summary>
/// Conversions applied to the arguments. /// Conversions applied to the arguments.
@ -290,7 +290,7 @@ namespace ICSharpCode.Decompiler.CSharp.Resolver
/// all methods in base types. /// all methods in base types.
/// </summary> /// </summary>
/// <param name="methodLists">The methods, grouped by declaring type. Base types must come first in the list.</param> /// <param name="methodLists">The methods, grouped by declaring type. Base types must come first in the list.</param>
public void AddMethodLists(IList<MethodListWithDeclaringType> methodLists) public void AddMethodLists(IReadOnlyList<MethodListWithDeclaringType> methodLists)
{ {
if (methodLists == null) if (methodLists == null)
throw new ArgumentNullException("methodLists"); throw new ArgumentNullException("methodLists");
@ -400,7 +400,7 @@ namespace ICSharpCode.Decompiler.CSharp.Resolver
return; return;
} }
ParameterizedType parameterizedDeclaringType = candidate.Member.DeclaringType as ParameterizedType; ParameterizedType parameterizedDeclaringType = candidate.Member.DeclaringType as ParameterizedType;
IList<IType> classTypeArguments; IReadOnlyList<IType> classTypeArguments;
if (parameterizedDeclaringType != null) { if (parameterizedDeclaringType != null) {
classTypeArguments = parameterizedDeclaringType.TypeArguments; classTypeArguments = parameterizedDeclaringType.TypeArguments;
} else { } else {
@ -442,7 +442,7 @@ namespace ICSharpCode.Decompiler.CSharp.Resolver
readonly CSharpConversions conversions; readonly CSharpConversions conversions;
public bool ConstraintsValid = true; public bool ConstraintsValid = true;
public ConstraintValidatingSubstitution(IList<IType> classTypeArguments, IList<IType> methodTypeArguments, OverloadResolution overloadResolution) public ConstraintValidatingSubstitution(IReadOnlyList<IType> classTypeArguments, IReadOnlyList<IType> methodTypeArguments, OverloadResolution overloadResolution)
: base(classTypeArguments, methodTypeArguments) : base(classTypeArguments, methodTypeArguments)
{ {
this.conversions = overloadResolution.conversions; this.conversions = overloadResolution.conversions;
@ -816,7 +816,7 @@ namespace ICSharpCode.Decompiler.CSharp.Resolver
get { return bestCandidateAmbiguousWith != null; } get { return bestCandidateAmbiguousWith != null; }
} }
public IList<IType> InferredTypeArguments { public IReadOnlyList<IType> InferredTypeArguments {
get { get {
if (bestCandidate != null && bestCandidate.InferredTypes != null) if (bestCandidate != null && bestCandidate.InferredTypes != null)
return bestCandidate.InferredTypes; return bestCandidate.InferredTypes;

18
ICSharpCode.Decompiler/CSharp/Resolver/ReducedExtensionMethod.cs

@ -122,7 +122,7 @@ namespace ICSharpCode.Decompiler.CSharp.Resolver
} }
} }
public System.Collections.Generic.IList<IMember> ImplementedInterfaceMembers { public IReadOnlyList<IMember> ImplementedInterfaceMembers {
get { get {
return baseMethod.ImplementedInterfaceMembers; return baseMethod.ImplementedInterfaceMembers;
} }
@ -167,28 +167,24 @@ namespace ICSharpCode.Decompiler.CSharp.Resolver
{ {
return Specialize(substitution); return Specialize(substitution);
} }
public bool IsParameterized {
get { return baseMethod.IsParameterized; }
}
#endregion #endregion
#region IMethod implementation #region IMethod implementation
public System.Collections.Generic.IList<IUnresolvedMethod> Parts { public IReadOnlyList<IUnresolvedMethod> Parts {
get { get {
return baseMethod.Parts; return baseMethod.Parts;
} }
} }
public System.Collections.Generic.IList<IAttribute> ReturnTypeAttributes { public IReadOnlyList<IAttribute> ReturnTypeAttributes {
get { get {
return baseMethod.ReturnTypeAttributes; return baseMethod.ReturnTypeAttributes;
} }
} }
public System.Collections.Generic.IList<ITypeParameter> TypeParameters { public IReadOnlyList<ITypeParameter> TypeParameters {
get { get {
return baseMethod.TypeParameters; return baseMethod.TypeParameters;
} }
@ -254,7 +250,7 @@ namespace ICSharpCode.Decompiler.CSharp.Resolver
} }
} }
public IList<IType> TypeArguments { public IReadOnlyList<IType> TypeArguments {
get { get {
return baseMethod.TypeArguments; return baseMethod.TypeArguments;
} }
@ -263,7 +259,7 @@ namespace ICSharpCode.Decompiler.CSharp.Resolver
#region IParameterizedMember implementation #region IParameterizedMember implementation
List<IParameter> parameters; List<IParameter> parameters;
public System.Collections.Generic.IList<IParameter> Parameters { public IReadOnlyList<IParameter> Parameters {
get { get {
if (parameters == null) if (parameters == null)
parameters = new List<IParameter> (baseMethod.Parameters.Skip (1)); parameters = new List<IParameter> (baseMethod.Parameters.Skip (1));
@ -311,7 +307,7 @@ namespace ICSharpCode.Decompiler.CSharp.Resolver
} }
} }
public System.Collections.Generic.IList<IAttribute> Attributes { public IReadOnlyList<IAttribute> Attributes {
get { get {
return baseMethod.Attributes; return baseMethod.Attributes;
} }

14
ICSharpCode.Decompiler/CSharp/Resolver/TypeInference.cs

@ -97,7 +97,7 @@ namespace ICSharpCode.Decompiler.CSharp.Resolver
IType[] parameterTypes; IType[] parameterTypes;
ResolveResult[] arguments; ResolveResult[] arguments;
bool[,] dependencyMatrix; bool[,] dependencyMatrix;
IList<IType> classTypeArguments; IReadOnlyList<IType> classTypeArguments;
#region InferTypeArguments (main function) #region InferTypeArguments (main function)
/// <summary> /// <summary>
@ -112,7 +112,7 @@ namespace ICSharpCode.Decompiler.CSharp.Resolver
/// when inferring a method group or lambda. /// when inferring a method group or lambda.
/// </param> /// </param>
/// <returns>The inferred type arguments.</returns> /// <returns>The inferred type arguments.</returns>
public IType[] InferTypeArguments(IList<ITypeParameter> typeParameters, IList<ResolveResult> arguments, IList<IType> parameterTypes, out bool success, IList<IType> classTypeArguments = null) public IType[] InferTypeArguments(IReadOnlyList<ITypeParameter> typeParameters, IReadOnlyList<ResolveResult> arguments, IReadOnlyList<IType> parameterTypes, out bool success, IReadOnlyList<IType> classTypeArguments = null)
{ {
if (typeParameters == null) if (typeParameters == null)
throw new ArgumentNullException("typeParameters"); throw new ArgumentNullException("typeParameters");
@ -170,7 +170,7 @@ namespace ICSharpCode.Decompiler.CSharp.Resolver
/// Infers type arguments for the <paramref name="typeParameters"/> occurring in the <paramref name="targetType"/> /// Infers type arguments for the <paramref name="typeParameters"/> occurring in the <paramref name="targetType"/>
/// so that the resulting type (after substition) satisfies the given bounds. /// so that the resulting type (after substition) satisfies the given bounds.
/// </summary> /// </summary>
public IType[] InferTypeArgumentsFromBounds(IList<ITypeParameter> typeParameters, IType targetType, IList<IType> lowerBounds, IList<IType> upperBounds, out bool success) public IType[] InferTypeArgumentsFromBounds(IReadOnlyList<ITypeParameter> typeParameters, IType targetType, IEnumerable<IType> lowerBounds, IEnumerable<IType> upperBounds, out bool success)
{ {
if (typeParameters == null) if (typeParameters == null)
throw new ArgumentNullException("typeParameters"); throw new ArgumentNullException("typeParameters");
@ -840,14 +840,14 @@ namespace ICSharpCode.Decompiler.CSharp.Resolver
/// <summary> /// <summary>
/// Finds a type that satisfies the given lower and upper bounds. /// Finds a type that satisfies the given lower and upper bounds.
/// </summary> /// </summary>
public IType FindTypeInBounds(IList<IType> lowerBounds, IList<IType> upperBounds) public IType FindTypeInBounds(IReadOnlyList<IType> lowerBounds, IReadOnlyList<IType> upperBounds)
{ {
if (lowerBounds == null) if (lowerBounds == null)
throw new ArgumentNullException("lowerBounds"); throw new ArgumentNullException("lowerBounds");
if (upperBounds == null) if (upperBounds == null)
throw new ArgumentNullException("upperBounds"); throw new ArgumentNullException("upperBounds");
IList<IType> result = FindTypesInBounds(lowerBounds, upperBounds); var result = FindTypesInBounds(lowerBounds, upperBounds);
if (algorithm == TypeInferenceAlgorithm.ImprovedReturnAllResults) { if (algorithm == TypeInferenceAlgorithm.ImprovedReturnAllResults) {
return IntersectionType.Create(result); return IntersectionType.Create(result);
@ -857,13 +857,13 @@ namespace ICSharpCode.Decompiler.CSharp.Resolver
} }
} }
static IType GetFirstTypePreferNonInterfaces(IList<IType> result) static IType GetFirstTypePreferNonInterfaces(IReadOnlyList<IType> result)
{ {
return result.FirstOrDefault(c => c.Kind != TypeKind.Interface) return result.FirstOrDefault(c => c.Kind != TypeKind.Interface)
?? result.FirstOrDefault() ?? SpecialType.UnknownType; ?? result.FirstOrDefault() ?? SpecialType.UnknownType;
} }
IList<IType> FindTypesInBounds(IList<IType> lowerBounds, IList<IType> upperBounds) IReadOnlyList<IType> FindTypesInBounds(IReadOnlyList<IType> lowerBounds, IReadOnlyList<IType> upperBounds)
{ {
// If there's only a single type; return that single type. // If there's only a single type; return that single type.
// If both inputs are empty, return the empty list. // If both inputs are empty, return the empty list.

14
ICSharpCode.Decompiler/CSharp/Syntax/TypeSystemAstBuilder.cs

@ -254,7 +254,7 @@ namespace ICSharpCode.Decompiler.CSharp.Syntax
return new SimpleType(type.Name); return new SimpleType(type.Name);
} }
AstType ConvertTypeHelper(ITypeDefinition typeDef, IList<IType> typeArguments) AstType ConvertTypeHelper(ITypeDefinition typeDef, IReadOnlyList<IType> typeArguments)
{ {
Debug.Assert(typeArguments.Count >= typeDef.TypeParameterCount); Debug.Assert(typeArguments.Count >= typeDef.TypeParameterCount);
@ -282,18 +282,18 @@ namespace ICSharpCode.Decompiler.CSharp.Syntax
} }
} }
IList<IType> localTypeArguments; IType[] localTypeArguments;
if (typeDef.TypeParameterCount > outerTypeParameterCount) { if (typeDef.TypeParameterCount > outerTypeParameterCount) {
localTypeArguments = new IType[typeDef.TypeParameterCount - outerTypeParameterCount]; localTypeArguments = new IType[typeDef.TypeParameterCount - outerTypeParameterCount];
for (int i = 0; i < localTypeArguments.Count; i++) { for (int i = 0; i < localTypeArguments.Length; i++) {
localTypeArguments[i] = typeArguments[outerTypeParameterCount + i]; localTypeArguments[i] = typeArguments[outerTypeParameterCount + i];
} }
} else { } else {
localTypeArguments = EmptyList<IType>.Instance; localTypeArguments = Empty<IType>.Array;
} }
ResolveResult rr = resolver.LookupSimpleNameOrTypeName(typeDef.Name, localTypeArguments, NameLookupMode); ResolveResult rr = resolver.LookupSimpleNameOrTypeName(typeDef.Name, localTypeArguments, NameLookupMode);
TypeResolveResult trr = rr as TypeResolveResult; TypeResolveResult trr = rr as TypeResolveResult;
if (trr != null || (localTypeArguments.Count == 0 && resolver.IsVariableReferenceWithSameType(rr, typeDef.Name, out trr))) { if (trr != null || (localTypeArguments.Length == 0 && resolver.IsVariableReferenceWithSameType(rr, typeDef.Name, out trr))) {
if (!trr.IsError && TypeMatches(trr.Type, typeDef, typeArguments)) { if (!trr.IsError && TypeMatches(trr.Type, typeDef, typeArguments)) {
// We can use the short type name // We can use the short type name
SimpleType shortResult = new SimpleType(typeDef.Name); SimpleType shortResult = new SimpleType(typeDef.Name);
@ -329,7 +329,7 @@ namespace ICSharpCode.Decompiler.CSharp.Syntax
/// <summary> /// <summary>
/// Gets whether 'type' is the same as 'typeDef' parameterized with the given type arguments. /// Gets whether 'type' is the same as 'typeDef' parameterized with the given type arguments.
/// </summary> /// </summary>
bool TypeMatches(IType type, ITypeDefinition typeDef, IList<IType> typeArguments) bool TypeMatches(IType type, ITypeDefinition typeDef, IReadOnlyList<IType> typeArguments)
{ {
if (typeDef.TypeParameterCount == 0) { if (typeDef.TypeParameterCount == 0) {
return typeDef.Equals(type); return typeDef.Equals(type);
@ -357,7 +357,7 @@ namespace ICSharpCode.Decompiler.CSharp.Syntax
/// <param name="typeArguments">The list of type arguments</param> /// <param name="typeArguments">The list of type arguments</param>
/// <param name="startIndex">Index of first type argument to add</param> /// <param name="startIndex">Index of first type argument to add</param>
/// <param name="endIndex">Index after last type argument to add</param> /// <param name="endIndex">Index after last type argument to add</param>
void AddTypeArguments(AstType result, ITypeDefinition typeDef, IList<IType> typeArguments, int startIndex, int endIndex) void AddTypeArguments(AstType result, ITypeDefinition typeDef, IReadOnlyList<IType> typeArguments, int startIndex, int endIndex)
{ {
Debug.Assert(endIndex <= typeDef.TypeParameterCount); Debug.Assert(endIndex <= typeDef.TypeParameterCount);
for (int i = startIndex; i < endIndex; i++) { for (int i = startIndex; i < endIndex; i++) {

2
ICSharpCode.Decompiler/CSharp/TypeSystem/MemberTypeOrNamespaceReference.cs

@ -79,7 +79,7 @@ namespace ICSharpCode.Decompiler.CSharp.TypeSystem
ResolveResult targetRR = target.Resolve(resolver); ResolveResult targetRR = target.Resolve(resolver);
if (targetRR.IsError) if (targetRR.IsError)
return targetRR; return targetRR;
IList<IType> typeArgs = typeArguments.Resolve(resolver.CurrentTypeResolveContext); IReadOnlyList<IType> typeArgs = typeArguments.Resolve(resolver.CurrentTypeResolveContext);
return resolver.ResolveMemberAccess(targetRR, identifier, typeArgs, lookupMode); return resolver.ResolveMemberAccess(targetRR, identifier, typeArgs, lookupMode);
} }

2
ICSharpCode.Decompiler/CSharp/TypeSystem/MethodTypeParameterWithInheritedConstraints.cs

@ -109,7 +109,7 @@ namespace ICSharpCode.Decompiler.CSharp.TypeSystem
// Substitute occurrences of the base method's type parameters in the constraints // Substitute occurrences of the base method's type parameters in the constraints
// with the type parameters from the // with the type parameters from the
IMethod owner = (IMethod)this.Owner; IMethod owner = (IMethod)this.Owner;
var substitution = new TypeParameterSubstitution(null, new ProjectedList<ITypeParameter, IType>(owner.TypeParameters, t => t)); var substitution = new TypeParameterSubstitution(null, owner.TypeParameters);
return baseTP.DirectBaseTypes.Select(t => t.AcceptVisitor(substitution)); return baseTP.DirectBaseTypes.Select(t => t.AcceptVisitor(substitution));
} else { } else {
return EmptyList<IType>.Instance; return EmptyList<IType>.Instance;

4
ICSharpCode.Decompiler/IL/Instructions/ILFunction.cs

@ -71,7 +71,7 @@ namespace ICSharpCode.Decompiler.IL
public readonly IType ReturnType; public readonly IType ReturnType;
public readonly IList<IParameter> Parameters; public readonly IReadOnlyList<IParameter> Parameters;
public ILFunction(IMethod method, MethodDefinition cecilMethod, ILInstruction body) : base(OpCode.ILFunction) public ILFunction(IMethod method, MethodDefinition cecilMethod, ILInstruction body) : base(OpCode.ILFunction)
{ {
@ -83,7 +83,7 @@ namespace ICSharpCode.Decompiler.IL
this.Variables = new ILVariableCollection(this); this.Variables = new ILVariableCollection(this);
} }
public ILFunction(IType returnType, IList<IParameter> parameters, ILInstruction body) : base(OpCode.ILFunction) public ILFunction(IType returnType, IReadOnlyList<IParameter> parameters, ILInstruction body) : base(OpCode.ILFunction)
{ {
this.Body = body; this.Body = body;
this.ReturnType = returnType; this.ReturnType = returnType;

4
ICSharpCode.Decompiler/NRExtensions.cs

@ -25,8 +25,8 @@ namespace ICSharpCode.Decompiler
{ {
public static IDecompilerTypeSystem GetSpecializingTypeSystem(this IDecompilerTypeSystem typeSystem, ITypeResolveContext decompilationContext) public static IDecompilerTypeSystem GetSpecializingTypeSystem(this IDecompilerTypeSystem typeSystem, ITypeResolveContext decompilationContext)
{ {
IList<IType> classTypeParameters = null; IReadOnlyList<IType> classTypeParameters = null;
IList<IType> methodTypeParameters = null; IReadOnlyList<IType> methodTypeParameters = null;
if (decompilationContext.CurrentTypeDefinition != null && decompilationContext.CurrentTypeDefinition.TypeParameterCount > 0) if (decompilationContext.CurrentTypeDefinition != null && decompilationContext.CurrentTypeDefinition.TypeParameterCount > 0)
classTypeParameters = decompilationContext.CurrentTypeDefinition.TypeArguments; classTypeParameters = decompilationContext.CurrentTypeDefinition.TypeArguments;

2
ICSharpCode.Decompiler/TypeSystem/AnonymousType.cs

@ -141,7 +141,7 @@ namespace ICSharpCode.Decompiler.TypeSystem
return compilation.FindType(KnownTypeCode.Object).GetMethods(filter, options); return compilation.FindType(KnownTypeCode.Object).GetMethods(filter, options);
} }
public override IEnumerable<IMethod> GetMethods(IList<IType> typeArguments, Predicate<IUnresolvedMethod> filter = null, GetMemberOptions options = GetMemberOptions.None) public override IEnumerable<IMethod> GetMethods(IReadOnlyList<IType> typeArguments, Predicate<IUnresolvedMethod> filter = null, GetMemberOptions options = GetMemberOptions.None)
{ {
if ((options & GetMemberOptions.IgnoreInheritedMembers) == GetMemberOptions.IgnoreInheritedMembers) if ((options & GetMemberOptions.IgnoreInheritedMembers) == GetMemberOptions.IgnoreInheritedMembers)
return EmptyList<IMethod>.Instance; return EmptyList<IMethod>.Instance;

2
ICSharpCode.Decompiler/TypeSystem/ArrayType.cs

@ -111,7 +111,7 @@ namespace ICSharpCode.Decompiler.TypeSystem
return compilation.FindType(KnownTypeCode.Array).GetMethods(filter, options); return compilation.FindType(KnownTypeCode.Array).GetMethods(filter, options);
} }
public override IEnumerable<IMethod> GetMethods(IList<IType> typeArguments, Predicate<IUnresolvedMethod> filter = null, GetMemberOptions options = GetMemberOptions.None) public override IEnumerable<IMethod> GetMethods(IReadOnlyList<IType> typeArguments, Predicate<IUnresolvedMethod> filter = null, GetMemberOptions options = GetMemberOptions.None)
{ {
if ((options & GetMemberOptions.IgnoreInheritedMembers) == GetMemberOptions.IgnoreInheritedMembers) if ((options & GetMemberOptions.IgnoreInheritedMembers) == GetMemberOptions.IgnoreInheritedMembers)
return EmptyList<IMethod>.Instance; return EmptyList<IMethod>.Instance;

6
ICSharpCode.Decompiler/TypeSystem/DecompilerTypeSystem.cs

@ -232,8 +232,8 @@ namespace ICSharpCode.Decompiler.TypeSystem
methodReference.Parameters.SkipWhile(p => !p.ParameterType.IsSentinel).Select(p => Resolve(p.ParameterType)) methodReference.Parameters.SkipWhile(p => !p.ParameterType.IsSentinel).Select(p => Resolve(p.ParameterType))
); );
} else if (methodReference.IsGenericInstance || methodReference.DeclaringType.IsGenericInstance) { } else if (methodReference.IsGenericInstance || methodReference.DeclaringType.IsGenericInstance) {
IList<IType> classTypeArguments = null; IReadOnlyList<IType> classTypeArguments = null;
IList<IType> methodTypeArguments = null; IReadOnlyList<IType> methodTypeArguments = null;
if (methodReference.IsGenericInstance) { if (methodReference.IsGenericInstance) {
var gim = ((GenericInstanceMethod)methodReference); var gim = ((GenericInstanceMethod)methodReference);
methodTypeArguments = gim.GenericArguments.SelectArray(Resolve); methodTypeArguments = gim.GenericArguments.SelectArray(Resolve);
@ -301,7 +301,7 @@ namespace ICSharpCode.Decompiler.TypeSystem
return method.Parameters.Count > 0 && method.Parameters[method.Parameters.Count - 1].Type.Kind == TypeKind.ArgList; return method.Parameters.Count > 0 && method.Parameters[method.Parameters.Count - 1].Type.Kind == TypeKind.ArgList;
} }
static bool CompareSignatures(IList<IParameter> parameters, IType[] parameterTypes) static bool CompareSignatures(IReadOnlyList<IParameter> parameters, IType[] parameterTypes)
{ {
if (parameterTypes.Length != parameters.Count) if (parameterTypes.Length != parameters.Count)
return false; return false;

8
ICSharpCode.Decompiler/TypeSystem/IAssembly.cs

@ -89,16 +89,16 @@ namespace ICSharpCode.Decompiler.TypeSystem
/// Gets the full assembly name (including public key token etc.) /// Gets the full assembly name (including public key token etc.)
/// </summary> /// </summary>
string FullAssemblyName { get; } string FullAssemblyName { get; }
/// <summary> /// <summary>
/// Gets the list of all assembly attributes in the project. /// Gets the list of all assembly attributes in the project.
/// </summary> /// </summary>
IList<IAttribute> AssemblyAttributes { get; } IReadOnlyList<IAttribute> AssemblyAttributes { get; }
/// <summary> /// <summary>
/// Gets the list of all module attributes in the project. /// Gets the list of all module attributes in the project.
/// </summary> /// </summary>
IList<IAttribute> ModuleAttributes { get; } IReadOnlyList<IAttribute> ModuleAttributes { get; }
/// <summary> /// <summary>
/// Gets whether the internals of this assembly are visible in the specified assembly. /// Gets whether the internals of this assembly are visible in the specified assembly.

4
ICSharpCode.Decompiler/TypeSystem/IEntity.cs

@ -127,11 +127,11 @@ namespace ICSharpCode.Decompiler.TypeSystem
/// This property never returns null. /// This property never returns null.
/// </summary> /// </summary>
IAssembly ParentAssembly { get; } IAssembly ParentAssembly { get; }
/// <summary> /// <summary>
/// Gets the attributes on this entity. /// Gets the attributes on this entity.
/// </summary> /// </summary>
IList<IAttribute> Attributes { get; } IReadOnlyList<IAttribute> Attributes { get; }
/// <summary> /// <summary>
/// Gets whether this entity is static. /// Gets whether this entity is static.

4
ICSharpCode.Decompiler/TypeSystem/IMember.cs

@ -132,11 +132,11 @@ namespace ICSharpCode.Decompiler.TypeSystem
/// This property never returns <c>null</c>. /// This property never returns <c>null</c>.
/// </summary> /// </summary>
IType ReturnType { get; } IType ReturnType { get; }
/// <summary> /// <summary>
/// Gets the interface members implemented by this member (both implicitly and explicitly). /// Gets the interface members implemented by this member (both implicitly and explicitly).
/// </summary> /// </summary>
IList<IMember> ImplementedInterfaceMembers { get; } IReadOnlyList<IMember> ImplementedInterfaceMembers { get; }
/// <summary> /// <summary>
/// Gets whether this member is explicitly implementing an interface. /// Gets whether this member is explicitly implementing an interface.

20
ICSharpCode.Decompiler/TypeSystem/IMethod.cs

@ -80,35 +80,25 @@ namespace ICSharpCode.Decompiler.TypeSystem
/// Gets the unresolved method parts. /// Gets the unresolved method parts.
/// For partial methods, this returns all parts. /// For partial methods, this returns all parts.
/// Otherwise, this returns an array with a single element (new[] { UnresolvedMember }). /// Otherwise, this returns an array with a single element (new[] { UnresolvedMember }).
/// NOTE: The type will change to IReadOnlyList&lt;IUnresolvedMethod&gt; in future versions.
/// </summary> /// </summary>
IList<IUnresolvedMethod> Parts { get; } IReadOnlyList<IUnresolvedMethod> Parts { get; }
/// <summary> /// <summary>
/// Gets the attributes associated with the return type. (e.g. [return: MarshalAs(...)]) /// Gets the attributes associated with the return type. (e.g. [return: MarshalAs(...)])
/// NOTE: The type will change to IReadOnlyList&lt;IAttribute&gt; in future versions.
/// </summary> /// </summary>
IList<IAttribute> ReturnTypeAttributes { get; } IReadOnlyList<IAttribute> ReturnTypeAttributes { get; }
/// <summary> /// <summary>
/// Gets the type parameters of this method; or an empty list if the method is not generic. /// Gets the type parameters of this method; or an empty list if the method is not generic.
/// NOTE: The type will change to IReadOnlyList&lt;ITypeParameter&gt; in future versions.
/// </summary> /// </summary>
IList<ITypeParameter> TypeParameters { get; } IReadOnlyList<ITypeParameter> TypeParameters { get; }
/// <summary>
/// Gets whether this is a generic method that has been parameterized.
/// </summary>
bool IsParameterized { get; }
/// <summary> /// <summary>
/// Gets the type arguments passed to this method. /// Gets the type arguments passed to this method.
/// If the method is generic but not parameterized yet, this property returns the type parameters, /// If the method is generic but not parameterized yet, this property returns the type parameters,
/// as if the method was parameterized with its own type arguments (<c>void M&lt;T&gt;() { M&lt;T&gt;(); }</c>). /// as if the method was parameterized with its own type arguments (<c>void M&lt;T&gt;() { M&lt;T&gt;(); }</c>).
///
/// NOTE: The type will change to IReadOnlyList&lt;IType&gt; in future versions.
/// </summary> /// </summary>
IList<IType> TypeArguments { get; } IReadOnlyList<IType> TypeArguments { get; }
bool IsExtensionMethod { get; } bool IsExtensionMethod { get; }
bool IsConstructor { get; } bool IsConstructor { get; }

4
ICSharpCode.Decompiler/TypeSystem/IParameter.cs

@ -36,7 +36,7 @@ namespace ICSharpCode.Decompiler.TypeSystem
/// Gets the type of the variable. /// Gets the type of the variable.
/// </summary> /// </summary>
ITypeReference Type { get; } ITypeReference Type { get; }
/// <summary> /// <summary>
/// Gets the list of attributes. /// Gets the list of attributes.
/// </summary> /// </summary>
@ -70,7 +70,7 @@ namespace ICSharpCode.Decompiler.TypeSystem
/// <summary> /// <summary>
/// Gets the list of attributes. /// Gets the list of attributes.
/// </summary> /// </summary>
IList<IAttribute> Attributes { get; } IReadOnlyList<IAttribute> Attributes { get; }
/// <summary> /// <summary>
/// Gets whether this parameter is a C# 'ref' parameter. /// Gets whether this parameter is a C# 'ref' parameter.

2
ICSharpCode.Decompiler/TypeSystem/IParameterizedMember.cs

@ -33,6 +33,6 @@ namespace ICSharpCode.Decompiler.TypeSystem
/// </summary> /// </summary>
public interface IParameterizedMember : IMember public interface IParameterizedMember : IMember
{ {
IList<IParameter> Parameters { get; } IReadOnlyList<IParameter> Parameters { get; }
} }
} }

15
ICSharpCode.Decompiler/TypeSystem/IType.cs

@ -85,15 +85,8 @@ namespace ICSharpCode.Decompiler.TypeSystem
/// Gets the type arguments passed to this type. /// Gets the type arguments passed to this type.
/// If this type is a generic type definition that is not parameterized, this property returns the type parameters, /// If this type is a generic type definition that is not parameterized, this property returns the type parameters,
/// as if the type was parameterized with its own type arguments (<c>class C&lt;T&gt; { C&lt;T&gt; field; }</c>). /// as if the type was parameterized with its own type arguments (<c>class C&lt;T&gt; { C&lt;T&gt; field; }</c>).
///
/// NOTE: The type will change to IReadOnlyList&lt;IType&gt; in future versions.
/// </summary>
IList<IType> TypeArguments { get; }
/// <summary>
/// If true the type represents an instance of a generic type.
/// </summary> /// </summary>
bool IsParameterized { get; } IReadOnlyList<IType> TypeArguments { get; }
/// <summary> /// <summary>
/// Calls ITypeVisitor.Visit for this type. /// Calls ITypeVisitor.Visit for this type.
@ -138,7 +131,7 @@ namespace ICSharpCode.Decompiler.TypeSystem
/// and also substitutes method type parameters with the specified method type arguments. /// and also substitutes method type parameters with the specified method type arguments.
/// Returns TypeParameterSubstitution.Identity if the type is not parametrized. /// Returns TypeParameterSubstitution.Identity if the type is not parametrized.
/// </summary> /// </summary>
TypeParameterSubstitution GetSubstitution(IList<IType> methodTypeArguments); TypeParameterSubstitution GetSubstitution(IReadOnlyList<IType> methodTypeArguments);
/// <summary> /// <summary>
@ -197,7 +190,7 @@ namespace ICSharpCode.Decompiler.TypeSystem
/// and thus 'leaked' to the caller in the same way the GetMembers() method does not specialize members /// and thus 'leaked' to the caller in the same way the GetMembers() method does not specialize members
/// from an <see cref="ITypeDefinition"/> and 'leaks' type parameters in member signatures. /// from an <see cref="ITypeDefinition"/> and 'leaks' type parameters in member signatures.
/// </remarks> /// </remarks>
IEnumerable<IType> GetNestedTypes(IList<IType> typeArguments, Predicate<ITypeDefinition> filter = null, GetMemberOptions options = GetMemberOptions.None); IEnumerable<IType> GetNestedTypes(IReadOnlyList<IType> typeArguments, Predicate<ITypeDefinition> filter = null, GetMemberOptions options = GetMemberOptions.None);
/// <summary> /// <summary>
/// Gets all instance constructors for this type. /// Gets all instance constructors for this type.
@ -261,7 +254,7 @@ namespace ICSharpCode.Decompiler.TypeSystem
/// and the other overload's remarks about ambiguous signatures apply here as well. /// and the other overload's remarks about ambiguous signatures apply here as well.
/// </para> /// </para>
/// </remarks> /// </remarks>
IEnumerable<IMethod> GetMethods(IList<IType> typeArguments, Predicate<IUnresolvedMethod> filter = null, GetMemberOptions options = GetMemberOptions.None); IEnumerable<IMethod> GetMethods(IReadOnlyList<IType> typeArguments, Predicate<IUnresolvedMethod> filter = null, GetMemberOptions options = GetMemberOptions.None);
/// <summary> /// <summary>
/// Gets all properties that can be called on this type. /// Gets all properties that can be called on this type.

14
ICSharpCode.Decompiler/TypeSystem/ITypeDefinition.cs

@ -100,12 +100,12 @@ namespace ICSharpCode.Decompiler.TypeSystem
/// Returns all parts that contribute to this type definition. /// Returns all parts that contribute to this type definition.
/// Non-partial classes have a single part that represents the whole class. /// Non-partial classes have a single part that represents the whole class.
/// </summary> /// </summary>
IList<IUnresolvedTypeDefinition> Parts { get; } IReadOnlyList<IUnresolvedTypeDefinition> Parts { get; }
IList<ITypeParameter> TypeParameters { get; } IReadOnlyList<ITypeParameter> TypeParameters { get; }
IList<ITypeDefinition> NestedTypes { get; } IReadOnlyList<ITypeDefinition> NestedTypes { get; }
IList<IMember> Members { get; } IReadOnlyList<IMember> Members { get; }
IEnumerable<IField> Fields { get; } IEnumerable<IField> Fields { get; }
IEnumerable<IMethod> Methods { get; } IEnumerable<IMethod> Methods { get; }
@ -153,7 +153,7 @@ namespace ICSharpCode.Decompiler.TypeSystem
/// or null if the type does not implement the interface. /// or null if the type does not implement the interface.
/// </returns> /// </returns>
IMember GetInterfaceImplementation(IMember interfaceMember); IMember GetInterfaceImplementation(IMember interfaceMember);
/// <summary> /// <summary>
/// Determines how this type is implementing the specified interface members. /// Determines how this type is implementing the specified interface members.
/// </summary> /// </summary>
@ -163,6 +163,6 @@ namespace ICSharpCode.Decompiler.TypeSystem
/// For interface members that are missing an implementation, the /// For interface members that are missing an implementation, the
/// result collection will contain a null element. /// result collection will contain a null element.
/// </returns> /// </returns>
IList<IMember> GetInterfaceImplementation(IList<IMember> interfaceMembers); IReadOnlyList<IMember> GetInterfaceImplementation(IReadOnlyList<IMember> interfaceMembers);
} }
} }

6
ICSharpCode.Decompiler/TypeSystem/ITypeParameter.cs

@ -85,11 +85,11 @@ namespace ICSharpCode.Decompiler.TypeSystem
/// Gets the name of the type parameter. /// Gets the name of the type parameter.
/// </summary> /// </summary>
new string Name { get; } new string Name { get; }
/// <summary> /// <summary>
/// Gets the list of attributes declared on this type parameter. /// Gets the list of attributes declared on this type parameter.
/// </summary> /// </summary>
IList<IAttribute> Attributes { get; } IReadOnlyList<IAttribute> Attributes { get; }
/// <summary> /// <summary>
/// Gets the variance of this type parameter. /// Gets the variance of this type parameter.
@ -109,7 +109,7 @@ namespace ICSharpCode.Decompiler.TypeSystem
/// <summary> /// <summary>
/// Gets the effective interface set of this type parameter. /// Gets the effective interface set of this type parameter.
/// </summary> /// </summary>
ICollection<IType> EffectiveInterfaceSet { get; } IReadOnlyCollection<IType> EffectiveInterfaceSet { get; }
/// <summary> /// <summary>
/// Gets if the type parameter has the 'new()' constraint. /// Gets if the type parameter has the 'new()' constraint.

2
ICSharpCode.Decompiler/TypeSystem/Implementation/AbstractResolvedEntity.cs

@ -64,7 +64,7 @@ namespace ICSharpCode.Decompiler.TypeSystem.Implementation
get { return parentContext.CurrentAssembly; } get { return parentContext.CurrentAssembly; }
} }
public IList<IAttribute> Attributes { get; protected set; } public IReadOnlyList<IAttribute> Attributes { get; protected set; }
public abstract ISymbolReference ToReference(); public abstract ISymbolReference ToReference();

10
ICSharpCode.Decompiler/TypeSystem/Implementation/AbstractResolvedMember.cs

@ -30,7 +30,7 @@ namespace ICSharpCode.Decompiler.TypeSystem.Implementation
protected new readonly IUnresolvedMember unresolved; protected new readonly IUnresolvedMember unresolved;
protected readonly ITypeResolveContext context; protected readonly ITypeResolveContext context;
volatile IType returnType; volatile IType returnType;
IList<IMember> implementedInterfaceMembers; IReadOnlyList<IMember> implementedInterfaceMembers;
protected AbstractResolvedMember(IUnresolvedMember unresolved, ITypeResolveContext parentContext) protected AbstractResolvedMember(IUnresolvedMember unresolved, ITypeResolveContext parentContext)
: base(unresolved, parentContext) : base(unresolved, parentContext)
@ -53,9 +53,9 @@ namespace ICSharpCode.Decompiler.TypeSystem.Implementation
get { return unresolved; } get { return unresolved; }
} }
public IList<IMember> ImplementedInterfaceMembers { public IReadOnlyList<IMember> ImplementedInterfaceMembers {
get { get {
IList<IMember> result = LazyInit.VolatileRead(ref this.implementedInterfaceMembers); IReadOnlyList<IMember> result = LazyInit.VolatileRead(ref this.implementedInterfaceMembers);
if (result != null) { if (result != null) {
return result; return result;
} else { } else {
@ -63,8 +63,8 @@ namespace ICSharpCode.Decompiler.TypeSystem.Implementation
} }
} }
} }
IList<IMember> FindImplementedInterfaceMembers() IReadOnlyList<IMember> FindImplementedInterfaceMembers()
{ {
if (unresolved.IsExplicitInterfaceImplementation) { if (unresolved.IsExplicitInterfaceImplementation) {
List<IMember> result = new List<IMember>(); List<IMember> result = new List<IMember>();

34
ICSharpCode.Decompiler/TypeSystem/Implementation/AbstractResolvedTypeParameter.cs

@ -19,6 +19,7 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Globalization; using System.Globalization;
using System.Linq;
using ICSharpCode.Decompiler.Util; using ICSharpCode.Decompiler.Util;
namespace ICSharpCode.Decompiler.TypeSystem.Implementation namespace ICSharpCode.Decompiler.TypeSystem.Implementation
@ -30,11 +31,11 @@ namespace ICSharpCode.Decompiler.TypeSystem.Implementation
readonly IEntity owner; readonly IEntity owner;
readonly int index; readonly int index;
readonly string name; readonly string name;
readonly IList<IAttribute> attributes; readonly IReadOnlyList<IAttribute> attributes;
readonly DomRegion region; readonly DomRegion region;
readonly VarianceModifier variance; readonly VarianceModifier variance;
protected AbstractTypeParameter(IEntity owner, int index, string name, VarianceModifier variance, IList<IAttribute> attributes, DomRegion region) protected AbstractTypeParameter(IEntity owner, int index, string name, VarianceModifier variance, IReadOnlyList<IAttribute> attributes, DomRegion region)
{ {
if (owner == null) if (owner == null)
throw new ArgumentNullException("owner"); throw new ArgumentNullException("owner");
@ -48,7 +49,7 @@ namespace ICSharpCode.Decompiler.TypeSystem.Implementation
this.variance = variance; this.variance = variance;
} }
protected AbstractTypeParameter(ICompilation compilation, SymbolKind ownerType, int index, string name, VarianceModifier variance, IList<IAttribute> attributes, DomRegion region) protected AbstractTypeParameter(ICompilation compilation, SymbolKind ownerType, int index, string name, VarianceModifier variance, IReadOnlyList<IAttribute> attributes, DomRegion region)
{ {
if (compilation == null) if (compilation == null)
throw new ArgumentNullException("compilation"); throw new ArgumentNullException("compilation");
@ -77,7 +78,7 @@ namespace ICSharpCode.Decompiler.TypeSystem.Implementation
get { return index; } get { return index; }
} }
public IList<IAttribute> Attributes { public IReadOnlyList<IAttribute> Attributes {
get { return attributes; } get { return attributes; }
} }
@ -135,9 +136,9 @@ namespace ICSharpCode.Decompiler.TypeSystem.Implementation
return result; return result;
} }
ICollection<IType> effectiveInterfaceSet; IReadOnlyCollection<IType> effectiveInterfaceSet;
public ICollection<IType> EffectiveInterfaceSet { public IReadOnlyCollection<IType> EffectiveInterfaceSet {
get { get {
var result = LazyInit.VolatileRead(ref effectiveInterfaceSet); var result = LazyInit.VolatileRead(ref effectiveInterfaceSet);
if (result != null) { if (result != null) {
@ -152,8 +153,8 @@ namespace ICSharpCode.Decompiler.TypeSystem.Implementation
} }
} }
} }
ICollection<IType> CalculateEffectiveInterfaceSet() IReadOnlyCollection<IType> CalculateEffectiveInterfaceSet()
{ {
HashSet<IType> result = new HashSet<IType>(); HashSet<IType> result = new HashSet<IType>();
foreach (IType constraint in this.DirectBaseTypes) { foreach (IType constraint in this.DirectBaseTypes) {
@ -163,7 +164,7 @@ namespace ICSharpCode.Decompiler.TypeSystem.Implementation
result.UnionWith(((ITypeParameter)constraint).EffectiveInterfaceSet); result.UnionWith(((ITypeParameter)constraint).EffectiveInterfaceSet);
} }
} }
return result; return result.ToArray();
} }
public abstract bool HasDefaultConstructorConstraint { get; } public abstract bool HasDefaultConstructorConstraint { get; }
@ -210,13 +211,8 @@ namespace ICSharpCode.Decompiler.TypeSystem.Implementation
get { return 0; } get { return 0; }
} }
bool IType.IsParameterized { IReadOnlyList<IType> IType.TypeArguments {
get { return false; } get { return Empty<IType>.Array; }
}
readonly static IList<IType> emptyTypeArguments = new IType[0];
IList<IType> IType.TypeArguments {
get { return emptyTypeArguments; }
} }
public abstract IEnumerable<IType> DirectBaseTypes { get; } public abstract IEnumerable<IType> DirectBaseTypes { get; }
@ -264,7 +260,7 @@ namespace ICSharpCode.Decompiler.TypeSystem.Implementation
return EmptyList<IType>.Instance; return EmptyList<IType>.Instance;
} }
IEnumerable<IType> IType.GetNestedTypes(IList<IType> typeArguments, Predicate<ITypeDefinition> filter, GetMemberOptions options) IEnumerable<IType> IType.GetNestedTypes(IReadOnlyList<IType> typeArguments, Predicate<ITypeDefinition> filter, GetMemberOptions options)
{ {
return EmptyList<IType>.Instance; return EmptyList<IType>.Instance;
} }
@ -291,7 +287,7 @@ namespace ICSharpCode.Decompiler.TypeSystem.Implementation
return GetMembersHelper.GetMethods(this, FilterNonStatic(filter), options); return GetMembersHelper.GetMethods(this, FilterNonStatic(filter), options);
} }
public IEnumerable<IMethod> GetMethods(IList<IType> typeArguments, Predicate<IUnresolvedMethod> filter = null, GetMemberOptions options = GetMemberOptions.None) public IEnumerable<IMethod> GetMethods(IReadOnlyList<IType> typeArguments, Predicate<IUnresolvedMethod> filter = null, GetMemberOptions options = GetMemberOptions.None)
{ {
if ((options & GetMemberOptions.IgnoreInheritedMembers) == GetMemberOptions.IgnoreInheritedMembers) if ((options & GetMemberOptions.IgnoreInheritedMembers) == GetMemberOptions.IgnoreInheritedMembers)
return EmptyList<IMethod>.Instance; return EmptyList<IMethod>.Instance;
@ -344,7 +340,7 @@ namespace ICSharpCode.Decompiler.TypeSystem.Implementation
return TypeParameterSubstitution.Identity; return TypeParameterSubstitution.Identity;
} }
public TypeParameterSubstitution GetSubstitution(IList<IType> methodTypeArguments) public TypeParameterSubstitution GetSubstitution(IReadOnlyList<IType> methodTypeArguments)
{ {
return TypeParameterSubstitution.Identity; return TypeParameterSubstitution.Identity;
} }

16
ICSharpCode.Decompiler/TypeSystem/Implementation/AbstractType.cs

@ -59,19 +59,15 @@ namespace ICSharpCode.Decompiler.TypeSystem.Implementation
get { return 0; } get { return 0; }
} }
readonly static IList<IType> emptyTypeArguments = new IType[0]; readonly static IReadOnlyList<IType> emptyTypeArguments = new IType[0];
public virtual IList<IType> TypeArguments { public virtual IReadOnlyList<IType> TypeArguments {
get { return emptyTypeArguments; } get { return emptyTypeArguments; }
} }
public virtual IType DeclaringType { public virtual IType DeclaringType {
get { return null; } get { return null; }
} }
public virtual bool IsParameterized {
get { return false; }
}
public virtual ITypeDefinition GetDefinition() public virtual ITypeDefinition GetDefinition()
{ {
return null; return null;
@ -88,7 +84,7 @@ namespace ICSharpCode.Decompiler.TypeSystem.Implementation
return EmptyList<IType>.Instance; return EmptyList<IType>.Instance;
} }
public virtual IEnumerable<IType> GetNestedTypes(IList<IType> typeArguments, Predicate<ITypeDefinition> filter = null, GetMemberOptions options = GetMemberOptions.None) public virtual IEnumerable<IType> GetNestedTypes(IReadOnlyList<IType> typeArguments, Predicate<ITypeDefinition> filter = null, GetMemberOptions options = GetMemberOptions.None)
{ {
return EmptyList<IType>.Instance; return EmptyList<IType>.Instance;
} }
@ -98,7 +94,7 @@ namespace ICSharpCode.Decompiler.TypeSystem.Implementation
return EmptyList<IMethod>.Instance; return EmptyList<IMethod>.Instance;
} }
public virtual IEnumerable<IMethod> GetMethods(IList<IType> typeArguments, Predicate<IUnresolvedMethod> filter = null, GetMemberOptions options = GetMemberOptions.None) public virtual IEnumerable<IMethod> GetMethods(IReadOnlyList<IType> typeArguments, Predicate<IUnresolvedMethod> filter = null, GetMemberOptions options = GetMemberOptions.None)
{ {
return EmptyList<IMethod>.Instance; return EmptyList<IMethod>.Instance;
} }
@ -142,7 +138,7 @@ namespace ICSharpCode.Decompiler.TypeSystem.Implementation
return TypeParameterSubstitution.Identity; return TypeParameterSubstitution.Identity;
} }
public TypeParameterSubstitution GetSubstitution(IList<IType> methodTypeArguments) public TypeParameterSubstitution GetSubstitution(IReadOnlyList<IType> methodTypeArguments)
{ {
return TypeParameterSubstitution.Identity; return TypeParameterSubstitution.Identity;
} }

4
ICSharpCode.Decompiler/TypeSystem/Implementation/AbstractUnresolvedMember.cs

@ -237,7 +237,7 @@ namespace ICSharpCode.Decompiler.TypeSystem.Implementation
return null; return null;
} }
static bool IsNonGenericMatch(IMember member, SymbolKind symbolKind, string name, IList<IType> parameterTypes) static bool IsNonGenericMatch(IMember member, SymbolKind symbolKind, string name, IReadOnlyList<IType> parameterTypes)
{ {
if (member.SymbolKind != symbolKind) if (member.SymbolKind != symbolKind)
return false; return false;
@ -249,7 +249,7 @@ namespace ICSharpCode.Decompiler.TypeSystem.Implementation
return IsParameterTypeMatch(member, parameterTypes); return IsParameterTypeMatch(member, parameterTypes);
} }
static bool IsParameterTypeMatch(IMember member, IList<IType> parameterTypes) static bool IsParameterTypeMatch(IMember member, IReadOnlyList<IType> parameterTypes)
{ {
IParameterizedMember parameterizedMember = member as IParameterizedMember; IParameterizedMember parameterizedMember = member as IParameterizedMember;
if (parameterizedMember == null) { if (parameterizedMember == null) {

7
ICSharpCode.Decompiler/TypeSystem/Implementation/DefaultParameter.cs

@ -19,6 +19,7 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Text; using System.Text;
using ICSharpCode.Decompiler.Util;
namespace ICSharpCode.Decompiler.TypeSystem.Implementation namespace ICSharpCode.Decompiler.TypeSystem.Implementation
{ {
@ -30,7 +31,7 @@ namespace ICSharpCode.Decompiler.TypeSystem.Implementation
readonly IType type; readonly IType type;
readonly string name; readonly string name;
readonly DomRegion region; readonly DomRegion region;
readonly IList<IAttribute> attributes; readonly IReadOnlyList<IAttribute> attributes;
readonly bool isRef, isOut, isParams, isOptional; readonly bool isRef, isOut, isParams, isOptional;
readonly object defaultValue; readonly object defaultValue;
readonly IParameterizedMember owner; readonly IParameterizedMember owner;
@ -45,7 +46,7 @@ namespace ICSharpCode.Decompiler.TypeSystem.Implementation
this.name = name; this.name = name;
} }
public DefaultParameter(IType type, string name, IParameterizedMember owner = null, DomRegion region = default(DomRegion), IList<IAttribute> attributes = null, public DefaultParameter(IType type, string name, IParameterizedMember owner = null, DomRegion region = default(DomRegion), IReadOnlyList<IAttribute> attributes = null,
bool isRef = false, bool isOut = false, bool isParams = false, bool isOptional = false, object defaultValue = null) bool isRef = false, bool isOut = false, bool isParams = false, bool isOptional = false, object defaultValue = null)
{ {
if (type == null) if (type == null)
@ -72,7 +73,7 @@ namespace ICSharpCode.Decompiler.TypeSystem.Implementation
get { return owner; } get { return owner; }
} }
public IList<IAttribute> Attributes { public IReadOnlyList<IAttribute> Attributes {
get { return attributes; } get { return attributes; }
} }

20
ICSharpCode.Decompiler/TypeSystem/Implementation/DefaultResolvedMethod.cs

@ -45,11 +45,11 @@ namespace ICSharpCode.Decompiler.TypeSystem.Implementation
this.IsExtensionMethod = isExtensionMethod; this.IsExtensionMethod = isExtensionMethod;
} }
class ListOfLists<T> : IList<T> class ListOfLists<T> : IList<T>, IReadOnlyList<T>
{ {
List<IList<T>> lists =new List<IList<T>> (); List<IReadOnlyList<T>> lists =new List<IReadOnlyList<T>> ();
public void AddList(IList<T> list) public void AddList(IReadOnlyList<T> list)
{ {
lists.Add (list); lists.Add (list);
} }
@ -168,24 +168,20 @@ namespace ICSharpCode.Decompiler.TypeSystem.Implementation
return method; return method;
} }
public IList<IParameter> Parameters { get; private set; } public IReadOnlyList<IParameter> Parameters { get; private set; }
public IList<IAttribute> ReturnTypeAttributes { get; private set; } public IReadOnlyList<IAttribute> ReturnTypeAttributes { get; private set; }
public IList<ITypeParameter> TypeParameters { get; private set; } public IReadOnlyList<ITypeParameter> TypeParameters { get; private set; }
public IList<IType> TypeArguments { public IReadOnlyList<IType> TypeArguments {
get { get {
// ToList() call is necessary because IList<> isn't covariant // ToList() call is necessary because IList<> isn't covariant
return TypeParameters.ToList<IType>(); return TypeParameters.ToList<IType>();
} }
} }
bool IMethod.IsParameterized {
get { return false; }
}
public bool IsExtensionMethod { get; private set; } public bool IsExtensionMethod { get; private set; }
public IList<IUnresolvedMethod> Parts { public IReadOnlyList<IUnresolvedMethod> Parts {
get { get {
return parts ?? new IUnresolvedMethod[] { (IUnresolvedMethod)unresolved }; return parts ?? new IUnresolvedMethod[] { (IUnresolvedMethod)unresolved };
} }

4
ICSharpCode.Decompiler/TypeSystem/Implementation/DefaultResolvedProperty.cs

@ -25,7 +25,7 @@ namespace ICSharpCode.Decompiler.TypeSystem.Implementation
public class DefaultResolvedProperty : AbstractResolvedMember, IProperty public class DefaultResolvedProperty : AbstractResolvedMember, IProperty
{ {
protected new readonly IUnresolvedProperty unresolved; protected new readonly IUnresolvedProperty unresolved;
readonly IList<IParameter> parameters; readonly IReadOnlyList<IParameter> parameters;
IMethod getter; IMethod getter;
IMethod setter; IMethod setter;
const Accessibility InvalidAccessibility = (Accessibility)0xff; const Accessibility InvalidAccessibility = (Accessibility)0xff;
@ -38,7 +38,7 @@ namespace ICSharpCode.Decompiler.TypeSystem.Implementation
this.parameters = unresolved.Parameters.CreateResolvedParameters(context); this.parameters = unresolved.Parameters.CreateResolvedParameters(context);
} }
public IList<IParameter> Parameters { public IReadOnlyList<IParameter> Parameters {
get { return parameters; } get { return parameters; }
} }

97
ICSharpCode.Decompiler/TypeSystem/Implementation/DefaultResolvedTypeDefinition.cs

@ -54,10 +54,10 @@ namespace ICSharpCode.Decompiler.TypeSystem.Implementation
accessibility = part.Accessibility; accessibility = part.Accessibility;
} }
} }
IReadOnlyList<ITypeParameter> typeParameters;
IList<ITypeParameter> typeParameters; public IReadOnlyList<ITypeParameter> TypeParameters {
public IList<ITypeParameter> TypeParameters {
get { get {
var result = LazyInit.VolatileRead(ref this.typeParameters); var result = LazyInit.VolatileRead(ref this.typeParameters);
if (result != null) { if (result != null) {
@ -83,30 +83,32 @@ namespace ICSharpCode.Decompiler.TypeSystem.Implementation
return LazyInit.GetOrSet(ref this.typeParameters, result); return LazyInit.GetOrSet(ref this.typeParameters, result);
} }
} }
IReadOnlyList<IAttribute> attributes;
IList<IAttribute> attributes; public IReadOnlyList<IAttribute> Attributes {
public IList<IAttribute> Attributes {
get { get {
var result = LazyInit.VolatileRead(ref this.attributes); var result = LazyInit.VolatileRead(ref this.attributes);
if (result != null) { if (result != null) {
return result; return result;
} }
result = new List<IAttribute>(); var newResult = new List<IAttribute>();
var context = parentContext.WithCurrentTypeDefinition(this); var context = parentContext.WithCurrentTypeDefinition(this);
foreach (IUnresolvedTypeDefinition part in parts) { foreach (IUnresolvedTypeDefinition part in parts) {
ITypeResolveContext parentContextForPart = part.CreateResolveContext(context); ITypeResolveContext parentContextForPart = part.CreateResolveContext(context);
foreach (var attr in part.Attributes) { foreach (var attr in part.Attributes) {
result.Add(attr.CreateResolvedAttribute(parentContextForPart)); newResult.Add(attr.CreateResolvedAttribute(parentContextForPart));
} }
} }
if (result.Count == 0) if (newResult.Count == 0)
result = EmptyList<IAttribute>.Instance; result = EmptyList<IAttribute>.Instance;
else
result = newResult;
return LazyInit.GetOrSet(ref this.attributes, result); return LazyInit.GetOrSet(ref this.attributes, result);
} }
} }
public IList<IUnresolvedTypeDefinition> Parts { public IReadOnlyList<IUnresolvedTypeDefinition> Parts {
get { return parts; } get { return parts; }
} }
@ -117,13 +119,13 @@ namespace ICSharpCode.Decompiler.TypeSystem.Implementation
public virtual TypeKind Kind { public virtual TypeKind Kind {
get { return parts[0].Kind; } get { return parts[0].Kind; }
} }
#region NestedTypes #region NestedTypes
IList<ITypeDefinition> nestedTypes; IReadOnlyList<ITypeDefinition> nestedTypes;
public IList<ITypeDefinition> NestedTypes { public IReadOnlyList<ITypeDefinition> NestedTypes {
get { get {
IList<ITypeDefinition> result = LazyInit.VolatileRead(ref this.nestedTypes); IReadOnlyList<ITypeDefinition> result = LazyInit.VolatileRead(ref this.nestedTypes);
if (result != null) { if (result != null) {
return result; return result;
} else { } else {
@ -132,7 +134,7 @@ namespace ICSharpCode.Decompiler.TypeSystem.Implementation
from nestedTypeRef in part.NestedTypes from nestedTypeRef in part.NestedTypes
group nestedTypeRef by new { nestedTypeRef.Name, nestedTypeRef.TypeParameters.Count } into g group nestedTypeRef by new { nestedTypeRef.Name, nestedTypeRef.TypeParameters.Count } into g
select new DefaultResolvedTypeDefinition(new SimpleTypeResolveContext(this), g.ToArray()) select new DefaultResolvedTypeDefinition(new SimpleTypeResolveContext(this), g.ToArray())
).ToList<ITypeDefinition>().AsReadOnly(); ).ToList<ITypeDefinition>();
return LazyInit.GetOrSet(ref this.nestedTypes, result); return LazyInit.GetOrSet(ref this.nestedTypes, result);
} }
} }
@ -140,7 +142,7 @@ namespace ICSharpCode.Decompiler.TypeSystem.Implementation
#endregion #endregion
#region Members #region Members
sealed class MemberList : IList<IMember> sealed class MemberList : IReadOnlyList<IMember>
{ {
internal readonly ITypeResolveContext[] contextPerMember; internal readonly ITypeResolveContext[] contextPerMember;
internal readonly IUnresolvedMember[] unresolvedMembers; internal readonly IUnresolvedMember[] unresolvedMembers;
@ -173,17 +175,12 @@ namespace ICSharpCode.Decompiler.TypeSystem.Implementation
} }
return LazyInit.GetOrSet(ref resolvedMembers[index], unresolvedMembers[index].CreateResolved(contextPerMember[index])); return LazyInit.GetOrSet(ref resolvedMembers[index], unresolvedMembers[index].CreateResolved(contextPerMember[index]));
} }
set { throw new NotSupportedException(); }
} }
public int Count { public int Count {
get { return resolvedMembers.Length; } get { return resolvedMembers.Length; }
} }
bool ICollection<IMember>.IsReadOnly {
get { return true; }
}
public int IndexOf(IMember item) public int IndexOf(IMember item)
{ {
for (int i = 0; i < this.Count; i++) { for (int i = 0; i < this.Count; i++) {
@ -193,43 +190,6 @@ namespace ICSharpCode.Decompiler.TypeSystem.Implementation
return -1; return -1;
} }
void IList<IMember>.Insert(int index, IMember item)
{
throw new NotSupportedException();
}
void IList<IMember>.RemoveAt(int index)
{
throw new NotSupportedException();
}
void ICollection<IMember>.Add(IMember item)
{
throw new NotSupportedException();
}
void ICollection<IMember>.Clear()
{
throw new NotSupportedException();
}
bool ICollection<IMember>.Contains(IMember item)
{
return IndexOf(item) >= 0;
}
void ICollection<IMember>.CopyTo(IMember[] array, int arrayIndex)
{
for (int i = 0; i < this.Count; i++) {
array[arrayIndex + i] = this[i];
}
}
bool ICollection<IMember>.Remove(IMember item)
{
throw new NotSupportedException();
}
public IEnumerator<IMember> GetEnumerator() public IEnumerator<IMember> GetEnumerator()
{ {
for (int i = 0; i < this.Count; i++) { for (int i = 0; i < this.Count; i++) {
@ -247,7 +207,7 @@ namespace ICSharpCode.Decompiler.TypeSystem.Implementation
{ {
public readonly string Name; public readonly string Name;
public readonly int TypeParameterCount; public readonly int TypeParameterCount;
public readonly IList<IParameter> Parameters; public readonly IReadOnlyList<IParameter> Parameters;
public readonly List<IUnresolvedMethod> Parts = new List<IUnresolvedMethod>(); public readonly List<IUnresolvedMethod> Parts = new List<IUnresolvedMethod>();
public readonly List<ITypeResolveContext> Contexts = new List<ITypeResolveContext>(); public readonly List<ITypeResolveContext> Contexts = new List<ITypeResolveContext>();
@ -336,7 +296,7 @@ namespace ICSharpCode.Decompiler.TypeSystem.Implementation
return LazyInit.GetOrSet(ref this.memberList, result); return LazyInit.GetOrSet(ref this.memberList, result);
} }
public IList<IMember> Members { public IReadOnlyList<IMember> Members {
get { return GetMemberList(); } get { return GetMemberList(); }
} }
@ -497,17 +457,12 @@ namespace ICSharpCode.Decompiler.TypeSystem.Implementation
get { return parts[0].TypeParameters.Count; } get { return parts[0].TypeParameters.Count; }
} }
public IList<IType> TypeArguments { public IReadOnlyList<IType> TypeArguments {
get { get {
// ToList() call is necessary because IList<> isn't covariant return TypeParameters;
return TypeParameters.ToList<IType>();
} }
} }
public bool IsParameterized {
get { return false; }
}
#region DirectBaseTypes #region DirectBaseTypes
IList<IType> directBaseTypes; IList<IType> directBaseTypes;
@ -714,7 +669,7 @@ namespace ICSharpCode.Decompiler.TypeSystem.Implementation
} }
} }
public IEnumerable<IType> GetNestedTypes(IList<IType> typeArguments, Predicate<ITypeDefinition> filter = null, GetMemberOptions options = GetMemberOptions.None) public IEnumerable<IType> GetNestedTypes(IReadOnlyList<IType> typeArguments, Predicate<ITypeDefinition> filter = null, GetMemberOptions options = GetMemberOptions.None)
{ {
return GetMembersHelper.GetNestedTypes(this, typeArguments, filter, options); return GetMembersHelper.GetNestedTypes(this, typeArguments, filter, options);
} }
@ -785,7 +740,7 @@ namespace ICSharpCode.Decompiler.TypeSystem.Implementation
} }
} }
public virtual IEnumerable<IMethod> GetMethods(IList<IType> typeArguments, Predicate<IUnresolvedMethod> filter = null, GetMemberOptions options = GetMemberOptions.None) public virtual IEnumerable<IMethod> GetMethods(IReadOnlyList<IType> typeArguments, Predicate<IUnresolvedMethod> filter = null, GetMemberOptions options = GetMemberOptions.None)
{ {
return GetMembersHelper.GetMethods(this, typeArguments, filter, options); return GetMembersHelper.GetMethods(this, typeArguments, filter, options);
} }
@ -884,7 +839,7 @@ namespace ICSharpCode.Decompiler.TypeSystem.Implementation
return GetInterfaceImplementation(new[] { interfaceMember })[0]; return GetInterfaceImplementation(new[] { interfaceMember })[0];
} }
public IList<IMember> GetInterfaceImplementation(IList<IMember> interfaceMembers) public IReadOnlyList<IMember> GetInterfaceImplementation(IReadOnlyList<IMember> interfaceMembers)
{ {
// TODO: review the subtle rules for interface reimplementation, // TODO: review the subtle rules for interface reimplementation,
// write tests and fix this method. // write tests and fix this method.
@ -923,7 +878,7 @@ namespace ICSharpCode.Decompiler.TypeSystem.Implementation
return TypeParameterSubstitution.Identity; return TypeParameterSubstitution.Identity;
} }
public TypeParameterSubstitution GetSubstitution(IList<IType> methodTypeArguments) public TypeParameterSubstitution GetSubstitution(IReadOnlyList<IType> methodTypeArguments)
{ {
return TypeParameterSubstitution.Identity; return TypeParameterSubstitution.Identity;
} }

10
ICSharpCode.Decompiler/TypeSystem/Implementation/DefaultResolvedTypeParameter.cs

@ -26,16 +26,16 @@ namespace ICSharpCode.Decompiler.TypeSystem.Implementation
readonly bool hasValueTypeConstraint; readonly bool hasValueTypeConstraint;
readonly bool hasReferenceTypeConstraint; readonly bool hasReferenceTypeConstraint;
readonly bool hasDefaultConstructorConstraint; readonly bool hasDefaultConstructorConstraint;
readonly IList<IType> constraints; readonly IReadOnlyList<IType> constraints;
public DefaultTypeParameter( public DefaultTypeParameter(
IEntity owner, IEntity owner,
int index, string name = null, int index, string name = null,
VarianceModifier variance = VarianceModifier.Invariant, VarianceModifier variance = VarianceModifier.Invariant,
IList<IAttribute> attributes = null, IReadOnlyList<IAttribute> attributes = null,
DomRegion region = default(DomRegion), DomRegion region = default(DomRegion),
bool hasValueTypeConstraint = false, bool hasReferenceTypeConstraint = false, bool hasDefaultConstructorConstraint = false, bool hasValueTypeConstraint = false, bool hasReferenceTypeConstraint = false, bool hasDefaultConstructorConstraint = false,
IList<IType> constraints = null) IReadOnlyList<IType> constraints = null)
: base(owner, index, name, variance, attributes, region) : base(owner, index, name, variance, attributes, region)
{ {
this.hasValueTypeConstraint = hasValueTypeConstraint; this.hasValueTypeConstraint = hasValueTypeConstraint;
@ -48,10 +48,10 @@ namespace ICSharpCode.Decompiler.TypeSystem.Implementation
ICompilation compilation, SymbolKind ownerType, ICompilation compilation, SymbolKind ownerType,
int index, string name = null, int index, string name = null,
VarianceModifier variance = VarianceModifier.Invariant, VarianceModifier variance = VarianceModifier.Invariant,
IList<IAttribute> attributes = null, IReadOnlyList<IAttribute> attributes = null,
DomRegion region = default(DomRegion), DomRegion region = default(DomRegion),
bool hasValueTypeConstraint = false, bool hasReferenceTypeConstraint = false, bool hasDefaultConstructorConstraint = false, bool hasValueTypeConstraint = false, bool hasReferenceTypeConstraint = false, bool hasDefaultConstructorConstraint = false,
IList<IType> constraints = null) IReadOnlyList<IType> constraints = null)
: base(compilation, ownerType, index, name, variance, attributes, region) : base(compilation, ownerType, index, name, variance, attributes, region)
{ {
this.hasValueTypeConstraint = hasValueTypeConstraint; this.hasValueTypeConstraint = hasValueTypeConstraint;

4
ICSharpCode.Decompiler/TypeSystem/Implementation/DefaultUnresolvedAssembly.cs

@ -320,8 +320,8 @@ namespace ICSharpCode.Decompiler.TypeSystem.Implementation
get { return unresolvedAssembly.FullAssemblyName; } get { return unresolvedAssembly.FullAssemblyName; }
} }
public IList<IAttribute> AssemblyAttributes { get; private set; } public IReadOnlyList<IAttribute> AssemblyAttributes { get; private set; }
public IList<IAttribute> ModuleAttributes { get; private set; } public IReadOnlyList<IAttribute> ModuleAttributes { get; private set; }
public INamespace RootNamespace { public INamespace RootNamespace {
get { return rootNamespace; } get { return rootNamespace; }

2
ICSharpCode.Decompiler/TypeSystem/Implementation/DefaultUnresolvedParameter.cs

@ -239,7 +239,7 @@ namespace ICSharpCode.Decompiler.TypeSystem.Implementation
public IType Type { get; internal set; } public IType Type { get; internal set; }
public string Name { get; internal set; } public string Name { get; internal set; }
public DomRegion Region { get; internal set; } public DomRegion Region { get; internal set; }
public IList<IAttribute> Attributes { get; internal set; } public IReadOnlyList<IAttribute> Attributes { get; internal set; }
public bool IsRef { get; internal set; } public bool IsRef { get; internal set; }
public bool IsOut { get; internal set; } public bool IsOut { get; internal set; }
public bool IsParams { get; internal set; } public bool IsParams { get; internal set; }

4
ICSharpCode.Decompiler/TypeSystem/Implementation/DummyTypeParameter.cs

@ -169,7 +169,7 @@ namespace ICSharpCode.Decompiler.TypeSystem.Implementation
get { return index; } get { return index; }
} }
IList<IAttribute> ITypeParameter.Attributes { IReadOnlyList<IAttribute> ITypeParameter.Attributes {
get { return EmptyList<IAttribute>.Instance; } get { return EmptyList<IAttribute>.Instance; }
} }
@ -193,7 +193,7 @@ namespace ICSharpCode.Decompiler.TypeSystem.Implementation
get { return SpecialType.UnknownType; } get { return SpecialType.UnknownType; }
} }
ICollection<IType> ITypeParameter.EffectiveInterfaceSet { IReadOnlyCollection<IType> ITypeParameter.EffectiveInterfaceSet {
get { return EmptyList<IType>.Instance; } get { return EmptyList<IType>.Instance; }
} }

8
ICSharpCode.Decompiler/TypeSystem/Implementation/GetMembersHelper.cs

@ -40,7 +40,7 @@ namespace ICSharpCode.Decompiler.TypeSystem.Implementation
return GetNestedTypes(type, null, filter, options); return GetNestedTypes(type, null, filter, options);
} }
public static IEnumerable<IType> GetNestedTypes(IType type, IList<IType> nestedTypeArguments, Predicate<ITypeDefinition> filter, GetMemberOptions options) public static IEnumerable<IType> GetNestedTypes(IType type, IReadOnlyList<IType> nestedTypeArguments, Predicate<ITypeDefinition> filter, GetMemberOptions options)
{ {
if ((options & GetMemberOptions.IgnoreInheritedMembers) == GetMemberOptions.IgnoreInheritedMembers) { if ((options & GetMemberOptions.IgnoreInheritedMembers) == GetMemberOptions.IgnoreInheritedMembers) {
return GetNestedTypesImpl(type, nestedTypeArguments, filter, options); return GetNestedTypesImpl(type, nestedTypeArguments, filter, options);
@ -49,7 +49,7 @@ namespace ICSharpCode.Decompiler.TypeSystem.Implementation
} }
} }
static IEnumerable<IType> GetNestedTypesImpl(IType outerType, IList<IType> nestedTypeArguments, Predicate<ITypeDefinition> filter, GetMemberOptions options) static IEnumerable<IType> GetNestedTypesImpl(IType outerType, IReadOnlyList<IType> nestedTypeArguments, Predicate<ITypeDefinition> filter, GetMemberOptions options)
{ {
ITypeDefinition outerTypeDef = outerType.GetDefinition(); ITypeDefinition outerTypeDef = outerType.GetDefinition();
if (outerTypeDef == null) if (outerTypeDef == null)
@ -92,7 +92,7 @@ namespace ICSharpCode.Decompiler.TypeSystem.Implementation
return GetMethods(type, null, filter, options); return GetMethods(type, null, filter, options);
} }
public static IEnumerable<IMethod> GetMethods(IType type, IList<IType> typeArguments, Predicate<IUnresolvedMethod> filter, GetMemberOptions options) public static IEnumerable<IMethod> GetMethods(IType type, IReadOnlyList<IType> typeArguments, Predicate<IUnresolvedMethod> filter, GetMemberOptions options)
{ {
if (typeArguments != null && typeArguments.Count > 0) { if (typeArguments != null && typeArguments.Count > 0) {
filter = FilterTypeParameterCount(typeArguments.Count).And(filter); filter = FilterTypeParameterCount(typeArguments.Count).And(filter);
@ -112,7 +112,7 @@ namespace ICSharpCode.Decompiler.TypeSystem.Implementation
const GetMemberOptions declaredMembers = GetMemberOptions.IgnoreInheritedMembers | GetMemberOptions.ReturnMemberDefinitions; const GetMemberOptions declaredMembers = GetMemberOptions.IgnoreInheritedMembers | GetMemberOptions.ReturnMemberDefinitions;
static IEnumerable<IMethod> GetMethodsImpl(IType baseType, IList<IType> methodTypeArguments, Predicate<IUnresolvedMethod> filter, GetMemberOptions options) static IEnumerable<IMethod> GetMethodsImpl(IType baseType, IReadOnlyList<IType> methodTypeArguments, Predicate<IUnresolvedMethod> filter, GetMemberOptions options)
{ {
IEnumerable<IMethod> declaredMethods = baseType.GetMethods(filter, options | declaredMembers); IEnumerable<IMethod> declaredMethods = baseType.GetMethods(filter, options | declaredMembers);

16
ICSharpCode.Decompiler/TypeSystem/Implementation/SpecializedMember.cs

@ -71,7 +71,7 @@ namespace ICSharpCode.Decompiler.TypeSystem.Implementation
return ToReference(); return ToReference();
} }
internal static IList<ITypeReference> ToTypeReference(IList<IType> typeArguments) internal static IList<ITypeReference> ToTypeReference(IReadOnlyList<IType> typeArguments)
{ {
if (typeArguments == null) if (typeArguments == null)
return null; return null;
@ -182,19 +182,19 @@ namespace ICSharpCode.Decompiler.TypeSystem.Implementation
get { return baseMember.DeclaringTypeDefinition; } get { return baseMember.DeclaringTypeDefinition; }
} }
public IList<IAttribute> Attributes { public IReadOnlyList<IAttribute> Attributes {
get { return baseMember.Attributes; } get { return baseMember.Attributes; }
} }
IList<IMember> implementedInterfaceMembers; IReadOnlyList<IMember> implementedInterfaceMembers;
public IList<IMember> ImplementedInterfaceMembers { public IReadOnlyList<IMember> ImplementedInterfaceMembers {
get { get {
return LazyInitializer.EnsureInitialized(ref implementedInterfaceMembers, FindImplementedInterfaceMembers); return LazyInitializer.EnsureInitialized(ref implementedInterfaceMembers, FindImplementedInterfaceMembers);
} }
} }
IList<IMember> FindImplementedInterfaceMembers() IReadOnlyList<IMember> FindImplementedInterfaceMembers()
{ {
var definitionImplementations = baseMember.ImplementedInterfaceMembers; var definitionImplementations = baseMember.ImplementedInterfaceMembers;
IMember[] result = new IMember[definitionImplementations.Count]; IMember[] result = new IMember[definitionImplementations.Count];
@ -317,14 +317,14 @@ namespace ICSharpCode.Decompiler.TypeSystem.Implementation
public abstract class SpecializedParameterizedMember : SpecializedMember, IParameterizedMember public abstract class SpecializedParameterizedMember : SpecializedMember, IParameterizedMember
{ {
IList<IParameter> parameters; IReadOnlyList<IParameter> parameters;
protected SpecializedParameterizedMember(IParameterizedMember memberDefinition) protected SpecializedParameterizedMember(IParameterizedMember memberDefinition)
: base(memberDefinition) : base(memberDefinition)
{ {
} }
public IList<IParameter> Parameters { public IReadOnlyList<IParameter> Parameters {
get { get {
var result = LazyInit.VolatileRead(ref this.parameters); var result = LazyInit.VolatileRead(ref this.parameters);
if (result != null) if (result != null)
@ -342,7 +342,7 @@ namespace ICSharpCode.Decompiler.TypeSystem.Implementation
} }
} }
protected IList<IParameter> CreateParameters(TypeVisitor substitution) protected IReadOnlyList<IParameter> CreateParameters(TypeVisitor substitution)
{ {
var paramDefs = ((IParameterizedMember)this.baseMember).Parameters; var paramDefs = ((IParameterizedMember)this.baseMember).Parameters;
if (paramDefs.Count == 0) { if (paramDefs.Count == 0) {

12
ICSharpCode.Decompiler/TypeSystem/Implementation/SpecializedMethod.cs

@ -74,23 +74,19 @@ namespace ICSharpCode.Decompiler.TypeSystem.Implementation
} }
} }
public IList<IType> TypeArguments { public IReadOnlyList<IType> TypeArguments {
get { return this.Substitution.MethodTypeArguments ?? EmptyList<IType>.Instance; } get { return this.Substitution.MethodTypeArguments ?? EmptyList<IType>.Instance; }
} }
public bool IsParameterized { public IReadOnlyList<IUnresolvedMethod> Parts {
get { return isParameterized; }
}
public IList<IUnresolvedMethod> Parts {
get { return methodDefinition.Parts; } get { return methodDefinition.Parts; }
} }
public IList<IAttribute> ReturnTypeAttributes { public IReadOnlyList<IAttribute> ReturnTypeAttributes {
get { return methodDefinition.ReturnTypeAttributes; } get { return methodDefinition.ReturnTypeAttributes; }
} }
public IList<ITypeParameter> TypeParameters { public IReadOnlyList<ITypeParameter> TypeParameters {
get { get {
return specializedTypeParameters ?? methodDefinition.TypeParameters; return specializedTypeParameters ?? methodDefinition.TypeParameters;
} }

2
ICSharpCode.Decompiler/TypeSystem/Implementation/VoidTypeDefinition.cs

@ -56,7 +56,7 @@ namespace ICSharpCode.Decompiler.TypeSystem.Implementation
return EmptyList<IMethod>.Instance; return EmptyList<IMethod>.Instance;
} }
public override IEnumerable<IMethod> GetMethods(IList<IType> typeArguments, Predicate<IUnresolvedMethod> filter, GetMemberOptions options) public override IEnumerable<IMethod> GetMethods(IReadOnlyList<IType> typeArguments, Predicate<IUnresolvedMethod> filter, GetMemberOptions options)
{ {
return EmptyList<IMethod>.Instance; return EmptyList<IMethod>.Instance;
} }

2
ICSharpCode.Decompiler/TypeSystem/IntersectionType.cs

@ -136,7 +136,7 @@ namespace ICSharpCode.Decompiler.TypeSystem
return GetMembersHelper.GetMethods(this, FilterNonStatic(filter), options); return GetMembersHelper.GetMethods(this, FilterNonStatic(filter), options);
} }
public override IEnumerable<IMethod> GetMethods(IList<IType> typeArguments, Predicate<IUnresolvedMethod> filter, GetMemberOptions options) public override IEnumerable<IMethod> GetMethods(IReadOnlyList<IType> typeArguments, Predicate<IUnresolvedMethod> filter, GetMemberOptions options)
{ {
return GetMembersHelper.GetMethods(this, typeArguments, filter, options); return GetMembersHelper.GetMethods(this, typeArguments, filter, options);
} }

6
ICSharpCode.Decompiler/TypeSystem/ParameterListComparer.cs

@ -31,7 +31,7 @@ namespace ICSharpCode.Decompiler.TypeSystem
/// For generic methods, "Method{T}(T a)" and "Method{S}(S b)" are considered equal. /// For generic methods, "Method{T}(T a)" and "Method{S}(S b)" are considered equal.
/// However, "Method(T a)" and "Method(S b)" are not considered equal when the type parameters T and S belong to classes. /// However, "Method(T a)" and "Method(S b)" are not considered equal when the type parameters T and S belong to classes.
/// </remarks> /// </remarks>
public sealed class ParameterListComparer : IEqualityComparer<IList<IParameter>> public sealed class ParameterListComparer : IEqualityComparer<IReadOnlyList<IParameter>>
{ {
public static readonly ParameterListComparer Instance = new ParameterListComparer(); public static readonly ParameterListComparer Instance = new ParameterListComparer();
@ -56,7 +56,7 @@ namespace ICSharpCode.Decompiler.TypeSystem
static readonly NormalizeTypeVisitor normalizationVisitor = new NormalizeTypeVisitor(); static readonly NormalizeTypeVisitor normalizationVisitor = new NormalizeTypeVisitor();
public bool Equals(IList<IParameter> x, IList<IParameter> y) public bool Equals(IReadOnlyList<IParameter> x, IReadOnlyList<IParameter> y)
{ {
if (x == y) if (x == y)
return true; return true;
@ -82,7 +82,7 @@ namespace ICSharpCode.Decompiler.TypeSystem
return true; return true;
} }
public int GetHashCode(IList<IParameter> obj) public int GetHashCode(IReadOnlyList<IParameter> obj)
{ {
int hashCode = obj.Count; int hashCode = obj.Count;
unchecked { unchecked {

8
ICSharpCode.Decompiler/TypeSystem/ParameterizedType.cs

@ -136,7 +136,7 @@ namespace ICSharpCode.Decompiler.TypeSystem
return ReflectionName; return ReflectionName;
} }
public IList<IType> TypeArguments { public IReadOnlyList<IType> TypeArguments {
get { get {
return typeArguments; return typeArguments;
} }
@ -184,7 +184,7 @@ namespace ICSharpCode.Decompiler.TypeSystem
/// of this parameterized type, /// of this parameterized type,
/// and also substitutes method type parameters with the specified method type arguments. /// and also substitutes method type parameters with the specified method type arguments.
/// </summary> /// </summary>
public TypeParameterSubstitution GetSubstitution(IList<IType> methodTypeArguments) public TypeParameterSubstitution GetSubstitution(IReadOnlyList<IType> methodTypeArguments)
{ {
return new TypeParameterSubstitution(typeArguments, methodTypeArguments); return new TypeParameterSubstitution(typeArguments, methodTypeArguments);
} }
@ -204,7 +204,7 @@ namespace ICSharpCode.Decompiler.TypeSystem
return GetMembersHelper.GetNestedTypes(this, filter, options); return GetMembersHelper.GetNestedTypes(this, filter, options);
} }
public IEnumerable<IType> GetNestedTypes(IList<IType> typeArguments, Predicate<ITypeDefinition> filter = null, GetMemberOptions options = GetMemberOptions.None) public IEnumerable<IType> GetNestedTypes(IReadOnlyList<IType> typeArguments, Predicate<ITypeDefinition> filter = null, GetMemberOptions options = GetMemberOptions.None)
{ {
if ((options & GetMemberOptions.ReturnMemberDefinitions) == GetMemberOptions.ReturnMemberDefinitions) if ((options & GetMemberOptions.ReturnMemberDefinitions) == GetMemberOptions.ReturnMemberDefinitions)
return genericType.GetNestedTypes(typeArguments, filter, options); return genericType.GetNestedTypes(typeArguments, filter, options);
@ -228,7 +228,7 @@ namespace ICSharpCode.Decompiler.TypeSystem
return GetMembersHelper.GetMethods(this, filter, options); return GetMembersHelper.GetMethods(this, filter, options);
} }
public IEnumerable<IMethod> GetMethods(IList<IType> typeArguments, Predicate<IUnresolvedMethod> filter = null, GetMemberOptions options = GetMemberOptions.None) public IEnumerable<IMethod> GetMethods(IReadOnlyList<IType> typeArguments, Predicate<IUnresolvedMethod> filter = null, GetMemberOptions options = GetMemberOptions.None)
{ {
if ((options & GetMemberOptions.ReturnMemberDefinitions) == GetMemberOptions.ReturnMemberDefinitions) if ((options & GetMemberOptions.ReturnMemberDefinitions) == GetMemberOptions.ReturnMemberDefinitions)
return genericType.GetMethods(typeArguments, filter, options); return genericType.GetMethods(typeArguments, filter, options);

16
ICSharpCode.Decompiler/TypeSystem/TypeParameterSubstitution.cs

@ -31,8 +31,8 @@ namespace ICSharpCode.Decompiler.TypeSystem
/// </summary> /// </summary>
public static readonly TypeParameterSubstitution Identity = new TypeParameterSubstitution(null, null); public static readonly TypeParameterSubstitution Identity = new TypeParameterSubstitution(null, null);
readonly IList<IType> classTypeArguments; readonly IReadOnlyList<IType> classTypeArguments;
readonly IList<IType> methodTypeArguments; readonly IReadOnlyList<IType> methodTypeArguments;
/// <summary> /// <summary>
/// Creates a new type parameter substitution. /// Creates a new type parameter substitution.
@ -45,7 +45,7 @@ namespace ICSharpCode.Decompiler.TypeSystem
/// The type arguments to substitute for method type parameters. /// The type arguments to substitute for method type parameters.
/// Pass <c>null</c> to keep method type parameters unmodified. /// Pass <c>null</c> to keep method type parameters unmodified.
/// </param> /// </param>
public TypeParameterSubstitution(IList<IType> classTypeArguments, IList<IType> methodTypeArguments) public TypeParameterSubstitution(IReadOnlyList<IType> classTypeArguments, IReadOnlyList<IType> methodTypeArguments)
{ {
this.classTypeArguments = classTypeArguments; this.classTypeArguments = classTypeArguments;
this.methodTypeArguments = methodTypeArguments; this.methodTypeArguments = methodTypeArguments;
@ -55,7 +55,7 @@ namespace ICSharpCode.Decompiler.TypeSystem
/// Gets the list of class type arguments. /// Gets the list of class type arguments.
/// Returns <c>null</c> if this substitution keeps class type parameters unmodified. /// Returns <c>null</c> if this substitution keeps class type parameters unmodified.
/// </summary> /// </summary>
public IList<IType> ClassTypeArguments { public IReadOnlyList<IType> ClassTypeArguments {
get { return classTypeArguments; } get { return classTypeArguments; }
} }
@ -63,7 +63,7 @@ namespace ICSharpCode.Decompiler.TypeSystem
/// Gets the list of method type arguments. /// Gets the list of method type arguments.
/// Returns <c>null</c> if this substitution keeps method type parameters unmodified. /// Returns <c>null</c> if this substitution keeps method type parameters unmodified.
/// </summary> /// </summary>
public IList<IType> MethodTypeArguments { public IReadOnlyList<IType> MethodTypeArguments {
get { return methodTypeArguments; } get { return methodTypeArguments; }
} }
@ -87,7 +87,7 @@ namespace ICSharpCode.Decompiler.TypeSystem
return new TypeParameterSubstitution(classTypeArguments, methodTypeArguments); return new TypeParameterSubstitution(classTypeArguments, methodTypeArguments);
} }
static IList<IType> GetComposedTypeArguments(IList<IType> input, TypeParameterSubstitution substitution) static IReadOnlyList<IType> GetComposedTypeArguments(IReadOnlyList<IType> input, TypeParameterSubstitution substitution)
{ {
IType[] result = new IType[input.Count]; IType[] result = new IType[input.Count];
for (int i = 0; i < result.Length; i++) { for (int i = 0; i < result.Length; i++) {
@ -114,7 +114,7 @@ namespace ICSharpCode.Decompiler.TypeSystem
} }
} }
static bool TypeListEquals(IList<IType> a, IList<IType> b) static bool TypeListEquals(IReadOnlyList<IType> a, IReadOnlyList<IType> b)
{ {
if (a == b) if (a == b)
return true; return true;
@ -129,7 +129,7 @@ namespace ICSharpCode.Decompiler.TypeSystem
return true; return true;
} }
static int TypeListHashCode(IList<IType> obj) static int TypeListHashCode(IReadOnlyList<IType> obj)
{ {
if (obj == null) if (obj == null)
return 0; return 0;

8
ICSharpCode.Decompiler/TypeSystem/TypeSystemExtensions.cs

@ -455,7 +455,7 @@ namespace ICSharpCode.Decompiler.TypeSystem
#endregion #endregion
#region Resolve on collections #region Resolve on collections
public static IList<IAttribute> CreateResolvedAttributes(this IList<IUnresolvedAttribute> attributes, ITypeResolveContext context) public static IReadOnlyList<IAttribute> CreateResolvedAttributes(this IList<IUnresolvedAttribute> attributes, ITypeResolveContext context)
{ {
if (attributes == null) if (attributes == null)
throw new ArgumentNullException("attributes"); throw new ArgumentNullException("attributes");
@ -465,7 +465,7 @@ namespace ICSharpCode.Decompiler.TypeSystem
return new ProjectedList<ITypeResolveContext, IUnresolvedAttribute, IAttribute>(context, attributes, (c, a) => a.CreateResolvedAttribute(c)); return new ProjectedList<ITypeResolveContext, IUnresolvedAttribute, IAttribute>(context, attributes, (c, a) => a.CreateResolvedAttribute(c));
} }
public static IList<ITypeParameter> CreateResolvedTypeParameters(this IList<IUnresolvedTypeParameter> typeParameters, ITypeResolveContext context) public static IReadOnlyList<ITypeParameter> CreateResolvedTypeParameters(this IList<IUnresolvedTypeParameter> typeParameters, ITypeResolveContext context)
{ {
if (typeParameters == null) if (typeParameters == null)
throw new ArgumentNullException("typeParameters"); throw new ArgumentNullException("typeParameters");
@ -475,7 +475,7 @@ namespace ICSharpCode.Decompiler.TypeSystem
return new ProjectedList<ITypeResolveContext, IUnresolvedTypeParameter, ITypeParameter>(context, typeParameters, (c, a) => a.CreateResolvedTypeParameter(c)); return new ProjectedList<ITypeResolveContext, IUnresolvedTypeParameter, ITypeParameter>(context, typeParameters, (c, a) => a.CreateResolvedTypeParameter(c));
} }
public static IList<IParameter> CreateResolvedParameters(this IList<IUnresolvedParameter> parameters, ITypeResolveContext context) public static IReadOnlyList<IParameter> CreateResolvedParameters(this IList<IUnresolvedParameter> parameters, ITypeResolveContext context)
{ {
if (parameters == null) if (parameters == null)
throw new ArgumentNullException("parameters"); throw new ArgumentNullException("parameters");
@ -485,7 +485,7 @@ namespace ICSharpCode.Decompiler.TypeSystem
return new ProjectedList<ITypeResolveContext, IUnresolvedParameter, IParameter>(context, parameters, (c, a) => a.CreateResolvedParameter(c)); return new ProjectedList<ITypeResolveContext, IUnresolvedParameter, IParameter>(context, parameters, (c, a) => a.CreateResolvedParameter(c));
} }
public static IList<IType> Resolve(this IList<ITypeReference> typeReferences, ITypeResolveContext context) public static IReadOnlyList<IType> Resolve(this IList<ITypeReference> typeReferences, ITypeResolveContext context)
{ {
if (typeReferences == null) if (typeReferences == null)
throw new ArgumentNullException("typeReferences"); throw new ArgumentNullException("typeReferences");

18
ICSharpCode.Decompiler/TypeSystem/VarArgInstanceMethod.cs

@ -49,7 +49,7 @@ namespace ICSharpCode.Decompiler.TypeSystem
get { return baseMethod.Parameters.Count - 1; } get { return baseMethod.Parameters.Count - 1; }
} }
public IList<IParameter> Parameters { public IReadOnlyList<IParameter> Parameters {
get { return parameters; } get { return parameters; }
} }
@ -102,23 +102,19 @@ namespace ICSharpCode.Decompiler.TypeSystem
parameters.Skip(baseMethod.Parameters.Count - 1).Select(p => p.Type.AcceptVisitor(substitution)).ToList()); parameters.Skip(baseMethod.Parameters.Count - 1).Select(p => p.Type.AcceptVisitor(substitution)).ToList());
} }
public IList<IUnresolvedMethod> Parts { public IReadOnlyList<IUnresolvedMethod> Parts {
get { return baseMethod.Parts; } get { return baseMethod.Parts; }
} }
public IList<IAttribute> ReturnTypeAttributes { public IReadOnlyList<IAttribute> ReturnTypeAttributes {
get { return baseMethod.ReturnTypeAttributes; } get { return baseMethod.ReturnTypeAttributes; }
} }
public IList<ITypeParameter> TypeParameters { public IReadOnlyList<ITypeParameter> TypeParameters {
get { return baseMethod.TypeParameters; } get { return baseMethod.TypeParameters; }
} }
public bool IsParameterized { public IReadOnlyList<IType> TypeArguments {
get { return baseMethod.IsParameterized; }
}
public IList<IType> TypeArguments {
get { return baseMethod.TypeArguments; } get { return baseMethod.TypeArguments; }
} }
@ -188,7 +184,7 @@ namespace ICSharpCode.Decompiler.TypeSystem
get { return baseMethod.ReturnType; } get { return baseMethod.ReturnType; }
} }
public IList<IMember> ImplementedInterfaceMembers { public IReadOnlyList<IMember> ImplementedInterfaceMembers {
get { return baseMethod.ImplementedInterfaceMembers; } get { return baseMethod.ImplementedInterfaceMembers; }
} }
@ -253,7 +249,7 @@ namespace ICSharpCode.Decompiler.TypeSystem
get { return baseMethod.ParentAssembly; } get { return baseMethod.ParentAssembly; }
} }
public IList<IAttribute> Attributes { public IReadOnlyList<IAttribute> Attributes {
get { return baseMethod.Attributes; } get { return baseMethod.Attributes; }
} }

57
ICSharpCode.Decompiler/Util/CollectionExtensions.cs

@ -46,7 +46,20 @@ namespace ICSharpCode.Decompiler.Util
} }
return max; return max;
} }
public static int IndexOf<T>(this IReadOnlyList<T> collection, T value)
{
var comparer = EqualityComparer<T>.Default;
int index = 0;
foreach (T item in collection) {
if (comparer.Equals(item, value)) {
return index;
}
index++;
}
return -1;
}
public static void AddRange<T>(this ICollection<T> collection, IEnumerable<T> input) public static void AddRange<T>(this ICollection<T> collection, IEnumerable<T> input)
{ {
foreach (T item in input) foreach (T item in input)
@ -67,6 +80,48 @@ namespace ICSharpCode.Decompiler.Util
return result; return result;
} }
/// <summary>
/// Equivalent to <code>collection.Select(func).ToArray()</code>, but more efficient as it makes
/// use of the input collection's known size.
/// </summary>
public static U[] SelectArray<T, U>(this IReadOnlyCollection<T> collection, Func<T, U> func)
{
U[] result = new U[collection.Count];
int index = 0;
foreach (var element in collection) {
result[index++] = func(element);
}
return result;
}
/// <summary>
/// Equivalent to <code>collection.Select(func).ToArray()</code>, but more efficient as it makes
/// use of the input collection's known size.
/// </summary>
public static U[] SelectArray<T, U>(this List<T> collection, Func<T, U> func)
{
U[] result = new U[collection.Count];
int index = 0;
foreach (var element in collection) {
result[index++] = func(element);
}
return result;
}
/// <summary>
/// Equivalent to <code>collection.Select(func).ToArray()</code>, but more efficient as it makes
/// use of the input collection's known size.
/// </summary>
public static U[] SelectArray<T, U>(this T[] collection, Func<T, U> func)
{
U[] result = new U[collection.Length];
int index = 0;
foreach (var element in collection) {
result[index++] = func(element);
}
return result;
}
/// <summary> /// <summary>
/// Equivalent to <code>collection.Select(func).ToList()</code>, but more efficient as it makes /// Equivalent to <code>collection.Select(func).ToList()</code>, but more efficient as it makes
/// use of the input collection's known size. /// use of the input collection's known size.

4
ICSharpCode.Decompiler/Util/ProjectedList.cs

@ -21,7 +21,7 @@ using System.Collections.Generic;
namespace ICSharpCode.Decompiler.Util namespace ICSharpCode.Decompiler.Util
{ {
public sealed class ProjectedList<TInput, TOutput> : IList<TOutput> where TOutput : class public sealed class ProjectedList<TInput, TOutput> : IList<TOutput>, IReadOnlyList<TOutput> where TOutput : class
{ {
readonly IList<TInput> input; readonly IList<TInput> input;
readonly Func<TInput, TOutput> projection; readonly Func<TInput, TOutput> projection;
@ -128,7 +128,7 @@ namespace ICSharpCode.Decompiler.Util
} }
} }
public sealed class ProjectedList<TContext, TInput, TOutput> : IList<TOutput> where TOutput : class public sealed class ProjectedList<TContext, TInput, TOutput> : IList<TOutput>, IReadOnlyList<TOutput> where TOutput : class
{ {
readonly IList<TInput> input; readonly IList<TInput> input;
readonly TContext context; readonly TContext context;

Loading…
Cancel
Save