Browse Source

Add GetMemberOptions.

newNRvisualizers
Daniel Grunwald 15 years ago
parent
commit
7a2c59ae4a
  1. 60
      ICSharpCode.NRefactory.Tests/CSharp/Parser/Expression/ArrayCreateExpressionTests.cs
  2. 64
      ICSharpCode.NRefactory.Tests/CSharp/Resolver/LambdaTests.cs
  3. 2
      ICSharpCode.NRefactory.Tests/CSharp/Resolver/NameLookupTests.cs
  4. 6
      ICSharpCode.NRefactory.Tests/CSharp/Resolver/ResolverTestBase.cs
  5. 3
      ICSharpCode.NRefactory.VB/Visitors/CSharpToVBConverterVisitor.cs
  6. 2
      ICSharpCode.NRefactory/CSharp/Analysis/ControlFlow.cs
  7. 9
      ICSharpCode.NRefactory/CSharp/Resolver/CSharpResolver.cs
  8. 17
      ICSharpCode.NRefactory/CSharp/Resolver/Conversions.cs
  9. 10
      ICSharpCode.NRefactory/CSharp/Resolver/InvocationResolveResult.cs
  10. 2
      ICSharpCode.NRefactory/CSharp/Resolver/OperatorResolveResult.cs
  11. 2
      ICSharpCode.NRefactory/CSharp/Resolver/OverloadResolution.cs
  12. 104
      ICSharpCode.NRefactory/CSharp/Resolver/ResolveVisitor.cs
  13. 16
      ICSharpCode.NRefactory/CSharp/Resolver/TypeInference.cs
  14. 1
      ICSharpCode.NRefactory/ICSharpCode.NRefactory.csproj
  15. 14
      ICSharpCode.NRefactory/TypeSystem/ArrayType.cs
  16. 2
      ICSharpCode.NRefactory/TypeSystem/ByReferenceType.cs
  17. 50
      ICSharpCode.NRefactory/TypeSystem/IType.cs
  18. 6
      ICSharpCode.NRefactory/TypeSystem/Implementation/AbstractFreezable.cs
  19. 26
      ICSharpCode.NRefactory/TypeSystem/Implementation/AbstractType.cs
  20. 124
      ICSharpCode.NRefactory/TypeSystem/Implementation/DefaultTypeDefinition.cs
  21. 62
      ICSharpCode.NRefactory/TypeSystem/Implementation/DefaultTypeParameter.cs
  22. 281
      ICSharpCode.NRefactory/TypeSystem/Implementation/GetMembersHelper.cs
  23. 10
      ICSharpCode.NRefactory/TypeSystem/Implementation/TypeParameterSubstitution.cs
  24. 14
      ICSharpCode.NRefactory/TypeSystem/Implementation/VoidTypeDefinition.cs
  25. 25
      ICSharpCode.NRefactory/TypeSystem/IntersectionType.cs
  26. 6
      ICSharpCode.NRefactory/TypeSystem/NullableType.cs
  27. 281
      ICSharpCode.NRefactory/TypeSystem/ParameterizedType.cs
  28. 2
      ICSharpCode.NRefactory/TypeSystem/PointerType.cs
  29. 90
      ICSharpCode.NRefactory/Utils/EmptyList.cs
  30. 9
      ICSharpCode.NRefactory/Utils/ExtensionMethods.cs

60
ICSharpCode.NRefactory.Tests/CSharp/Parser/Expression/ArrayCreateExpressionTests.cs

@ -50,6 +50,37 @@ namespace ICSharpCode.NRefactory.CSharp.Parser.Expression
}); });
} }
[Test]
public void ArrayWithImplicitSize()
{
ParseUtilCSharp.AssertExpression(
"new int[] { 1 }",
new ArrayCreateExpression {
Type = new PrimitiveType("int"),
Initializer = new ArrayInitializerExpression {
Elements = { new PrimitiveExpression(1) }
}
});
}
[Test]
public void ArrayWithImplicitSize2D()
{
ParseUtilCSharp.AssertExpression(
"new int[,] { { 1 } }",
new ArrayCreateExpression {
Type = new PrimitiveType("int"),
Arguments = { new EmptyExpression(), new EmptyExpression() }, // TODO: can we improve the AST for this?
Initializer = new ArrayInitializerExpression {
Elements = {
new ArrayInitializerExpression {
Elements = { new PrimitiveExpression(1) }
}
}
}
});
}
[Test] [Test]
public void ImplicitlyTypedArrayCreateExpression() public void ImplicitlyTypedArrayCreateExpression()
{ {
@ -63,9 +94,32 @@ namespace ICSharpCode.NRefactory.CSharp.Parser.Expression
new PrimitiveExpression(100), new PrimitiveExpression(100),
new PrimitiveExpression(1000) new PrimitiveExpression(1000)
} }
} }});
}); }
[Test]
public void ImplicitlyTypedArrayCreateExpression2D()
{
ParseUtilCSharp.AssertExpression(
"new [,] { { 1, 10 }, { 100, 1000 } }",
new ArrayCreateExpression {
Arguments = { new EmptyExpression(), new EmptyExpression() }, // TODO: can we improve the AST for this?
Initializer = new ArrayInitializerExpression {
Elements = {
new ArrayInitializerExpression {
Elements = {
new PrimitiveExpression(1),
new PrimitiveExpression(10)
}
},
new ArrayInitializerExpression {
Elements = {
new PrimitiveExpression(100),
new PrimitiveExpression(1000)
}
}
}
}});
} }
} }
} }

64
ICSharpCode.NRefactory.Tests/CSharp/Resolver/LambdaTests.cs

@ -72,7 +72,7 @@ class SomeClass<T> {
Assert.AreEqual("System.String", lrr.Type.ReflectionName); Assert.AreEqual("System.String", lrr.Type.ReflectionName);
} }
#region Lambda In Initializer #region Lambda In Array Initializer
[Test] [Test]
public void LambdaInArrayInitializer1() public void LambdaInArrayInitializer1()
{ {
@ -83,8 +83,7 @@ class TestClass {
i => $i$.ToString() i => $i$.ToString()
}; };
} }
} }";
";
var lrr = Resolve<LocalResolveResult>(program); var lrr = Resolve<LocalResolveResult>(program);
Assert.AreEqual("System.Int32", lrr.Type.ReflectionName); Assert.AreEqual("System.Int32", lrr.Type.ReflectionName);
} }
@ -99,8 +98,7 @@ class TestClass {
i => $i$.ToString() i => $i$.ToString()
}; };
} }
} }";
";
var lrr = Resolve<LocalResolveResult>(program); var lrr = Resolve<LocalResolveResult>(program);
Assert.AreEqual("System.Int32", lrr.Type.ReflectionName); Assert.AreEqual("System.Int32", lrr.Type.ReflectionName);
} }
@ -113,8 +111,7 @@ class TestClass {
Converter<int, string>[] field = new Converter<int, string>[] { Converter<int, string>[] field = new Converter<int, string>[] {
i => $i$.ToString() i => $i$.ToString()
}; };
} }";
";
var lrr = Resolve<LocalResolveResult>(program); var lrr = Resolve<LocalResolveResult>(program);
Assert.AreEqual("System.Int32", lrr.Type.ReflectionName); Assert.AreEqual("System.Int32", lrr.Type.ReflectionName);
} }
@ -127,13 +124,42 @@ class TestClass {
Converter<int, string>[] field = { Converter<int, string>[] field = {
i => $i$.ToString() i => $i$.ToString()
}; };
} }";
";
var lrr = Resolve<LocalResolveResult>(program); var lrr = Resolve<LocalResolveResult>(program);
Assert.AreEqual("System.Int32", lrr.Type.ReflectionName); Assert.AreEqual("System.Int32", lrr.Type.ReflectionName);
} }
[Test] [Test]
public void LambdaIn2DArrayInitializer()
{
string program = @"using System;
class TestClass {
static void Main() {
Converter<int, string>[,] arr = {
{ i => $i$.ToString() }
};
}
}";
var lrr = Resolve<LocalResolveResult>(program);
Assert.AreEqual("System.Int32", lrr.Type.ReflectionName);
}
[Test, Ignore("Fails due to parser problem")]
public void LambdaInInferred2DArrayInitializer()
{
string program = @"using System;
class TestClass {
static void Main() {
var c = new [,] { { null, (Converter<int, string>)null }, { a => $a$.ToString(), b => b.ToString() }};
}
}";
var lrr = Resolve<LocalResolveResult>(program);
Assert.AreEqual("System.Int32", lrr.Type.ReflectionName);
}
#endregion
#region Lambda In Collection Initializer
[Test, Ignore("Parser doesn't support collection initializers yet")]
public void LambdaInCollectionInitializer1() public void LambdaInCollectionInitializer1()
{ {
string program = @"using System; using System.Collections.Generic; string program = @"using System; using System.Collections.Generic;
@ -143,13 +169,12 @@ class TestClass {
i => $i$.ToString() i => $i$.ToString()
}; };
} }
} }";
";
var lrr = Resolve<LocalResolveResult>(program); var lrr = Resolve<LocalResolveResult>(program);
Assert.AreEqual("System.Int32", lrr.Type.ReflectionName); Assert.AreEqual("System.Int32", lrr.Type.ReflectionName);
} }
[Test] [Test, Ignore("Parser doesn't support collection initializers yet")]
public void LambdaInCollectionInitializer2() public void LambdaInCollectionInitializer2()
{ {
string program = @"using System; using System.Collections.Generic; string program = @"using System; using System.Collections.Generic;
@ -159,14 +184,13 @@ class TestClass {
{ i => $i$.ToString(), i => i.ToString() } { i => $i$.ToString(), i => i.ToString() }
}; };
} }
} }";
";
var lrr = Resolve<LocalResolveResult>(program); var lrr = Resolve<LocalResolveResult>(program);
Assert.AreEqual("System.Char", lrr.Type.ReflectionName); Assert.AreEqual("System.Char", lrr.Type.ReflectionName);
} }
[Test] [Test, Ignore("Parser doesn't support collection initializers yet")]
public void LambdaInCollectionInitializer3() public void LambdaInCollectionInitializer3()
{ {
string program = @"using System; using System.Collections.Generic; string program = @"using System; using System.Collections.Generic;
@ -176,13 +200,13 @@ class TestClass {
{ i => i.ToString(), $i$ => i.ToString() } { i => i.ToString(), $i$ => i.ToString() }
}; };
} }
} }";
";
var lrr = Resolve<LocalResolveResult>(program); var lrr = Resolve<LocalResolveResult>(program);
Assert.AreEqual("System.Int32", lrr.Type.ReflectionName); Assert.AreEqual("System.Int32", lrr.Type.ReflectionName);
} }
#endregion
[Test] [Test, Ignore("Parser doesn't support object initializers yet")]
public void LambdaInObjectInitializerTest() public void LambdaInObjectInitializerTest()
{ {
string program = @"using System; string program = @"using System;
@ -195,12 +219,10 @@ class X {
} }
class Helper { class Helper {
public Converter<int, string> F; public Converter<int, string> F;
} }";
";
var lrr = Resolve<LocalResolveResult>(program); var lrr = Resolve<LocalResolveResult>(program);
Assert.AreEqual("System.Int32", lrr.Type.ReflectionName); Assert.AreEqual("System.Int32", lrr.Type.ReflectionName);
} }
#endregion
[Test] [Test]
public void LambdaExpressionInCastExpression() public void LambdaExpressionInCastExpression()

2
ICSharpCode.NRefactory.Tests/CSharp/Resolver/NameLookupTests.cs

@ -843,7 +843,7 @@ class B
Assert.AreEqual("B.x", mrr.Member.FullName); Assert.AreEqual("B.x", mrr.Member.FullName);
} }
[Test] [Test, Ignore("Parser produces incorrect positions")]
public void SubstituteClassAndMethodTypeParametersAtOnce() public void SubstituteClassAndMethodTypeParametersAtOnce()
{ {
string program = @"class C<X> { static void M<T>(X a, T b) { $C<T>.M<X>$(b, a); } }"; string program = @"class C<X> { static void M<T>(X a, T b) { $C<T>.M<X>$(b, a); } }";

6
ICSharpCode.NRefactory.Tests/CSharp/Resolver/ResolverTestBase.cs

@ -192,11 +192,9 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
AstLocation[] dollars = FindDollarSigns(code).ToArray(); AstLocation[] dollars = FindDollarSigns(code).ToArray();
Assert.AreEqual(2, dollars.Length, "Expected 2 dollar signs marking start+end of desired node"); Assert.AreEqual(2, dollars.Length, "Expected 2 dollar signs marking start+end of desired node");
UsingScope rootUsingScope = resolver.UsingScope; SetUp();
while (rootUsingScope.Parent != null)
rootUsingScope = rootUsingScope.Parent;
ParsedFile parsedFile = new ParsedFile("test.cs", rootUsingScope); ParsedFile parsedFile = new ParsedFile("test.cs", resolver.UsingScope);
TypeSystemConvertVisitor convertVisitor = new TypeSystemConvertVisitor(parsedFile, resolver.UsingScope, null); TypeSystemConvertVisitor convertVisitor = new TypeSystemConvertVisitor(parsedFile, resolver.UsingScope, null);
cu.AcceptVisitor(convertVisitor, null); cu.AcceptVisitor(convertVisitor, null);
project.UpdateProjectContent(null, convertVisitor.ParsedFile); project.UpdateProjectContent(null, convertVisitor.ParsedFile);

3
ICSharpCode.NRefactory.VB/Visitors/CSharpToVBConverterVisitor.cs

@ -2061,7 +2061,8 @@ namespace ICSharpCode.NRefactory.VB.Visitors
.GetChildrenByRole(CSharp.AstNode.Roles.Constraint) .GetChildrenByRole(CSharp.AstNode.Roles.Constraint)
.SingleOrDefault(c => c.TypeParameter == typeParameterDeclaration.Name); .SingleOrDefault(c => c.TypeParameter == typeParameterDeclaration.Name);
ConvertNodes(constraint == null ? Enumerable.Empty<CSharp.AstType>() : constraint.BaseTypes, param.Constraints); if (constraint != null)
ConvertNodes(constraint.BaseTypes, param.Constraints);
// TODO : typeParameterDeclaration.Attributes get lost? // TODO : typeParameterDeclaration.Attributes get lost?
//ConvertNodes(typeParameterDeclaration.Attributes //ConvertNodes(typeParameterDeclaration.Attributes

2
ICSharpCode.NRefactory/CSharp/Analysis/ControlFlow.cs

@ -111,7 +111,7 @@ namespace ICSharpCode.NRefactory.CSharp.Analysis
/// Gets the try-finally statements that this control flow edge is leaving. /// Gets the try-finally statements that this control flow edge is leaving.
/// </summary> /// </summary>
public IEnumerable<TryCatchStatement> TryFinallyStatements { public IEnumerable<TryCatchStatement> TryFinallyStatements {
get { return jumpOutOfTryFinally ?? Enumerable.Empty<TryCatchStatement>(); } get { return jumpOutOfTryFinally ?? EmptyList<TryCatchStatement>.Instance; }
} }
} }

