Browse Source

Fixed SD2-1095: Autogenerated code for IEnumerable generic interface does not compile

git-svn-id: svn://svn.sharpdevelop.net/sharpdevelop/trunk@2066 1ccf3a8d-04fe-1044-b7c0-cef0b8235c61
shortcuts
Daniel Grunwald 19 years ago
parent
commit
5d0fc5b83c
  1. 21
      src/AddIns/Misc/UnitTesting/Test/Utils/MockMember.cs
  2. 15
      src/AddIns/Misc/UnitTesting/Test/Utils/MockMethod.cs
  3. 12
      src/Main/Base/Project/Src/TextEditor/Commands/ClassBookmarkMenuBuilder.cs
  4. 2
      src/Main/Base/Project/Src/TextEditor/Commands/CodeGenerators/InterfaceImplementorCodeGenerator.cs
  5. 2
      src/Main/Base/Test/GenericResolverTests.cs
  6. 2
      src/Main/Base/Test/NRefactoryResolverTests.cs
  7. 36
      src/Main/Base/Test/SearchGenericClassTests.cs
  8. 1
      src/Main/ICSharpCode.SharpDevelop.Dom/Project/ICSharpCode.SharpDevelop.Dom.csproj
  9. 14
      src/Main/ICSharpCode.SharpDevelop.Dom/Project/Src/CecilReader.cs
  10. 6
      src/Main/ICSharpCode.SharpDevelop.Dom/Project/Src/ClassFinder.cs
  11. 31
      src/Main/ICSharpCode.SharpDevelop.Dom/Project/Src/Implementations/AbstractMember.cs
  12. 12
      src/Main/ICSharpCode.SharpDevelop.Dom/Project/Src/Implementations/ConstructedReturnType.cs
  13. 18
      src/Main/ICSharpCode.SharpDevelop.Dom/Project/Src/Implementations/DefaultEvent.cs
  14. 13
      src/Main/ICSharpCode.SharpDevelop.Dom/Project/Src/Implementations/DefaultMethod.cs
  15. 12
      src/Main/ICSharpCode.SharpDevelop.Dom/Project/Src/Implementations/DefaultProperty.cs
  16. 4
      src/Main/ICSharpCode.SharpDevelop.Dom/Project/Src/Implementations/DefaultReturnType.cs
  17. 17
      src/Main/ICSharpCode.SharpDevelop.Dom/Project/Src/Implementations/DefaultUsing.cs
  18. 55
      src/Main/ICSharpCode.SharpDevelop.Dom/Project/Src/Interfaces/ExplicitInterfaceImplementation.cs
  19. 4
      src/Main/ICSharpCode.SharpDevelop.Dom/Project/Src/Interfaces/IEvent.cs
  20. 18
      src/Main/ICSharpCode.SharpDevelop.Dom/Project/Src/Interfaces/IMember.cs
  21. 4
      src/Main/ICSharpCode.SharpDevelop.Dom/Project/Src/Interfaces/IMethod.cs
  22. 10
      src/Main/ICSharpCode.SharpDevelop.Dom/Project/Src/Interfaces/IUsing.cs
  23. 18
      src/Main/ICSharpCode.SharpDevelop.Dom/Project/Src/LanguageProperties.cs
  24. 6
      src/Main/ICSharpCode.SharpDevelop.Dom/Project/Src/ProjectContent/DefaultProjectContent.cs
  25. 114
      src/Main/ICSharpCode.SharpDevelop.Dom/Project/Src/Refactoring/CodeGenerator.cs
  26. 34
      src/Main/ICSharpCode.SharpDevelop.Dom/Project/Src/ReflectionLayer/DomPersistence.cs

21
src/AddIns/Misc/UnitTesting/Test/Utils/MockMember.cs

@ -211,5 +211,26 @@ namespace UnitTesting.Tests.Utils
{ {
throw new NotImplementedException(); throw new NotImplementedException();
} }
public IReturnType DeclaringTypeReference {
get {
throw new NotImplementedException();
}
set {
throw new NotImplementedException();
}
}
public DomRegion BodyRegion {
get {
throw new NotImplementedException();
}
}
public IList<ExplicitInterfaceImplementation> InterfaceImplementations {
get {
throw new NotImplementedException();
}
}
} }
} }

15
src/AddIns/Misc/UnitTesting/Test/Utils/MockMethod.cs

@ -262,5 +262,20 @@ namespace UnitTesting.Tests.Utils
{ {
throw new NotImplementedException(); throw new NotImplementedException();
} }
public IReturnType DeclaringTypeReference {
get {
throw new NotImplementedException();
}
set {
throw new NotImplementedException();
}
}
public IList<ExplicitInterfaceImplementation> InterfaceImplementations {
get {
throw new NotImplementedException();
}
}
} }
} }

12
src/Main/Base/Project/Src/TextEditor/Commands/ClassBookmarkMenuBuilder.cs

