Browse Source

Merge remote-tracking branch 'upstream/master' into mansheng

newNRvisualizers
Mansheng Yang 14 years ago
parent
commit
a1cbcc20b9
  1. 2
      ICSharpCode.NRefactory.CSharp/ICSharpCode.NRefactory.CSharp.csproj
  2. 25
      ICSharpCode.NRefactory.CSharp/Resolver/CSharpResolver.cs
  3. 73
      ICSharpCode.NRefactory.CSharp/Resolver/DynamicInvocationResolveResult.cs
  4. 57
      ICSharpCode.NRefactory.CSharp/Resolver/DynamicMemberResolveResult.cs
  5. 29
      ICSharpCode.NRefactory.CSharp/Resolver/ResolveVisitor.cs
  6. 2
      ICSharpCode.NRefactory.ConsistencyCheck/Program.cs
  7. 2
      ICSharpCode.NRefactory.ConsistencyCheck/ResolverTest.cs
  8. 103
      ICSharpCode.NRefactory.Tests/CSharp/Resolver/DynamicTests.cs
  9. 15
      ICSharpCode.NRefactory.Tests/CSharp/Resolver/MethodTests.cs
  10. 17
      ICSharpCode.NRefactory.Tests/CSharp/Resolver/UnaryOperatorTests.cs
  11. 2
      ICSharpCode.NRefactory.Tests/ICSharpCode.NRefactory.Tests.csproj
  12. 36
      ICSharpCode.NRefactory.Tests/TypeSystem/LazyLoadedCecilLoaderTests.cs
  13. 239
      ICSharpCode.NRefactory/TypeSystem/CecilLoader.cs
  14. 6
      ICSharpCode.NRefactory/TypeSystem/ITypeDefinition.cs
  15. 2
      ICSharpCode.NRefactory/TypeSystem/Implementation/AbstractUnresolvedEntity.cs
  16. 5
      ICSharpCode.NRefactory/TypeSystem/Implementation/DefaultResolvedTypeDefinition.cs

2
ICSharpCode.NRefactory.CSharp/ICSharpCode.NRefactory.CSharp.csproj

@ -286,6 +286,8 @@
<Compile Include="Refactoring\Script.cs" /> <Compile Include="Refactoring\Script.cs" />
<Compile Include="Refactoring\TypeSystemAstBuilder.cs" /> <Compile Include="Refactoring\TypeSystemAstBuilder.cs" />
<Compile Include="Resolver\CompositeResolveVisitorNavigator.cs" /> <Compile Include="Resolver\CompositeResolveVisitorNavigator.cs" />
<Compile Include="Resolver\DynamicInvocationResolveResult.cs" />
<Compile Include="Resolver\DynamicMemberResolveResult.cs" />
<Compile Include="Resolver\CSharpConversions.cs" /> <Compile Include="Resolver\CSharpConversions.cs" />
<Compile Include="Resolver\CSharpAstResolver.cs" /> <Compile Include="Resolver\CSharpAstResolver.cs" />
<Compile Include="Resolver\CSharpInvocationResolveResult.cs" /> <Compile Include="Resolver\CSharpInvocationResolveResult.cs" />

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