9
ICSharpCode.NRefactory/CSharp/Resolver/CSharpResolver.cs

@ -2203,7 +2203,14 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
} }
IMethod invokeMethod = target.Type.GetDelegateInvokeMethod(); IMethod invokeMethod = target.Type.GetDelegateInvokeMethod();
if (invokeMethod != null) { if (invokeMethod != null) {
return new ResolveResult(invokeMethod.ReturnType.Resolve(context)); OverloadResolution or = new OverloadResolution(context, arguments, argumentNames);
or.AddCandidate(invokeMethod);
return new InvocationResolveResult(
target, invokeMethod, invokeMethod.ReturnType.Resolve(context),
or.GetArgumentsWithConversions(), or.BestCandidateErrors,
isExpandedForm: or.BestCandidateIsExpandedForm,
isDelegateInvocation: true,
argumentToParameterMap: or.GetArgumentToParameterMap());
} }
return ErrorResult; return ErrorResult;
} }

17
ICSharpCode.NRefactory/CSharp/Resolver/Conversions.cs

@ -549,13 +549,13 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
} }
// conversion from single-dimensional array S[] to IList<T>: // conversion from single-dimensional array S[] to IList<T>:
ParameterizedType toPT = toType as ParameterizedType; ParameterizedType toPT = toType as ParameterizedType;
if (fromArray.Dimensions == 1 && toPT != null && toPT.TypeArguments.Count == 1 if (fromArray.Dimensions == 1 && toPT != null && toPT.TypeParameterCount == 1
&& toPT.Namespace == "System.Collections.Generic" && toPT.Namespace == "System.Collections.Generic"
&& (toPT.Name == "IList" || toPT.Name == "ICollection" || toPT.Name == "IEnumerable")) && (toPT.Name == "IList" || toPT.Name == "ICollection" || toPT.Name == "IEnumerable"))
{ {
// array covariance plays a part here as well (string[] is IList<object>) // array covariance plays a part here as well (string[] is IList<object>)
return IdentityConversion(fromArray.ElementType, toPT.TypeArguments[0]) return IdentityConversion(fromArray.ElementType, toPT.GetTypeArgument(0))
|| ImplicitReferenceConversion(fromArray.ElementType, toPT.TypeArguments[0]); || ImplicitReferenceConversion(fromArray.ElementType, toPT.GetTypeArgument(0));
} }
// conversion from any array to System.Array and the interfaces it implements: // conversion from any array to System.Array and the interfaces it implements:
ITypeDefinition systemArray = context.GetTypeDefinition("System", "Array", 0, StringComparer.Ordinal); ITypeDefinition systemArray = context.GetTypeDefinition("System", "Array", 0, StringComparer.Ordinal);
@ -588,14 +588,11 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
if (def != null && def.Equals(t.GetDefinition())) { if (def != null && def.Equals(t.GetDefinition())) {
ParameterizedType ps = s as ParameterizedType; ParameterizedType ps = s as ParameterizedType;
ParameterizedType pt = t as ParameterizedType; ParameterizedType pt = t as ParameterizedType;
if (ps != null && pt != null if (ps != null && pt != null) {
&& ps.TypeArguments.Count == pt.TypeArguments.Count
&& ps.TypeArguments.Count == def.TypeParameters.Count)
{
// C# 4.0 spec: §13.1.3.2 Variance Conversion // C# 4.0 spec: §13.1.3.2 Variance Conversion
for (int i = 0; i < def.TypeParameters.Count; i++) { for (int i = 0; i < def.TypeParameters.Count; i++) {
IType si = ps.TypeArguments[i]; IType si = ps.GetTypeArgument(i);
IType ti = pt.TypeArguments[i]; IType ti = pt.GetTypeArgument(i);
if (IdentityConversion(si, ti)) if (IdentityConversion(si, ti))
continue; continue;
ITypeParameter xi = def.TypeParameters[i]; ITypeParameter xi = def.TypeParameters[i];
@ -902,7 +899,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
{ {
ParameterizedType pt = type as ParameterizedType; ParameterizedType pt = type as ParameterizedType;
if (pt != null && pt.TypeParameterCount == 1 && pt.Name == "Expression" && pt.Namespace == "System.Linq.Expressions") { if (pt != null && pt.TypeParameterCount == 1 && pt.Name == "Expression" && pt.Namespace == "System.Linq.Expressions") {
return pt.TypeArguments[0]; return pt.GetTypeArgument(0);
} else { } else {
return type; return type;
} }

10
ICSharpCode.NRefactory/CSharp/Resolver/InvocationResolveResult.cs

@ -39,6 +39,11 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
/// </summary> /// </summary>
public readonly bool IsExtensionMethodInvocation; public readonly bool IsExtensionMethodInvocation;
/// <summary>
/// Gets whether this invocation is calling a delegate (without explicitly calling ".Invoke()").
/// </summary>
public readonly bool IsDelegateInvocation;
/// <summary> /// <summary>
/// Gets whether a params-Array is being used in its expanded form. /// Gets whether a params-Array is being used in its expanded form.
/// </summary> /// </summary>
@ -70,8 +75,10 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
ResolveResult targetResult, IParameterizedMember member, IType returnType, ResolveResult targetResult, IParameterizedMember member, IType returnType,
IList<ResolveResult> arguments, IList<ResolveResult> arguments,
OverloadResolutionErrors overloadResolutionErrors = OverloadResolutionErrors.None, OverloadResolutionErrors overloadResolutionErrors = OverloadResolutionErrors.None,
bool isExtensionMethodInvocation = false, bool isExpandedForm = false, bool isExtensionMethodInvocation = false,
bool isExpandedForm = false,
bool isLiftedOperatorInvocation = false, bool isLiftedOperatorInvocation = false,
bool isDelegateInvocation = false,
IList<int> argumentToParameterMap = null) IList<int> argumentToParameterMap = null)
: base(targetResult, member, returnType) : base(targetResult, member, returnType)
{ {
@ -80,6 +87,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
this.IsExtensionMethodInvocation = isExtensionMethodInvocation; this.IsExtensionMethodInvocation = isExtensionMethodInvocation;
this.IsExpandedForm = isExpandedForm; this.IsExpandedForm = isExpandedForm;
this.IsLiftedOperatorInvocation = isLiftedOperatorInvocation; this.IsLiftedOperatorInvocation = isLiftedOperatorInvocation;
this.IsDelegateInvocation = isDelegateInvocation;
this.argumentToParameterMap = argumentToParameterMap; this.argumentToParameterMap = argumentToParameterMap;
} }

2
ICSharpCode.NRefactory/CSharp/Resolver/OperatorResolveResult.cs

@ -208,7 +208,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
if (SizeArguments != null && InitializerElements != null) if (SizeArguments != null && InitializerElements != null)
return SizeArguments.Concat(InitializerElements); return SizeArguments.Concat(InitializerElements);
else else
return SizeArguments ?? InitializerElements ?? Enumerable.Empty<ResolveResult>(); return SizeArguments ?? InitializerElements ?? EmptyList<ResolveResult>.Instance;
} }
} }
} }

2
ICSharpCode.NRefactory/CSharp/Resolver/OverloadResolution.cs

