Browse Source

Fixed resolving partial method definitions.

newNRvisualizers
Daniel Grunwald 14 years ago
parent
commit
cf331bb4af
  1. 10
      ICSharpCode.NRefactory.CSharp/Resolver/ResolveVisitor.cs
  2. 48
      ICSharpCode.NRefactory.Tests/CSharp/Resolver/MemberLookupTests.cs
  3. 101
      ICSharpCode.NRefactory/TypeSystem/Implementation/DefaultResolvedTypeDefinition.cs

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

@ -653,7 +653,15 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver @@ -653,7 +653,15 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
ITypeDefinition typeDef = resolver.CurrentTypeDefinition;
if (typeDef == null)
return null;
return typeDef.GetMembers(m => m.ParsedFile == parsedFile && m.Region.IsInside(location), GetMemberOptions.IgnoreInheritedMembers | GetMemberOptions.ReturnMemberDefinitions).FirstOrDefault();
return typeDef.GetMembers(
delegate (IUnresolvedMember m) {
if (m.ParsedFile != parsedFile)
return false;
DomRegion region = m.Region;
return !region.IsEmpty && region.Begin <= location && region.End > location;
},
GetMemberOptions.IgnoreInheritedMembers | GetMemberOptions.ReturnMemberDefinitions
).FirstOrDefault();
}
ResolveResult IAstVisitor<ResolveResult>.VisitVariableInitializer(VariableInitializer variableInitializer)

48
ICSharpCode.NRefactory.Tests/CSharp/Resolver/MemberLookupTests.cs

@ -363,5 +363,53 @@ class TestClass { @@ -363,5 +363,53 @@ class TestClass {
new[] { "System.Int32" },
((SpecializedMethod)conversion.Method).TypeArguments.Select(t => t.ReflectionName).ToArray());
}
[Test]
public void PartialMethod_WithoutImplementation()
{
string program = @"using System;
class TestClass {
$partial void M();$
}";
var mrr = Resolve<MemberResolveResult>(program);
Assert.AreEqual("TestClass.M", mrr.Member.FullName);
}
[Test]
public void PartialMethod_Declaration()
{
string program = @"using System;
class TestClass {
$partial void M();$
partial void M() {}
}";
var mrr = Resolve<MemberResolveResult>(program);
Assert.AreEqual("TestClass.M", mrr.Member.FullName);
}
[Test]
public void PartialMethod_Implementation()
{
string program = @"using System;
class TestClass {
partial void M();
$partial void M() {}$
}";
var mrr = Resolve<MemberResolveResult>(program);
Assert.AreEqual("TestClass.M", mrr.Member.FullName);
}
[Test]
public void MembersWithoutWhitespace()
{
string program = @"using System;
class TestClass {
void A();$void B();$void C();
}";
var mrr = Resolve<MemberResolveResult>(program);
Assert.AreEqual("TestClass.B", mrr.Member.FullName);
}
}
}

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