@ -119,6 +119,8 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
/// </summary> /// </summary>
public CSharpResolver WithCheckForOverflow(bool checkForOverflow) public CSharpResolver WithCheckForOverflow(bool checkForOverflow)
{ {
if (checkForOverflow == this.checkForOverflow)
return this;
return new CSharpResolver(compilation, conversions, context, checkForOverflow, isWithinLambdaExpression, currentTypeDefinitionCache, localVariableStack, objectInitializerStack); return new CSharpResolver(compilation, conversions, context, checkForOverflow, isWithinLambdaExpression, currentTypeDefinitionCache, localVariableStack, objectInitializerStack);
} }
@ -431,7 +433,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
// evaluate as (E)(~(U)x); // evaluate as (E)(~(U)x);
var U = compilation.FindType(expression.ConstantValue.GetType()); var U = compilation.FindType(expression.ConstantValue.GetType());
var unpackedEnum = new ConstantResolveResult(U, expression.ConstantValue); var unpackedEnum = new ConstantResolveResult(U, expression.ConstantValue);
return CheckErrorAndResolveCast(expression.Type, ResolveUnaryOperator(op, unpackedEnum)); return CheckErrorAndResolveUncheckedCast(expression.Type, ResolveUnaryOperator(op, unpackedEnum));
} else { } else {
return UnaryOperatorResolveResult(expression.Type, op, expression, isNullable); return UnaryOperatorResolveResult(expression.Type, op, expression, isNullable);
} }
@ -911,7 +913,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
rhs = ResolveCast(elementType, rhs); rhs = ResolveCast(elementType, rhs);
if (rhs.IsError) if (rhs.IsError)
return rhs; return rhs;
return CheckErrorAndResolveCast(elementType, ResolveBinaryOperator(BinaryOperatorType.Subtract, lhs, rhs)); return CheckErrorAndResolveUncheckedCast(elementType, ResolveBinaryOperator(BinaryOperatorType.Subtract, lhs, rhs));
} }
IType resultType = MakeNullable(elementType, isNullable); IType resultType = MakeNullable(elementType, isNullable);
return BinaryOperatorResolveResult(resultType, lhs, BinaryOperatorType.Subtract, rhs, isNullable); return BinaryOperatorResolveResult(resultType, lhs, BinaryOperatorType.Subtract, rhs, isNullable);
@ -937,7 +939,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
rhs = ResolveCast(elementType, rhs); rhs = ResolveCast(elementType, rhs);
if (rhs.IsError) if (rhs.IsError)
return rhs; return rhs;
return CheckErrorAndResolveCast(enumType, ResolveBinaryOperator(op, lhs, rhs)); return CheckErrorAndResolveUncheckedCast(enumType, ResolveBinaryOperator(op, lhs, rhs));
} }
IType resultType = MakeNullable(enumType, isNullable); IType resultType = MakeNullable(enumType, isNullable);
return BinaryOperatorResolveResult(resultType, lhs, op, rhs, isNullable); return BinaryOperatorResolveResult(resultType, lhs, op, rhs, isNullable);
@ -1260,7 +1262,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
{ {
if (c == Conversion.IdentityConversion) if (c == Conversion.IdentityConversion)
return rr; return rr;
else if (rr.IsCompileTimeConstant && c != Conversion.None) else if (rr.IsCompileTimeConstant && c != Conversion.None && !c.IsUserDefined)
return ResolveCast(targetType, rr); return ResolveCast(targetType, rr);
else else
return new ConversionResolveResult(targetType, rr, c, checkForOverflow); return new ConversionResolveResult(targetType, rr, c, checkForOverflow);
@ -1269,7 +1271,8 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
public ResolveResult ResolveCast(IType targetType, ResolveResult expression) public ResolveResult ResolveCast(IType targetType, ResolveResult expression)
{ {
// C# 4.0 spec: §7.7.6 Cast expressions // C# 4.0 spec: §7.7.6 Cast expressions
if (expression.IsCompileTimeConstant) { Conversion c = conversions.ExplicitConversion(expression, targetType);
if (expression.IsCompileTimeConstant && !c.IsUserDefined) {
TypeCode code = ReflectionHelper.GetTypeCode(targetType); TypeCode code = ReflectionHelper.GetTypeCode(targetType);
if (code >= TypeCode.Boolean && code <= TypeCode.Decimal && expression.ConstantValue != null) { if (code >= TypeCode.Boolean && code <= TypeCode.Decimal && expression.ConstantValue != null) {
try { try {
@ -1293,7 +1296,6 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
} }
} }
} }
Conversion c = conversions.ExplicitConversion(expression, targetType);
return new ConversionResolveResult(targetType, expression, c, checkForOverflow); return new ConversionResolveResult(targetType, expression, c, checkForOverflow);
} }
@ -1302,12 +1304,12 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
return Utils.CSharpPrimitiveCast.Cast(targetType, input, this.CheckForOverflow); return Utils.CSharpPrimitiveCast.Cast(targetType, input, this.CheckForOverflow);
} }
ResolveResult CheckErrorAndResolveCast(IType targetType, ResolveResult expression) ResolveResult CheckErrorAndResolveUncheckedCast(IType targetType, ResolveResult expression)
{ {
if (expression.IsError) if (expression.IsError)
return expression; return expression;
else else
return ResolveCast(targetType, expression); return WithCheckForOverflow(false).ResolveCast(targetType, expression);
} }
#endregion #endregion
@ -1596,7 +1598,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
} }
if (target.Type.Kind == TypeKind.Dynamic) if (target.Type.Kind == TypeKind.Dynamic)
return new ResolveResult(SpecialType.Dynamic); return new DynamicMemberResolveResult(target, identifier);
MemberLookup lookup = CreateMemberLookup(lookupMode); MemberLookup lookup = CreateMemberLookup(lookupMode);
ResolveResult result; ResolveResult result;
@ -1893,8 +1895,9 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
{ {
// C# 4.0 spec: §7.6.5 // C# 4.0 spec: §7.6.5
if (target.Type.Kind == TypeKind.Dynamic) if (target.Type.Kind == TypeKind.Dynamic) {
return new ResolveResult(SpecialType.Dynamic); return new DynamicInvocationResolveResult(target, arguments.Select((a, i) => new DynamicInvocationArgument(argumentNames != null ? argumentNames[i] : null, a)).ToList().AsReadOnly());
}
MethodGroupResolveResult mgrr = target as MethodGroupResolveResult; MethodGroupResolveResult mgrr = target as MethodGroupResolveResult;
if (mgrr != null) { if (mgrr != null) {

73
ICSharpCode.NRefactory.CSharp/Resolver/DynamicInvocationResolveResult.cs

@ -0,0 +1,73 @@
// 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.Globalization;
using System.Linq;
using ICSharpCode.NRefactory.Semantics;
using ICSharpCode.NRefactory.TypeSystem;
namespace ICSharpCode.NRefactory.CSharp.Resolver
{
/// <summary>
/// Represents a single argument in a dynamic invocation.
/// </summary>
public class DynamicInvocationArgument {
/// <summary>
/// Parameter name, if the argument is named. Null otherwise.
/// </summary>
public readonly string Name;
/// <summary>
/// Value of the argument.
/// </summary>
public readonly ResolveResult Value;
public DynamicInvocationArgument(string name, ResolveResult value) {
Name = name;
Value = value;
}
}
/// <summary>
/// Represents the result of an invocation of a member of a dynamic object.
/// </summary>
public class DynamicInvocationResolveResult : ResolveResult
{
/// <summary>
/// Target of the invocation (a dynamic object).
/// </summary>
public readonly ResolveResult Target;
/// <summary>
/// Arguments for the call.
/// </summary>
public readonly IList<DynamicInvocationArgument> Arguments;
public DynamicInvocationResolveResult(ResolveResult target, IList<DynamicInvocationArgument> arguments) : base(SpecialType.Dynamic) {
this.Target = target;
this.Arguments = arguments ?? EmptyList<DynamicInvocationArgument>.Instance;
}
public override string ToString()
{
return string.Format(CultureInfo.InvariantCulture, "[Dynamic invocation ]");
}
}
}

57
ICSharpCode.NRefactory.CSharp/Resolver/DynamicMemberResolveResult.cs

@ -0,0 +1,57 @@
// 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.Globalization;
using System.Linq;
using ICSharpCode.NRefactory.Semantics;
using ICSharpCode.NRefactory.TypeSystem;
namespace ICSharpCode.NRefactory.CSharp.Resolver
{
/// <summary>
/// Represents the result of an access to a member of a dynamic object.
/// </summary>
public class DynamicMemberResolveResult : ResolveResult
{
/// <summary>
/// Target of the member access (a dynamic object).
/// </summary>
public readonly ResolveResult Target;
/// <summary>
/// Name of the accessed member.
/// </summary>
public readonly string Member;
public DynamicMemberResolveResult(ResolveResult target, string member) : base(SpecialType.Dynamic) {
this.Target = target;
this.Member = member;
}
public override string ToString()
{
return string.Format(CultureInfo.InvariantCulture, "[Dynamic member '{0}']", Member);
}
public override IEnumerable<ResolveResult> GetChildResults() {
return new[] { Target };
}
}
}

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

@ -854,21 +854,20 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
resolver.CurrentTypeResolveContext, propertyOrIndexerDeclaration.EntityType, name, resolver.CurrentTypeResolveContext, propertyOrIndexerDeclaration.EntityType, name,
explicitInterfaceType, parameterTypeReferences: parameterTypeReferences); explicitInterfaceType, parameterTypeReferences: parameterTypeReferences);
} }
// We need to use the property as current member so that indexer parameters can be resolved correctly.
resolver = resolver.WithCurrentMember(member);
var resolverWithPropertyAsMember = resolver;
for (AstNode node = propertyOrIndexerDeclaration.FirstChild; node != null; node = node.NextSibling) { for (AstNode node = propertyOrIndexerDeclaration.FirstChild; node != null; node = node.NextSibling) {
if (node.Role == PropertyDeclaration.GetterRole && member is IProperty) { if (node.Role == PropertyDeclaration.GetterRole && member is IProperty) {
resolver = resolver.PushBlock();
resolver = resolver.WithCurrentMember(((IProperty)member).Getter); resolver = resolver.WithCurrentMember(((IProperty)member).Getter);
Scan(node); Scan(node);
resolver = resolver.PopBlock(); resolver = resolverWithPropertyAsMember;
} } else if (node.Role == PropertyDeclaration.SetterRole && member is IProperty) {
else if (node.Role == PropertyDeclaration.SetterRole && member is IProperty) {
resolver = resolver.PushBlock();
resolver = resolver.WithCurrentMember(((IProperty)member).Setter); resolver = resolver.WithCurrentMember(((IProperty)member).Setter);
Scan(node); Scan(node);
resolver = resolver.PopBlock(); resolver = resolverWithPropertyAsMember;
} } else {
else {
Scan(node); Scan(node);
} }
} }
@ -908,21 +907,19 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
explicitInterfaceAstType.ToTypeReference()); explicitInterfaceAstType.ToTypeReference());
} }
} }
resolver = resolver.WithCurrentMember(member);
var resolverWithEventAsMember = resolver;
for (AstNode node = eventDeclaration.FirstChild; node != null; node = node.NextSibling) { for (AstNode node = eventDeclaration.FirstChild; node != null; node = node.NextSibling) {
if (node.Role == CustomEventDeclaration.AddAccessorRole && member is IEvent) { if (node.Role == CustomEventDeclaration.AddAccessorRole && member is IEvent) {
resolver = resolver.PushBlock();
resolver = resolver.WithCurrentMember(((IEvent)member).AddAccessor); resolver = resolver.WithCurrentMember(((IEvent)member).AddAccessor);
Scan(node); Scan(node);
resolver = resolver.PopBlock(); resolver = resolverWithEventAsMember;
} } else if (node.Role == CustomEventDeclaration.RemoveAccessorRole && member is IEvent) {
else if (node.Role == CustomEventDeclaration.RemoveAccessorRole && member is IEvent) {
resolver = resolver.PushBlock();
resolver = resolver.WithCurrentMember(((IEvent)member).RemoveAccessor); resolver = resolver.WithCurrentMember(((IEvent)member).RemoveAccessor);
Scan(node); Scan(node);
resolver = resolver.PopBlock(); resolver = resolverWithEventAsMember;
} } else {
else {
Scan(node); Scan(node);
} }
} }