@ -174,7 +174,7 @@ namespace ICSharpCode.SharpDevelop.DefaultEditor.Commands
return b.ToString(); return b.ToString();
} }
void AddImplementInterfaceCommandItems(List<ToolStripItem> subItems, IClass c, bool explicitImpl, ModifierEnum modifier) void AddImplementInterfaceCommandItems(List<ToolStripItem> subItems, IClass c, bool explicitImpl)
{ {
CodeGenerator codeGen = c.ProjectContent.Language.CodeGenerator; CodeGenerator codeGen = c.ProjectContent.Language.CodeGenerator;
IAmbience ambience = AmbienceService.CurrentAmbience; IAmbience ambience = AmbienceService.CurrentAmbience;
@ -186,7 +186,7 @@ namespace ICSharpCode.SharpDevelop.DefaultEditor.Commands
EventHandler eh = delegate { EventHandler eh = delegate {
TextEditorDocument d = new TextEditorDocument(GetDocument(c)); TextEditorDocument d = new TextEditorDocument(GetDocument(c));
if (d != null) if (d != null)
codeGen.ImplementInterface(rtCopy, d, explicitImpl, modifier, c); codeGen.ImplementInterface(rtCopy, d, explicitImpl, c);
ParserService.ParseCurrentViewContent(); ParserService.ParseCurrentViewContent();
}; };
subItems.Add(new MenuCommand(ambience.Convert(interf), eh)); subItems.Add(new MenuCommand(ambience.Convert(interf), eh));
@ -200,16 +200,14 @@ namespace ICSharpCode.SharpDevelop.DefaultEditor.Commands
if (codeGen == null) return; if (codeGen == null) return;
List<ToolStripItem> subItems = new List<ToolStripItem>(); List<ToolStripItem> subItems = new List<ToolStripItem>();
if (c.ProjectContent.Language.SupportsImplicitInterfaceImplementation) { if (c.ProjectContent.Language.SupportsImplicitInterfaceImplementation) {
AddImplementInterfaceCommandItems(subItems, c, false, ModifierEnum.Public); AddImplementInterfaceCommandItems(subItems, c, false);
if (subItems.Count > 0) { if (subItems.Count > 0) {
list.Add(new ICSharpCode.Core.Menu("${res:SharpDevelop.Refactoring.ImplementInterfaceImplicit}", subItems.ToArray())); list.Add(new ICSharpCode.Core.Menu("${res:SharpDevelop.Refactoring.ImplementInterfaceImplicit}", subItems.ToArray()));
subItems = new List<ToolStripItem>(); subItems = new List<ToolStripItem>();
} }
AddImplementInterfaceCommandItems(subItems, c, true, ModifierEnum.None);
} else {
AddImplementInterfaceCommandItems(subItems, c, true, ModifierEnum.Public);
} }
AddImplementInterfaceCommandItems(subItems, c, true);
if (subItems.Count > 0) { if (subItems.Count > 0) {
if (c.ProjectContent.Language.SupportsImplicitInterfaceImplementation) { if (c.ProjectContent.Language.SupportsImplicitInterfaceImplementation) {
list.Add(new ICSharpCode.Core.Menu("${res:SharpDevelop.Refactoring.ImplementInterfaceExplicit}", subItems.ToArray())); list.Add(new ICSharpCode.Core.Menu("${res:SharpDevelop.Refactoring.ImplementInterfaceExplicit}", subItems.ToArray()));

2
src/Main/Base/Project/Src/TextEditor/Commands/CodeGenerators/InterfaceImplementorCodeGenerator.cs

@ -63,7 +63,7 @@ namespace ICSharpCode.SharpDevelop.DefaultEditor.Commands
foreach (ClassWrapper w in items) { foreach (ClassWrapper w in items) {
codeGen.ImplementInterface(nodes, w.ClassType, codeGen.ImplementInterface(nodes, w.ClassType,
!currentClass.ProjectContent.Language.SupportsImplicitInterfaceImplementation, !currentClass.ProjectContent.Language.SupportsImplicitInterfaceImplementation,
ModifierEnum.Public, currentClass); currentClass);
} }
} }

2
src/Main/Base/Test/GenericResolverTests.cs

@ -187,7 +187,7 @@ class DerivedClass<A,B> : BaseClass<B,A> {
#region CodeCompletion inside generic classes #region CodeCompletion inside generic classes
const string genericClass = @"using System; const string genericClass = @"using System;
public class GenericClass<T> where T : IDisposable public class GenericClass<T> where T : IDisposable {
void Method<G>(T par1, G par2) where G : IConvertible, IFormattable { void Method<G>(T par1, G par2) where G : IConvertible, IFormattable {
T var1; G var2; T var1; G var2;

2
src/Main/Base/Test/NRefactoryResolverTests.cs

@ -38,6 +38,7 @@ namespace ICSharpCode.SharpDevelop.Tests
NRefactoryASTConvertVisitor visitor = new NRefactoryASTConvertVisitor(pc); NRefactoryASTConvertVisitor visitor = new NRefactoryASTConvertVisitor(pc);
visitor.VisitCompilationUnit(p.CompilationUnit, null); visitor.VisitCompilationUnit(p.CompilationUnit, null);
visitor.Cu.FileName = fileName; visitor.Cu.FileName = fileName;
Assert.AreEqual(0, p.Errors.Count, "Parse error preparing compilation unit");
visitor.Cu.ErrorsDuringCompile = p.Errors.Count > 0; visitor.Cu.ErrorsDuringCompile = p.Errors.Count > 0;
foreach (IClass c in visitor.Cu.Classes) { foreach (IClass c in visitor.Cu.Classes) {
pc.AddClassToNamespaceList(c); pc.AddClassToNamespaceList(c);
@ -64,6 +65,7 @@ namespace ICSharpCode.SharpDevelop.Tests
NRefactoryASTConvertVisitor visitor = new NRefactoryASTConvertVisitor(pc); NRefactoryASTConvertVisitor visitor = new NRefactoryASTConvertVisitor(pc);
visitor.VisitCompilationUnit(p.CompilationUnit, null); visitor.VisitCompilationUnit(p.CompilationUnit, null);
visitor.Cu.FileName = fileName; visitor.Cu.FileName = fileName;
Assert.AreEqual(0, p.Errors.Count, "Parse error preparing compilation unit");
visitor.Cu.ErrorsDuringCompile = p.Errors.Count > 0; visitor.Cu.ErrorsDuringCompile = p.Errors.Count > 0;
foreach (IClass c in visitor.Cu.Classes) { foreach (IClass c in visitor.Cu.Classes) {
pc.AddClassToNamespaceList(c); pc.AddClassToNamespaceList(c);

36
src/Main/Base/Test/SearchGenericClassTests.cs

@ -19,18 +19,26 @@ namespace ICSharpCode.SharpDevelop.Tests
ProjectContentRegistry projectContentRegistry = ParserService.DefaultProjectContentRegistry; ProjectContentRegistry projectContentRegistry = ParserService.DefaultProjectContentRegistry;
#region Helper methods #region Helper methods
ICompilationUnit Prepare(LanguageProperties language) // usingMode: 0 = one using-statement for each namespace (correctly cased)
// 1 = mixture of using statements and default imports (incorrectly cased)
// 2 = all default imports (incorrectly cased)
ICompilationUnit Prepare(LanguageProperties language, int usingMode)
{ {
DefaultProjectContent pc = new DefaultProjectContent(); DefaultProjectContent pc = new DefaultProjectContent();
pc.ReferencedContents.Add(projectContentRegistry.Mscorlib); pc.ReferencedContents.Add(projectContentRegistry.Mscorlib);
pc.Language = language; pc.Language = language;
DefaultCompilationUnit cu = new DefaultCompilationUnit(pc); DefaultCompilationUnit cu = new DefaultCompilationUnit(pc);
if (language == LanguageProperties.VBNet) { if (usingMode == 1) {
cu.Usings.Add(CreateUsing(pc, "syStEm.coLLectIons")); cu.Usings.Add(CreateUsing(pc, "syStEm.coLLectIons"));
pc.DefaultImports = new DefaultUsing(pc); pc.DefaultImports = new DefaultUsing(pc);
pc.DefaultImports.Usings.Add("syStEm"); pc.DefaultImports.Usings.Add("syStEm");
pc.DefaultImports.Usings.Add("syStEm.coLLEctionS.GeNeRic"); pc.DefaultImports.Usings.Add("syStEm.coLLEctionS.GeNeRic");
} else { } else if (usingMode == 2) {
pc.DefaultImports = new DefaultUsing(pc);
pc.DefaultImports.Usings.Add("syStEm");
pc.DefaultImports.Usings.Add("syStEm.coLLEctioNs");
pc.DefaultImports.Usings.Add("syStEm.coLLEctionS.GeNeRic");
} else { // usingMode == 0
cu.Usings.Add(CreateUsing(pc, "System")); cu.Usings.Add(CreateUsing(pc, "System"));
cu.Usings.Add(CreateUsing(pc, "System.Collections")); cu.Usings.Add(CreateUsing(pc, "System.Collections"));
cu.Usings.Add(CreateUsing(pc, "System.Collections.Generic")); cu.Usings.Add(CreateUsing(pc, "System.Collections.Generic"));
@ -47,7 +55,7 @@ namespace ICSharpCode.SharpDevelop.Tests
IReturnType SearchType(string type, int typeParameterCount) IReturnType SearchType(string type, int typeParameterCount)
{ {
ICompilationUnit cu = Prepare(LanguageProperties.CSharp); ICompilationUnit cu = Prepare(LanguageProperties.CSharp, 0);
IReturnType c = cu.ProjectContent.SearchType(new SearchTypeRequest(type, typeParameterCount, null, cu, 1, 1)).Result; IReturnType c = cu.ProjectContent.SearchType(new SearchTypeRequest(type, typeParameterCount, null, cu, 1, 1)).Result;
Assert.IsNotNull(c, type + "not found"); Assert.IsNotNull(c, type + "not found");
return c; return c;
@ -55,10 +63,22 @@ namespace ICSharpCode.SharpDevelop.Tests
IReturnType SearchTypeVB(string type, int typeParameterCount) IReturnType SearchTypeVB(string type, int typeParameterCount)
{ {
ICompilationUnit cu = Prepare(LanguageProperties.VBNet); ICompilationUnit cu;
IReturnType c = cu.ProjectContent.SearchType(new SearchTypeRequest(type, typeParameterCount, null, cu, 1, 1)).Result; cu = Prepare(LanguageProperties.VBNet, 0);
Assert.IsNotNull(c, type + "not found"); IReturnType c0 = cu.ProjectContent.SearchType(new SearchTypeRequest(type, typeParameterCount, null, cu, 1, 1)).Result;
return c; Assert.IsNotNull(c0, type + "not found for mode=0");
cu = Prepare(LanguageProperties.VBNet, 1);
IReturnType c1 = cu.ProjectContent.SearchType(new SearchTypeRequest(type, typeParameterCount, null, cu, 1, 1)).Result;
Assert.IsNotNull(c1, type + "not found for mode=1");
cu = Prepare(LanguageProperties.VBNet, 2);
IReturnType c2 = cu.ProjectContent.SearchType(new SearchTypeRequest(type, typeParameterCount, null, cu, 1, 1)).Result;
Assert.IsNotNull(c2, type + "not found for mode=2");
Assert.IsTrue(c0.Equals(c1) && c0.Equals(c2));
return c0;
} }
void CheckType(string shortName, string vbShortName, string fullType, int typeParameterCount) void CheckType(string shortName, string vbShortName, string fullType, int typeParameterCount)

1
src/Main/ICSharpCode.SharpDevelop.Dom/Project/ICSharpCode.SharpDevelop.Dom.csproj

@ -83,6 +83,7 @@
<Compile Include="Src\Implementations\ProxyReturnType.cs" /> <Compile Include="Src\Implementations\ProxyReturnType.cs" />
<Compile Include="Src\Implementations\SearchClassReturnType.cs" /> <Compile Include="Src\Implementations\SearchClassReturnType.cs" />
<Compile Include="Src\Implementations\SystemTypes.cs" /> <Compile Include="Src\Implementations\SystemTypes.cs" />
<Compile Include="Src\Interfaces\ExplicitInterfaceImplementation.cs" />
<Compile Include="Src\NRefactoryResolver\NRefactoryASTConvertVisitor.cs" /> <Compile Include="Src\NRefactoryResolver\NRefactoryASTConvertVisitor.cs" />
<Compile Include="Src\NRefactoryResolver\NRefactoryInformationProvider.cs" /> <Compile Include="Src\NRefactoryResolver\NRefactoryInformationProvider.cs" />
<Compile Include="Src\NRefactoryResolver\NRefactoryResolver.cs" /> <Compile Include="Src\NRefactoryResolver\NRefactoryResolver.cs" />

14
src/Main/ICSharpCode.SharpDevelop.Dom/Project/Src/CecilReader.cs

@ -328,10 +328,24 @@ namespace ICSharpCode.SharpDevelop.Dom
m.Modifiers = TranslateModifiers(method); m.Modifiers = TranslateModifiers(method);
} }
AddParameters(m, method.Parameters); AddParameters(m, method.Parameters);
AddExplicitInterfaceImplementations(method.Overrides, m);
Methods.Add(m); Methods.Add(m);
} }
} }
void AddExplicitInterfaceImplementations(OverrideCollection overrides, IMember targetMember)
{
foreach (MethodReference overrideRef in overrides) {
if (overrideRef.Name == targetMember.Name && targetMember.IsPublic) {
continue; // is like implicit interface implementation / normal override
}
targetMember.InterfaceImplementations.Add(new ExplicitInterfaceImplementation(
CreateType(this.ProjectContent, targetMember, overrideRef.DeclaringType),
overrideRef.Name
));
}
}
void AddParameters(IMethodOrProperty target, ParameterDefinitionCollection plist) void AddParameters(IMethodOrProperty target, ParameterDefinitionCollection plist)
{ {
foreach (ParameterDefinition par in plist) { foreach (ParameterDefinition par in plist) {

6
src/Main/ICSharpCode.SharpDevelop.Dom/Project/Src/ClassFinder.cs

@ -32,6 +32,12 @@ namespace ICSharpCode.SharpDevelop.Dom
} }
} }
public LanguageProperties Language {
get {
return projectContent.Language;
}
}
public ClassFinder(string fileName, string fileContent, int offset) public ClassFinder(string fileName, string fileContent, int offset)
{ {
caretLine = 0; caretLine = 0;

31
src/Main/ICSharpCode.SharpDevelop.Dom/Project/Src/Implementations/AbstractMember.cs

@ -6,6 +6,7 @@
// </file> // </file>
using System; using System;
using System.Collections.Generic;
namespace ICSharpCode.SharpDevelop.Dom namespace ICSharpCode.SharpDevelop.Dom
{ {
@ -13,6 +14,9 @@ namespace ICSharpCode.SharpDevelop.Dom
{ {
IReturnType returnType; IReturnType returnType;
DomRegion region; DomRegion region;
DomRegion bodyRegion;
List<ExplicitInterfaceImplementation> interfaceImplementations;
IReturnType declaringTypeReference;
public virtual DomRegion Region { public virtual DomRegion Region {
get { get {
@ -23,6 +27,15 @@ namespace ICSharpCode.SharpDevelop.Dom
} }
} }
public virtual DomRegion BodyRegion {
get {
return bodyRegion;
}
protected set {
bodyRegion = value;
}
}
public virtual IReturnType ReturnType { public virtual IReturnType ReturnType {
get { get {
return returnType; return returnType;
@ -32,6 +45,24 @@ namespace ICSharpCode.SharpDevelop.Dom
} }
} }
/// <summary>
/// Gets the declaring type reference (declaring type incl. type arguments)
/// </summary>
public virtual IReturnType DeclaringTypeReference {
get {
return declaringTypeReference ?? this.DeclaringType.DefaultReturnType;
}
set {
declaringTypeReference = value;
}
}
public IList<ExplicitInterfaceImplementation> InterfaceImplementations {
get {
return interfaceImplementations ?? (interfaceImplementations = new List<ExplicitInterfaceImplementation>());
}
}
public AbstractMember(IClass declaringType, string name) : base(declaringType, name) public AbstractMember(IClass declaringType, string name) : base(declaringType, name)
{ {
} }

12
src/Main/ICSharpCode.SharpDevelop.Dom/Project/Src/Implementations/ConstructedReturnType.cs

@ -162,6 +162,9 @@ namespace ICSharpCode.SharpDevelop.Dom
for (int i = 0; i < l.Count; ++i) { for (int i = 0; i < l.Count; ++i) {
if (CheckReturnType(l[i].ReturnType) || CheckParameters(l[i].Parameters)) { if (CheckReturnType(l[i].ReturnType) || CheckParameters(l[i].Parameters)) {
l[i] = (IMethod)l[i].Clone(); l[i] = (IMethod)l[i].Clone();
if (l[i].DeclaringType == baseType.GetUnderlyingClass()) {
l[i].DeclaringTypeReference = this;
}
l[i].ReturnType = TranslateType(l[i].ReturnType); l[i].ReturnType = TranslateType(l[i].ReturnType);
for (int j = 0; j < l[i].Parameters.Count; ++j) { for (int j = 0; j < l[i].Parameters.Count; ++j) {
l[i].Parameters[j].ReturnType = TranslateType(l[i].Parameters[j].ReturnType); l[i].Parameters[j].ReturnType = TranslateType(l[i].Parameters[j].ReturnType);
@ -177,6 +180,9 @@ namespace ICSharpCode.SharpDevelop.Dom
for (int i = 0; i < l.Count; ++i) { for (int i = 0; i < l.Count; ++i) {
if (CheckReturnType(l[i].ReturnType) || CheckParameters(l[i].Parameters)) { if (CheckReturnType(l[i].ReturnType) || CheckParameters(l[i].Parameters)) {
l[i] = (IProperty)l[i].Clone(); l[i] = (IProperty)l[i].Clone();
if (l[i].DeclaringType == baseType.GetUnderlyingClass()) {
l[i].DeclaringTypeReference = this;
}
l[i].ReturnType = TranslateType(l[i].ReturnType); l[i].ReturnType = TranslateType(l[i].ReturnType);
for (int j = 0; j < l[i].Parameters.Count; ++j) { for (int j = 0; j < l[i].Parameters.Count; ++j) {
l[i].Parameters[j].ReturnType = TranslateType(l[i].Parameters[j].ReturnType); l[i].Parameters[j].ReturnType = TranslateType(l[i].Parameters[j].ReturnType);
@ -192,6 +198,9 @@ namespace ICSharpCode.SharpDevelop.Dom
for (int i = 0; i < l.Count; ++i) { for (int i = 0; i < l.Count; ++i) {
if (CheckReturnType(l[i].ReturnType)) { if (CheckReturnType(l[i].ReturnType)) {
l[i] = (IField)l[i].Clone(); l[i] = (IField)l[i].Clone();
if (l[i].DeclaringType == baseType.GetUnderlyingClass()) {
l[i].DeclaringTypeReference = this;
}
l[i].ReturnType = TranslateType(l[i].ReturnType); l[i].ReturnType = TranslateType(l[i].ReturnType);
} }
} }
@ -204,6 +213,9 @@ namespace ICSharpCode.SharpDevelop.Dom
for (int i = 0; i < l.Count; ++i) { for (int i = 0; i < l.Count; ++i) {
if (CheckReturnType(l[i].ReturnType)) { if (CheckReturnType(l[i].ReturnType)) {
l[i] = (IEvent)l[i].Clone(); l[i] = (IEvent)l[i].Clone();
if (l[i].DeclaringType == baseType.GetUnderlyingClass()) {
l[i].DeclaringTypeReference = this;
}
l[i].ReturnType = TranslateType(l[i].ReturnType); l[i].ReturnType = TranslateType(l[i].ReturnType);
} }
} }

18
src/Main/ICSharpCode.SharpDevelop.Dom/Project/Src/Implementations/DefaultEvent.cs

@ -11,7 +11,6 @@ namespace ICSharpCode.SharpDevelop.Dom
{ {
public class DefaultEvent : AbstractMember, IEvent public class DefaultEvent : AbstractMember, IEvent
{ {
DomRegion bodyRegion;
IMethod addMethod; IMethod addMethod;
IMethod removeMethod; IMethod removeMethod;
IMethod raiseMethod; IMethod raiseMethod;
@ -22,18 +21,13 @@ namespace ICSharpCode.SharpDevelop.Dom
} }
} }
public virtual DomRegion BodyRegion {
get {
return bodyRegion;
}
protected set {
bodyRegion = value;
}
}
public override IMember Clone() public override IMember Clone()
{ {
return new DefaultEvent(Name, ReturnType, Modifiers, Region, BodyRegion, DeclaringType); DefaultEvent de = new DefaultEvent(Name, ReturnType, Modifiers, Region, BodyRegion, DeclaringType);
foreach (ExplicitInterfaceImplementation eii in InterfaceImplementations) {
de.InterfaceImplementations.Add(eii.Clone());
}
return de;
} }
public DefaultEvent(IClass declaringType, string name) : base(declaringType, name) public DefaultEvent(IClass declaringType, string name) : base(declaringType, name)
@ -44,7 +38,7 @@ namespace ICSharpCode.SharpDevelop.Dom
{ {
this.ReturnType = type; this.ReturnType = type;
this.Region = region; this.Region = region;
this.bodyRegion = bodyRegion; this.BodyRegion = bodyRegion;
Modifiers = (ModifierEnum)m; Modifiers = (ModifierEnum)m;
if (Modifiers == ModifierEnum.None) { if (Modifiers == ModifierEnum.None) {
Modifiers = ModifierEnum.Private; Modifiers = ModifierEnum.Private;

13
src/Main/ICSharpCode.SharpDevelop.Dom/Project/Src/Implementations/DefaultMethod.cs

@ -49,8 +49,6 @@ namespace ICSharpCode.SharpDevelop.Dom
[Serializable] [Serializable]
public class DefaultMethod : AbstractMember, IMethod public class DefaultMethod : AbstractMember, IMethod
{ {
DomRegion bodyRegion;
IList<IParameter> parameters = null; IList<IParameter> parameters = null;
IList<ITypeParameter> typeParameters = null; IList<ITypeParameter> typeParameters = null;
@ -72,6 +70,9 @@ namespace ICSharpCode.SharpDevelop.Dom
p.typeParameters = this.typeParameters; p.typeParameters = this.typeParameters;
p.documentationTag = DocumentationTag; p.documentationTag = DocumentationTag;
p.isExtensionMethod = this.isExtensionMethod; p.isExtensionMethod = this.isExtensionMethod;
foreach (ExplicitInterfaceImplementation eii in InterfaceImplementations) {
p.InterfaceImplementations.Add(eii.Clone());
}
return p; return p;
} }
@ -110,12 +111,6 @@ namespace ICSharpCode.SharpDevelop.Dom
} }
} }
public virtual DomRegion BodyRegion {
get {
return bodyRegion;
}
}
public virtual IList<ITypeParameter> TypeParameters { public virtual IList<ITypeParameter> TypeParameters {
get { get {
if (typeParameters == null) { if (typeParameters == null) {
@ -154,7 +149,7 @@ namespace ICSharpCode.SharpDevelop.Dom
{ {
this.ReturnType = type; this.ReturnType = type;
this.Region = region; this.Region = region;
this.bodyRegion = bodyRegion; this.BodyRegion = bodyRegion;
Modifiers = m; Modifiers = m;
} }

12
src/Main/ICSharpCode.SharpDevelop.Dom/Project/Src/Implementations/DefaultProperty.cs

@ -12,7 +12,6 @@ namespace ICSharpCode.SharpDevelop.Dom {
public class DefaultProperty : AbstractMember, IProperty public class DefaultProperty : AbstractMember, IProperty
{ {
DomRegion bodyRegion = DomRegion.Empty;
DomRegion getterRegion = DomRegion.Empty; DomRegion getterRegion = DomRegion.Empty;
DomRegion setterRegion = DomRegion.Empty; DomRegion setterRegion = DomRegion.Empty;
@ -49,17 +48,14 @@ namespace ICSharpCode.SharpDevelop.Dom {
} }
} }
public virtual DomRegion BodyRegion {
get {
return bodyRegion;
}
}
public override IMember Clone() public override IMember Clone()
{ {
DefaultProperty p = new DefaultProperty(Name, ReturnType, Modifiers, Region, BodyRegion, DeclaringType); DefaultProperty p = new DefaultProperty(Name, ReturnType, Modifiers, Region, BodyRegion, DeclaringType);
p.parameters = DefaultParameter.Clone(this.Parameters); p.parameters = DefaultParameter.Clone(this.Parameters);
p.accessFlags = this.accessFlags; p.accessFlags = this.accessFlags;
foreach (ExplicitInterfaceImplementation eii in InterfaceImplementations) {
p.InterfaceImplementations.Add(eii.Clone());
}
return p; return p;
} }
@ -101,7 +97,7 @@ namespace ICSharpCode.SharpDevelop.Dom {
{ {
this.ReturnType = type; this.ReturnType = type;
this.Region = region; this.Region = region;
this.bodyRegion = bodyRegion; this.BodyRegion = bodyRegion;
Modifiers = m; Modifiers = m;
} }

4
src/Main/ICSharpCode.SharpDevelop.Dom/Project/Src/Implementations/DefaultReturnType.cs

@ -77,7 +77,7 @@ namespace ICSharpCode.SharpDevelop.Dom
StringComparer comparer = m.DeclaringType.ProjectContent.Language.NameComparer; StringComparer comparer = m.DeclaringType.ProjectContent.Language.NameComparer;
foreach (IMethod oldMethod in c.Methods) { foreach (IMethod oldMethod in c.Methods) {
if (comparer.Equals(oldMethod.Name, m.Name)) { if (comparer.Equals(oldMethod.Name, m.Name)) {
if (m.IsStatic == oldMethod.IsStatic) { if (m.IsStatic == oldMethod.IsStatic && object.Equals(m.ReturnType, oldMethod.ReturnType)) {
if (DiffUtility.Compare(oldMethod.Parameters, m.Parameters) == 0) { if (DiffUtility.Compare(oldMethod.Parameters, m.Parameters) == 0) {
ok = false; ok = false;
break; break;
@ -118,7 +118,7 @@ namespace ICSharpCode.SharpDevelop.Dom
StringComparer comparer = p.DeclaringType.ProjectContent.Language.NameComparer; StringComparer comparer = p.DeclaringType.ProjectContent.Language.NameComparer;
foreach (IProperty oldProperty in c.Properties) { foreach (IProperty oldProperty in c.Properties) {
if (comparer.Equals(oldProperty.Name, p.Name)) { if (comparer.Equals(oldProperty.Name, p.Name)) {
if (p.IsStatic == oldProperty.IsStatic) { if (p.IsStatic == oldProperty.IsStatic && object.Equals(p.ReturnType, oldProperty.ReturnType)) {
if (DiffUtility.Compare(oldProperty.Parameters, p.Parameters) == 0) { if (DiffUtility.Compare(oldProperty.Parameters, p.Parameters) == 0) {
ok = false; ok = false;
break; break;

17
src/Main/ICSharpCode.SharpDevelop.Dom/Project/Src/Implementations/DefaultUsing.cs

@ -92,7 +92,13 @@ namespace ICSharpCode.SharpDevelop.Dom
return null; return null;
} }
public IReturnType SearchType(string partialTypeName, int typeParameterCount) /// <summary>
/// Returns a collection of possible types that could be meant when using this Import
/// to search the type.
/// Types with the incorrect type parameter count might be returned, but for each
/// same using entry or alias entry at most one (the best matching) type should be returned.
/// </summary>
public IEnumerable<IReturnType> SearchType(string partialTypeName, int typeParameterCount)
{ {
if (HasAliases) { if (HasAliases) {
foreach (KeyValuePair<string, IReturnType> entry in aliases) { foreach (KeyValuePair<string, IReturnType> entry in aliases) {
@ -100,14 +106,14 @@ namespace ICSharpCode.SharpDevelop.Dom
if (projectContent.Language.NameComparer.Equals(partialTypeName, aliasString)) { if (projectContent.Language.NameComparer.Equals(partialTypeName, aliasString)) {
if (entry.Value.IsDefaultReturnType && entry.Value.GetUnderlyingClass() == null) if (entry.Value.IsDefaultReturnType && entry.Value.GetUnderlyingClass() == null)
continue; // type not found, maybe entry was a namespace continue; // type not found, maybe entry was a namespace
return entry.Value; yield return entry.Value;
} }
if (partialTypeName.Length > aliasString.Length) { if (partialTypeName.Length > aliasString.Length) {
if (projectContent.Language.NameComparer.Equals(partialTypeName.Substring(0, aliasString.Length + 1), aliasString + ".")) { if (projectContent.Language.NameComparer.Equals(partialTypeName.Substring(0, aliasString.Length + 1), aliasString + ".")) {
string className = entry.Value.FullyQualifiedName + partialTypeName.Remove(0, aliasString.Length); string className = entry.Value.FullyQualifiedName + partialTypeName.Remove(0, aliasString.Length);
IClass c = projectContent.GetClass(className, typeParameterCount); IClass c = projectContent.GetClass(className, typeParameterCount);
if (c != null) { if (c != null) {
return c.DefaultReturnType; yield return c.DefaultReturnType;
} }
} }
} }
@ -117,7 +123,7 @@ namespace ICSharpCode.SharpDevelop.Dom
foreach (string str in usings) { foreach (string str in usings) {
IClass c = projectContent.GetClass(str + "." + partialTypeName, typeParameterCount); IClass c = projectContent.GetClass(str + "." + partialTypeName, typeParameterCount);
if (c != null) { if (c != null) {
return c.DefaultReturnType; yield return c.DefaultReturnType;
} }
} }
} else { } else {
@ -135,12 +141,11 @@ namespace ICSharpCode.SharpDevelop.Dom
if (c != null) { if (c != null) {
c = projectContent.GetClass(str + "." + partialTypeName, typeParameterCount); c = projectContent.GetClass(str + "." + partialTypeName, typeParameterCount);
if (c != null) { if (c != null) {
return c.DefaultReturnType; yield return c.DefaultReturnType;
} }
} }
} }
} }
return null;
} }
public override string ToString() public override string ToString()

55
src/Main/ICSharpCode.SharpDevelop.Dom/Project/Src/Interfaces/ExplicitInterfaceImplementation.cs

@ -0,0 +1,55 @@
// <file>
// <copyright see="prj:///doc/copyright.txt"/>
// <license see="prj:///doc/license.txt"/>
// <owner name="Daniel Grunwald" email="daniel@danielgrunwald.de"/>
// <version>$Revision: 1965 $</version>
// </file>
using System;
using System.Collections.Generic;
namespace ICSharpCode.SharpDevelop.Dom
{
public sealed class ExplicitInterfaceImplementation : IEquatable<ExplicitInterfaceImplementation>
{
readonly IReturnType interfaceReference;
readonly string memberName;
public ExplicitInterfaceImplementation(IReturnType interfaceReference, string memberName)
{
this.interfaceReference = interfaceReference;
this.memberName = memberName;
}
public IReturnType InterfaceReference {
get { return interfaceReference; }
}
public string MemberName {
get { return memberName; }
}
public ExplicitInterfaceImplementation Clone()
{
return this; // object is immutable, no Clone() required
}
public override int GetHashCode()
{
return interfaceReference.GetHashCode() ^ memberName.GetHashCode();
}
public override bool Equals(object obj)
{
return Equals(obj as ExplicitInterfaceImplementation);
}
public bool Equals(ExplicitInterfaceImplementation other)
{
if (other == null)
return false;
else
return this.interfaceReference == other.interfaceReference && this.memberName == other.memberName;
}
}
}

4
src/Main/ICSharpCode.SharpDevelop.Dom/Project/Src/Interfaces/IEvent.cs

@ -11,10 +11,6 @@ namespace ICSharpCode.SharpDevelop.Dom
{ {
public interface IEvent : IMember public interface IEvent : IMember
{ {
DomRegion BodyRegion {
get;
}
IMethod AddMethod { IMethod AddMethod {
get; get;
} }

18
src/Main/ICSharpCode.SharpDevelop.Dom/Project/Src/Interfaces/IMember.cs

@ -6,6 +6,7 @@
// </file> // </file>
using System; using System;
using System.Collections.Generic;
namespace ICSharpCode.SharpDevelop.Dom namespace ICSharpCode.SharpDevelop.Dom
{ {
@ -15,6 +16,15 @@ namespace ICSharpCode.SharpDevelop.Dom
get; get;
} }
/// <summary>
/// Gets/Sets the declaring type reference (declaring type incl. type arguments).
/// If set to null, the getter returns the default type reference to the <see cref="DeclaringType"/>.
/// </summary>
IReturnType DeclaringTypeReference {
get;
set;
}
/// <summary> /// <summary>
/// Declaration region of the member (without body!) /// Declaration region of the member (without body!)
/// </summary> /// </summary>
@ -38,5 +48,13 @@ namespace ICSharpCode.SharpDevelop.Dom
get; get;
set; set;
} }
DomRegion BodyRegion {
get;
}
IList<ExplicitInterfaceImplementation> InterfaceImplementations {
get;
}
} }
} }

4
src/Main/ICSharpCode.SharpDevelop.Dom/Project/Src/Interfaces/IMethod.cs

@ -12,10 +12,6 @@ namespace ICSharpCode.SharpDevelop.Dom
{ {
public interface IMethodOrProperty : IMember public interface IMethodOrProperty : IMember
{ {
DomRegion BodyRegion {
get;
}
IList<IParameter> Parameters { IList<IParameter> Parameters {
get; get;
} }

10
src/Main/ICSharpCode.SharpDevelop.Dom/Project/Src/Interfaces/IUsing.cs

@ -31,7 +31,15 @@ namespace ICSharpCode.SharpDevelop.Dom
get; get;
} }
IReturnType SearchType(string partialTypeName, int typeParameterCount); /// <summary>
/// Returns a collection of possible types that could be meant when using this Import
/// to search the type.
/// Types with the incorrect type parameter count might be returned, but for each
/// same using entry or alias entry at most one (the best matching) type should be returned.
/// </summary>
/// <returns>An IEnumerable with zero or more non-null return types.</returns>
IEnumerable<IReturnType> SearchType(string partialTypeName, int typeParameterCount);
string SearchNamespace(string partialNamespaceName); string SearchNamespace(string partialNamespaceName);
} }
} }

18
src/Main/ICSharpCode.SharpDevelop.Dom/Project/Src/LanguageProperties.cs

@ -169,6 +169,18 @@ namespace ICSharpCode.SharpDevelop.Dom
} }
} }
/// <summary>
/// Gets if the language enforces that explicit interface implementations are uncallable except through
/// the interface itself.
/// If this property is false, code generators may assume that multiple explicit interface implementations
/// with conflicting return types are invalid unless they are renamed.
/// </summary>
public virtual bool ExplicitInterfaceImplementationIsPrivateScope {
get {
return false;
}
}
/// <summary> /// <summary>
/// Gets if events explicitly implementing an interface require add {} remove {} regions. /// Gets if events explicitly implementing an interface require add {} remove {} regions.
/// </summary> /// </summary>
@ -250,6 +262,12 @@ namespace ICSharpCode.SharpDevelop.Dom
} }
} }
public override bool ExplicitInterfaceImplementationIsPrivateScope {
get {
return true;
}
}
/// <summary> /// <summary>
/// Gets if events explicitly implementing an interface require add {} remove {} regions. /// Gets if events explicitly implementing an interface require add {} remove {} regions.
/// </summary> /// </summary>

6
src/Main/ICSharpCode.SharpDevelop.Dom/Project/Src/ProjectContent/DefaultProjectContent.cs

@ -811,8 +811,7 @@ namespace ICSharpCode.SharpDevelop.Dom
// Combine name with usings // Combine name with usings
foreach (IUsing u in request.CurrentCompilationUnit.Usings) { foreach (IUsing u in request.CurrentCompilationUnit.Usings) {
if (u != null) { if (u != null) {
IReturnType r = u.SearchType(name, request.TypeParameterCount); foreach (IReturnType r in u.SearchType(name, request.TypeParameterCount)) {
if (r != null) {
if (r.TypeParameterCount == request.TypeParameterCount) { if (r.TypeParameterCount == request.TypeParameterCount) {
return new SearchTypeResult(r, u); return new SearchTypeResult(r, u);
} else { } else {
@ -823,8 +822,7 @@ namespace ICSharpCode.SharpDevelop.Dom
} }
} }
if (defaultImports != null) { if (defaultImports != null) {
IReturnType r = defaultImports.SearchType(name, request.TypeParameterCount); foreach (IReturnType r in defaultImports.SearchType(name, request.TypeParameterCount)) {
if (r != null) {
if (r.TypeParameterCount == request.TypeParameterCount) { if (r.TypeParameterCount == request.TypeParameterCount) {
return new SearchTypeResult(r, defaultImports); return new SearchTypeResult(r, defaultImports);
} else { } else {

114
src/Main/ICSharpCode.SharpDevelop.Dom/Project/Src/Refactoring/CodeGenerator.cs

@ -431,68 +431,140 @@ namespace ICSharpCode.SharpDevelop.Dom.Refactoring
return member.DeclaringType.FullyQualifiedName; return member.DeclaringType.FullyQualifiedName;
} }
public void ImplementInterface(IReturnType interf, IDocument document, bool explicitImpl, ModifierEnum implModifier, IClass targetClass) public virtual void ImplementInterface(IReturnType interf, IDocument document, bool explicitImpl, IClass targetClass)
{ {
List<AbstractNode> nodes = new List<AbstractNode>(); List<AbstractNode> nodes = new List<AbstractNode>();
ImplementInterface(nodes, interf, explicitImpl, implModifier, targetClass); ImplementInterface(nodes, interf, explicitImpl, targetClass);
InsertCodeAtEnd(targetClass.Region, document, nodes.ToArray()); InsertCodeAtEnd(targetClass.Region, document, nodes.ToArray());
} }
static bool InterfaceMemberAlreadyImplementedParametersAreIdentical(IMember a, IMember b)
{
if (a is IMethodOrProperty && b is IMethodOrProperty) {
return DiffUtility.Compare(((IMethodOrProperty)a).Parameters,
((IMethodOrProperty)b).Parameters) == 0;
} else {
return true;
}
}
static T CloneAndAddExplicitImpl<T>(T member, IClass targetClass)
where T : class, IMember
{
T copy = (T)member.Clone();
copy.DeclaringTypeReference = targetClass.DefaultReturnType;
copy.InterfaceImplementations.Add(new ExplicitInterfaceImplementation(member.DeclaringTypeReference, member.Name));
return copy;
}
static bool InterfaceMemberAlreadyImplemented<T>(IEnumerable<T> existingMembers, T interfaceMember,
out bool requireAlternativeImplementation)
where T : class, IMember
{
IReturnType interf = interfaceMember.DeclaringTypeReference;
requireAlternativeImplementation = false;
foreach (T existing in existingMembers) {
StringComparer nameComparer = existing.DeclaringType.ProjectContent.Language.NameComparer;
// if existing has same name as interfaceMember, and for methods the parameter list must also be identical:
if (nameComparer.Equals(existing.Name, interfaceMember.Name)) {
if (InterfaceMemberAlreadyImplementedParametersAreIdentical(existing, interfaceMember)) {
// implicit implementation found
if (object.Equals(existing.ReturnType, interfaceMember.ReturnType)) {
return true;
} else {
requireAlternativeImplementation = true;
}
}
} else {
foreach (ExplicitInterfaceImplementation eii in existing.InterfaceImplementations) {
if (object.Equals(eii.InterfaceReference, interf) && nameComparer.Equals(eii.MemberName, interfaceMember.Name)) {
if (InterfaceMemberAlreadyImplementedParametersAreIdentical(existing, interfaceMember)) {
// explicit implementation found
if (object.Equals(existing.ReturnType, interfaceMember.ReturnType)) {
return true;
} else {
requireAlternativeImplementation = true;
}
}
}
}
}
}
return false;
}
static InterfaceImplementation CreateInterfaceImplementation(IMember interfaceMember, ClassFinder context)
{
return new InterfaceImplementation(ConvertType(interfaceMember.DeclaringTypeReference, context), interfaceMember.Name);
}
/// <summary> /// <summary>
/// Adds the methods implementing the <paramref name="interf"/> to the list /// Adds the methods implementing the <paramref name="interf"/> to the list
/// <paramref name="nodes"/>. /// <paramref name="nodes"/>.
/// </summary> /// </summary>
public virtual void ImplementInterface(IList<AbstractNode> nodes, IReturnType interf, bool explicitImpl, ModifierEnum implModifier, IClass targetClass) public virtual void ImplementInterface(IList<AbstractNode> nodes, IReturnType interf, bool explicitImpl, IClass targetClass)
{ {
ClassFinder context = new ClassFinder(targetClass, targetClass.Region.BeginLine + 1, 0); ClassFinder context = new ClassFinder(targetClass, targetClass.Region.BeginLine + 1, 0);
TypeReference interfaceReference = ConvertType(interf, context); Modifiers implicitImplModifier = ConvertModifier(ModifierEnum.Public, context);
Modifiers modifier = ConvertModifier(implModifier, context); Modifiers explicitImplModifier = ConvertModifier(context.Language.ExplicitInterfaceImplementationIsPrivateScope ? ModifierEnum.None : ModifierEnum.Public, context);
List<IEvent> targetClassEvents = targetClass.DefaultReturnType.GetEvents(); List<IEvent> targetClassEvents = targetClass.DefaultReturnType.GetEvents();
bool requireAlternativeImplementation;
foreach (IEvent e in interf.GetEvents()) { foreach (IEvent e in interf.GetEvents()) {
if (targetClassEvents.Find(delegate(IEvent te) { return e.Name == te.Name; }) == null) { if (!InterfaceMemberAlreadyImplemented(targetClassEvents, e, out requireAlternativeImplementation)) {
EventDeclaration ed = ConvertMember(e, context); EventDeclaration ed = ConvertMember(e, context);
if (explicitImpl) { if (explicitImpl || requireAlternativeImplementation) {
ed.InterfaceImplementations.Add(new InterfaceImplementation(interfaceReference, ed.Name)); ed.InterfaceImplementations.Add(CreateInterfaceImplementation(e, context));
if (context.ProjectContent.Language.RequiresAddRemoveRegionInExplicitInterfaceImplementation) { if (context.Language.RequiresAddRemoveRegionInExplicitInterfaceImplementation) {
ed.AddRegion = new EventAddRegion(null); ed.AddRegion = new EventAddRegion(null);
ed.AddRegion.Block = CreateNotImplementedBlock(); ed.AddRegion.Block = CreateNotImplementedBlock();
ed.RemoveRegion = new EventRemoveRegion(null); ed.RemoveRegion = new EventRemoveRegion(null);
ed.RemoveRegion.Block = CreateNotImplementedBlock(); ed.RemoveRegion.Block = CreateNotImplementedBlock();
} }
targetClassEvents.Add(CloneAndAddExplicitImpl(e, targetClass));
ed.Modifier = explicitImplModifier;
} else {
targetClassEvents.Add(e);
ed.Modifier = implicitImplModifier;
} }
ed.Modifier = modifier;
nodes.Add(ed); nodes.Add(ed);
} }
} }
List<IProperty> targetClassProperties = targetClass.DefaultReturnType.GetProperties(); List<IProperty> targetClassProperties = targetClass.DefaultReturnType.GetProperties();
foreach (IProperty p in interf.GetProperties()) { foreach (IProperty p in interf.GetProperties()) {
if (targetClassProperties.Find(delegate(IProperty tp) { return p.Name == tp.Name; }) == null) { if (!InterfaceMemberAlreadyImplemented(targetClassProperties, p, out requireAlternativeImplementation)) {
AttributedNode pd = ConvertMember(p, context); AttributedNode pd = ConvertMember(p, context);
if (explicitImpl) { if (explicitImpl || requireAlternativeImplementation) {
InterfaceImplementation impl = new InterfaceImplementation(interfaceReference, p.Name); InterfaceImplementation impl = CreateInterfaceImplementation(p, context);
if (pd is IndexerDeclaration) { if (pd is IndexerDeclaration) {
((IndexerDeclaration)pd).InterfaceImplementations.Add(impl); ((IndexerDeclaration)pd).InterfaceImplementations.Add(impl);
} else { } else {
((PropertyDeclaration)pd).InterfaceImplementations.Add(impl); ((PropertyDeclaration)pd).InterfaceImplementations.Add(impl);
} }
targetClassProperties.Add(CloneAndAddExplicitImpl(p, targetClass));
pd.Modifier = explicitImplModifier;
} else {
targetClassProperties.Add(p);
pd.Modifier = implicitImplModifier;
} }
pd.Modifier = modifier;
nodes.Add(pd); nodes.Add(pd);
} }
} }
List<IMethod> targetClassMethods = targetClass.DefaultReturnType.GetMethods(); List<IMethod> targetClassMethods = targetClass.DefaultReturnType.GetMethods();
foreach (IMethod m in interf.GetMethods()) { foreach (IMethod m in interf.GetMethods()) {
if (targetClassMethods.Find(delegate(IMethod mp) { if (!InterfaceMemberAlreadyImplemented(targetClassMethods, m, out requireAlternativeImplementation)) {
return m.Name == mp.Name && DiffUtility.Compare(m.Parameters, mp.Parameters) == 0;
}) == null)
{
MethodDeclaration md = ConvertMember(m, context) as MethodDeclaration; MethodDeclaration md = ConvertMember(m, context) as MethodDeclaration;
if (md != null) { if (md != null) {
if (explicitImpl) { if (explicitImpl || requireAlternativeImplementation) {
md.InterfaceImplementations.Add(new InterfaceImplementation(interfaceReference, md.Name)); md.InterfaceImplementations.Add(CreateInterfaceImplementation(m, context));
targetClassMethods.Add(CloneAndAddExplicitImpl(m, targetClass));
md.Modifier = explicitImplModifier;
} else {
targetClassMethods.Add(m);
md.Modifier = implicitImplModifier;
} }
md.Modifier = modifier;
nodes.Add(md); nodes.Add(md);
} }
} }

34
src/Main/ICSharpCode.SharpDevelop.Dom/Project/Src/ReflectionLayer/DomPersistence.cs

@ -20,7 +20,7 @@ namespace ICSharpCode.SharpDevelop.Dom
{ {
public const long FileMagic = 0x11635233ED2F428C; public const long FileMagic = 0x11635233ED2F428C;
public const long IndexFileMagic = 0x11635233ED2F427D; public const long IndexFileMagic = 0x11635233ED2F427D;
public const short FileVersion = 8; public const short FileVersion = 9;
ProjectContentRegistry registry; ProjectContentRegistry registry;
string cacheDirectory; string cacheDirectory;
@ -221,10 +221,12 @@ namespace ICSharpCode.SharpDevelop.Dom
{ {
ReflectionProjectContent pc; ReflectionProjectContent pc;
// for writing:
readonly BinaryWriter writer; readonly BinaryWriter writer;
readonly Dictionary<ClassNameTypeCountPair, int> classIndices = new Dictionary<ClassNameTypeCountPair, int>(); readonly Dictionary<ClassNameTypeCountPair, int> classIndices = new Dictionary<ClassNameTypeCountPair, int>();
readonly Dictionary<string, int> stringDict = new Dictionary<string, int>(); readonly Dictionary<string, int> stringDict = new Dictionary<string, int>();
// for reading:
readonly BinaryReader reader; readonly BinaryReader reader;
IReturnType[] types; IReturnType[] types;
string[] stringArray; string[] stringArray;
@ -494,16 +496,13 @@ namespace ICSharpCode.SharpDevelop.Dom
} }
} }
foreach (IField f in c.Fields) { foreach (IField f in c.Fields) {
AddStrings(stringList, f); CreateExternalTypeListMember(externalTypes, stringList, classCount, f);
AddExternalType(f.ReturnType, externalTypes, classCount);
} }
foreach (IEvent f in c.Events) { foreach (IEvent f in c.Events) {
AddStrings(stringList, f); CreateExternalTypeListMember(externalTypes, stringList, classCount, f);
AddExternalType(f.ReturnType, externalTypes, classCount);
} }
foreach (IProperty p in c.Properties) { foreach (IProperty p in c.Properties) {
AddStrings(stringList, p); CreateExternalTypeListMember(externalTypes, stringList, classCount, p);
AddExternalType(p.ReturnType, externalTypes, classCount);
foreach (IParameter parameter in p.Parameters) { foreach (IParameter parameter in p.Parameters) {
AddString(stringList, parameter.Name); AddString(stringList, parameter.Name);
AddStrings(stringList, parameter.Attributes); AddStrings(stringList, parameter.Attributes);
@ -511,8 +510,7 @@ namespace ICSharpCode.SharpDevelop.Dom
} }
} }
foreach (IMethod m in c.Methods) { foreach (IMethod m in c.Methods) {
AddStrings(stringList, m); CreateExternalTypeListMember(externalTypes, stringList, classCount, m);
AddExternalType(m.ReturnType, externalTypes, classCount);
foreach (IParameter parameter in m.Parameters) { foreach (IParameter parameter in m.Parameters) {
AddString(stringList, parameter.Name); AddString(stringList, parameter.Name);
AddStrings(stringList, parameter.Attributes); AddStrings(stringList, parameter.Attributes);
@ -528,10 +526,17 @@ namespace ICSharpCode.SharpDevelop.Dom
} }
} }
void AddStrings(List<string> stringList, IMember member) void CreateExternalTypeListMember(List<ClassNameTypeCountPair> externalTypes,
List<string> stringList, int classCount,
IMember member)
{ {
AddString(stringList, member.Name); AddString(stringList, member.Name);
AddStrings(stringList, member.Attributes); AddStrings(stringList, member.Attributes);
foreach (ExplicitInterfaceImplementation eii in member.InterfaceImplementations) {
AddString(stringList, eii.MemberName);
AddExternalType(eii.InterfaceReference, externalTypes, classCount);
}
AddExternalType(member.ReturnType, externalTypes, classCount);
} }
void AddString(List<string> stringList, string text) void AddString(List<string> stringList, string text)
@ -657,6 +662,11 @@ namespace ICSharpCode.SharpDevelop.Dom
WriteString(m.Name); WriteString(m.Name);
writer.Write((int)m.Modifiers); writer.Write((int)m.Modifiers);
WriteAttributes(m.Attributes); WriteAttributes(m.Attributes);
writer.Write((ushort)m.InterfaceImplementations.Count);
foreach (ExplicitInterfaceImplementation iee in m.InterfaceImplementations) {
WriteType(iee.InterfaceReference);
WriteString(iee.MemberName);
}
if (!(m is IMethod)) { if (!(m is IMethod)) {
// method must store ReturnType AFTER Template definitions // method must store ReturnType AFTER Template definitions
WriteType(m.ReturnType); WriteType(m.ReturnType);
@ -668,6 +678,10 @@ namespace ICSharpCode.SharpDevelop.Dom
// name is already read by the method that calls the member constructor // name is already read by the method that calls the member constructor
m.Modifiers = (ModifierEnum)reader.ReadInt32(); m.Modifiers = (ModifierEnum)reader.ReadInt32();
ReadAttributes(m); ReadAttributes(m);
int interfaceImplCount = reader.ReadUInt16();
for (int i = 0; i < interfaceImplCount; i++) {
m.InterfaceImplementations.Add(new ExplicitInterfaceImplementation(ReadType(), ReadString()));
}
if (!(m is IMethod)) { if (!(m is IMethod)) {
m.ReturnType = ReadType(); m.ReturnType = ReadType();
} }

Loading…
Cancel
Save