@ -323,7 +323,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
var typeParameters = newParameterizedType.GetDefinition().TypeParameters; var typeParameters = newParameterizedType.GetDefinition().TypeParameters;
for (int i = 0; i < typeParameters.Count; i++) { for (int i = 0; i < typeParameters.Count; i++) {
ITypeParameter tp = typeParameters[i]; ITypeParameter tp = typeParameters[i];
IType typeArg = newParameterizedType.TypeArguments[i]; IType typeArg = newParameterizedType.GetTypeArgument(i);
switch (typeArg.Kind) { // void, null, and pointers cannot be used as type arguments switch (typeArg.Kind) { // void, null, and pointers cannot be used as type arguments
case TypeKind.Void: case TypeKind.Void:
case TypeKind.Null: case TypeKind.Null:

104
ICSharpCode.NRefactory/CSharp/Resolver/ResolveVisitor.cs

@ -203,15 +203,6 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
return result; return result;
} }
ResolveResult[] Resolve(AstNodeCollection<Expression> expressions)
{
ResolveResult[] results = new ResolveResult[expressions.Count];
int pos = 0;
foreach (var node in expressions)
results[pos++] = Resolve(node);
return results;
}
void StoreState(AstNode node, CSharpResolver resolverState) void StoreState(AstNode node, CSharpResolver resolverState)
{ {
Debug.Assert(resolverState != null); Debug.Assert(resolverState != null);
@ -489,7 +480,19 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
} }
} }
} }
ResolveAndProcessConversion(variableInitializer.Initializer, result.Type); ArrayInitializerExpression aie = variableInitializer.Initializer as ArrayInitializerExpression;
ArrayType arrayType = result.Type as ArrayType;
if (aie != null && arrayType != null) {
StoreState(aie, resolver.Clone());
List<ResolveResult> list = new List<ResolveResult>();
UnpackArrayInitializer(list, aie, arrayType.Dimensions);
ResolveResult[] initializerElements = list.ToArray();
ResolveResult arrayCreation = resolver.ResolveArrayCreation(arrayType.ElementType, arrayType.Dimensions, null, initializerElements);
StoreResult(aie, arrayCreation);
ProcessConversionsInResult(arrayCreation);
} else {
ResolveAndProcessConversion(variableInitializer.Initializer, result.Type);
}
return result; return result;
} else { } else {
ScanChildren(variableInitializer); ScanChildren(variableInitializer);
@ -800,17 +803,24 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
dimensions = 1; dimensions = 1;
sizeArguments = null; sizeArguments = null;
} else { } else {
if (arrayCreateExpression.Arguments.All(e => e is EmptyExpression)) if (arrayCreateExpression.Arguments.All(e => e is EmptyExpression)) {
sizeArguments = null; sizeArguments = null;
else } else {
sizeArguments = Resolve(arrayCreateExpression.Arguments); sizeArguments = new ResolveResult[dimensions];
int pos = 0;
foreach (var node in arrayCreateExpression.Arguments)
sizeArguments[pos++] = Resolve(node);
}
} }
ResolveResult[] initializerElements; ResolveResult[] initializerElements;
if (arrayCreateExpression.Initializer.IsNull) if (arrayCreateExpression.Initializer.IsNull) {
initializerElements = null; initializerElements = null;
else } else {
initializerElements = Resolve(arrayCreateExpression.Initializer.Elements); List<ResolveResult> list = new List<ResolveResult>();
UnpackArrayInitializer(list, arrayCreateExpression.Initializer, dimensions);
initializerElements = list.ToArray();
}
if (arrayCreateExpression.Type.IsNull) { if (arrayCreateExpression.Type.IsNull) {
return resolver.ResolveArrayCreation(null, dimensions, sizeArguments, initializerElements); return resolver.ResolveArrayCreation(null, dimensions, sizeArguments, initializerElements);
@ -823,6 +833,30 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
} }
} }
void UnpackArrayInitializer(List<ResolveResult> list, ArrayInitializerExpression initializer, int dimensions)
{
Debug.Assert(dimensions >= 1);
if (dimensions > 1) {
foreach (var node in initializer.Elements) {
ArrayInitializerExpression aie = node as ArrayInitializerExpression;
if (aie != null)
UnpackArrayInitializer(list, aie, dimensions - 1);
else
list.Add(Resolve(node));
}
} else {
foreach (var expr in initializer.Elements)
list.Add(Resolve(expr));
}
}
public override ResolveResult VisitArrayInitializerExpression(ArrayInitializerExpression arrayInitializerExpression, object data)
{
// Array initializers are handled by their parent expression.
ScanChildren(arrayInitializerExpression);
return errorResult;
}
public override ResolveResult VisitAsExpression(AsExpression asExpression, object data) public override ResolveResult VisitAsExpression(AsExpression asExpression, object data)
{ {
if (resolverEnabled) { if (resolverEnabled) {
@ -1754,8 +1788,14 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
while (undecidedLambdas.Count > 0) { while (undecidedLambdas.Count > 0) {
LambdaBase lambda = undecidedLambdas[0]; LambdaBase lambda = undecidedLambdas[0];
AstNode parent = lambda.LambdaExpression.Parent; AstNode parent = lambda.LambdaExpression.Parent;
while (ActsAsParenthesizedExpression(parent)) // Continue going upwards until we find a node that can be resolved and provides
// an expected type.
while (parent is ParenthesizedExpression
|| parent is CheckedExpression || parent is UncheckedExpression
|| parent is NamedArgumentExpression || parent is ArrayInitializerExpression)
{
parent = parent.Parent; parent = parent.Parent;
}
CSharpResolver storedResolver; CSharpResolver storedResolver;
if (parent != null && resolverBeforeDict.TryGetValue(parent, out storedResolver)) { if (parent != null && resolverBeforeDict.TryGetValue(parent, out storedResolver)) {
Log.WriteLine("Trying to resolve '" + parent + "' in order to merge the lambda..."); Log.WriteLine("Trying to resolve '" + parent + "' in order to merge the lambda...");
@ -1774,16 +1814,6 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
Log.Unindent(); Log.Unindent();
Log.WriteLine("MergeUndecidedLambdas() finished."); Log.WriteLine("MergeUndecidedLambdas() finished.");
} }
/// <summary>
/// Gets whether the node acts as a parenthesized expression,
/// that is, it directly returns
/// </summary>
static bool ActsAsParenthesizedExpression(AstNode node)
{
return node is ParenthesizedExpression || node is CheckedExpression || node is UncheckedExpression
|| node is NamedArgumentExpression;
}
#endregion #endregion
#region AnalyzeLambda #region AnalyzeLambda
@ -2073,16 +2103,16 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
/// </summary> /// </summary>
ITypeReference MakeTypeReference(AstType type, AstNode initializerExpression, bool isForEach) ITypeReference MakeTypeReference(AstType type, AstNode initializerExpression, bool isForEach)
{ {
bool needsResolving; bool typeNeedsResolving;
if (mode == ResolveVisitorNavigationMode.ResolveAll) { if (mode == ResolveVisitorNavigationMode.ResolveAll) {
needsResolving = true; typeNeedsResolving = true;
} else { } else {
var modeForType = navigator.Scan(type); var modeForType = navigator.Scan(type);
needsResolving = (modeForType == ResolveVisitorNavigationMode.Resolve || modeForType == ResolveVisitorNavigationMode.ResolveAll); typeNeedsResolving = (modeForType == ResolveVisitorNavigationMode.Resolve || modeForType == ResolveVisitorNavigationMode.ResolveAll);
} }
if (initializerExpression != null && IsVar(type)) { if (initializerExpression != null && IsVar(type)) {
var typeRef = new VarTypeReference(this, resolver.Clone(), initializerExpression, isForEach); var typeRef = new VarTypeReference(this, resolver.Clone(), initializerExpression, isForEach);
if (needsResolving) { if (typeNeedsResolving) {
// Hack: I don't see a clean way to make the 'var' SimpleType resolve to the inferred type, // Hack: I don't see a clean way to make the 'var' SimpleType resolve to the inferred type,
// so we just do it here and store the result in the resolver cache. // so we just do it here and store the result in the resolver cache.
IType actualType = typeRef.Resolve(resolver.Context); IType actualType = typeRef.Resolve(resolver.Context);
@ -2099,7 +2129,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
// Perf: avoid duplicate resolving of the type (once as ITypeReference, once directly in ResolveVisitor) // Perf: avoid duplicate resolving of the type (once as ITypeReference, once directly in ResolveVisitor)
// if possible. By using ResolveType when we know we need to resolve the node anyways, the resolve cache // if possible. By using ResolveType when we know we need to resolve the node anyways, the resolve cache
// can take care of the duplicate call. // can take care of the duplicate call.
if (needsResolving) if (typeNeedsResolving)
return ResolveType(type); return ResolveType(type);
else else
return MakeTypeReference(type); return MakeTypeReference(type);
@ -2174,7 +2204,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
if (baseTypeDef.Namespace == "System.Collections.Generic" && baseTypeDef.TypeParameterCount == 1) { if (baseTypeDef.Namespace == "System.Collections.Generic" && baseTypeDef.TypeParameterCount == 1) {
ParameterizedType pt = baseType as ParameterizedType; ParameterizedType pt = baseType as ParameterizedType;
if (pt != null) { if (pt != null) {
return pt.TypeArguments[0]; return pt.GetTypeArgument(0);
} }
} else if (baseTypeDef.Namespace == "System.Collections" && baseTypeDef.TypeParameterCount == 0) { } else if (baseTypeDef.Namespace == "System.Collections" && baseTypeDef.TypeParameterCount == 0) {
foundSimpleIEnumerable = true; foundSimpleIEnumerable = true;
@ -2333,14 +2363,6 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
} }
#endregion #endregion
public override ResolveResult VisitArrayInitializerExpression(ArrayInitializerExpression arrayInitializerExpression, object data)
{
// TODO: array initializers are valid expressions if the parent node is a variable/field declaration
// that explicitly defines an array type
ScanChildren(arrayInitializerExpression);
return errorResult;
}
#region Token Nodes #region Token Nodes
public override ResolveResult VisitIdentifier(Identifier identifier, object data) public override ResolveResult VisitIdentifier(Identifier identifier, object data)
{ {

16
ICSharpCode.NRefactory/CSharp/Resolver/TypeInference.cs

@ -373,7 +373,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
if (pt != null && pt.TypeParameterCount == 1 && pt.Name == "Expression" if (pt != null && pt.TypeParameterCount == 1 && pt.Name == "Expression"
&& pt.Namespace == "System.Linq.Expressions") && pt.Namespace == "System.Linq.Expressions")
{ {
t = pt.TypeArguments[0]; t = pt.GetTypeArgument(0);
} }
return t.GetDelegateInvokeMethod(); return t.GetDelegateInvokeMethod();
} }
@ -577,7 +577,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
{ {
Log.Indent(); Log.Indent();
for (int i = 0; i < pU.TypeParameterCount; i++) { for (int i = 0; i < pU.TypeParameterCount; i++) {
MakeExactInference(pU.TypeArguments[i], pV.TypeArguments[i]); MakeExactInference(pU.GetTypeArgument(i), pV.GetTypeArgument(i));
} }
Log.Unindent(); Log.Unindent();
} }
@ -620,7 +620,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
MakeLowerBoundInference(arrU.ElementType, arrV.ElementType); MakeLowerBoundInference(arrU.ElementType, arrV.ElementType);
return; return;
} else if (arrU != null && IsIEnumerableCollectionOrList(pV) && arrU.Dimensions == 1) { } else if (arrU != null && IsIEnumerableCollectionOrList(pV) && arrU.Dimensions == 1) {
MakeLowerBoundInference(arrU.ElementType, pV.TypeArguments[0]); MakeLowerBoundInference(arrU.ElementType, pV.GetTypeArgument(0));
return; return;
} }
// Handle parameterized types: // Handle parameterized types:
@ -638,8 +638,8 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
Log.Indent(); Log.Indent();
if (uniqueBaseType != null) { if (uniqueBaseType != null) {
for (int i = 0; i < uniqueBaseType.TypeParameterCount; i++) { for (int i = 0; i < uniqueBaseType.TypeParameterCount; i++) {
IType Ui = uniqueBaseType.TypeArguments[i]; IType Ui = uniqueBaseType.GetTypeArgument(i);
IType Vi = pV.TypeArguments[i]; IType Vi = pV.GetTypeArgument(i);
if (Ui.IsReferenceType(context) == true) { if (Ui.IsReferenceType(context) == true) {
// look for variance // look for variance
ITypeParameter Xi = pV.GetDefinition().TypeParameters[i]; ITypeParameter Xi = pV.GetDefinition().TypeParameters[i];
@ -704,7 +704,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
MakeUpperBoundInference(arrU.ElementType, arrV.ElementType); MakeUpperBoundInference(arrU.ElementType, arrV.ElementType);
return; return;
} else if (arrV != null && IsIEnumerableCollectionOrList(pU) && arrV.Dimensions == 1) { } else if (arrV != null && IsIEnumerableCollectionOrList(pU) && arrV.Dimensions == 1) {
MakeUpperBoundInference(pU.TypeArguments[0], arrV.ElementType); MakeUpperBoundInference(pU.GetTypeArgument(0), arrV.ElementType);
return; return;
} }
// Handle parameterized types: // Handle parameterized types:
@ -722,8 +722,8 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
Log.Indent(); Log.Indent();
if (uniqueBaseType != null) { if (uniqueBaseType != null) {
for (int i = 0; i < uniqueBaseType.TypeParameterCount; i++) { for (int i = 0; i < uniqueBaseType.TypeParameterCount; i++) {
IType Ui = pU.TypeArguments[i]; IType Ui = pU.GetTypeArgument(i);
IType Vi = uniqueBaseType.TypeArguments[i]; IType Vi = uniqueBaseType.GetTypeArgument(i);
if (Ui.IsReferenceType(context) == true) { if (Ui.IsReferenceType(context) == true) {
// look for variance // look for variance
ITypeParameter Xi = pU.GetDefinition().TypeParameters[i]; ITypeParameter Xi = pU.GetDefinition().TypeParameters[i];

1
ICSharpCode.NRefactory/ICSharpCode.NRefactory.csproj

@ -249,6 +249,7 @@
<Compile Include="TypeSystem\Implementation\DefaultTypeParameter.cs" /> <Compile Include="TypeSystem\Implementation\DefaultTypeParameter.cs" />
<Compile Include="TypeSystem\Implementation\GetClassTypeReference.cs" /> <Compile Include="TypeSystem\Implementation\GetClassTypeReference.cs" />
<Compile Include="TypeSystem\Implementation\CompositeTypeResolveContext.cs" /> <Compile Include="TypeSystem\Implementation\CompositeTypeResolveContext.cs" />
<Compile Include="TypeSystem\Implementation\GetMembersHelper.cs" />
<Compile Include="TypeSystem\Implementation\TypeParameterSubstitution.cs" /> <Compile Include="TypeSystem\Implementation\TypeParameterSubstitution.cs" />
<Compile Include="TypeSystem\Implementation\NestedTypeReference.cs" /> <Compile Include="TypeSystem\Implementation\NestedTypeReference.cs" />
<Compile Include="TypeSystem\Implementation\ProxyTypeResolveContext.cs" /> <Compile Include="TypeSystem\Implementation\ProxyTypeResolveContext.cs" />

14
ICSharpCode.NRefactory/TypeSystem/ArrayType.cs

@ -25,7 +25,7 @@ namespace ICSharpCode.NRefactory.TypeSystem
/// <summary> /// <summary>
/// Represents an array type. /// Represents an array type.
/// </summary> /// </summary>
public class ArrayType : TypeWithElementType public sealed class ArrayType : TypeWithElementType
{ {
readonly int dimensions; readonly int dimensions;
@ -83,19 +83,21 @@ namespace ICSharpCode.NRefactory.TypeSystem
return baseTypes; return baseTypes;
} }
public override IEnumerable<IMethod> GetMethods(ITypeResolveContext context, Predicate<IMethod> filter = null) public override IEnumerable<IMethod> GetMethods(ITypeResolveContext context, Predicate<IMethod> filter = null, GetMemberOptions options = GetMemberOptions.None)
{ {
return systemArray.Resolve(context).GetMethods(context, filter); return systemArray.Resolve(context).GetMethods(context, filter, options);
} }
static readonly DefaultParameter indexerParam = new DefaultParameter(KnownTypeReference.Int32, string.Empty); static readonly DefaultParameter indexerParam = new DefaultParameter(KnownTypeReference.Int32, string.Empty);
public override IEnumerable<IProperty> GetProperties(ITypeResolveContext context, Predicate<IProperty> filter = null) public override IEnumerable<IProperty> GetProperties(ITypeResolveContext context, Predicate<IProperty> filter = null, GetMemberOptions options = GetMemberOptions.None)
{ {
ITypeDefinition arrayDef = systemArray.Resolve(context) as ITypeDefinition; ITypeDefinition arrayDef = systemArray.Resolve(context) as ITypeDefinition;
if (arrayDef != null) { if (arrayDef != null) {
foreach (IProperty p in arrayDef.GetProperties(context, filter)) { if ((options & GetMemberOptions.IgnoreInheritedMembers) == 0) {
yield return p; foreach (IProperty p in arrayDef.GetProperties(context, filter, options)) {
yield return p;
}
} }
DefaultProperty indexer = new DefaultProperty(arrayDef, "Items") { DefaultProperty indexer = new DefaultProperty(arrayDef, "Items") {
EntityType = EntityType.Indexer, EntityType = EntityType.Indexer,

2
ICSharpCode.NRefactory/TypeSystem/ByReferenceType.cs

@ -21,7 +21,7 @@ using ICSharpCode.NRefactory.TypeSystem.Implementation;
namespace ICSharpCode.NRefactory.TypeSystem namespace ICSharpCode.NRefactory.TypeSystem
{ {
public class ByReferenceType : TypeWithElementType public sealed class ByReferenceType : TypeWithElementType
{ {
public ByReferenceType(IType elementType) : base(elementType) public ByReferenceType(IType elementType) : base(elementType)
{ {

50
ICSharpCode.NRefactory/TypeSystem/IType.cs

@ -145,7 +145,7 @@ namespace ICSharpCode.NRefactory.TypeSystem
/// Base.GetNestedTypes() = { Base`1+Nested`1[`0, unbound] } /// Base.GetNestedTypes() = { Base`1+Nested`1[`0, unbound] }
/// </code> /// </code>
/// </example> /// </example>
IEnumerable<IType> GetNestedTypes(ITypeResolveContext context, Predicate<ITypeDefinition> filter = null); IEnumerable<IType> GetNestedTypes(ITypeResolveContext context, Predicate<ITypeDefinition> filter = null, GetMemberOptions options = GetMemberOptions.None);
// Note that we cannot 'leak' the additional type parameter as we leak the normal type parameters, because // Note that we cannot 'leak' the additional type parameter as we leak the normal type parameters, because
// the index might collide. For example, // the index might collide. For example,
@ -170,7 +170,7 @@ namespace ICSharpCode.NRefactory.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, ITypeResolveContext context, Predicate<ITypeDefinition> filter = null); IEnumerable<IType> GetNestedTypes(IList<IType> typeArguments, ITypeResolveContext context, Predicate<ITypeDefinition> filter = null, GetMemberOptions options = GetMemberOptions.None);
/// <summary> /// <summary>
/// Gets all instance constructors for this type. /// Gets all instance constructors for this type.
@ -185,7 +185,7 @@ namespace ICSharpCode.NRefactory.TypeSystem
/// and the appropriate <see cref="SpecializedMethod"/> will be returned. /// and the appropriate <see cref="SpecializedMethod"/> will be returned.
/// </para> /// </para>
/// </remarks> /// </remarks>
IEnumerable<IMethod> GetConstructors(ITypeResolveContext context, Predicate<IMethod> filter = null); IEnumerable<IMethod> GetConstructors(ITypeResolveContext context, Predicate<IMethod> filter = null, GetMemberOptions options = GetMemberOptions.IgnoreInheritedMembers);
/// <summary> /// <summary>
/// Gets all methods that can be called on this type. /// Gets all methods that can be called on this type.
@ -212,7 +212,7 @@ namespace ICSharpCode.NRefactory.TypeSystem
/// the ambiguity can be avoided. /// the ambiguity can be avoided.
/// </para> /// </para>
/// </remarks> /// </remarks>
IEnumerable<IMethod> GetMethods(ITypeResolveContext context, Predicate<IMethod> filter = null); IEnumerable<IMethod> GetMethods(ITypeResolveContext context, Predicate<IMethod> filter = null, GetMemberOptions options = GetMemberOptions.None);
/// <summary> /// <summary>
/// Gets all generic methods that can be called on this type with the specified type arguments. /// Gets all generic methods that can be called on this type with the specified type arguments.
@ -233,7 +233,7 @@ namespace ICSharpCode.NRefactory.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, ITypeResolveContext context, Predicate<IMethod> filter = null); IEnumerable<IMethod> GetMethods(IList<IType> typeArguments, ITypeResolveContext context, Predicate<IMethod> 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.
@ -245,7 +245,7 @@ namespace ICSharpCode.NRefactory.TypeSystem
/// For properties on parameterized types, type substitution will be performed on the property signature, /// For properties on parameterized types, type substitution will be performed on the property signature,
/// and the appropriate <see cref="SpecializedProperty"/> will be returned. /// and the appropriate <see cref="SpecializedProperty"/> will be returned.
/// </remarks> /// </remarks>
IEnumerable<IProperty> GetProperties(ITypeResolveContext context, Predicate<IProperty> filter = null); IEnumerable<IProperty> GetProperties(ITypeResolveContext context, Predicate<IProperty> filter = null, GetMemberOptions options = GetMemberOptions.None);
/// <summary> /// <summary>
/// Gets all fields that can be accessed on this type. /// Gets all fields that can be accessed on this type.
@ -257,7 +257,7 @@ namespace ICSharpCode.NRefactory.TypeSystem
/// For fields on parameterized types, type substitution will be performed on the field's return type, /// For fields on parameterized types, type substitution will be performed on the field's return type,
/// and the appropriate <see cref="SpecializedField"/> will be returned. /// and the appropriate <see cref="SpecializedField"/> will be returned.
/// </remarks> /// </remarks>
IEnumerable<IField> GetFields(ITypeResolveContext context, Predicate<IField> filter = null); IEnumerable<IField> GetFields(ITypeResolveContext context, Predicate<IField> filter = null, GetMemberOptions options = GetMemberOptions.None);
/// <summary> /// <summary>
/// Gets all events that can be accessed on this type. /// Gets all events that can be accessed on this type.
@ -269,7 +269,7 @@ namespace ICSharpCode.NRefactory.TypeSystem
/// For fields on parameterized types, type substitution will be performed on the event's return type, /// For fields on parameterized types, type substitution will be performed on the event's return type,
/// and the appropriate <see cref="SpecializedEvent"/> will be returned. /// and the appropriate <see cref="SpecializedEvent"/> will be returned.
/// </remarks> /// </remarks>
IEnumerable<IEvent> GetEvents(ITypeResolveContext context, Predicate<IEvent> filter = null); IEnumerable<IEvent> GetEvents(ITypeResolveContext context, Predicate<IEvent> filter = null, GetMemberOptions options = GetMemberOptions.None);
/// <summary> /// <summary>
/// Gets all members that can be called on this type. /// Gets all members that can be called on this type.
@ -288,7 +288,25 @@ namespace ICSharpCode.NRefactory.TypeSystem
/// <see cref="GetMethods(ITypeResolveContext, Predicate{IMethod})"/> method apply here as well. /// <see cref="GetMethods(ITypeResolveContext, Predicate{IMethod})"/> method apply here as well.
/// </para> /// </para>
/// </remarks> /// </remarks>
IEnumerable<IMember> GetMembers(ITypeResolveContext context, Predicate<IMember> filter = null); IEnumerable<IMember> GetMembers(ITypeResolveContext context, Predicate<IMember> filter = null, GetMemberOptions options = GetMemberOptions.None);
}
[Flags]
public enum GetMemberOptions
{
/// <summary>
/// No options specified - this is the default.
/// Members will be specialized, and inherited members will be included.
/// </summary>
None = 0x00,
/// <summary>
/// Do not specialize the returned members - directly return the definitions.
/// </summary>
ReturnMemberDefinitions = 0x01,
/// <summary>
/// Do not list inherited members - only list members defined directly on this type.
/// </summary>
IgnoreInheritedMembers = 0x02
} }
#if WITH_CONTRACTS #if WITH_CONTRACTS
@ -319,49 +337,49 @@ namespace ICSharpCode.NRefactory.TypeSystem
return null; return null;
} }
IEnumerable<IType> IType.GetNestedTypes(ITypeResolveContext context, Predicate<ITypeDefinition> filter) IEnumerable<IType> IType.GetNestedTypes(ITypeResolveContext context, Predicate<ITypeDefinition> filter, GetMemberOptions options)
{ {
Contract.Requires(context != null); Contract.Requires(context != null);
Contract.Ensures(Contract.Result<IEnumerable<IType>>() != null); Contract.Ensures(Contract.Result<IEnumerable<IType>>() != null);
return null; return null;
} }
IEnumerable<IMethod> IType.GetMethods(ITypeResolveContext context, Predicate<IMethod> filter) IEnumerable<IMethod> IType.GetMethods(ITypeResolveContext context, Predicate<IMethod> filter, GetMemberOptions options)
{ {
Contract.Requires(context != null); Contract.Requires(context != null);
Contract.Ensures(Contract.Result<IEnumerable<IMethod>>() != null); Contract.Ensures(Contract.Result<IEnumerable<IMethod>>() != null);
return null; return null;
} }
IEnumerable<IMethod> IType.GetConstructors(ITypeResolveContext context, Predicate<IMethod> filter) IEnumerable<IMethod> IType.GetConstructors(ITypeResolveContext context, Predicate<IMethod> filter, GetMemberOptions options)
{ {
Contract.Requires(context != null); Contract.Requires(context != null);
Contract.Ensures(Contract.Result<IEnumerable<IMethod>>() != null); Contract.Ensures(Contract.Result<IEnumerable<IMethod>>() != null);
return null; return null;
} }
IEnumerable<IProperty> IType.GetProperties(ITypeResolveContext context, Predicate<IProperty> filter) IEnumerable<IProperty> IType.GetProperties(ITypeResolveContext context, Predicate<IProperty> filter, GetMemberOptions options)
{ {
Contract.Requires(context != null); Contract.Requires(context != null);
Contract.Ensures(Contract.Result<IEnumerable<IProperty>>() != null); Contract.Ensures(Contract.Result<IEnumerable<IProperty>>() != null);
return null; return null;
} }
IEnumerable<IField> IType.GetFields(ITypeResolveContext context, Predicate<IField> filter) IEnumerable<IField> IType.GetFields(ITypeResolveContext context, Predicate<IField> filter, GetMemberOptions options)
{ {
Contract.Requires(context != null); Contract.Requires(context != null);
Contract.Ensures(Contract.Result<IEnumerable<IField>>() != null); Contract.Ensures(Contract.Result<IEnumerable<IField>>() != null);
return null; return null;
} }
IEnumerable<IEvent> IType.GetEvents(ITypeResolveContext context, Predicate<IEvent> filter) IEnumerable<IEvent> IType.GetEvents(ITypeResolveContext context, Predicate<IEvent> filter, GetMemberOptions options)
{ {
Contract.Requires(context != null); Contract.Requires(context != null);
Contract.Ensures(Contract.Result<IEnumerable<IEvent>>() != null); Contract.Ensures(Contract.Result<IEnumerable<IEvent>>() != null);
return null; return null;
} }
IEnumerable<IMember> IType.GetEvents(ITypeResolveContext context, Predicate<IMember> filter) IEnumerable<IMember> IType.GetEvents(ITypeResolveContext context, Predicate<IMember> filter, GetMemberOptions options)
{ {
Contract.Requires(context != null); Contract.Requires(context != null);
Contract.Ensures(Contract.Result<IEnumerable<IMember>>() != null); Contract.Ensures(Contract.Result<IEnumerable<IMember>>() != null);

6
ICSharpCode.NRefactory/TypeSystem/Implementation/AbstractFreezable.cs

@ -78,7 +78,7 @@ namespace ICSharpCode.NRefactory.TypeSystem.Implementation
return new List<T>(inputList); return new List<T>(inputList);
} }
protected static ReadOnlyCollection<T> FreezeList<T>(IList<T> list) where T : IFreezable protected static IList<T> FreezeList<T>(IList<T> list) where T : IFreezable
{ {
if (list == null || list.Count == 0) if (list == null || list.Count == 0)
return EmptyList<T>.Instance; return EmptyList<T>.Instance;
@ -89,7 +89,7 @@ namespace ICSharpCode.NRefactory.TypeSystem.Implementation
return result; return result;
} }
protected static ReadOnlyCollection<string> FreezeList(IList<string> list) protected static IList<string> FreezeList(IList<string> list)
{ {
if (list == null || list.Count == 0) if (list == null || list.Count == 0)
return EmptyList<string>.Instance; return EmptyList<string>.Instance;
@ -97,7 +97,7 @@ namespace ICSharpCode.NRefactory.TypeSystem.Implementation
return new ReadOnlyCollection<string>(list.ToArray()); return new ReadOnlyCollection<string>(list.ToArray());
} }
protected static ReadOnlyCollection<ITypeReference> FreezeList(IList<ITypeReference> list) protected static IList<ITypeReference> FreezeList(IList<ITypeReference> list)
{ {
if (list == null || list.Count == 0) if (list == null || list.Count == 0)
return EmptyList<ITypeReference>.Instance; return EmptyList<ITypeReference>.Instance;

26
ICSharpCode.NRefactory/TypeSystem/Implementation/AbstractType.cs

@ -77,52 +77,52 @@ namespace ICSharpCode.NRefactory.TypeSystem.Implementation
return EmptyList<IType>.Instance; return EmptyList<IType>.Instance;
} }
public virtual IEnumerable<IType> GetNestedTypes(ITypeResolveContext context, Predicate<ITypeDefinition> filter = null) public virtual IEnumerable<IType> GetNestedTypes(ITypeResolveContext context, Predicate<ITypeDefinition> filter = null, GetMemberOptions options = GetMemberOptions.None)
{ {
return EmptyList<IType>.Instance; return EmptyList<IType>.Instance;
} }
public virtual IEnumerable<IType> GetNestedTypes(IList<IType> typeArguments, ITypeResolveContext context, Predicate<ITypeDefinition> filter = null) public virtual IEnumerable<IType> GetNestedTypes(IList<IType> typeArguments, ITypeResolveContext context, Predicate<ITypeDefinition> filter = null, GetMemberOptions options = GetMemberOptions.None)
{ {
return EmptyList<IType>.Instance; return EmptyList<IType>.Instance;
} }
public virtual IEnumerable<IMethod> GetMethods(ITypeResolveContext context, Predicate<IMethod> filter = null) public virtual IEnumerable<IMethod> GetMethods(ITypeResolveContext context, Predicate<IMethod> filter = null, GetMemberOptions options = GetMemberOptions.None)
{ {
return EmptyList<IMethod>.Instance; return EmptyList<IMethod>.Instance;
} }
public virtual IEnumerable<IMethod> GetMethods(IList<IType> typeArguments, ITypeResolveContext context, Predicate<IMethod> filter) public virtual IEnumerable<IMethod> GetMethods(IList<IType> typeArguments, ITypeResolveContext context, Predicate<IMethod> filter = null, GetMemberOptions options = GetMemberOptions.None)
{ {
return EmptyList<IMethod>.Instance; return EmptyList<IMethod>.Instance;
} }
public virtual IEnumerable<IMethod> GetConstructors(ITypeResolveContext context, Predicate<IMethod> filter = null) public virtual IEnumerable<IMethod> GetConstructors(ITypeResolveContext context, Predicate<IMethod> filter = null, GetMemberOptions options = GetMemberOptions.IgnoreInheritedMembers)
{ {
return EmptyList<IMethod>.Instance; return EmptyList<IMethod>.Instance;
} }
public virtual IEnumerable<IProperty> GetProperties(ITypeResolveContext context, Predicate<IProperty> filter = null) public virtual IEnumerable<IProperty> GetProperties(ITypeResolveContext context, Predicate<IProperty> filter = null, GetMemberOptions options = GetMemberOptions.None)
{ {
return EmptyList<IProperty>.Instance; return EmptyList<IProperty>.Instance;
} }
public virtual IEnumerable<IField> GetFields(ITypeResolveContext context, Predicate<IField> filter = null) public virtual IEnumerable<IField> GetFields(ITypeResolveContext context, Predicate<IField> filter = null, GetMemberOptions options = GetMemberOptions.None)
{ {
return EmptyList<IField>.Instance; return EmptyList<IField>.Instance;
} }
public virtual IEnumerable<IEvent> GetEvents(ITypeResolveContext context, Predicate<IEvent> filter = null) public virtual IEnumerable<IEvent> GetEvents(ITypeResolveContext context, Predicate<IEvent> filter = null, GetMemberOptions options = GetMemberOptions.None)
{ {
return EmptyList<IEvent>.Instance; return EmptyList<IEvent>.Instance;
} }
public virtual IEnumerable<IMember> GetMembers(ITypeResolveContext context, Predicate<IMember> filter = null) public virtual IEnumerable<IMember> GetMembers(ITypeResolveContext context, Predicate<IMember> filter = null, GetMemberOptions options = GetMemberOptions.None)
{ {
return GetMethods(context, filter).SafeCast<IMethod, IMember>() return GetMethods(context, filter, options).SafeCast<IMethod, IMember>()
.Concat(GetProperties(context, filter).SafeCast<IProperty, IMember>()) .Concat(GetProperties(context, filter, options).SafeCast<IProperty, IMember>())
.Concat(GetFields(context, filter).SafeCast<IField, IMember>()) .Concat(GetFields(context, filter, options).SafeCast<IField, IMember>())
.Concat(GetEvents(context, filter).SafeCast<IEvent, IMember>()); .Concat(GetEvents(context, filter, options).SafeCast<IEvent, IMember>());
} }
public override bool Equals(object obj) public override bool Equals(object obj)

124
ICSharpCode.NRefactory/TypeSystem/Implementation/DefaultTypeDefinition.cs

@ -441,72 +441,142 @@ namespace ICSharpCode.NRefactory.TypeSystem.Implementation
return this; return this;
} }
public IEnumerable<IType> GetNestedTypes(ITypeResolveContext context, Predicate<ITypeDefinition> filter = null) #region GetMembers
public IEnumerable<IType> GetNestedTypes(ITypeResolveContext context, Predicate<ITypeDefinition> filter = null, GetMemberOptions options = GetMemberOptions.None)
{ {
return ParameterizedType.GetNestedTypes(this, context, filter); const GetMemberOptions opt = GetMemberOptions.IgnoreInheritedMembers | GetMemberOptions.ReturnMemberDefinitions;
if ((options & opt) == opt) {
ITypeDefinition compound = this.compoundTypeDefinition;
if (compound != this)
return compound.GetNestedTypes(context, filter, options);
return ApplyFilter(this.NestedTypes, filter);
} else {
return GetMembersHelper.GetNestedTypes(this, context, filter, options);
}
} }
public IEnumerable<IType> GetNestedTypes(IList<IType> typeArguments, ITypeResolveContext context, Predicate<ITypeDefinition> filter = null) public IEnumerable<IType> GetNestedTypes(IList<IType> typeArguments, ITypeResolveContext context, Predicate<ITypeDefinition> filter = null, GetMemberOptions options = GetMemberOptions.None)
{ {
return ParameterizedType.GetNestedTypes(this, typeArguments, context, filter); return GetMembersHelper.GetNestedTypes(this, typeArguments, context, filter, options);
} }
public virtual IEnumerable<IMethod> GetMethods(ITypeResolveContext context, Predicate<IMethod> filter = null) public virtual IEnumerable<IMethod> GetMethods(ITypeResolveContext context, Predicate<IMethod> filter = null, GetMemberOptions options = GetMemberOptions.None)
{ {
return ParameterizedType.GetMethods(this, context, filter); if ((options & GetMemberOptions.IgnoreInheritedMembers) == GetMemberOptions.IgnoreInheritedMembers) {
ITypeDefinition compound = this.compoundTypeDefinition;
if (compound != this)
return compound.GetMethods(context, filter, options);
return ApplyFilter(this.Methods, Utils.ExtensionMethods.And(m => !m.IsConstructor, filter));
} else {
return GetMembersHelper.GetMethods(this, context, filter, options);
}
} }
public virtual IEnumerable<IMethod> GetMethods(IList<IType> typeArguments, ITypeResolveContext context, Predicate<IMethod> filter = null) public virtual IEnumerable<IMethod> GetMethods(IList<IType> typeArguments, ITypeResolveContext context, Predicate<IMethod> filter = null, GetMemberOptions options = GetMemberOptions.None)
{ {
return ParameterizedType.GetMethods(this, typeArguments, context, filter); return GetMembersHelper.GetMethods(this, typeArguments, context, filter, options);
} }
public virtual IEnumerable<IMethod> GetConstructors(ITypeResolveContext context, Predicate<IMethod> filter = null) public virtual IEnumerable<IMethod> GetConstructors(ITypeResolveContext context, Predicate<IMethod> filter = null, GetMemberOptions options = GetMemberOptions.IgnoreInheritedMembers)
{ {
ITypeDefinition compound = this.compoundTypeDefinition; if ((options & GetMemberOptions.IgnoreInheritedMembers) == GetMemberOptions.IgnoreInheritedMembers) {
if (compound != this) ITypeDefinition compound = this.compoundTypeDefinition;
return compound.GetConstructors(context, filter); if (compound != this)
return compound.GetConstructors(context, filter, options);
List<IMethod> methods = new List<IMethod>();
return GetConstructorsImpl(filter);
} else {
return GetMembersHelper.GetConstructors(this, context, filter, options);
}
}
IEnumerable<IMethod> GetConstructorsImpl(Predicate<IMethod> filter)
{
bool foundCtor = false;
foreach (IMethod m in this.Methods) { foreach (IMethod m in this.Methods) {
if (m.IsConstructor && !m.IsStatic) { if (m.IsConstructor && !m.IsStatic) {
if (filter == null || filter(m)) foundCtor = true;
methods.Add(m); if (filter == null || filter(m)) {
yield return m;
}
} }
} }
if (this.AddDefaultConstructorIfRequired) { if (this.AddDefaultConstructorIfRequired) {
if (kind == TypeKind.Class && methods.Count == 0 && !this.IsStatic if (kind == TypeKind.Class && !foundCtor && !this.IsStatic
|| kind == TypeKind.Enum || kind == TypeKind.Struct) || kind == TypeKind.Enum || kind == TypeKind.Struct)
{ {
var m = DefaultMethod.CreateDefaultConstructor(this); var m = DefaultMethod.CreateDefaultConstructor(this);
if (filter == null || filter(m)) if (filter == null || filter(m))
methods.Add(m); yield return m;
} }
} }
return methods;
} }
public virtual IEnumerable<IProperty> GetProperties(ITypeResolveContext context, Predicate<IProperty> filter = null) public virtual IEnumerable<IProperty> GetProperties(ITypeResolveContext context, Predicate<IProperty> filter = null, GetMemberOptions options = GetMemberOptions.None)
{ {
return ParameterizedType.GetProperties(this, context, filter); if ((options & GetMemberOptions.IgnoreInheritedMembers) == GetMemberOptions.IgnoreInheritedMembers) {
ITypeDefinition compound = this.compoundTypeDefinition;
if (compound != this)
return compound.GetProperties(context, filter, options);
return ApplyFilter(this.Properties, filter);
} else {
return GetMembersHelper.GetProperties(this, context, filter, options);
}
} }
public virtual IEnumerable<IField> GetFields(ITypeResolveContext context, Predicate<IField> filter = null) public virtual IEnumerable<IField> GetFields(ITypeResolveContext context, Predicate<IField> filter = null, GetMemberOptions options = GetMemberOptions.None)
{ {
return ParameterizedType.GetFields(this, context, filter); if ((options & GetMemberOptions.IgnoreInheritedMembers) == GetMemberOptions.IgnoreInheritedMembers) {
ITypeDefinition compound = this.compoundTypeDefinition;
if (compound != this)
return compound.GetFields(context, filter, options);
return ApplyFilter(this.Fields, filter);
} else {
return GetMembersHelper.GetFields(this, context, filter, options);
}
} }
public virtual IEnumerable<IEvent> GetEvents(ITypeResolveContext context, Predicate<IEvent> filter = null) public virtual IEnumerable<IEvent> GetEvents(ITypeResolveContext context, Predicate<IEvent> filter = null, GetMemberOptions options = GetMemberOptions.None)
{ {
return ParameterizedType.GetEvents(this, context, filter); if ((options & GetMemberOptions.IgnoreInheritedMembers) == GetMemberOptions.IgnoreInheritedMembers) {
ITypeDefinition compound = this.compoundTypeDefinition;
if (compound != this)
return compound.GetEvents(context, filter, options);
return ApplyFilter(this.Events, filter);
} else {
return GetMembersHelper.GetEvents(this, context, filter, options);
}
} }
public virtual IEnumerable<IMember> GetMembers(ITypeResolveContext context, Predicate<IMember> filter = null) public virtual IEnumerable<IMember> GetMembers(ITypeResolveContext context, Predicate<IMember> filter = null, GetMemberOptions options = GetMemberOptions.None)
{ {
return ParameterizedType.GetMembers(this, context, filter); return GetMembersHelper.GetMembers(this, context, filter, options);
} }
static IEnumerable<T> ApplyFilter<T>(IList<T> enumerable, Predicate<T> filter) where T : class
{
if (enumerable.Count == 0)
return EmptyList<T>.Instance;
if (filter == null)
return enumerable;
else
return ApplyFilterImpl(enumerable, filter);
}
static IEnumerable<T> ApplyFilterImpl<T>(IList<T> enumerable, Predicate<T> filter) where T : class
{
foreach (T item in enumerable)
if (filter(item))
yield return item;
}
#endregion
#region Equals / GetHashCode #region Equals / GetHashCode
bool IEquatable<IType>.Equals(IType other) bool IEquatable<IType>.Equals(IType other)
{ {

62
ICSharpCode.NRefactory/TypeSystem/Implementation/DefaultTypeParameter.cs

@ -249,44 +249,66 @@ namespace ICSharpCode.NRefactory.TypeSystem.Implementation
return c; return c;
} }
public IEnumerable<IMethod> GetConstructors(ITypeResolveContext context, Predicate<IMethod> filter = null) public IEnumerable<IMethod> GetConstructors(ITypeResolveContext context, Predicate<IMethod> filter = null, GetMemberOptions options = GetMemberOptions.IgnoreInheritedMembers)
{ {
if (HasDefaultConstructorConstraint || HasValueTypeConstraint) { if ((options & GetMemberOptions.IgnoreInheritedMembers) == GetMemberOptions.IgnoreInheritedMembers) {
DefaultMethod m = DefaultMethod.CreateDefaultConstructor(GetDummyClassForTypeParameter()); if (HasDefaultConstructorConstraint || HasValueTypeConstraint) {
if (filter(m)) DefaultMethod m = DefaultMethod.CreateDefaultConstructor(GetDummyClassForTypeParameter());
return new [] { m }; if (filter(m))
return new [] { m };
}
return EmptyList<IMethod>.Instance;
} else {
return GetMembersHelper.GetConstructors(this, context, filter, options);
} }
return EmptyList<IMethod>.Instance;
} }
public IEnumerable<IMethod> GetMethods(ITypeResolveContext context, Predicate<IMethod> filter = null) public IEnumerable<IMethod> GetMethods(ITypeResolveContext context, Predicate<IMethod> filter = null, GetMemberOptions options = GetMemberOptions.None)
{ {
return ParameterizedType.GetMethods(this, context, FilterNonStatic(filter)); if ((options & GetMemberOptions.IgnoreInheritedMembers) == GetMemberOptions.IgnoreInheritedMembers)
return EmptyList<IMethod>.Instance;
else
return GetMembersHelper.GetMethods(this, context, FilterNonStatic(filter), options);
} }
public IEnumerable<IMethod> GetMethods(IList<IType> typeArguments, ITypeResolveContext context, Predicate<IMethod> filter = null) public IEnumerable<IMethod> GetMethods(IList<IType> typeArguments, ITypeResolveContext context, Predicate<IMethod> filter = null, GetMemberOptions options = GetMemberOptions.None)
{ {
return ParameterizedType.GetMethods(this, typeArguments, context, FilterNonStatic(filter)); if ((options & GetMemberOptions.IgnoreInheritedMembers) == GetMemberOptions.IgnoreInheritedMembers)
return EmptyList<IMethod>.Instance;
else
return GetMembersHelper.GetMethods(this, typeArguments, context, FilterNonStatic(filter), options);
} }
public IEnumerable<IProperty> GetProperties(ITypeResolveContext context, Predicate<IProperty> filter = null) public IEnumerable<IProperty> GetProperties(ITypeResolveContext context, Predicate<IProperty> filter = null, GetMemberOptions options = GetMemberOptions.None)
{ {
return ParameterizedType.GetProperties(this, context, FilterNonStatic(filter)); if ((options & GetMemberOptions.IgnoreInheritedMembers) == GetMemberOptions.IgnoreInheritedMembers)
return EmptyList<IProperty>.Instance;
else
return GetMembersHelper.GetProperties(this, context, FilterNonStatic(filter), options);
} }
public IEnumerable<IField> GetFields(ITypeResolveContext context, Predicate<IField> filter = null) public IEnumerable<IField> GetFields(ITypeResolveContext context, Predicate<IField> filter = null, GetMemberOptions options = GetMemberOptions.None)
{ {
return ParameterizedType.GetFields(this, context, FilterNonStatic(filter)); if ((options & GetMemberOptions.IgnoreInheritedMembers) == GetMemberOptions.IgnoreInheritedMembers)
return EmptyList<IField>.Instance;
else
return GetMembersHelper.GetFields(this, context, FilterNonStatic(filter), options);
} }
public IEnumerable<IEvent> GetEvents(ITypeResolveContext context, Predicate<IEvent> filter = null) public IEnumerable<IEvent> GetEvents(ITypeResolveContext context, Predicate<IEvent> filter = null, GetMemberOptions options = GetMemberOptions.None)
{ {
return ParameterizedType.GetEvents(this, context, FilterNonStatic(filter)); if ((options & GetMemberOptions.IgnoreInheritedMembers) == GetMemberOptions.IgnoreInheritedMembers)
return EmptyList<IEvent>.Instance;
else
return GetMembersHelper.GetEvents(this, context, FilterNonStatic(filter), options);
} }
public IEnumerable<IMember> GetMembers(ITypeResolveContext context, Predicate<IMember> filter = null) public IEnumerable<IMember> GetMembers(ITypeResolveContext context, Predicate<IMember> filter = null, GetMemberOptions options = GetMemberOptions.None)
{ {
return ParameterizedType.GetMembers(this, context, FilterNonStatic(filter)); if ((options & GetMemberOptions.IgnoreInheritedMembers) == GetMemberOptions.IgnoreInheritedMembers)
return EmptyList<IMember>.Instance;
else
return GetMembersHelper.GetMembers(this, context, FilterNonStatic(filter), options);
} }
static Predicate<T> FilterNonStatic<T>(Predicate<T> filter) where T : class, IMember static Predicate<T> FilterNonStatic<T>(Predicate<T> filter) where T : class, IMember
@ -297,12 +319,12 @@ namespace ICSharpCode.NRefactory.TypeSystem.Implementation
return member => !member.IsStatic && filter(member); return member => !member.IsStatic && filter(member);
} }
IEnumerable<IType> IType.GetNestedTypes(ITypeResolveContext context, Predicate<ITypeDefinition> filter) IEnumerable<IType> IType.GetNestedTypes(ITypeResolveContext context, Predicate<ITypeDefinition> filter, GetMemberOptions options)
{ {
return EmptyList<IType>.Instance; return EmptyList<IType>.Instance;
} }
IEnumerable<IType> IType.GetNestedTypes(IList<IType> typeArguments, ITypeResolveContext context, Predicate<ITypeDefinition> filter) IEnumerable<IType> IType.GetNestedTypes(IList<IType> typeArguments, ITypeResolveContext context, Predicate<ITypeDefinition> filter, GetMemberOptions options)
{ {
return EmptyList<IType>.Instance; return EmptyList<IType>.Instance;
} }

281
ICSharpCode.NRefactory/TypeSystem/Implementation/GetMembersHelper.cs

@ -0,0 +1,281 @@
// Copyright (c) AlphaSierraPapa for the SharpDevelop Team
//
// Permission is hereby granted, free of charge, to any person obtaining a copy of this
// software and associated documentation files (the "Software"), to deal in the Software
// without restriction, including without limitation the rights to use, copy, modify, merge,
// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons
// to whom the Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all copies or
// substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE
// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
using System;
using System.Collections.Generic;
using System.Linq;
using ICSharpCode.NRefactory.Utils;
namespace ICSharpCode.NRefactory.TypeSystem.Implementation
{
/// <summary>
/// Provides helper methods for implementing GetMembers() on IType-implementations.
/// Note: GetMembersHelper will recursively call back into IType.GetMembers(), but only with
/// both GetMemberOptions.IgnoreInheritedMembers and GetMemberOptions.ReturnMemberDefinitions set,
/// and only the 'simple' overloads (not taking type arguments).
///
/// Ensure that your IType implementation does not use the GetMembersHelper if both flags are set,
/// otherwise you'll get a StackOverflowException!
/// </summary>
static class GetMembersHelper
{
#region GetNestedTypes
public static IEnumerable<IType> GetNestedTypes(IType type, ITypeResolveContext context, Predicate<ITypeDefinition> filter, GetMemberOptions options)
{
return GetNestedTypes(type, null, context, filter, options);
}
public static IEnumerable<IType> GetNestedTypes(IType type, IList<IType> nestedTypeArguments, ITypeResolveContext context, Predicate<ITypeDefinition> filter, GetMemberOptions options)
{
if ((options & GetMemberOptions.IgnoreInheritedMembers) == GetMemberOptions.IgnoreInheritedMembers) {
return GetNestedTypesImpl(type, nestedTypeArguments, context, filter, options);
} else {
return type.GetNonInterfaceBaseTypes(context).SelectMany(t => GetNestedTypesImpl(t, nestedTypeArguments, context, filter, options));
}
}
static IEnumerable<IType> GetNestedTypesImpl(IType outerType, IList<IType> nestedTypeArguments, ITypeResolveContext context, Predicate<ITypeDefinition> filter, GetMemberOptions options)
{
ITypeDefinition outerTypeDef = outerType.GetDefinition();
if (outerTypeDef == null)
yield break;
int outerTypeParameterCount = outerTypeDef.TypeParameterCount;
ParameterizedType pt = outerType as ParameterizedType;
foreach (ITypeDefinition nestedType in outerTypeDef.NestedTypes) {
int totalTypeParameterCount = nestedType.TypeParameterCount;
if (nestedTypeArguments != null) {
if (totalTypeParameterCount - outerTypeParameterCount != nestedTypeArguments.Count)
continue;
}
if (!(filter == null || filter(nestedType)))
continue;
if ((options & GetMemberOptions.ReturnMemberDefinitions) == GetMemberOptions.ReturnMemberDefinitions) {
yield return nestedType;
} else if (totalTypeParameterCount == 0 || (pt == null && totalTypeParameterCount == outerTypeParameterCount)) {
// The nested type has no new type parameters, and there are no type arguments
// to copy from the outer type
// -> we can directly return the nested type definition
yield return nestedType;
} else {
// We need to parameterize the nested type
IType[] newTypeArguments = new IType[totalTypeParameterCount];
for (int i = 0; i < outerTypeParameterCount; i++) {
newTypeArguments[i] = pt != null ? pt.GetTypeArgument(i) : outerTypeDef.TypeParameters[i];
}
for (int i = outerTypeParameterCount; i < totalTypeParameterCount; i++) {
if (nestedTypeArguments != null)
newTypeArguments[i] = nestedTypeArguments[i - outerTypeParameterCount];
else
newTypeArguments[i] = SharedTypes.UnboundTypeArgument;
}
yield return new ParameterizedType(nestedType, newTypeArguments);
}
}
}
#endregion
#region GetMethods
public static IEnumerable<IMethod> GetMethods(IType type, ITypeResolveContext context, Predicate<IMethod> filter, GetMemberOptions options)
{
return GetMethods(type, null, context, filter, options);
}
public static IEnumerable<IMethod> GetMethods(IType type, IList<IType> typeArguments, ITypeResolveContext context, Predicate<IMethod> filter, GetMemberOptions options)
{
if (typeArguments != null && typeArguments.Count > 0) {
filter = FilterTypeParameterCount(typeArguments.Count).And(filter);
}
if ((options & GetMemberOptions.IgnoreInheritedMembers) == GetMemberOptions.IgnoreInheritedMembers) {
return GetMethodsImpl(type, typeArguments, context, filter, options);
} else {
return type.GetNonInterfaceBaseTypes(context).SelectMany(t => GetMethodsImpl(t, typeArguments, context, filter, options));
}
}
static Predicate<IMethod> FilterTypeParameterCount(int expectedTypeParameterCount)
{
return m => m.TypeParameters.Count == expectedTypeParameterCount;
}
const GetMemberOptions declaredMembers = GetMemberOptions.IgnoreInheritedMembers | GetMemberOptions.ReturnMemberDefinitions;
static IEnumerable<IMethod> GetMethodsImpl(IType baseType, IList<IType> methodTypeArguments, ITypeResolveContext context, Predicate<IMethod> filter, GetMemberOptions options)
{
IEnumerable<IMethod> declaredMethods = baseType.GetMethods(context, filter, options | declaredMembers);
ParameterizedType pt = baseType as ParameterizedType;
if ((options & GetMemberOptions.ReturnMemberDefinitions) == 0
&& (pt != null || (methodTypeArguments != null && methodTypeArguments.Count > 0)))
{
TypeParameterSubstitution substitution = null;
foreach (IMethod m in declaredMethods) {
if (methodTypeArguments != null && methodTypeArguments.Count > 0) {
if (m.TypeParameters.Count != methodTypeArguments.Count)
continue;
}
if (substitution == null) {
if (pt != null)
substitution = pt.GetSubstitution(methodTypeArguments);
else
substitution = new TypeParameterSubstitution(null, methodTypeArguments);
}
yield return new SpecializedMethod(baseType, m, methodTypeArguments, substitution, context);
}
} else {
foreach (IMethod m in declaredMethods) {
yield return m;
}
}
}
#endregion
#region GetConstructors
public static IEnumerable<IMethod> GetConstructors(IType type, ITypeResolveContext context, Predicate<IMethod> filter, GetMemberOptions options)
{
if ((options & GetMemberOptions.IgnoreInheritedMembers) == GetMemberOptions.IgnoreInheritedMembers) {
return GetConstructorsImpl(type, context, filter, options);
} else {
return type.GetNonInterfaceBaseTypes(context).SelectMany(t => GetConstructorsImpl(t, context, filter, options));
}
}
static IEnumerable<IMethod> GetConstructorsImpl(IType baseType, ITypeResolveContext context, Predicate<IMethod> filter, GetMemberOptions options)
{
IEnumerable<IMethod> declaredCtors = baseType.GetConstructors(context, filter, options | declaredMembers);
if ((options & GetMemberOptions.ReturnMemberDefinitions) == GetMemberOptions.ReturnMemberDefinitions) {
return declaredCtors;
}
ParameterizedType pt = baseType as ParameterizedType;
if (pt != null) {
var substitution = pt.GetSubstitution();
return declaredCtors.Select(m => new SpecializedMethod(pt, m, null, substitution, context));
} else {
return declaredCtors;
}
}
#endregion
#region GetProperties
public static IEnumerable<IProperty> GetProperties(IType type, ITypeResolveContext context, Predicate<IProperty> filter, GetMemberOptions options)
{
if ((options & GetMemberOptions.IgnoreInheritedMembers) == GetMemberOptions.IgnoreInheritedMembers) {
return GetPropertiesImpl(type, context, filter, options);
} else {
return type.GetNonInterfaceBaseTypes(context).SelectMany(t => GetPropertiesImpl(t, context, filter, options));
}
}
static IEnumerable<IProperty> GetPropertiesImpl(IType baseType, ITypeResolveContext context, Predicate<IProperty> filter, GetMemberOptions options)
{
IEnumerable<IProperty> declaredProperties = baseType.GetProperties(context, filter, options | declaredMembers);
if ((options & GetMemberOptions.ReturnMemberDefinitions) == GetMemberOptions.ReturnMemberDefinitions) {
return declaredProperties;
}
ParameterizedType pt = baseType as ParameterizedType;
if (pt != null) {
var substitution = pt.GetSubstitution();
return declaredProperties.Select(m => new SpecializedProperty(pt, m, substitution, context));
} else {
return declaredProperties;
}
}
#endregion
#region GetFields
public static IEnumerable<IField> GetFields(IType type, ITypeResolveContext context, Predicate<IField> filter, GetMemberOptions options)
{
if ((options & GetMemberOptions.IgnoreInheritedMembers) == GetMemberOptions.IgnoreInheritedMembers) {
return GetFieldsImpl(type, context, filter, options);
} else {
return type.GetNonInterfaceBaseTypes(context).SelectMany(t => GetFieldsImpl(t, context, filter, options));
}
}
static IEnumerable<IField> GetFieldsImpl(IType baseType, ITypeResolveContext context, Predicate<IField> filter, GetMemberOptions options)
{
IEnumerable<IField> declaredFields = baseType.GetFields(context, filter, options | declaredMembers);
if ((options & GetMemberOptions.ReturnMemberDefinitions) == GetMemberOptions.ReturnMemberDefinitions) {
return declaredFields;
}
ParameterizedType pt = baseType as ParameterizedType;
if (pt != null) {
var substitution = pt.GetSubstitution();
return declaredFields.Select(m => new SpecializedField(pt, m, substitution, context));
} else {
return declaredFields;
}
}
#endregion
#region GetEvents
public static IEnumerable<IEvent> GetEvents(IType type, ITypeResolveContext context, Predicate<IEvent> filter, GetMemberOptions options)
{
if ((options & GetMemberOptions.IgnoreInheritedMembers) == GetMemberOptions.IgnoreInheritedMembers) {
return GetEventsImpl(type, context, filter, options);
} else {
return type.GetNonInterfaceBaseTypes(context).SelectMany(t => GetEventsImpl(t, context, filter, options));
}
}
static IEnumerable<IEvent> GetEventsImpl(IType baseType, ITypeResolveContext context, Predicate<IEvent> filter, GetMemberOptions options)
{
IEnumerable<IEvent> declaredEvents = baseType.GetEvents(context, filter, options | declaredMembers);
if ((options & GetMemberOptions.ReturnMemberDefinitions) == GetMemberOptions.ReturnMemberDefinitions) {
return declaredEvents;
}
ParameterizedType pt = baseType as ParameterizedType;
if (pt != null) {
var substitution = pt.GetSubstitution();
return declaredEvents.Select(m => new SpecializedEvent(pt, m, substitution, context));
} else {
return declaredEvents;
}
}
#endregion
#region GetMembers
public static IEnumerable<IMember> GetMembers(IType type, ITypeResolveContext context, Predicate<IMember> filter, GetMemberOptions options)
{
if ((options & GetMemberOptions.IgnoreInheritedMembers) == GetMemberOptions.IgnoreInheritedMembers) {
return GetMembersImpl(type, context, filter, options);
} else {
return type.GetNonInterfaceBaseTypes(context).SelectMany(t => GetMembersImpl(t, context, filter, options));
}
}
static IEnumerable<IMember> GetMembersImpl(IType baseType, ITypeResolveContext context, Predicate<IMember> filter, GetMemberOptions options)
{
foreach (var m in GetMethodsImpl(baseType, null, context, filter, options))
yield return m;
foreach (var m in GetPropertiesImpl(baseType, context, filter, options))
yield return m;
foreach (var m in GetFieldsImpl(baseType, context, filter, options))
yield return m;
foreach (var m in GetEventsImpl(baseType, context, filter, options))
yield return m;
}
#endregion
}
}

10
ICSharpCode.NRefactory/TypeSystem/Implementation/TypeParameterSubstitution.cs

@ -72,10 +72,7 @@ namespace ICSharpCode.NRefactory.TypeSystem.Implementation
bool first = true; bool first = true;
if (classTypeArguments != null) { if (classTypeArguments != null) {
for (int i = 0; i < classTypeArguments.Count; i++) { for (int i = 0; i < classTypeArguments.Count; i++) {
if (first) { if (first) first = false; else b.Append(", ");
first = false;
b.Append(", ");
}
b.Append('`'); b.Append('`');
b.Append(i); b.Append(i);
b.Append(" -> "); b.Append(" -> ");
@ -84,10 +81,7 @@ namespace ICSharpCode.NRefactory.TypeSystem.Implementation
} }
if (methodTypeArguments != null) { if (methodTypeArguments != null) {
for (int i = 0; i < methodTypeArguments.Count; i++) { for (int i = 0; i < methodTypeArguments.Count; i++) {
if (first) { if (first) first = false; else b.Append(", ");
first = false;
b.Append(", ");
}
b.Append("``"); b.Append("``");
b.Append(i); b.Append(i);
b.Append(" -> "); b.Append(" -> ");

14
ICSharpCode.NRefactory/TypeSystem/Implementation/VoidTypeDefinition.cs

@ -34,37 +34,37 @@ namespace ICSharpCode.NRefactory.TypeSystem.Implementation
this.IsSealed = true; this.IsSealed = true;
} }
public override IEnumerable<IMethod> GetConstructors(ITypeResolveContext context, Predicate<IMethod> filter) public override IEnumerable<IMethod> GetConstructors(ITypeResolveContext context, Predicate<IMethod> filter, GetMemberOptions options)
{ {
return EmptyList<IMethod>.Instance; return EmptyList<IMethod>.Instance;
} }
public override IEnumerable<IEvent> GetEvents(ITypeResolveContext context, Predicate<IEvent> filter) public override IEnumerable<IEvent> GetEvents(ITypeResolveContext context, Predicate<IEvent> filter, GetMemberOptions options)
{ {
return EmptyList<IEvent>.Instance; return EmptyList<IEvent>.Instance;
} }
public override IEnumerable<IField> GetFields(ITypeResolveContext context, Predicate<IField> filter) public override IEnumerable<IField> GetFields(ITypeResolveContext context, Predicate<IField> filter, GetMemberOptions options)
{ {
return EmptyList<IField>.Instance; return EmptyList<IField>.Instance;
} }
public override IEnumerable<IMethod> GetMethods(ITypeResolveContext context, Predicate<IMethod> filter) public override IEnumerable<IMethod> GetMethods(ITypeResolveContext context, Predicate<IMethod> filter, GetMemberOptions options)
{ {
return EmptyList<IMethod>.Instance; return EmptyList<IMethod>.Instance;
} }
public override IEnumerable<IMethod> GetMethods(IList<IType> typeArguments, ITypeResolveContext context, Predicate<IMethod> filter) public override IEnumerable<IMethod> GetMethods(IList<IType> typeArguments, ITypeResolveContext context, Predicate<IMethod> filter, GetMemberOptions options)
{ {
return EmptyList<IMethod>.Instance; return EmptyList<IMethod>.Instance;
} }
public override IEnumerable<IProperty> GetProperties(ITypeResolveContext context, Predicate<IProperty> filter) public override IEnumerable<IProperty> GetProperties(ITypeResolveContext context, Predicate<IProperty> filter, GetMemberOptions options)
{ {
return EmptyList<IProperty>.Instance; return EmptyList<IProperty>.Instance;
} }
public override IEnumerable<IMember> GetMembers(ITypeResolveContext context, Predicate<IMember> filter) public override IEnumerable<IMember> GetMembers(ITypeResolveContext context, Predicate<IMember> filter, GetMemberOptions options)
{ {
return EmptyList<IMember>.Instance; return EmptyList<IMember>.Instance;
} }

25
ICSharpCode.NRefactory/TypeSystem/IntersectionType.cs

@ -123,29 +123,34 @@ namespace ICSharpCode.NRefactory.TypeSystem
return types; return types;
} }
public override IEnumerable<IMethod> GetMethods(ITypeResolveContext context, Predicate<IMethod> filter) public override IEnumerable<IMethod> GetMethods(ITypeResolveContext context, Predicate<IMethod> filter, GetMemberOptions options)
{ {
return ParameterizedType.GetMethods(this, context, FilterNonStatic(filter)); return GetMembersHelper.GetMethods(this, context, FilterNonStatic(filter), options);
} }
public override IEnumerable<IProperty> GetProperties(ITypeResolveContext context, Predicate<IProperty> filter) public override IEnumerable<IMethod> GetMethods(IList<IType> typeArguments, ITypeResolveContext context, Predicate<IMethod> filter, GetMemberOptions options)
{ {
return ParameterizedType.GetProperties(this, context, FilterNonStatic(filter)); return GetMembersHelper.GetMethods(this, typeArguments, context, filter, options);
} }
public override IEnumerable<IField> GetFields(ITypeResolveContext context, Predicate<IField> filter) public override IEnumerable<IProperty> GetProperties(ITypeResolveContext context, Predicate<IProperty> filter, GetMemberOptions options)
{ {
return ParameterizedType.GetFields(this, context, FilterNonStatic(filter)); return GetMembersHelper.GetProperties(this, context, FilterNonStatic(filter), options);
} }
public override IEnumerable<IEvent> GetEvents(ITypeResolveContext context, Predicate<IEvent> filter) public override IEnumerable<IField> GetFields(ITypeResolveContext context, Predicate<IField> filter, GetMemberOptions options)
{ {
return ParameterizedType.GetEvents(this, context, FilterNonStatic(filter)); return GetMembersHelper.GetFields(this, context, FilterNonStatic(filter), options);
} }
public override IEnumerable<IMember> GetMembers(ITypeResolveContext context, Predicate<IMember> filter) public override IEnumerable<IEvent> GetEvents(ITypeResolveContext context, Predicate<IEvent> filter, GetMemberOptions options)
{ {
return ParameterizedType.GetMembers(this, context, FilterNonStatic(filter)); return GetMembersHelper.GetEvents(this, context, FilterNonStatic(filter), options);
}
public override IEnumerable<IMember> GetMembers(ITypeResolveContext context, Predicate<IMember> filter, GetMemberOptions options)
{
return GetMembersHelper.GetMembers(this, context, FilterNonStatic(filter), options);
} }
static Predicate<T> FilterNonStatic<T>(Predicate<T> filter) where T : class, IMember static Predicate<T> FilterNonStatic<T>(Predicate<T> filter) where T : class, IMember

6
ICSharpCode.NRefactory/TypeSystem/NullableType.cs

@ -34,7 +34,7 @@ namespace ICSharpCode.NRefactory.TypeSystem
if (type == null) if (type == null)
throw new ArgumentNullException("type"); throw new ArgumentNullException("type");
ParameterizedType pt = type as ParameterizedType; ParameterizedType pt = type as ParameterizedType;
return pt != null && pt.TypeArguments.Count == 1 && pt.FullName == "System.Nullable"; return pt != null && pt.TypeParameterCount == 1 && pt.FullName == "System.Nullable";
} }
public static bool IsNonNullableValueType(IType type, ITypeResolveContext context) public static bool IsNonNullableValueType(IType type, ITypeResolveContext context)
@ -51,8 +51,8 @@ namespace ICSharpCode.NRefactory.TypeSystem
if (type == null) if (type == null)
throw new ArgumentNullException("type"); throw new ArgumentNullException("type");
ParameterizedType pt = type as ParameterizedType; ParameterizedType pt = type as ParameterizedType;
if (pt != null && pt.TypeArguments.Count == 1 && pt.FullName == "System.Nullable") if (pt != null && pt.TypeParameterCount == 1 && pt.FullName == "System.Nullable")
return pt.TypeArguments[0]; return pt.GetTypeArgument(0);
else else
return type; return type;
} }

281
ICSharpCode.NRefactory/TypeSystem/ParameterizedType.cs

@ -94,7 +94,7 @@ namespace ICSharpCode.NRefactory.TypeSystem
} }
public int TypeParameterCount { public int TypeParameterCount {
get { return genericType.TypeParameterCount; } get { return typeArguments.Length; }
} }
public string FullName { public string FullName {
@ -136,6 +136,14 @@ namespace ICSharpCode.NRefactory.TypeSystem
} }
} }
/// <summary>
/// Same as 'parameterizedType.TypeArguments[index]', but is a bit more efficient.
/// </summary>
internal IType GetTypeArgument(int index)
{
return typeArguments[index];
}
public ITypeDefinition GetDefinition() public ITypeDefinition GetDefinition()
{ {
return genericType.GetDefinition(); return genericType.GetDefinition();
@ -169,7 +177,7 @@ namespace ICSharpCode.NRefactory.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 TypeVisitor GetSubstitution(IList<IType> methodTypeArguments) public TypeParameterSubstitution GetSubstitution(IList<IType> methodTypeArguments)
{ {
return new TypeParameterSubstitution(typeArguments, methodTypeArguments); return new TypeParameterSubstitution(typeArguments, methodTypeArguments);
} }
@ -180,259 +188,76 @@ namespace ICSharpCode.NRefactory.TypeSystem
return genericType.GetBaseTypes(context).Select(t => t.AcceptVisitor(substitution)); return genericType.GetBaseTypes(context).Select(t => t.AcceptVisitor(substitution));
} }
public IEnumerable<IType> GetNestedTypes(ITypeResolveContext context, Predicate<ITypeDefinition> filter = null) public IEnumerable<IType> GetNestedTypes(ITypeResolveContext context, Predicate<ITypeDefinition> filter = null, GetMemberOptions options = GetMemberOptions.None)
{
return GetNestedTypes(this, context, filter);
}
public IEnumerable<IType> GetNestedTypes(IList<IType> typeArguments, ITypeResolveContext context, Predicate<ITypeDefinition> filter = null)
{
return GetNestedTypes(this, typeArguments, context, filter);
}
internal static IEnumerable<IType> GetNestedTypes(IType type, ITypeResolveContext context, Predicate<ITypeDefinition> filter)
{
return GetNestedTypes(type, null, context, filter);
}
internal static IEnumerable<IType> GetNestedTypes(IType type, IList<IType> nestedTypeArguments, ITypeResolveContext context, Predicate<ITypeDefinition> filter)
{
return type.GetNonInterfaceBaseTypes(context).SelectMany(t => GetNestedTypesInternal(t, nestedTypeArguments, context, filter));
}
static IEnumerable<IType> GetNestedTypesInternal(IType baseType, IList<IType> nestedTypeArguments, ITypeResolveContext context, Predicate<ITypeDefinition> filter)
{
ITypeDefinition baseTypeDef = baseType.GetDefinition();
if (baseTypeDef == null)
yield break;
int outerTypeParameterCount = baseTypeDef.TypeParameterCount;
ParameterizedType pt = baseType as ParameterizedType;
foreach (ITypeDefinition nestedType in baseTypeDef.NestedTypes) {
int totalTypeParameterCount = nestedType.TypeParameterCount;
if (nestedTypeArguments != null) {
if (totalTypeParameterCount - outerTypeParameterCount != nestedTypeArguments.Count)
continue;
}
if (!(filter == null || filter(nestedType)))
continue;
if (totalTypeParameterCount == 0 || (pt == null && totalTypeParameterCount == outerTypeParameterCount)) {
// The nested type has no new type parameters, and there are no type arguments
// to copy from the outer type
// -> we can directly return the nested type definition
yield return nestedType;
} else {
// We need to parameterize the nested type
IType[] newTypeArguments = new IType[totalTypeParameterCount];
for (int i = 0; i < outerTypeParameterCount; i++) {
newTypeArguments[i] = pt != null ? pt.typeArguments[i] : baseTypeDef.TypeParameters[i];
}
for (int i = outerTypeParameterCount; i < totalTypeParameterCount; i++) {
if (nestedTypeArguments != null)
newTypeArguments[i] = nestedTypeArguments[i - outerTypeParameterCount];
else
newTypeArguments[i] = SharedTypes.UnboundTypeArgument;
}
yield return new ParameterizedType(nestedType, newTypeArguments);
}
}
}
public IEnumerable<IMethod> GetConstructors(ITypeResolveContext context, Predicate<IMethod> filter = null)
{
var substitution = GetSubstitution();
List<IMethod> methods = genericType.GetConstructors(context, filter).ToList();
for (int i = 0; i < methods.Count; i++) {
methods[i] = new SpecializedMethod(this, methods[i], null, substitution, context);
}
return methods;
}
public IEnumerable<IMethod> GetMethods(ITypeResolveContext context, Predicate<IMethod> filter = null)
{
return GetMethods(this, context, filter);
}
public IEnumerable<IMethod> GetMethods(IList<IType> typeArguments, ITypeResolveContext context, Predicate<IMethod> filter = null)
{ {
return GetMethods(this, typeArguments, context, filter); if ((options & GetMemberOptions.ReturnMemberDefinitions) == GetMemberOptions.ReturnMemberDefinitions)
} return genericType.GetNestedTypes(context, filter, options);
internal static IEnumerable<IMethod> GetMethods(IType type, ITypeResolveContext context, Predicate<IMethod> filter)
{
return GetMethods(type, null, context, filter);
}
internal static IEnumerable<IMethod> GetMethods(IType type, IList<IType> typeArguments, ITypeResolveContext context, Predicate<IMethod> filter)
{
Predicate<IMethod> newFilter;
if (filter == null)
newFilter = m => !m.IsConstructor;
else else
newFilter = m => !m.IsConstructor && filter(m); return GetMembersHelper.GetNestedTypes(this, context, filter, options);
return type.GetNonInterfaceBaseTypes(context).SelectMany(t => GetMethodsInternal(t, typeArguments, context, newFilter));
}
static IEnumerable<IMethod> GetMethodsInternal(IType baseType, IList<IType> methodTypeArguments, ITypeResolveContext context, Predicate<IMethod> filter)
{
ITypeDefinition baseTypeDef = baseType.GetDefinition();
if (baseTypeDef == null)
yield break;
ParameterizedType pt = baseType as ParameterizedType;
if (pt != null || (methodTypeArguments != null && methodTypeArguments.Count > 0)) {
TypeVisitor substitution = null;
foreach (IMethod m in baseTypeDef.Methods) {
if (methodTypeArguments != null && methodTypeArguments.Count > 0) {
if (m.TypeParameters.Count != methodTypeArguments.Count)
continue;
}
if (!(filter == null || filter(m)))
continue;
if (substitution == null) {
substitution = new TypeParameterSubstitution(pt != null ? pt.typeArguments : null, methodTypeArguments);
}
yield return new SpecializedMethod(baseType, m, methodTypeArguments, substitution, context);
}
} else {
foreach (IMethod m in baseTypeDef.Methods) {
if (filter == null || filter(m))
yield return m;
}
}
}
public IEnumerable<IProperty> GetProperties(ITypeResolveContext context, Predicate<IProperty> filter = null)
{
return GetProperties(this, context, filter);
}
internal static IEnumerable<IProperty> GetProperties(IType type, ITypeResolveContext context, Predicate<IProperty> filter)
{
return type.GetNonInterfaceBaseTypes(context).SelectMany(t => GetPropertiesInternal(t, context, filter));
}
static IEnumerable<IProperty> GetPropertiesInternal(IType baseType, ITypeResolveContext context, Predicate<IProperty> filter)
{
ITypeDefinition baseTypeDef = baseType.GetDefinition();
if (baseTypeDef == null)
yield break;
ParameterizedType pt = baseType as ParameterizedType;
if (pt != null) {
TypeParameterSubstitution substitution = null;
foreach (IProperty p in baseTypeDef.Properties) {
if (!(filter == null || filter(p)))
continue;
if (substitution == null) {
substitution = pt.GetSubstitution();
}
yield return new SpecializedProperty(pt, p, substitution, context);
}
} else {
foreach (IProperty p in baseTypeDef.Properties) {
if (filter == null || filter(p))
yield return p;
}
}
}
public IEnumerable<IField> GetFields(ITypeResolveContext context, Predicate<IField> filter = null)
{
return GetFields(this, context, filter);
} }
internal static IEnumerable<IField> GetFields(IType type, ITypeResolveContext context, Predicate<IField> filter) public IEnumerable<IType> GetNestedTypes(IList<IType> typeArguments, ITypeResolveContext context, Predicate<ITypeDefinition> filter = null, GetMemberOptions options = GetMemberOptions.None)
{ {
return type.GetNonInterfaceBaseTypes(context).SelectMany(t => GetFieldsInternal(t, context, filter)); if ((options & GetMemberOptions.ReturnMemberDefinitions) == GetMemberOptions.ReturnMemberDefinitions)
return genericType.GetNestedTypes(typeArguments, context, filter, options);
else
return GetMembersHelper.GetNestedTypes(this, typeArguments, context, filter, options);
} }
static IEnumerable<IField> GetFieldsInternal(IType baseType, ITypeResolveContext context, Predicate<IField> filter) public IEnumerable<IMethod> GetConstructors(ITypeResolveContext context, Predicate<IMethod> filter = null, GetMemberOptions options = GetMemberOptions.IgnoreInheritedMembers)
{ {
ITypeDefinition baseTypeDef = baseType.GetDefinition(); if ((options & GetMemberOptions.ReturnMemberDefinitions) == GetMemberOptions.ReturnMemberDefinitions)
if (baseTypeDef == null) return genericType.GetConstructors(context, filter, options);
yield break; else
return GetMembersHelper.GetConstructors(this, context, filter, options);
ParameterizedType pt = baseType as ParameterizedType;
if (pt != null) {
TypeParameterSubstitution substitution = null;
foreach (IField f in baseTypeDef.Fields) {
if (!(filter == null || filter(f)))
continue;
if (substitution == null) {
substitution = pt.GetSubstitution();
}
yield return new SpecializedField(pt, f, substitution, context);
}
} else {
foreach (IField f in baseTypeDef.Fields) {
if (filter == null || filter(f))
yield return f;
}
}
} }
public IEnumerable<IEvent> GetEvents(ITypeResolveContext context, Predicate<IEvent> filter = null) public IEnumerable<IMethod> GetMethods(ITypeResolveContext context, Predicate<IMethod> filter = null, GetMemberOptions options = GetMemberOptions.None)
{ {
return GetEvents(this, context, filter); if ((options & GetMemberOptions.ReturnMemberDefinitions) == GetMemberOptions.ReturnMemberDefinitions)
return genericType.GetMethods(context, filter, options);
else
return GetMembersHelper.GetMethods(this, context, filter, options);
} }
internal static IEnumerable<IEvent> GetEvents(IType type, ITypeResolveContext context, Predicate<IEvent> filter) public IEnumerable<IMethod> GetMethods(IList<IType> typeArguments, ITypeResolveContext context, Predicate<IMethod> filter = null, GetMemberOptions options = GetMemberOptions.None)
{ {
return type.GetNonInterfaceBaseTypes(context).SelectMany(t => GetEventsInternal(t, context, filter)); if ((options & GetMemberOptions.ReturnMemberDefinitions) == GetMemberOptions.ReturnMemberDefinitions)
return genericType.GetMethods(typeArguments, context, filter, options);
else
return GetMembersHelper.GetMethods(this, typeArguments, context, filter, options);
} }
static IEnumerable<IEvent> GetEventsInternal(IType baseType, ITypeResolveContext context, Predicate<IEvent> filter) public IEnumerable<IProperty> GetProperties(ITypeResolveContext context, Predicate<IProperty> filter = null, GetMemberOptions options = GetMemberOptions.None)
{ {
ITypeDefinition baseTypeDef = baseType.GetDefinition(); if ((options & GetMemberOptions.ReturnMemberDefinitions) == GetMemberOptions.ReturnMemberDefinitions)
if (baseTypeDef == null) return genericType.GetProperties(context, filter, options);
yield break; else
return GetMembersHelper.GetProperties(this, context, filter, options);
ParameterizedType pt = baseType as ParameterizedType;
if (pt != null) {
TypeParameterSubstitution substitution = null;
foreach (IEvent e in baseTypeDef.Events) {
if (!(filter == null || filter(e)))
continue;
if (substitution == null) {
substitution = pt.GetSubstitution();
}
yield return new SpecializedEvent(pt, e, substitution, context);
}
} else {
foreach (IEvent e in baseTypeDef.Events) {
if (filter == null || filter(e))
yield return e;
}
}
} }
public IEnumerable<IMember> GetMembers(ITypeResolveContext context, Predicate<IMember> filter = null) public IEnumerable<IField> GetFields(ITypeResolveContext context, Predicate<IField> filter = null, GetMemberOptions options = GetMemberOptions.None)
{ {
return GetMembers(this, context, filter); if ((options & GetMemberOptions.ReturnMemberDefinitions) == GetMemberOptions.ReturnMemberDefinitions)
return genericType.GetFields(context, filter, options);
else
return GetMembersHelper.GetFields(this, context, filter, options);
} }
internal static IEnumerable<IMember> GetMembers(IType type, ITypeResolveContext context, Predicate<IMember> filter) public IEnumerable<IEvent> GetEvents(ITypeResolveContext context, Predicate<IEvent> filter = null, GetMemberOptions options = GetMemberOptions.None)
{ {
Predicate<IMethod> methodFilter; if ((options & GetMemberOptions.ReturnMemberDefinitions) == GetMemberOptions.ReturnMemberDefinitions)
if (filter == null) return genericType.GetEvents(context, filter, options);
methodFilter = m => !m.IsConstructor;
else else
methodFilter = m => !m.IsConstructor && filter(m); return GetMembersHelper.GetEvents(this, context, filter, options);
return type.GetNonInterfaceBaseTypes(context).SelectMany(t => GetMembersInternal(t, context, filter));
} }
static IEnumerable<IMember> GetMembersInternal(IType baseType, ITypeResolveContext context, Predicate<IMember> filter) public IEnumerable<IMember> GetMembers(ITypeResolveContext context, Predicate<IMember> filter = null, GetMemberOptions options = GetMemberOptions.None)
{ {
foreach (var m in GetMethodsInternal(baseType, null, context, filter)) if ((options & GetMemberOptions.ReturnMemberDefinitions) == GetMemberOptions.ReturnMemberDefinitions)
yield return m; return genericType.GetMembers(context, filter, options);
foreach (var m in GetPropertiesInternal(baseType, context, filter)) else
yield return m; return GetMembersHelper.GetMembers(this, context, filter, options);
foreach (var m in GetFieldsInternal(baseType, context, filter))
yield return m;
foreach (var m in GetEventsInternal(baseType, context, filter))
yield return m;
} }
public override bool Equals(object obj) public override bool Equals(object obj)

2
ICSharpCode.NRefactory/TypeSystem/PointerType.cs

@ -22,7 +22,7 @@ using ICSharpCode.NRefactory.TypeSystem.Implementation;
namespace ICSharpCode.NRefactory.TypeSystem namespace ICSharpCode.NRefactory.TypeSystem
{ {
public class PointerType : TypeWithElementType public sealed class PointerType : TypeWithElementType
{ {
public PointerType(IType elementType) : base(elementType) public PointerType(IType elementType) : base(elementType)
{ {

90
ICSharpCode.NRefactory/Utils/EmptyList.cs

@ -17,12 +17,98 @@
// DEALINGS IN THE SOFTWARE. // DEALINGS IN THE SOFTWARE.
using System; using System;
using System.Collections;
using System.Collections.Generic;
using System.Collections.ObjectModel; using System.Collections.ObjectModel;
namespace ICSharpCode.NRefactory namespace ICSharpCode.NRefactory
{ {
static class EmptyList<T> sealed class EmptyList<T> : IList<T>, IEnumerator<T>
{ {
public static readonly ReadOnlyCollection<T> Instance = new ReadOnlyCollection<T>(new T[0]); public static readonly IList<T> Instance = new EmptyList<T>();
private EmptyList() {}
T IList<T>.this[int index] {
get { throw new IndexOutOfRangeException(); }
set { throw new IndexOutOfRangeException(); }
}
int ICollection<T>.Count {
get { return 0; }
}
bool ICollection<T>.IsReadOnly {
get { return true; }
}
int IList<T>.IndexOf(T item)
{
return -1;
}
void IList<T>.Insert(int index, T item)
{
throw new NotSupportedException();
}
void IList<T>.RemoveAt(int index)
{
throw new NotSupportedException();
}
void ICollection<T>.Add(T item)
{
throw new NotSupportedException();
}
void ICollection<T>.Clear()
{
}
bool ICollection<T>.Contains(T item)
{
return false;
}
void ICollection<T>.CopyTo(T[] array, int arrayIndex)
{
}
bool ICollection<T>.Remove(T item)
{
return false;
}
IEnumerator<T> IEnumerable<T>.GetEnumerator()
{
return this;
}
System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
{
return this;
}
T IEnumerator<T>.Current {
get { return default(T); }
}
object IEnumerator.Current {
get { return default(T); }
}
void IDisposable.Dispose()
{
}
bool IEnumerator.MoveNext()
{
return false;
}
void IEnumerator.Reset()
{
}
} }
} }

9
ICSharpCode.NRefactory/Utils/ExtensionMethods.cs

@ -31,5 +31,14 @@ namespace ICSharpCode.NRefactory.Utils
foreach (T item in input) foreach (T item in input)
target.Add(item); target.Add(item);
} }
public static Predicate<T> And<T>(this Predicate<T> filter1, Predicate<T> filter2)
{
if (filter1 == null)
return filter2;
if (filter2 == null)
return filter1;
return m => filter1(m) && filter2(m);
}
} }
} }

Loading…
Cancel
Save