2
ICSharpCode.NRefactory.ConsistencyCheck/Program.cs

@ -57,7 +57,7 @@ namespace ICSharpCode.NRefactory.ConsistencyCheck
solution.AllFiles.Count(), solution.AllFiles.Count(),
solution.Projects.Count); solution.Projects.Count);
//using (new Timer("ID String test... ")) TypeSystemTests.IDStringConsistencyCheck(solution); using (new Timer("ID String test... ")) TypeSystemTests.IDStringConsistencyCheck(solution);
using (new Timer("Resolve unresolved members... ")) TypeSystemTests.ResolvedUnresolvedMembers(solution); using (new Timer("Resolve unresolved members... ")) TypeSystemTests.ResolvedUnresolvedMembers(solution);
//RunTestOnAllFiles("Roundtripping test", RoundtripTest.RunTest); //RunTestOnAllFiles("Roundtripping test", RoundtripTest.RunTest);
RunTestOnAllFiles("Resolver test", ResolverTest.RunTest); RunTestOnAllFiles("Resolver test", ResolverTest.RunTest);

2
ICSharpCode.NRefactory.ConsistencyCheck/ResolverTest.cs

@ -71,7 +71,7 @@ namespace ICSharpCode.NRefactory.ConsistencyCheck
if (CSharpAstResolver.IsUnresolvableNode(node)) if (CSharpAstResolver.IsUnresolvableNode(node))
throw new InvalidOperationException("Resolved unresolvable node"); throw new InvalidOperationException("Resolved unresolvable node");
if (!ParenthesizedExpression.ActsAsParenthesizedExpression(node)) if (!ParenthesizedExpression.ActsAsParenthesizedExpression(node))
if (!resolveResults.Add(result)) if (!resolveResults.Add(result) && result != ErrorResolveResult.UnknownError)
throw new InvalidOperationException("Duplicate resolve result"); throw new InvalidOperationException("Duplicate resolve result");
if (result.IsError && !allowErrors) { if (result.IsError && !allowErrors) {

103
ICSharpCode.NRefactory.Tests/CSharp/Resolver/DynamicTests.cs

@ -0,0 +1,103 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using ICSharpCode.NRefactory.Semantics;
using ICSharpCode.NRefactory.TypeSystem;
using NUnit.Framework;
namespace ICSharpCode.NRefactory.CSharp.Resolver {
[TestFixture]
public class DynamicTests : ResolverTestBase {
[Test]
public void AccessToDynamicMember() {
string program = @"using System;
class TestClass {
void F() {
dynamic obj = null;
$obj.SomeProperty$ = 10;
}
}";
var rr = Resolve<DynamicMemberResolveResult>(program);
Assert.That(rr.Type.Kind, Is.EqualTo(TypeKind.Dynamic));
Assert.That(rr.Target is LocalResolveResult && ((LocalResolveResult)rr.Target).Variable.Name == "obj");
Assert.That(rr.Member, Is.EqualTo("SomeProperty"));
}
[Test]
public void DynamicInvocation() {
string program = @"using System;
class TestClass {
void F() {
dynamic obj = null;
int a = 0;
string b = null;
$obj.SomeMethod(a, b)$;
}
}";
var rr = Resolve<DynamicInvocationResolveResult>(program);
Assert.That(rr.Type.Kind, Is.EqualTo(TypeKind.Dynamic));
Assert.That(rr.Target, Is.InstanceOf<DynamicMemberResolveResult>());
var dynamicMember = (DynamicMemberResolveResult)rr.Target;
Assert.That(dynamicMember.Target is LocalResolveResult && ((LocalResolveResult)dynamicMember.Target).Variable.Name == "obj");
Assert.That(dynamicMember.Member, Is.EqualTo("SomeMethod"));
Assert.That(rr.Arguments.Count, Is.EqualTo(2));
Assert.That(rr.Arguments[0].Name, Is.Null);
Assert.That(rr.Arguments[0].Value is LocalResolveResult && ((LocalResolveResult)rr.Arguments[0].Value).Variable.Name == "a");
Assert.That(rr.Arguments[1].Name, Is.Null);
Assert.That(rr.Arguments[1].Value is LocalResolveResult && ((LocalResolveResult)rr.Arguments[1].Value).Variable.Name == "b");
}
[Test]
public void DynamicInvocationWithNamedArguments() {
string program = @"using System;
class TestClass {
void F() {
dynamic obj = null;
int a = 0, x = 0;
string b = null;
$obj.SomeMethod(x, param1: a, param2: b)$;
}
}";
var rr = Resolve<DynamicInvocationResolveResult>(program);
Assert.That(rr.Type.Kind, Is.EqualTo(TypeKind.Dynamic));
Assert.That(rr.Target, Is.InstanceOf<DynamicMemberResolveResult>());
var dynamicMember = (DynamicMemberResolveResult)rr.Target;
Assert.That(dynamicMember.Target is LocalResolveResult && ((LocalResolveResult)dynamicMember.Target).Variable.Name == "obj");
Assert.That(dynamicMember.Member, Is.EqualTo("SomeMethod"));
Assert.That(rr.Arguments.Count, Is.EqualTo(3));
Assert.That(rr.Arguments[0].Name, Is.Null);
Assert.That(rr.Arguments[0].Value is LocalResolveResult && ((LocalResolveResult)rr.Arguments[0].Value).Variable.Name == "x");
Assert.That(rr.Arguments[1].Name, Is.EqualTo("param1"));
Assert.That(rr.Arguments[1].Value is LocalResolveResult && ((LocalResolveResult)rr.Arguments[1].Value).Variable.Name == "a");
Assert.That(rr.Arguments[2].Name, Is.EqualTo("param2"));
Assert.That(rr.Arguments[2].Value is LocalResolveResult && ((LocalResolveResult)rr.Arguments[2].Value).Variable.Name == "b");
}
[Test]
public void TwoDynamicInvocationsInARow() {
string program = @"using System;
class TestClass {
void F() {
dynamic obj = null;
int a = 0, b = 0;
$obj.SomeMethod(a)(b)$;
}
}";
var rr = Resolve<DynamicInvocationResolveResult>(program);
Assert.That(rr.Type.Kind, Is.EqualTo(TypeKind.Dynamic));
Assert.That(rr.Target, Is.InstanceOf<DynamicInvocationResolveResult>());
var innerInvocation = (DynamicInvocationResolveResult)rr.Target;
Assert.That(innerInvocation.Target, Is.InstanceOf<DynamicMemberResolveResult>());
var dynamicMember = (DynamicMemberResolveResult)innerInvocation.Target;
Assert.That(dynamicMember.Target is LocalResolveResult && ((LocalResolveResult)dynamicMember.Target).Variable.Name == "obj");
Assert.That(dynamicMember.Member, Is.EqualTo("SomeMethod"));
Assert.That(innerInvocation.Arguments.Count, Is.EqualTo(1));
Assert.That(innerInvocation.Arguments[0].Name, Is.Null);
Assert.That(innerInvocation.Arguments[0].Value is LocalResolveResult && ((LocalResolveResult)innerInvocation.Arguments[0].Value).Variable.Name == "a");
Assert.That(rr.Arguments.Count, Is.EqualTo(1));
Assert.That(rr.Arguments[0].Name, Is.Null);
Assert.That(rr.Arguments[0].Value is LocalResolveResult && ((LocalResolveResult)rr.Arguments[0].Value).Variable.Name == "b");
}
}
}

15
ICSharpCode.NRefactory.Tests/CSharp/Resolver/MethodTests.cs

@ -126,6 +126,21 @@ class TestClass {
Assert.IsTrue(ReferenceEquals(value1, value2)); Assert.IsTrue(ReferenceEquals(value1, value2));
} }
[Test]
public void ResolveParameterDeclarationInIndexer()
{
string code = @"using System;
class TestClass {
int[,] myField;
int this[$int i$, int j] {
get { return myField[i, j]; }
set { myField[i, j] = value; }
}
}";
var rr = Resolve<LocalResolveResult>(code);
Assert.IsTrue(rr.IsParameter);
}
[Test] [Test]
public void ParameterIdentityInEventAdder() public void ParameterIdentityInEventAdder()
{ {

17
ICSharpCode.NRefactory.Tests/CSharp/Resolver/UnaryOperatorTests.cs

@ -257,5 +257,22 @@ class Test {
Assert.IsFalse(irr.IsError); Assert.IsFalse(irr.IsError);
Assert.IsTrue(irr.IsLiftedOperator); Assert.IsTrue(irr.IsLiftedOperator);
} }
[Test]
public void UShortEnumNegation()
{
string program = @"
class Test {
enum UShortEnum : ushort { Three = 3 }
static void Inc() {
checked { // even in checked context, the implicit cast back to enum is unchecked
var a = $~UShortEnum.Three$;
}
}
}";
var rr = Resolve<ConstantResolveResult>(program);
Assert.IsFalse(rr.IsError);
Assert.AreEqual(unchecked( (ushort)~3 ), rr.ConstantValue);
}
} }
} }

