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 @@ -211,5 +211,26 @@ namespace UnitTesting.Tests.Utils
{
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 @@ -262,5 +262,20 @@ namespace UnitTesting.Tests.Utils
{
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 @@ -174,7 +174,7 @@ namespace ICSharpCode.SharpDevelop.DefaultEditor.Commands
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;
IAmbience ambience = AmbienceService.CurrentAmbience;
@ -186,7 +186,7 @@ namespace ICSharpCode.SharpDevelop.DefaultEditor.Commands @@ -186,7 +186,7 @@ namespace ICSharpCode.SharpDevelop.DefaultEditor.Commands
EventHandler eh = delegate {
TextEditorDocument d = new TextEditorDocument(GetDocument(c));
if (d != null)
codeGen.ImplementInterface(rtCopy, d, explicitImpl, modifier, c);
codeGen.ImplementInterface(rtCopy, d, explicitImpl, c);
ParserService.ParseCurrentViewContent();
};
subItems.Add(new MenuCommand(ambience.Convert(interf), eh));
@ -200,16 +200,14 @@ namespace ICSharpCode.SharpDevelop.DefaultEditor.Commands @@ -200,16 +200,14 @@ namespace ICSharpCode.SharpDevelop.DefaultEditor.Commands
if (codeGen == null) return;
List<ToolStripItem> subItems = new List<ToolStripItem>();
if (c.ProjectContent.Language.SupportsImplicitInterfaceImplementation) {
AddImplementInterfaceCommandItems(subItems, c, false, ModifierEnum.Public);
AddImplementInterfaceCommandItems(subItems, c, false);
if (subItems.Count > 0) {
list.Add(new ICSharpCode.Core.Menu("${res:SharpDevelop.Refactoring.ImplementInterfaceImplicit}", subItems.ToArray()));
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 (c.ProjectContent.Language.SupportsImplicitInterfaceImplementation) {
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 @@ -63,7 +63,7 @@ namespace ICSharpCode.SharpDevelop.DefaultEditor.Commands
foreach (ClassWrapper w in items) {
codeGen.ImplementInterface(nodes, w.ClassType,
!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> { @@ -187,7 +187,7 @@ class DerivedClass<A,B> : BaseClass<B,A> {
#region CodeCompletion inside generic classes
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 {
T var1; G var2;

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

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

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

@ -19,18 +19,26 @@ namespace ICSharpCode.SharpDevelop.Tests @@ -19,18 +19,26 @@ namespace ICSharpCode.SharpDevelop.Tests
ProjectContentRegistry projectContentRegistry = ParserService.DefaultProjectContentRegistry;
#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();
pc.ReferencedContents.Add(projectContentRegistry.Mscorlib);
pc.Language = language;
DefaultCompilationUnit cu = new DefaultCompilationUnit(pc);
if (language == LanguageProperties.VBNet) {
if (usingMode == 1) {
cu.Usings.Add(CreateUsing(pc, "syStEm.coLLectIons"));
pc.DefaultImports = new DefaultUsing(pc);
pc.DefaultImports.Usings.Add("syStEm");
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.Collections"));
cu.Usings.Add(CreateUsing(pc, "System.Collections.Generic"));
@ -47,7 +55,7 @@ namespace ICSharpCode.SharpDevelop.Tests @@ -47,7 +55,7 @@ namespace ICSharpCode.SharpDevelop.Tests
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;
Assert.IsNotNull(c, type + "not found");
return c;
@ -55,10 +63,22 @@ namespace ICSharpCode.SharpDevelop.Tests @@ -55,10 +63,22 @@ namespace ICSharpCode.SharpDevelop.Tests
IReturnType SearchTypeVB(string type, int typeParameterCount)
{
ICompilationUnit cu = Prepare(LanguageProperties.VBNet);
IReturnType c = cu.ProjectContent.SearchType(new SearchTypeRequest(type, typeParameterCount, null, cu, 1, 1)).Result;
Assert.IsNotNull(c, type + "not found");
return c;
ICompilationUnit cu;
cu = Prepare(LanguageProperties.VBNet, 0);
IReturnType c0 = cu.ProjectContent.SearchType(new SearchTypeRequest(type, typeParameterCount, null, cu, 1, 1)).Result;
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)

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

@ -83,6 +83,7 @@ @@ -83,6 +83,7 @@
<Compile Include="Src\Implementations\ProxyReturnType.cs" />
<Compile Include="Src\Implementations\SearchClassReturnType.cs" />
<Compile Include="Src\Implementations\SystemTypes.cs" />
<Compile Include="Src\Interfaces\ExplicitInterfaceImplementation.cs" />
<Compile Include="Src\NRefactoryResolver\NRefactoryASTConvertVisitor.cs" />
<Compile Include="Src\NRefactoryResolver\NRefactoryInformationProvider.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 @@ -328,10 +328,24 @@ namespace ICSharpCode.SharpDevelop.Dom
m.Modifiers = TranslateModifiers(method);
}
AddParameters(m, method.Parameters);
AddExplicitInterfaceImplementations(method.Overrides, 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)
{
foreach (ParameterDefinition par in plist) {

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

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

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

@ -6,6 +6,7 @@ @@ -6,6 +6,7 @@
// </file>
using System;
using System.Collections.Generic;
namespace ICSharpCode.SharpDevelop.Dom
{
@ -13,6 +14,9 @@ namespace ICSharpCode.SharpDevelop.Dom @@ -13,6 +14,9 @@ namespace ICSharpCode.SharpDevelop.Dom
{
IReturnType returnType;
DomRegion region;
DomRegion bodyRegion;
List<ExplicitInterfaceImplementation> interfaceImplementations;
IReturnType declaringTypeReference;
public virtual DomRegion Region {
get {
@ -23,6 +27,15 @@ namespace ICSharpCode.SharpDevelop.Dom @@ -23,6 +27,15 @@ namespace ICSharpCode.SharpDevelop.Dom
}
}
public virtual DomRegion BodyRegion {
get {
return bodyRegion;
}
protected set {
bodyRegion = value;
}
}
public virtual IReturnType ReturnType {
get {
return returnType;
@ -32,6 +45,24 @@ namespace ICSharpCode.SharpDevelop.Dom @@ -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)
{
}

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

@ -162,6 +162,9 @@ namespace ICSharpCode.SharpDevelop.Dom @@ -162,6 +162,9 @@ namespace ICSharpCode.SharpDevelop.Dom
for (int i = 0; i < l.Count; ++i) {
if (CheckReturnType(l[i].ReturnType) || CheckParameters(l[i].Parameters)) {
l[i] = (IMethod)l[i].Clone();
if (l[i].DeclaringType == baseType.GetUnderlyingClass()) {
l[i].DeclaringTypeReference = this;
}
l[i].ReturnType = TranslateType(l[i].ReturnType);
for (int j = 0; j < l[i].Parameters.Count; ++j) {
l[i].Parameters[j].ReturnType = TranslateType(l[i].Parameters[j].ReturnType);
@ -177,6 +180,9 @@ namespace ICSharpCode.SharpDevelop.Dom @@ -177,6 +180,9 @@ namespace ICSharpCode.SharpDevelop.Dom
for (int i = 0; i < l.Count; ++i) {
if (CheckReturnType(l[i].ReturnType) || CheckParameters(l[i].Parameters)) {
l[i] = (IProperty)l[i].Clone();
if (l[i].DeclaringType == baseType.GetUnderlyingClass()) {
l[i].DeclaringTypeReference = this;
}
l[i].ReturnType = TranslateType(l[i].ReturnType);
for (int j = 0; j < l[i].Parameters.Count; ++j) {
l[i].Parameters[j].ReturnType = TranslateType(l[i].Parameters[j].ReturnType);
@ -192,6 +198,9 @@ namespace ICSharpCode.SharpDevelop.Dom @@ -192,6 +198,9 @@ namespace ICSharpCode.SharpDevelop.Dom
for (int i = 0; i < l.Count; ++i) {
if (CheckReturnType(l[i].ReturnType)) {
l[i] = (IField)l[i].Clone();
if (l[i].DeclaringType == baseType.GetUnderlyingClass()) {
l[i].DeclaringTypeReference = this;
}
l[i].ReturnType = TranslateType(l[i].ReturnType);
}
}
@ -204,6 +213,9 @@ namespace ICSharpCode.SharpDevelop.Dom @@ -204,6 +213,9 @@ namespace ICSharpCode.SharpDevelop.Dom
for (int i = 0; i < l.Count; ++i) {
if (CheckReturnType(l[i].ReturnType)) {
l[i] = (IEvent)l[i].Clone();
if (l[i].DeclaringType == baseType.GetUnderlyingClass()) {
l[i].DeclaringTypeReference = this;
}
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 @@ -11,7 +11,6 @@ namespace ICSharpCode.SharpDevelop.Dom
{
public class DefaultEvent : AbstractMember, IEvent
{
DomRegion bodyRegion;
IMethod addMethod;
IMethod removeMethod;
IMethod raiseMethod;
@ -22,18 +21,13 @@ namespace ICSharpCode.SharpDevelop.Dom @@ -22,18 +21,13 @@ namespace ICSharpCode.SharpDevelop.Dom
}
}
public virtual DomRegion BodyRegion {
get {
return bodyRegion;
}
protected set {
bodyRegion = value;
}
}
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)
@ -44,7 +38,7 @@ namespace ICSharpCode.SharpDevelop.Dom @@ -44,7 +38,7 @@ namespace ICSharpCode.SharpDevelop.Dom
{
this.ReturnType = type;
this.Region = region;
this.bodyRegion = bodyRegion;
this.BodyRegion = bodyRegion;
Modifiers = (ModifierEnum)m;
if (Modifiers == ModifierEnum.None) {
Modifiers = ModifierEnum.Private;

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

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

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

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

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

@ -77,7 +77,7 @@ namespace ICSharpCode.SharpDevelop.Dom @@ -77,7 +77,7 @@ namespace ICSharpCode.SharpDevelop.Dom
StringComparer comparer = m.DeclaringType.ProjectContent.Language.NameComparer;
foreach (IMethod oldMethod in c.Methods) {
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) {
ok = false;
break;
@ -118,7 +118,7 @@ namespace ICSharpCode.SharpDevelop.Dom @@ -118,7 +118,7 @@ namespace ICSharpCode.SharpDevelop.Dom
StringComparer comparer = p.DeclaringType.ProjectContent.Language.NameComparer;
foreach (IProperty oldProperty in c.Properties) {
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) {
ok = false;
break;

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

@ -92,7 +92,13 @@ namespace ICSharpCode.SharpDevelop.Dom @@ -92,7 +92,13 @@ namespace ICSharpCode.SharpDevelop.Dom
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) {
foreach (KeyValuePair<string, IReturnType> entry in aliases) {
@ -100,14 +106,14 @@ namespace ICSharpCode.SharpDevelop.Dom @@ -100,14 +106,14 @@ namespace ICSharpCode.SharpDevelop.Dom
if (projectContent.Language.NameComparer.Equals(partialTypeName, aliasString)) {
if (entry.Value.IsDefaultReturnType && entry.Value.GetUnderlyingClass() == null)
continue; // type not found, maybe entry was a namespace
return entry.Value;
yield return entry.Value;
}
if (partialTypeName.Length > aliasString.Length) {
if (projectContent.Language.NameComparer.Equals(partialTypeName.Substring(0, aliasString.Length + 1), aliasString + ".")) {
string className = entry.Value.FullyQualifiedName + partialTypeName.Remove(0, aliasString.Length);
IClass c = projectContent.GetClass(className, typeParameterCount);
if (c != null) {
return c.DefaultReturnType;
yield return c.DefaultReturnType;
}
}
}
@ -117,7 +123,7 @@ namespace ICSharpCode.SharpDevelop.Dom @@ -117,7 +123,7 @@ namespace ICSharpCode.SharpDevelop.Dom
foreach (string str in usings) {
IClass c = projectContent.GetClass(str + "." + partialTypeName, typeParameterCount);
if (c != null) {
return c.DefaultReturnType;
yield return c.DefaultReturnType;
}
}
} else {
@ -135,12 +141,11 @@ namespace ICSharpCode.SharpDevelop.Dom @@ -135,12 +141,11 @@ namespace ICSharpCode.SharpDevelop.Dom
if (c != null) {
c = projectContent.GetClass(str + "." + partialTypeName, typeParameterCount);
if (c != null) {
return c.DefaultReturnType;
yield return c.DefaultReturnType;
}
}
}
}
return null;
}
public override string ToString()

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

@ -0,0 +1,55 @@ @@ -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 @@ -11,10 +11,6 @@ namespace ICSharpCode.SharpDevelop.Dom
{
public interface IEvent : IMember
{
DomRegion BodyRegion {
get;
}
IMethod AddMethod {
get;
}

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

@ -6,6 +6,7 @@ @@ -6,6 +6,7 @@
// </file>
using System;
using System.Collections.Generic;
namespace ICSharpCode.SharpDevelop.Dom
{
@ -15,6 +16,15 @@ namespace ICSharpCode.SharpDevelop.Dom @@ -15,6 +16,15 @@ namespace ICSharpCode.SharpDevelop.Dom
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>
/// Declaration region of the member (without body!)
/// </summary>
@ -38,5 +48,13 @@ namespace ICSharpCode.SharpDevelop.Dom @@ -38,5 +48,13 @@ namespace ICSharpCode.SharpDevelop.Dom
get;
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 @@ -12,10 +12,6 @@ namespace ICSharpCode.SharpDevelop.Dom
{
public interface IMethodOrProperty : IMember
{
DomRegion BodyRegion {
get;
}
IList<IParameter> Parameters {
get;
}

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

@ -31,7 +31,15 @@ namespace ICSharpCode.SharpDevelop.Dom @@ -31,7 +31,15 @@ namespace ICSharpCode.SharpDevelop.Dom
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);
}
}

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

@ -169,6 +169,18 @@ namespace ICSharpCode.SharpDevelop.Dom @@ -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>
/// Gets if events explicitly implementing an interface require add {} remove {} regions.
/// </summary>
@ -250,6 +262,12 @@ namespace ICSharpCode.SharpDevelop.Dom @@ -250,6 +262,12 @@ namespace ICSharpCode.SharpDevelop.Dom
}
}
public override bool ExplicitInterfaceImplementationIsPrivateScope {
get {
return true;
}
}
/// <summary>
/// Gets if events explicitly implementing an interface require add {} remove {} regions.
/// </summary>

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

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

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

@ -431,68 +431,140 @@ namespace ICSharpCode.SharpDevelop.Dom.Refactoring @@ -431,68 +431,140 @@ namespace ICSharpCode.SharpDevelop.Dom.Refactoring
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>();
ImplementInterface(nodes, interf, explicitImpl, implModifier, targetClass);
ImplementInterface(nodes, interf, explicitImpl, targetClass);
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>
/// Adds the methods implementing the <paramref name="interf"/> to the list
/// <paramref name="nodes"/>.
/// </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);
TypeReference interfaceReference = ConvertType(interf, context);
Modifiers modifier = ConvertModifier(implModifier, context);
Modifiers implicitImplModifier = ConvertModifier(ModifierEnum.Public, context);
Modifiers explicitImplModifier = ConvertModifier(context.Language.ExplicitInterfaceImplementationIsPrivateScope ? ModifierEnum.None : ModifierEnum.Public, context);
List<IEvent> targetClassEvents = targetClass.DefaultReturnType.GetEvents();
bool requireAlternativeImplementation;
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);
if (explicitImpl) {
ed.InterfaceImplementations.Add(new InterfaceImplementation(interfaceReference, ed.Name));
if (explicitImpl || requireAlternativeImplementation) {
ed.InterfaceImplementations.Add(CreateInterfaceImplementation(e, context));
if (context.ProjectContent.Language.RequiresAddRemoveRegionInExplicitInterfaceImplementation) {
if (context.Language.RequiresAddRemoveRegionInExplicitInterfaceImplementation) {
ed.AddRegion = new EventAddRegion(null);
ed.AddRegion.Block = CreateNotImplementedBlock();
ed.RemoveRegion = new EventRemoveRegion(null);
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);
}
}
List<IProperty> targetClassProperties = targetClass.DefaultReturnType.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);
if (explicitImpl) {
InterfaceImplementation impl = new InterfaceImplementation(interfaceReference, p.Name);
if (explicitImpl || requireAlternativeImplementation) {
InterfaceImplementation impl = CreateInterfaceImplementation(p, context);
if (pd is IndexerDeclaration) {
((IndexerDeclaration)pd).InterfaceImplementations.Add(impl);
} else {
((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);
}
}
List<IMethod> targetClassMethods = targetClass.DefaultReturnType.GetMethods();
foreach (IMethod m in interf.GetMethods()) {
if (targetClassMethods.Find(delegate(IMethod mp) {
return m.Name == mp.Name && DiffUtility.Compare(m.Parameters, mp.Parameters) == 0;
}) == null)
{
if (!InterfaceMemberAlreadyImplemented(targetClassMethods, m, out requireAlternativeImplementation)) {
MethodDeclaration md = ConvertMember(m, context) as MethodDeclaration;
if (md != null) {
if (explicitImpl) {
md.InterfaceImplementations.Add(new InterfaceImplementation(interfaceReference, md.Name));
if (explicitImpl || requireAlternativeImplementation) {
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);
}
}

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

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

Loading…
Cancel
Save