@ -149,17 +149,21 @@ namespace ICSharpCode.NRefactory.TypeSystem.Implementation @@ -149,17 +149,21 @@ namespace ICSharpCode.NRefactory.TypeSystem.Implementation
internal readonly ITypeResolveContext[] contextPerMember;
internal readonly IUnresolvedMember[] unresolvedMembers;
internal readonly IMember[] resolvedMembers;
internal readonly int NonPartialMemberCount;
public MemberList(ITypeResolveContext[] contextPerMember, IUnresolvedMember[] unresolvedMembers, List<PartialMethodInfo> partialMethodInfos)
public MemberList(List<ITypeResolveContext> contextPerMember, List<IUnresolvedMember> unresolvedNonPartialMembers, List<PartialMethodInfo> partialMethodInfos)
{
this.contextPerMember = contextPerMember;
this.unresolvedMembers = unresolvedMembers;
this.resolvedMembers = new IMember[unresolvedMembers.Length];
if (partialMethodInfos != null) {
foreach (var info in partialMethodInfos) {
unresolvedMembers[info.MemberIndex] = info.Parts[0];
contextPerMember[info.MemberIndex] = info.PrimaryContext;
resolvedMembers[info.MemberIndex] = DefaultResolvedMethod.CreateFromMultipleParts(
this.NonPartialMemberCount = unresolvedNonPartialMembers.Count;
this.contextPerMember = contextPerMember.ToArray();
this.unresolvedMembers = unresolvedNonPartialMembers.ToArray();
if (partialMethodInfos == null) {
this.resolvedMembers = new IMember[unresolvedNonPartialMembers.Count];
} else {
this.resolvedMembers = new IMember[unresolvedNonPartialMembers.Count + partialMethodInfos.Count];
for (int i = 0; i < partialMethodInfos.Count; i++) {
var info = partialMethodInfos[i];
int memberIndex = NonPartialMemberCount + i;
resolvedMembers[memberIndex] = DefaultResolvedMethod.CreateFromMultipleParts(
info.Parts.ToArray(), info.PrimaryContext, false);
}
}
@ -178,7 +182,7 @@ namespace ICSharpCode.NRefactory.TypeSystem.Implementation @@ -178,7 +182,7 @@ namespace ICSharpCode.NRefactory.TypeSystem.Implementation
}
public int Count {
get { return unresolvedMembers.Length; }
get { return resolvedMembers.Length; }
}
bool ICollection<IMember>.IsReadOnly {
@ -249,16 +253,14 @@ namespace ICSharpCode.NRefactory.TypeSystem.Implementation @@ -249,16 +253,14 @@ namespace ICSharpCode.NRefactory.TypeSystem.Implementation
public readonly string Name;
public readonly int TypeParameterCount;
public readonly IList<IParameter> Parameters;
public readonly int MemberIndex;
public readonly List<IUnresolvedMethod> Parts = new List<IUnresolvedMethod>();
public ITypeResolveContext PrimaryContext;
public PartialMethodInfo(IUnresolvedMethod method, ITypeResolveContext context, int memberIndex)
public PartialMethodInfo(IUnresolvedMethod method, ITypeResolveContext context)
{
this.Name = method.Name;
this.TypeParameterCount = method.TypeParameters.Count;
this.Parameters = method.Parameters.CreateResolvedParameters(context);
this.MemberIndex = memberIndex;
this.Parts.Add(method);
this.PrimaryContext = context;
}
@ -304,7 +306,7 @@ namespace ICSharpCode.NRefactory.TypeSystem.Implementation @@ -304,7 +306,7 @@ namespace ICSharpCode.NRefactory.TypeSystem.Implementation
// Merge partial method declaration and implementation
if (partialMethodInfos == null)
partialMethodInfos = new List<PartialMethodInfo>();
PartialMethodInfo newInfo = new PartialMethodInfo(method, contextForPart, unresolvedMembers.Count);
PartialMethodInfo newInfo = new PartialMethodInfo(method, contextForPart);
PartialMethodInfo existingInfo = null;
foreach (var info in partialMethodInfos) {
if (newInfo.IsSameSignature(info, Compilation.NameComparer)) {
@ -315,14 +317,13 @@ namespace ICSharpCode.NRefactory.TypeSystem.Implementation @@ -315,14 +317,13 @@ namespace ICSharpCode.NRefactory.TypeSystem.Implementation
if (existingInfo != null) {
// Add the unresolved method to the PartialMethodInfo:
existingInfo.AddPart(method, contextForPart);
// We handled this unresolved method; do not add it to unresolvedMembers.
continue;
} else {
partialMethodInfos.Add(newInfo);
}
} else {
unresolvedMembers.Add(member);
contextPerMember.Add(contextForPart);
}
unresolvedMembers.Add(member);
contextPerMember.Add(contextForPart);
}
DefaultUnresolvedTypeDefinition dutd = part as DefaultUnresolvedTypeDefinition;
@ -339,7 +340,7 @@ namespace ICSharpCode.NRefactory.TypeSystem.Implementation @@ -339,7 +340,7 @@ namespace ICSharpCode.NRefactory.TypeSystem.Implementation
unresolvedMembers.Add(DefaultUnresolvedMethod.CreateDefaultConstructor(parts[0]));
}
}
result = new MemberList(contextPerMember.ToArray(), unresolvedMembers.ToArray(), partialMethodInfos);
result = new MemberList(contextPerMember, unresolvedMembers, partialMethodInfos);
return LazyInit.GetOrSet(ref this.memberList, result);
}
@ -350,7 +351,7 @@ namespace ICSharpCode.NRefactory.TypeSystem.Implementation @@ -350,7 +351,7 @@ namespace ICSharpCode.NRefactory.TypeSystem.Implementation
public IEnumerable<IField> Fields {
get {
var members = GetMemberList();
for (int i = 0; i < members.Count; i++) {
for (int i = 0; i < members.unresolvedMembers.Length; i++) {
if (members.unresolvedMembers[i].EntityType == EntityType.Field)
yield return (IField)members[i];
}
@ -360,17 +361,20 @@ namespace ICSharpCode.NRefactory.TypeSystem.Implementation @@ -360,17 +361,20 @@ namespace ICSharpCode.NRefactory.TypeSystem.Implementation
public IEnumerable<IMethod> Methods {
get {
var members = GetMemberList();
for (int i = 0; i < members.Count; i++) {
for (int i = 0; i < members.unresolvedMembers.Length; i++) {
if (members.unresolvedMembers[i] is IUnresolvedMethod)
yield return (IMethod)members[i];
}
for (int i = members.unresolvedMembers.Length; i < members.Count; i++) {
yield return (IMethod)members[i];
}
}
}
public IEnumerable<IProperty> Properties {
get {
var members = GetMemberList();
for (int i = 0; i < members.Count; i++) {
for (int i = 0; i < members.unresolvedMembers.Length; i++) {
switch (members.unresolvedMembers[i].EntityType) {
case EntityType.Property:
case EntityType.Indexer:
@ -384,7 +388,7 @@ namespace ICSharpCode.NRefactory.TypeSystem.Implementation @@ -384,7 +388,7 @@ namespace ICSharpCode.NRefactory.TypeSystem.Implementation
public IEnumerable<IEvent> Events {
get {
var members = GetMemberList();
for (int i = 0; i < members.Count; i++) {
for (int i = 0; i < members.unresolvedMembers.Length; i++) {
if (members.unresolvedMembers[i].EntityType == EntityType.Event)
yield return (IEvent)members[i];
}
@ -710,17 +714,52 @@ namespace ICSharpCode.NRefactory.TypeSystem.Implementation @@ -710,17 +714,52 @@ namespace ICSharpCode.NRefactory.TypeSystem.Implementation
IEnumerable<IMember> GetFilteredMembers(Predicate<IUnresolvedMember> filter)
{
var members = GetMemberList();
for (int i = 0; i < members.Count; i++) {
for (int i = 0; i < members.unresolvedMembers.Length; i++) {
if (filter == null || filter(members.unresolvedMembers[i])) {
yield return members[i];
}
}
for (int i = members.unresolvedMembers.Length; i < members.Count; i++) {
var method = (IMethod)members[i];
bool ok = false;
foreach (var part in method.Parts) {
if (filter == null || filter(part)) {
ok = true;
break;
}
}
if (ok)
yield return method;
}
}
IEnumerable<IMethod> GetFilteredMethods(Predicate<IUnresolvedMethod> filter)
{
var members = GetMemberList();
for (int i = 0; i < members.unresolvedMembers.Length; i++) {
IUnresolvedMethod unresolved = members.unresolvedMembers[i] as IUnresolvedMethod;
if (unresolved != null && (filter == null || filter(unresolved))) {
yield return (IMethod)members[i];
}
}
for (int i = members.unresolvedMembers.Length; i < members.Count; i++) {
var method = (IMethod)members[i];
bool ok = false;
foreach (var part in method.Parts) {
if (filter == null || filter(part)) {
ok = true;
break;
}
}
if (ok)
yield return method;
}
}
IEnumerable<TResolved> GetFilteredMembers<TUnresolved, TResolved>(Predicate<TUnresolved> filter) where TUnresolved : class, IUnresolvedMember where TResolved : class, IMember
IEnumerable<TResolved> GetFilteredNonMethods<TUnresolved, TResolved>(Predicate<TUnresolved> filter) where TUnresolved : class, IUnresolvedMember where TResolved : class, IMember
{
var members = GetMemberList();
for (int i = 0; i < members.Count; i++) {
for (int i = 0; i < members.unresolvedMembers.Length; i++) {
TUnresolved unresolved = members.unresolvedMembers[i] as TUnresolved;
if (unresolved != null && (filter == null || filter(unresolved))) {
yield return (TResolved)members[i];
@ -731,7 +770,7 @@ namespace ICSharpCode.NRefactory.TypeSystem.Implementation @@ -731,7 +770,7 @@ namespace ICSharpCode.NRefactory.TypeSystem.Implementation
public virtual IEnumerable<IMethod> GetMethods(Predicate<IUnresolvedMethod> filter = null, GetMemberOptions options = GetMemberOptions.None)
{
if ((options & GetMemberOptions.IgnoreInheritedMembers) == GetMemberOptions.IgnoreInheritedMembers) {
return GetFilteredMembers<IUnresolvedMethod, IMethod>(Utils.ExtensionMethods.And(m => !m.IsConstructor, filter));
return GetFilteredMethods(Utils.ExtensionMethods.And(m => !m.IsConstructor, filter));
} else {
return GetMembersHelper.GetMethods(this, filter, options);
}
@ -754,7 +793,7 @@ namespace ICSharpCode.NRefactory.TypeSystem.Implementation @@ -754,7 +793,7 @@ namespace ICSharpCode.NRefactory.TypeSystem.Implementation
return EmptyList<IMethod>.Instance;
}
if ((options & GetMemberOptions.IgnoreInheritedMembers) == GetMemberOptions.IgnoreInheritedMembers) {
return GetFilteredMembers<IUnresolvedMethod, IMethod>(Utils.ExtensionMethods.And(m => m.IsConstructor && !m.IsStatic, filter));
return GetFilteredMethods(Utils.ExtensionMethods.And(m => m.IsConstructor && !m.IsStatic, filter));
} else {
return GetMembersHelper.GetConstructors(this, filter, options);
}
@ -763,7 +802,7 @@ namespace ICSharpCode.NRefactory.TypeSystem.Implementation @@ -763,7 +802,7 @@ namespace ICSharpCode.NRefactory.TypeSystem.Implementation
public virtual IEnumerable<IProperty> GetProperties(Predicate<IUnresolvedProperty> filter = null, GetMemberOptions options = GetMemberOptions.None)
{
if ((options & GetMemberOptions.IgnoreInheritedMembers) == GetMemberOptions.IgnoreInheritedMembers) {
return GetFilteredMembers<IUnresolvedProperty, IProperty>(filter);
return GetFilteredNonMethods<IUnresolvedProperty, IProperty>(filter);
} else {
return GetMembersHelper.GetProperties(this, filter, options);
}
@ -772,7 +811,7 @@ namespace ICSharpCode.NRefactory.TypeSystem.Implementation @@ -772,7 +811,7 @@ namespace ICSharpCode.NRefactory.TypeSystem.Implementation
public virtual IEnumerable<IField> GetFields(Predicate<IUnresolvedField> filter = null, GetMemberOptions options = GetMemberOptions.None)
{
if ((options & GetMemberOptions.IgnoreInheritedMembers) == GetMemberOptions.IgnoreInheritedMembers) {
return GetFilteredMembers<IUnresolvedField, IField>(filter);
return GetFilteredNonMethods<IUnresolvedField, IField>(filter);
} else {
return GetMembersHelper.GetFields(this, filter, options);
}
@ -781,7 +820,7 @@ namespace ICSharpCode.NRefactory.TypeSystem.Implementation @@ -781,7 +820,7 @@ namespace ICSharpCode.NRefactory.TypeSystem.Implementation
public virtual IEnumerable<IEvent> GetEvents(Predicate<IUnresolvedEvent> filter = null, GetMemberOptions options = GetMemberOptions.None)
{
if ((options & GetMemberOptions.IgnoreInheritedMembers) == GetMemberOptions.IgnoreInheritedMembers) {
return GetFilteredMembers<IUnresolvedEvent, IEvent>(filter);
return GetFilteredNonMethods<IUnresolvedEvent, IEvent>(filter);
} else {
return GetMembersHelper.GetEvents(this, filter, options);
}

Loading…
Cancel
Save