2
ICSharpCode.NRefactory.Tests/ICSharpCode.NRefactory.Tests.csproj

@ -190,6 +190,7 @@
<Compile Include="CSharp\Resolver\CastTests.cs" /> <Compile Include="CSharp\Resolver\CastTests.cs" />
<Compile Include="CSharp\Resolver\ComTests.cs" /> <Compile Include="CSharp\Resolver\ComTests.cs" />
<Compile Include="CSharp\Resolver\ConditionalOperatorTests.cs" /> <Compile Include="CSharp\Resolver\ConditionalOperatorTests.cs" />
<Compile Include="CSharp\Resolver\DynamicTests.cs" />
<Compile Include="CSharp\Resolver\ExtensionMethodTests.cs" /> <Compile Include="CSharp\Resolver\ExtensionMethodTests.cs" />
<Compile Include="CSharp\Resolver\FindReferencesTest.cs" /> <Compile Include="CSharp\Resolver\FindReferencesTest.cs" />
<Compile Include="CSharp\Resolver\InvocationTests.cs" /> <Compile Include="CSharp\Resolver\InvocationTests.cs" />
@ -221,6 +222,7 @@
<Compile Include="TypeSystem\CecilLoaderTests.cs" /> <Compile Include="TypeSystem\CecilLoaderTests.cs" />
<Compile Include="TypeSystem\GetAllBaseTypesTest.cs" /> <Compile Include="TypeSystem\GetAllBaseTypesTest.cs" />
<Compile Include="TypeSystem\GetMembersTests.cs" /> <Compile Include="TypeSystem\GetMembersTests.cs" />
<Compile Include="TypeSystem\LazyLoadedCecilLoaderTests.cs" />
<Compile Include="TypeSystem\ReflectionHelperTests.cs" /> <Compile Include="TypeSystem\ReflectionHelperTests.cs" />
<Compile Include="TypeSystem\SerializedCecilLoaderTests.cs" /> <Compile Include="TypeSystem\SerializedCecilLoaderTests.cs" />
<Compile Include="TypeSystem\StructureTests.cs" /> <Compile Include="TypeSystem\StructureTests.cs" />

36
ICSharpCode.NRefactory.Tests/TypeSystem/LazyLoadedCecilLoaderTests.cs

@ -0,0 +1,36 @@
// 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 ICSharpCode.NRefactory.TypeSystem.Implementation;
using NUnit.Framework;
namespace ICSharpCode.NRefactory.TypeSystem
{
[TestFixture]
public class LazyLoadedCecilLoaderTests : TypeSystemTests
{
[TestFixtureSetUp]
public void FixtureSetUp()
{
CecilLoader loader = new CecilLoader() { IncludeInternalMembers = true, LazyLoad = true };
IUnresolvedAssembly pc = loader.LoadAssemblyFile(typeof(TestCase.SimplePublicClass).Assembly.Location);
base.compilation = new SimpleCompilation(pc, CecilLoaderTests.Mscorlib);
}
}
}

239
ICSharpCode.NRefactory/TypeSystem/CecilLoader.cs

@ -47,6 +47,16 @@ namespace ICSharpCode.NRefactory.TypeSystem
/// </summary> /// </summary>
public bool IncludeInternalMembers { get; set; } public bool IncludeInternalMembers { get; set; }
/// <summary>
/// Specifies whether to use lazy loading. The default is false.
/// If this property is set to true, the CecilLoader will not copy all the relevant information
/// out of the Cecil object model, but will maintain references to the Cecil objects.
/// This speeds up the loading process and avoids loading unnecessary information, but it causes
/// the Cecil objects to stay in memory (which can significantly increase memory usage).
/// It also prevents serialization of the Cecil-loaded type system.
/// </summary>
public bool LazyLoad { get; set; }
/// <summary> /// <summary>
/// Gets/Sets the documentation provider that is used to retrieve the XML documentation for all members. /// Gets/Sets the documentation provider that is used to retrieve the XML documentation for all members.
/// </summary> /// </summary>
@ -137,7 +147,7 @@ namespace ICSharpCode.NRefactory.TypeSystem
this.CancellationToken.ThrowIfCancellationRequested(); this.CancellationToken.ThrowIfCancellationRequested();
if (this.IncludeInternalMembers || (td.Attributes & TypeAttributes.VisibilityMask) == TypeAttributes.Public) { if (this.IncludeInternalMembers || (td.Attributes & TypeAttributes.VisibilityMask) == TypeAttributes.Public) {
string name = td.Name; string name = td.Name;
if (name.Length == 0 || name[0] == '<') if (name.Length == 0)
continue; continue;
var t = CreateTopLevelTypeDefinition(td); var t = CreateTopLevelTypeDefinition(td);
@ -166,6 +176,7 @@ namespace ICSharpCode.NRefactory.TypeSystem
/// This causes ReadTypeReference() to use <see cref="DefaultAssemblyReference.CurrentAssembly"/> for references /// This causes ReadTypeReference() to use <see cref="DefaultAssemblyReference.CurrentAssembly"/> for references
/// in that module. /// in that module.
/// </summary> /// </summary>
[CLSCompliant(false)]
public void SetCurrentModule(ModuleDefinition module) public void SetCurrentModule(ModuleDefinition module)
{ {
this.currentModule = module; this.currentModule = module;
@ -1449,65 +1460,76 @@ namespace ICSharpCode.NRefactory.TypeSystem
{ {
string name = ReflectionHelper.SplitTypeParameterCountFromReflectionName(typeDefinition.Name); string name = ReflectionHelper.SplitTypeParameterCountFromReflectionName(typeDefinition.Name);
var td = new DefaultUnresolvedTypeDefinition(typeDefinition.Namespace, name); var td = new DefaultUnresolvedTypeDefinition(typeDefinition.Namespace, name);
InitTypeParameters(typeDefinition, td); if (typeDefinition.HasGenericParameters)
InitTypeParameters(typeDefinition, td.TypeParameters);
return td; return td;
} }
static void InitTypeParameters(TypeDefinition typeDefinition, DefaultUnresolvedTypeDefinition td) static void InitTypeParameters(TypeDefinition typeDefinition, IList<IUnresolvedTypeParameter> typeParameters)
{ {
// Type parameters are initialized within the constructor so that the class can be put into the type storage // Type parameters are initialized within the constructor so that the class can be put into the type storage
// before the rest of the initialization runs - this allows it to be available for early binding as soon as possible. // before the rest of the initialization runs - this allows it to be available for early binding as soon as possible.
for (int i = 0; i < typeDefinition.GenericParameters.Count; i++) { for (int i = 0; i < typeDefinition.GenericParameters.Count; i++) {
if (typeDefinition.GenericParameters[i].Position != i) if (typeDefinition.GenericParameters[i].Position != i)
throw new InvalidOperationException("g.Position != i"); throw new InvalidOperationException("g.Position != i");
td.TypeParameters.Add(new DefaultUnresolvedTypeParameter( typeParameters.Add(new DefaultUnresolvedTypeParameter(
EntityType.TypeDefinition, i, typeDefinition.GenericParameters[i].Name)); EntityType.TypeDefinition, i, typeDefinition.GenericParameters[i].Name));
} }
} }
void InitTypeParameterConstraints(TypeDefinition typeDefinition, IList<IUnresolvedTypeParameter> typeParameters)
{
for (int i = 0; i < typeParameters.Count; i++) {
AddConstraints((DefaultUnresolvedTypeParameter)typeParameters[i], typeDefinition.GenericParameters[i]);
}
}
void InitTypeDefinition(TypeDefinition typeDefinition, DefaultUnresolvedTypeDefinition td) void InitTypeDefinition(TypeDefinition typeDefinition, DefaultUnresolvedTypeDefinition td)
{ {
td.Kind = GetTypeKind(typeDefinition);
InitTypeModifiers(typeDefinition, td); InitTypeModifiers(typeDefinition, td);
InitTypeParameterConstraints(typeDefinition, td.TypeParameters);
if (typeDefinition.HasGenericParameters) { // nested types can be initialized only after generic parameters were created
for (int i = 0; i < typeDefinition.GenericParameters.Count; i++) { InitNestedTypes(typeDefinition, td, td.NestedTypes);
AddConstraints((DefaultUnresolvedTypeParameter)td.TypeParameters[i], typeDefinition.GenericParameters[i]);
}
}
InitNestedTypes(typeDefinition, td); // nested types can be initialized only after generic parameters were created
AddAttributes(typeDefinition, td); AddAttributes(typeDefinition, td);
td.HasExtensionMethods = HasExtensionAttribute(typeDefinition); td.HasExtensionMethods = HasExtensionAttribute(typeDefinition);
InitBaseTypes(typeDefinition, td.BaseTypes);
td.AddDefaultConstructorIfRequired = (td.Kind == TypeKind.Struct || td.Kind == TypeKind.Enum);
InitMembers(typeDefinition, td, td.Members);
if (HasCecilReferences)
typeSystemTranslationTable[td] = typeDefinition;
if (this.InterningProvider != null) {
td.ApplyInterningProvider(this.InterningProvider);
}
td.Freeze();
}
void InitBaseTypes(TypeDefinition typeDefinition, IList<ITypeReference> baseTypes)
{
// set base classes // set base classes
if (typeDefinition.IsEnum) { if (typeDefinition.IsEnum) {
foreach (FieldDefinition enumField in typeDefinition.Fields) { foreach (FieldDefinition enumField in typeDefinition.Fields) {
if (!enumField.IsStatic) { if (!enumField.IsStatic) {
td.BaseTypes.Add(ReadTypeReference(enumField.FieldType)); baseTypes.Add(ReadTypeReference(enumField.FieldType));
break; break;
} }
} }
} else { } else {
if (typeDefinition.BaseType != null) { if (typeDefinition.BaseType != null) {
td.BaseTypes.Add(ReadTypeReference(typeDefinition.BaseType)); baseTypes.Add(ReadTypeReference(typeDefinition.BaseType));
} }
if (typeDefinition.HasInterfaces) { if (typeDefinition.HasInterfaces) {
foreach (TypeReference iface in typeDefinition.Interfaces) { foreach (TypeReference iface in typeDefinition.Interfaces) {
td.BaseTypes.Add(ReadTypeReference(iface)); baseTypes.Add(ReadTypeReference(iface));
} }
} }
} }
InitMembers(typeDefinition, td);
if (HasCecilReferences)
typeSystemTranslationTable[td] = typeDefinition;
if (this.InterningProvider != null) {
td.ApplyInterningProvider(this.InterningProvider);
}
td.Freeze();
} }
void InitNestedTypes(TypeDefinition typeDefinition, DefaultUnresolvedTypeDefinition td) void InitNestedTypes(TypeDefinition typeDefinition, IUnresolvedTypeDefinition declaringTypeDefinition, IList<IUnresolvedTypeDefinition> nestedTypes)
{ {
if (!typeDefinition.HasNestedTypes) if (!typeDefinition.HasNestedTypes)
return; return;
@ -1522,33 +1544,35 @@ namespace ICSharpCode.NRefactory.TypeSystem
int pos = name.LastIndexOf('/'); int pos = name.LastIndexOf('/');
if (pos > 0) if (pos > 0)
name = name.Substring(pos + 1); name = name.Substring(pos + 1);
if (name.Length == 0 || name[0] == '<')
continue;
name = ReflectionHelper.SplitTypeParameterCountFromReflectionName(name); name = ReflectionHelper.SplitTypeParameterCountFromReflectionName(name);
var nestedType = new DefaultUnresolvedTypeDefinition(td, name); var nestedType = new DefaultUnresolvedTypeDefinition(declaringTypeDefinition, name);
InitTypeParameters(nestedTypeDef, nestedType); InitTypeParameters(nestedTypeDef, nestedType.TypeParameters);
td.NestedTypes.Add(nestedType); nestedTypes.Add(nestedType);
InitTypeDefinition(nestedTypeDef, nestedType); InitTypeDefinition(nestedTypeDef, nestedType);
} }
} }
} }
static void InitTypeModifiers(TypeDefinition typeDefinition, DefaultUnresolvedTypeDefinition td) static TypeKind GetTypeKind(TypeDefinition typeDefinition)
{ {
// set classtype // set classtype
if (typeDefinition.IsInterface) { if (typeDefinition.IsInterface) {
td.Kind = TypeKind.Interface; return TypeKind.Interface;
} else if (typeDefinition.IsEnum) { } else if (typeDefinition.IsEnum) {
td.Kind = TypeKind.Enum; return TypeKind.Enum;
} else if (typeDefinition.IsValueType) { } else if (typeDefinition.IsValueType) {
td.Kind = TypeKind.Struct; return TypeKind.Struct;
} else if (IsDelegate(typeDefinition)) { } else if (IsDelegate(typeDefinition)) {
td.Kind = TypeKind.Delegate; return TypeKind.Delegate;
} else if (IsModule(typeDefinition)) { } else if (IsModule(typeDefinition)) {
td.Kind = TypeKind.Module; return TypeKind.Module;
} else { } else {
td.Kind = TypeKind.Class; return TypeKind.Class;
} }
}
static void InitTypeModifiers(TypeDefinition typeDefinition, AbstractUnresolvedEntity td)
{
td.IsSealed = typeDefinition.IsSealed; td.IsSealed = typeDefinition.IsSealed;
td.IsAbstract = typeDefinition.IsAbstract; td.IsAbstract = typeDefinition.IsAbstract;
switch (typeDefinition.Attributes & TypeAttributes.VisibilityMask) { switch (typeDefinition.Attributes & TypeAttributes.VisibilityMask) {
@ -1598,9 +1622,8 @@ namespace ICSharpCode.NRefactory.TypeSystem
return false; return false;
} }
void InitMembers(TypeDefinition typeDefinition, DefaultUnresolvedTypeDefinition td) void InitMembers(TypeDefinition typeDefinition, IUnresolvedTypeDefinition td, IList<IUnresolvedMember> members)
{ {
td.AddDefaultConstructorIfRequired = (td.Kind == TypeKind.Struct || td.Kind == TypeKind.Enum);
if (typeDefinition.HasMethods) { if (typeDefinition.HasMethods) {
foreach (MethodDefinition method in typeDefinition.Methods) { foreach (MethodDefinition method in typeDefinition.Methods) {
if (IsVisible(method.Attributes) && !IsAccessor(method.SemanticsAttributes)) { if (IsVisible(method.Attributes) && !IsAccessor(method.SemanticsAttributes)) {
@ -1611,14 +1634,14 @@ namespace ICSharpCode.NRefactory.TypeSystem
else if (method.Name.StartsWith("op_", StringComparison.Ordinal)) else if (method.Name.StartsWith("op_", StringComparison.Ordinal))
type = EntityType.Operator; type = EntityType.Operator;
} }
td.Members.Add(ReadMethod(method, td, type)); members.Add(ReadMethod(method, td, type));
} }
} }
} }
if (typeDefinition.HasFields) { if (typeDefinition.HasFields) {
foreach (FieldDefinition field in typeDefinition.Fields) { foreach (FieldDefinition field in typeDefinition.Fields) {
if (IsVisible(field.Attributes) && !field.IsSpecialName) { if (IsVisible(field.Attributes) && !field.IsSpecialName) {
td.Members.Add(ReadField(field, td)); members.Add(ReadField(field, td));
} }
} }
} }
@ -1634,14 +1657,14 @@ namespace ICSharpCode.NRefactory.TypeSystem
bool setterVisible = property.SetMethod != null && IsVisible(property.SetMethod.Attributes); bool setterVisible = property.SetMethod != null && IsVisible(property.SetMethod.Attributes);
if (getterVisible || setterVisible) { if (getterVisible || setterVisible) {
EntityType type = property.Name == defaultMemberName ? EntityType.Indexer : EntityType.Property; EntityType type = property.Name == defaultMemberName ? EntityType.Indexer : EntityType.Property;
td.Members.Add(ReadProperty(property, td, type)); members.Add(ReadProperty(property, td, type));
} }
} }
} }
if (typeDefinition.HasEvents) { if (typeDefinition.HasEvents) {
foreach (EventDefinition ev in typeDefinition.Events) { foreach (EventDefinition ev in typeDefinition.Events) {
if (ev.AddMethod != null && IsVisible(ev.AddMethod.Attributes)) { if (ev.AddMethod != null && IsVisible(ev.AddMethod.Attributes)) {
td.Members.Add(ReadEvent(ev, td)); members.Add(ReadEvent(ev, td));
} }
} }
} }
@ -1653,6 +1676,140 @@ namespace ICSharpCode.NRefactory.TypeSystem
} }
#endregion #endregion
#region Lazy-Loaded Type Definition
sealed class LazyCecilTypeDefinition : AbstractUnresolvedEntity, IUnresolvedTypeDefinition
{
readonly CecilLoader loader;
readonly string namespaceName;
readonly TypeDefinition cecilTypeDef;
readonly TypeKind kind;
readonly IList<IUnresolvedTypeParameter> typeParameters;
IList<ITypeReference> baseTypes;
IList<IUnresolvedTypeDefinition> nestedTypes;
IList<IUnresolvedMember> members;
public LazyCecilTypeDefinition(CecilLoader loader, TypeDefinition typeDefinition)
{
this.loader = loader;
this.cecilTypeDef = typeDefinition;
this.EntityType = EntityType.TypeDefinition;
this.namespaceName = cecilTypeDef.Namespace;
this.Name = ReflectionHelper.SplitTypeParameterCountFromReflectionName(cecilTypeDef.Name);
var tps = new List<IUnresolvedTypeParameter>();
InitTypeParameters(cecilTypeDef, tps);
this.typeParameters = FreezableHelper.FreezeList(tps);
this.kind = GetTypeKind(typeDefinition);
InitTypeModifiers(typeDefinition, this);
loader.InitTypeParameterConstraints(typeDefinition, typeParameters);
loader.AddAttributes(typeDefinition, this);
flags[FlagHasExtensionMethods] = HasExtensionAttribute(typeDefinition);
if (loader.HasCecilReferences)
loader.typeSystemTranslationTable[this] = typeDefinition;
if (loader.InterningProvider != null) {
this.ApplyInterningProvider(loader.InterningProvider);
}
this.Freeze();
}
public override string Namespace {
get { return namespaceName; }
set { throw new NotSupportedException(); }
}
public TypeKind Kind {
get { return kind; }
}
public IList<IUnresolvedTypeParameter> TypeParameters {
get { return typeParameters; }
}
public IList<ITypeReference> BaseTypes {
get {
var result = LazyInit.VolatileRead(ref this.baseTypes);
if (result != null) {
return result;
} else {
result = new List<ITypeReference>();
loader.InitBaseTypes(cecilTypeDef, result);
return LazyInit.GetOrSet(ref this.baseTypes, FreezableHelper.FreezeList(result));
}
}
}
public IList<IUnresolvedTypeDefinition> NestedTypes {
get {
var result = LazyInit.VolatileRead(ref this.nestedTypes);
if (result != null) {
return result;
} else {
result = new List<IUnresolvedTypeDefinition>();
loader.InitNestedTypes(cecilTypeDef, this, result);
return LazyInit.GetOrSet(ref this.nestedTypes, FreezableHelper.FreezeList(result));
}
}
}
public IList<IUnresolvedMember> Members {
get {
var result = LazyInit.VolatileRead(ref this.members);
if (result != null) {
return result;
} else {
result = new List<IUnresolvedMember>();
loader.InitMembers(cecilTypeDef, this, result);
return LazyInit.GetOrSet(ref this.members, FreezableHelper.FreezeList(result));
}
}
}
public IEnumerable<IUnresolvedMethod> Methods {
get { return Members.OfType<IUnresolvedMethod>(); }
}
public IEnumerable<IUnresolvedProperty> Properties {
get { return Members.OfType<IUnresolvedProperty>(); }
}
public IEnumerable<IUnresolvedField> Fields {
get { return Members.OfType<IUnresolvedField>(); }
}
public IEnumerable<IUnresolvedEvent> Events {
get { return Members.OfType<IUnresolvedEvent>(); }
}
public bool AddDefaultConstructorIfRequired {
get { return kind == TypeKind.Struct || kind == TypeKind.Enum; }
}
public bool? HasExtensionMethods {
get { return flags[FlagHasExtensionMethods]; }
// we always return true or false, never null.
// FlagHasNoExtensionMethods is unused in LazyCecilTypeDefinition
}
public IType Resolve(ITypeResolveContext context)
{
if (context == null)
throw new ArgumentNullException("context");
if (context.CurrentAssembly == null)
throw new ArgumentException("An ITypeDefinition cannot be resolved in a context without a current assembly.");
return context.CurrentAssembly.GetTypeDefinition(this)
?? (IType)new UnknownType(this.Namespace, this.Name, this.TypeParameters.Count);
}
public ITypeResolveContext CreateResolveContext(ITypeResolveContext parentContext)
{
return parentContext;
}
}
#endregion
#region Read Method #region Read Method
[CLSCompliant(false)] [CLSCompliant(false)]
public IUnresolvedMethod ReadMethod(MethodDefinition method, IUnresolvedTypeDefinition parentType, EntityType methodType = EntityType.Method) public IUnresolvedMethod ReadMethod(MethodDefinition method, IUnresolvedTypeDefinition parentType, EntityType methodType = EntityType.Method)

6
ICSharpCode.NRefactory/TypeSystem/ITypeDefinition.cs

@ -48,6 +48,12 @@ namespace ICSharpCode.NRefactory.TypeSystem
/// </summary> /// </summary>
bool? HasExtensionMethods { get; } bool? HasExtensionMethods { get; }
/// <summary>
/// Gets whether this unresolved type definition causes the addition of a default constructor
/// if no other constructor is present.
/// </summary>
bool AddDefaultConstructorIfRequired { get; }
/// <summary> /// <summary>
/// Looks up the resolved type definition from the <paramref name="context"/> corresponding to this unresolved /// Looks up the resolved type definition from the <paramref name="context"/> corresponding to this unresolved
/// type definition. /// type definition.

2
ICSharpCode.NRefactory/TypeSystem/Implementation/AbstractUnresolvedEntity.cs

@ -50,7 +50,7 @@ namespace ICSharpCode.NRefactory.TypeSystem.Implementation
internal const ushort FlagShadowing = 0x0008; internal const ushort FlagShadowing = 0x0008;
internal const ushort FlagSynthetic = 0x0010; internal const ushort FlagSynthetic = 0x0010;
internal const ushort FlagStatic = 0x0020; internal const ushort FlagStatic = 0x0020;
// flags for DefaultUnresolvedTypeDefinition // flags for DefaultUnresolvedTypeDefinition/LazyCecilTypeDefinition
internal const ushort FlagAddDefaultConstructorIfRequired = 0x0040; internal const ushort FlagAddDefaultConstructorIfRequired = 0x0040;
internal const ushort FlagHasExtensionMethods = 0x0080; internal const ushort FlagHasExtensionMethods = 0x0080;
internal const ushort FlagHasNoExtensionMethods = 0x0100; internal const ushort FlagHasNoExtensionMethods = 0x0100;

5
ICSharpCode.NRefactory/TypeSystem/Implementation/DefaultResolvedTypeDefinition.cs

@ -322,10 +322,7 @@ namespace ICSharpCode.NRefactory.TypeSystem.Implementation
} }
} }
DefaultUnresolvedTypeDefinition dutd = part as DefaultUnresolvedTypeDefinition; addDefaultConstructorIfRequired |= part.AddDefaultConstructorIfRequired;
if (dutd != null) {
addDefaultConstructorIfRequired |= dutd.AddDefaultConstructorIfRequired;
}
} }
if (addDefaultConstructorIfRequired) { if (addDefaultConstructorIfRequired) {
TypeKind kind = this.Kind; TypeKind kind = this.Kind;

Loading…
Cancel
Save