Browse Source

Fixed SD2-420: Non-generic classes and generic classes with the same name collide in the DOM.

git-svn-id: svn://svn.sharpdevelop.net/sharpdevelop/trunk@533 1ccf3a8d-04fe-1044-b7c0-cef0b8235c61
shortcuts
Daniel Grunwald 20 years ago
parent
commit
b473396c67
  1. 8
      src/AddIns/BackendBindings/CSharpBinding/Project/Src/Parser/ExpressionFinder.cs
  2. 12
      src/AddIns/BackendBindings/VBNetBinding/Project/Src/MyNamespaceBuilder.cs
  3. 2
      src/AddIns/DisplayBindings/FormDesigner/Project/Src/FormDesigner/DesignerLoader/NRefactoryDesignerLoader.cs
  4. 5
      src/AddIns/DisplayBindings/XmlEditor/Test/XmlEditor.Tests.csproj.user
  5. 4
      src/AddIns/Misc/Debugger/Debugger.Tests/Project/Debugger.Tests.csproj.user
  6. 8
      src/Main/Base/Project/Src/Dom/ClassFinder.cs
  7. 7
      src/Main/Base/Project/Src/Dom/IReturnType.cs
  8. 2
      src/Main/Base/Project/Src/Dom/IUsing.cs
  9. 8
      src/Main/Base/Project/Src/Dom/Implementations/AbstractReturnType.cs
  10. 6
      src/Main/Base/Project/Src/Dom/Implementations/CombinedReturnType.cs
  11. 2
      src/Main/Base/Project/Src/Dom/Implementations/ConstructedReturnType.cs
  12. 2
      src/Main/Base/Project/Src/Dom/Implementations/DefaultClass.cs
  13. 6
      src/Main/Base/Project/Src/Dom/Implementations/DefaultReturnType.cs
  14. 10
      src/Main/Base/Project/Src/Dom/Implementations/DefaultUsing.cs
  15. 18
      src/Main/Base/Project/Src/Dom/Implementations/GetClassReturnType.cs
  16. 7
      src/Main/Base/Project/Src/Dom/Implementations/ProxyReturnType.cs
  17. 21
      src/Main/Base/Project/Src/Dom/Implementations/SearchClassReturnType.cs
  18. 8
      src/Main/Base/Project/Src/Dom/NRefactoryResolver/NRefactoryResolver.cs
  19. 11
      src/Main/Base/Project/Src/Dom/NRefactoryResolver/TypeVisitor.cs
  20. 57
      src/Main/Base/Project/Src/Dom/ReflectionLayer/DomPersistence.cs
  21. 6
      src/Main/Base/Project/Src/Dom/ReflectionLayer/ReflectionReturnType.cs
  22. 285
      src/Main/Base/Project/Src/Services/ParserService/DefaultProjectContent.cs
  23. 7
      src/Main/Base/Project/Src/Services/ParserService/IProjectContent.cs
  24. 2
      src/Main/Base/Project/Src/Services/ParserService/ReflectionProjectContent.cs
  25. 4
      src/Main/Base/Project/Src/TextEditor/Commands/CodeGenerators/EqualsCodeGenerator.cs
  26. 2
      src/Main/Base/Project/Src/TextEditor/Gui/Editor/QuickClassBrowserPanel.cs
  27. 1
      src/Main/Base/Test/ICSharpCode.SharpDevelop.Tests.csproj
  28. 4
      src/Main/Base/Test/ICSharpCode.SharpDevelop.Tests.csproj.user
  29. 2
      src/Main/Base/Test/ReflectionLayerTests.cs
  30. 6
      src/Main/Base/Test/SearchClassTests.cs
  31. 99
      src/Main/Base/Test/SearchGenericClassTests.cs

8
src/AddIns/BackendBindings/CSharpBinding/Project/Src/Parser/ExpressionFinder.cs

@ -61,15 +61,21 @@ namespace CSharpBinding.Parser @@ -61,15 +61,21 @@ namespace CSharpBinding.Parser
string className = text.Substring(typeStart, typeEnd - typeStart);
int pos = className.IndexOf('<');
string nonGenericClassName, genericPart;
int typeParameterCount = 0;
if (pos > 0) {
nonGenericClassName = className.Substring(0, pos);
genericPart = className.Substring(pos);
pos = 0;
do {
typeParameterCount += 1;
pos = genericPart.IndexOf(',', pos + 1);
} while (pos > 0);
} else {
nonGenericClassName = className;
genericPart = null;
}
ClassFinder finder = new ClassFinder(fileName, text, typeStart);
IReturnType t = finder.SearchType(nonGenericClassName);
IReturnType t = finder.SearchType(nonGenericClassName, typeParameterCount);
IClass c = (t != null) ? t.GetUnderlyingClass() : null;
if (c != null) {
ExpressionContext context = ExpressionContext.TypeDerivingFrom(c, true);

12
src/AddIns/BackendBindings/VBNetBinding/Project/Src/MyNamespaceBuilder.cs

@ -47,21 +47,21 @@ namespace VBNetBinding @@ -47,21 +47,21 @@ namespace VBNetBinding
// we need to use GetClassReturnType instead of DefaultReturnType because we need
// a reference to the compound class.
c.Properties.Add(new DefaultProperty("Application",
new GetClassReturnType(pc, myApp.FullyQualifiedName),
new GetClassReturnType(pc, myApp.FullyQualifiedName, 0),
ModifierEnum.Public | ModifierEnum.Static,
DomRegion.Empty, DomRegion.Empty, c));
c.Properties.Add(new DefaultProperty("Computer",
new GetClassReturnType(pc, myComp.FullyQualifiedName),
new GetClassReturnType(pc, myComp.FullyQualifiedName, 0),
ModifierEnum.Public | ModifierEnum.Static,
DomRegion.Empty, DomRegion.Empty, c));
if (myForms != null) {
c.Properties.Add(new DefaultProperty("Forms",
new GetClassReturnType(pc, myForms.FullyQualifiedName),
new GetClassReturnType(pc, myForms.FullyQualifiedName, 0),
ModifierEnum.Public | ModifierEnum.Static,
DomRegion.Empty, DomRegion.Empty, c));
}
c.Properties.Add(new DefaultProperty("User",
new GetClassReturnType(pc, "Microsoft.VisualBasic.ApplicationServices.User"),
new GetClassReturnType(pc, "Microsoft.VisualBasic.ApplicationServices.User", 0),
ModifierEnum.Public | ModifierEnum.Static,
DomRegion.Empty, DomRegion.Empty, c));
cu.Classes.Add(c);
@ -90,7 +90,7 @@ namespace VBNetBinding @@ -90,7 +90,7 @@ namespace VBNetBinding
static IReturnType CreateBaseType(ICompilationUnit cu, string fullName)
{
return new GetClassReturnType(cu.ProjectContent, fullName);
return new GetClassReturnType(cu.ProjectContent, fullName, 0);
}
static IClass CreateMyComputer(ICompilationUnit cu, IProject project, string ns)
@ -128,7 +128,7 @@ namespace VBNetBinding @@ -128,7 +128,7 @@ namespace VBNetBinding
foreach (IClass c in this.ProjectContent.Classes) {
if (c.BaseClass == formClass) {
properties.Add(new DefaultProperty(c.Name,
new GetClassReturnType(this.ProjectContent, c.FullyQualifiedName),
new GetClassReturnType(this.ProjectContent, c.FullyQualifiedName, 0),
ModifierEnum.Public | ModifierEnum.Static,
DomRegion.Empty, DomRegion.Empty, c));
}

2
src/AddIns/DisplayBindings/FormDesigner/Project/Src/FormDesigner/DesignerLoader/NRefactoryDesignerLoader.cs

@ -204,7 +204,7 @@ namespace ICSharpCode.FormDesigner @@ -204,7 +204,7 @@ namespace ICSharpCode.FormDesigner
FixTypeReference(tref, location, domCu);
}
ICSharpCode.SharpDevelop.Dom.IClass curType = domCu.GetInnermostClass(location.Y, location.X);
ICSharpCode.SharpDevelop.Dom.IReturnType rt = domCu.ProjectContent.SearchType(type.Type, curType, domCu, location.Y, location.X);
ICSharpCode.SharpDevelop.Dom.IReturnType rt = domCu.ProjectContent.SearchType(type.Type, type.GenericTypes.Count, curType, domCu, location.Y, location.X);
if (rt != null) {
type.Type = rt.FullyQualifiedName;
}

5
src/AddIns/DisplayBindings/XmlEditor/Test/XmlEditor.Tests.csproj.user

@ -1,4 +1 @@ @@ -1,4 +1 @@
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' " />
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' " />
</Project>
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003" />

4
src/AddIns/Misc/Debugger/Debugger.Tests/Project/Debugger.Tests.csproj.user

@ -1,3 +1 @@ @@ -1,3 +1 @@
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' " />
</Project>
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003" />

8
src/Main/Base/Project/Src/Dom/ClassFinder.cs

@ -60,14 +60,14 @@ namespace ICSharpCode.SharpDevelop.Dom @@ -60,14 +60,14 @@ namespace ICSharpCode.SharpDevelop.Dom
}
}
public IClass GetClass(string fullName)
public IClass GetClass(string fullName, int typeParameterCount)
{
return projectContent.GetClass(fullName);
return projectContent.GetClass(fullName, typeParameterCount);
}
public IReturnType SearchType(string name)
public IReturnType SearchType(string name, int typeParameterCount)
{
return projectContent.SearchType(name, callingClass, cu, caretLine, caretColumn);
return projectContent.SearchType(name, typeParameterCount, callingClass, cu, caretLine, caretColumn);
}
public string SearchNamespace(string name)

7
src/Main/Base/Project/Src/Dom/IReturnType.cs

@ -70,6 +70,13 @@ namespace ICSharpCode.SharpDevelop.Dom @@ -70,6 +70,13 @@ namespace ICSharpCode.SharpDevelop.Dom
get;
}
/// <summary>
/// Gets the count of type parameters the target class should have.
/// </summary>
int TypeParameterCount {
get;
}
/// <summary>
/// Gets if the return type is a default type, i.e. no array, generic etc.
/// </summary>

2
src/Main/Base/Project/Src/Dom/IUsing.cs

@ -31,7 +31,7 @@ namespace ICSharpCode.SharpDevelop.Dom @@ -31,7 +31,7 @@ namespace ICSharpCode.SharpDevelop.Dom
get;
}
IReturnType SearchType(string partitialTypeName);
IReturnType SearchType(string partitialTypeName, int typeParameterCount);
string SearchNamespace(string partitialNamespaceName);
}
}

8
src/Main/Base/Project/Src/Dom/Implementations/AbstractReturnType.cs

@ -22,11 +22,17 @@ namespace ICSharpCode.SharpDevelop.Dom @@ -22,11 +22,17 @@ namespace ICSharpCode.SharpDevelop.Dom
public abstract List<IField> GetFields();
public abstract List<IEvent> GetEvents();
public virtual int TypeParameterCount {
get {
return 0;
}
}
public override bool Equals(object o)
{
IReturnType rt = o as IReturnType;
if (rt == null) return false;
return rt.IsDefaultReturnType && this.FullyQualifiedName == rt.FullyQualifiedName;
return rt.IsDefaultReturnType && this.FullyQualifiedName == rt.FullyQualifiedName && this.TypeParameterCount == rt.TypeParameterCount;
}
public override int GetHashCode()

6
src/Main/Base/Project/Src/Dom/Implementations/CombinedReturnType.cs

@ -149,6 +149,12 @@ namespace ICSharpCode.SharpDevelop.Dom @@ -149,6 +149,12 @@ namespace ICSharpCode.SharpDevelop.Dom
}
}
public int TypeParameterCount {
get {
return 0;
}
}
public IClass GetUnderlyingClass()
{
return null;

2
src/Main/Base/Project/Src/Dom/Implementations/ConstructedReturnType.cs

@ -50,7 +50,7 @@ namespace ICSharpCode.SharpDevelop.Dom @@ -50,7 +50,7 @@ namespace ICSharpCode.SharpDevelop.Dom
if (!baseType.Equals(rt.baseType)) return false;
if (typeParameters.Count != rt.typeParameters.Count) return false;
for (int i = 0; i < typeParameters.Count; ++i) {
if (!typeParameters[i].Equals(rt.typeParameters[i])) return false;
if (!object.Equals(typeParameters[i], rt.typeParameters[i])) return false;
}
return true;
}

2
src/Main/Base/Project/Src/Dom/Implementations/DefaultClass.cs

@ -64,7 +64,7 @@ namespace ICSharpCode.SharpDevelop.Dom @@ -64,7 +64,7 @@ namespace ICSharpCode.SharpDevelop.Dom
protected virtual IReturnType CreateDefaultReturnType()
{
if (IsPartial) {
return new GetClassReturnType(ProjectContent, FullyQualifiedName);
return new GetClassReturnType(ProjectContent, FullyQualifiedName, TypeParameters.Count);
} else {
return new DefaultReturnType(this);
}

6
src/Main/Base/Project/Src/Dom/Implementations/DefaultReturnType.cs

@ -27,6 +27,12 @@ namespace ICSharpCode.SharpDevelop.Dom @@ -27,6 +27,12 @@ namespace ICSharpCode.SharpDevelop.Dom
this.c = c;
}
public override int TypeParameterCount {
get {
return c.TypeParameters.Count;
}
}
public override IClass GetUnderlyingClass()
{
return c;

10
src/Main/Base/Project/Src/Dom/Implementations/DefaultUsing.cs

@ -94,7 +94,7 @@ namespace ICSharpCode.SharpDevelop.Dom @@ -94,7 +94,7 @@ namespace ICSharpCode.SharpDevelop.Dom
return null;
}
public IReturnType SearchType(string partitialTypeName)
public IReturnType SearchType(string partitialTypeName, int typeParameterCount)
{
if (HasAliases) {
foreach (KeyValuePair<string, IReturnType> entry in aliases) {
@ -107,7 +107,7 @@ namespace ICSharpCode.SharpDevelop.Dom @@ -107,7 +107,7 @@ namespace ICSharpCode.SharpDevelop.Dom
if (partitialTypeName.Length > aliasString.Length) {
if (projectContent.Language.NameComparer.Equals(partitialTypeName.Substring(0, aliasString.Length + 1), aliasString + ".")) {
string className = entry.Value.FullyQualifiedName + partitialTypeName.Remove(0, aliasString.Length);
IClass c = projectContent.GetClass(className);
IClass c = projectContent.GetClass(className, typeParameterCount);
if (c != null) {
return c.DefaultReturnType;
}
@ -117,7 +117,7 @@ namespace ICSharpCode.SharpDevelop.Dom @@ -117,7 +117,7 @@ namespace ICSharpCode.SharpDevelop.Dom
}
if (projectContent.Language.ImportNamespaces) {
foreach (string str in usings) {
IClass c = projectContent.GetClass(str + "." + partitialTypeName);
IClass c = projectContent.GetClass(str + "." + partitialTypeName, typeParameterCount);
if (c != null) {
return c.DefaultReturnType;
}
@ -133,9 +133,9 @@ namespace ICSharpCode.SharpDevelop.Dom @@ -133,9 +133,9 @@ namespace ICSharpCode.SharpDevelop.Dom
subClassName = partitialTypeName.Substring(pos + 1);
}
foreach (string str in usings) {
IClass c = projectContent.GetClass(str + "." + className);
IClass c = projectContent.GetClass(str + "." + className, typeParameterCount);
if (c != null) {
c = projectContent.GetClass(str + "." + partitialTypeName);
c = projectContent.GetClass(str + "." + partitialTypeName, typeParameterCount);
if (c != null) {
return c.DefaultReturnType;
}

18
src/Main/Base/Project/Src/Dom/Implementations/GetClassReturnType.cs

@ -20,10 +20,12 @@ namespace ICSharpCode.SharpDevelop.Dom @@ -20,10 +20,12 @@ namespace ICSharpCode.SharpDevelop.Dom
IProjectContent content;
string fullName;
string shortName;
int typeParameterCount;
public GetClassReturnType(IProjectContent content, string fullName)
public GetClassReturnType(IProjectContent content, string fullName, int typeParameterCount)
{
this.content = content;
this.typeParameterCount = typeParameterCount;
SetFullyQualifiedName(fullName);
}
@ -33,28 +35,34 @@ namespace ICSharpCode.SharpDevelop.Dom @@ -33,28 +35,34 @@ namespace ICSharpCode.SharpDevelop.Dom
}
}
public override int TypeParameterCount {
get {
return typeParameterCount;
}
}
public override bool Equals(object o)
{
GetClassReturnType rt = o as GetClassReturnType;
if (rt == null) {
IReturnType rt2 = o as IReturnType;
if (rt2 != null && rt2.IsDefaultReturnType)
return rt2.FullyQualifiedName == fullName;
return rt2.FullyQualifiedName == fullName && rt2.TypeParameterCount == this.TypeParameterCount;
else
return false;
}
return fullName == rt.fullName;
return fullName == rt.fullName && typeParameterCount == rt.typeParameterCount && content == rt.content;
}
public override int GetHashCode()
{
return content.GetHashCode() ^ fullName.GetHashCode();
return content.GetHashCode() ^ fullName.GetHashCode() ^ (typeParameterCount * 5);
}
// TODO: Cache BaseType until a new CompilationUnit is generated (static counter in ParserService)
public override IReturnType BaseType {
get {
IClass c = content.GetClass(fullName);
IClass c = content.GetClass(fullName, typeParameterCount);
return (c != null) ? c.DefaultReturnType : null;
}
}

7
src/Main/Base/Project/Src/Dom/Implementations/ProxyReturnType.cs

@ -48,6 +48,13 @@ namespace ICSharpCode.SharpDevelop.Dom @@ -48,6 +48,13 @@ namespace ICSharpCode.SharpDevelop.Dom
}
}
public virtual int TypeParameterCount {
get {
IReturnType baseType = BaseType;
return (baseType != null) ? baseType.TypeParameterCount : 0;
}
}
/// <summary>
/// Gets the array ranks of the return type.
/// When the return type is not an array, this property returns null.

21
src/Main/Base/Project/Src/Dom/Implementations/SearchClassReturnType.cs

@ -23,8 +23,9 @@ namespace ICSharpCode.SharpDevelop.Dom @@ -23,8 +23,9 @@ namespace ICSharpCode.SharpDevelop.Dom
int caretColumn;
string name;
string shortName;
int typeParameterCount;
public SearchClassReturnType(IProjectContent projectContent, IClass declaringClass, int caretLine, int caretColumn, string name)
public SearchClassReturnType(IProjectContent projectContent, IClass declaringClass, int caretLine, int caretColumn, string name, int typeParameterCount)
{
if (declaringClass == null)
throw new ArgumentNullException("declaringClass");
@ -32,6 +33,7 @@ namespace ICSharpCode.SharpDevelop.Dom @@ -32,6 +33,7 @@ namespace ICSharpCode.SharpDevelop.Dom
this.pc = projectContent;
this.caretLine = caretLine;
this.caretColumn = caretColumn;
this.typeParameterCount = typeParameterCount;
this.name = name;
int pos = name.LastIndexOf('.');
if (pos < 0)
@ -40,24 +42,35 @@ namespace ICSharpCode.SharpDevelop.Dom @@ -40,24 +42,35 @@ namespace ICSharpCode.SharpDevelop.Dom
shortName = name.Substring(pos + 1);
}
public override int TypeParameterCount {
get {
return typeParameterCount;
}
}
public override bool Equals(object o)
{
SearchClassReturnType rt = o as SearchClassReturnType;
if (rt == null) {
IReturnType rt2 = o as IReturnType;
if (rt2 != null && rt2.IsDefaultReturnType)
return rt2.FullyQualifiedName == this.FullyQualifiedName;
return rt2.FullyQualifiedName == this.FullyQualifiedName && rt2.TypeParameterCount == this.TypeParameterCount;
else
return false;
}
if (declaringClass.FullyQualifiedName != rt.declaringClass.FullyQualifiedName) return false;
if (typeParameterCount != rt.typeParameterCount) return false;
if (caretLine != rt.caretLine) return false;
if (caretColumn != rt.caretColumn) return false;
if (typeParameterCount != rt.typeParameterCount) return false;
return name == rt.name;
}
public override int GetHashCode()
{
unchecked {
return declaringClass.GetHashCode() ^ name.GetHashCode() ^ caretLine << 8 + caretColumn;
return declaringClass.GetHashCode() ^ name.GetHashCode()
^ (typeParameterCount << 16 + caretLine << 8 + caretColumn);
}
}
@ -101,7 +114,7 @@ namespace ICSharpCode.SharpDevelop.Dom @@ -101,7 +114,7 @@ namespace ICSharpCode.SharpDevelop.Dom
return type;
try {
isSearching = true;
type = pc.SearchType(name, declaringClass, caretLine, caretColumn);
type = pc.SearchType(name, typeParameterCount, declaringClass, caretLine, caretColumn);
cache[this] = type;
return type;
} finally {

8
src/Main/Base/Project/Src/Dom/NRefactoryResolver/NRefactoryResolver.cs

@ -343,7 +343,7 @@ namespace ICSharpCode.SharpDevelop.Dom.NRefactoryResolver @@ -343,7 +343,7 @@ namespace ICSharpCode.SharpDevelop.Dom.NRefactoryResolver
if (projectContent.NamespaceExists(combinedName)) {
return new NamespaceResolveResult(callingClass, callingMember, combinedName);
}
c = projectContent.GetClass(combinedName);
c = GetClass(combinedName);
if (c != null) {
return new TypeResolveResult(callingClass, callingMember, c);
}
@ -533,7 +533,7 @@ namespace ICSharpCode.SharpDevelop.Dom.NRefactoryResolver @@ -533,7 +533,7 @@ namespace ICSharpCode.SharpDevelop.Dom.NRefactoryResolver
if (languageProperties.CanImportClasses) {
foreach (IUsing @using in cu.Usings) {
foreach (string import in @using.Usings) {
IClass c = projectContent.GetClass(import);
IClass c = GetClass(import);
if (c != null) {
IMember member = GetMember(c.DefaultReturnType, identifier);
if (member != null) {
@ -694,7 +694,7 @@ namespace ICSharpCode.SharpDevelop.Dom.NRefactoryResolver @@ -694,7 +694,7 @@ namespace ICSharpCode.SharpDevelop.Dom.NRefactoryResolver
public IReturnType SearchType(string name)
{
return projectContent.SearchType(name, callingClass, cu, caretLine, caretColumn);
return projectContent.SearchType(name, 0, callingClass, cu, caretLine, caretColumn);
}
#region Helper for TypeVisitor
@ -709,7 +709,7 @@ namespace ICSharpCode.SharpDevelop.Dom.NRefactoryResolver @@ -709,7 +709,7 @@ namespace ICSharpCode.SharpDevelop.Dom.NRefactoryResolver
if (languageProperties.CanImportClasses) {
foreach (IUsing @using in cu.Usings) {
foreach (string import in @using.Usings) {
IClass c = projectContent.GetClass(import);
IClass c = projectContent.GetClass(import, 0);
if (c != null) {
methods = SearchMethod(c.DefaultReturnType, memberName);
if (methods.Count > 0)

11
src/Main/Base/Project/Src/Dom/NRefactoryResolver/TypeVisitor.cs

@ -260,7 +260,7 @@ namespace ICSharpCode.SharpDevelop.Dom.NRefactoryResolver @@ -260,7 +260,7 @@ namespace ICSharpCode.SharpDevelop.Dom.NRefactoryResolver
if (resolver.ProjectContent.NamespaceExists(combinedName)) {
return new NamespaceReturnType(combinedName);
}
IClass c = resolver.ProjectContent.GetClass(combinedName);
IClass c = resolver.GetClass(combinedName);
if (c != null) {
return c.DefaultReturnType;
}
@ -510,18 +510,19 @@ namespace ICSharpCode.SharpDevelop.Dom.NRefactoryResolver @@ -510,18 +510,19 @@ namespace ICSharpCode.SharpDevelop.Dom.NRefactoryResolver
// keyword-type like void, int, string etc.
t = ProjectContentRegistry.Mscorlib.GetClass(reference.SystemType).DefaultReturnType;
} else {
int typeParameterCount = reference.GenericTypes.Count;
if (useLazyReturnType) {
if (reference.IsGlobal)
t = new GetClassReturnType(projectContent, reference.SystemType);
t = new GetClassReturnType(projectContent, reference.SystemType, typeParameterCount);
else
t = new SearchClassReturnType(projectContent, callingClass, caretLine, caretColumn, reference.SystemType);
t = new SearchClassReturnType(projectContent, callingClass, caretLine, caretColumn, reference.SystemType, typeParameterCount);
} else {
IClass c;
if (reference.IsGlobal) {
c = projectContent.GetClass(reference.SystemType);
c = projectContent.GetClass(reference.SystemType, typeParameterCount);
t = (c != null) ? c.DefaultReturnType : null;
} else {
t = projectContent.SearchType(reference.SystemType, callingClass, caretLine, caretColumn);
t = projectContent.SearchType(reference.SystemType, typeParameterCount, callingClass, caretLine, caretColumn);
}
if (t == null) {
if (reference.GenericTypes.Count == 0 && !reference.IsArrayType) {

57
src/Main/Base/Project/Src/Dom/ReflectionLayer/DomPersistence.cs

@ -21,7 +21,7 @@ namespace ICSharpCode.SharpDevelop.Dom @@ -21,7 +21,7 @@ namespace ICSharpCode.SharpDevelop.Dom
{
public const long FileMagic = 0x11635233ED2F428C;
public const long IndexFileMagic = 0x11635233ED2F427D;
public const short FileVersion = 2;
public const short FileVersion = 3;
#region Cache management
#if DEBUG
@ -160,12 +160,39 @@ namespace ICSharpCode.SharpDevelop.Dom @@ -160,12 +160,39 @@ namespace ICSharpCode.SharpDevelop.Dom
}
#endregion
private struct ClassNameTypeCountPair {
public readonly string ClassName;
public readonly byte TypeParameterCount;
public ClassNameTypeCountPair(IClass c) {
this.ClassName = c.FullyQualifiedName;
this.TypeParameterCount = (byte)c.TypeParameters.Count;
}
public ClassNameTypeCountPair(IReturnType rt) {
this.ClassName = rt.FullyQualifiedName;
this.TypeParameterCount = (byte)rt.TypeParameterCount;
}
public override bool Equals(object obj) {
if (!(obj is ClassNameTypeCountPair)) return false;
ClassNameTypeCountPair myClassNameTypeCountPair = (ClassNameTypeCountPair)obj;
if (!ClassName.Equals(myClassNameTypeCountPair.ClassName, StringComparison.InvariantCultureIgnoreCase)) return false;
if (TypeParameterCount != myClassNameTypeCountPair.TypeParameterCount) return false;
return true;
}
public override int GetHashCode() {
return StringComparer.InvariantCultureIgnoreCase.GetHashCode(ClassName) ^ ((int)TypeParameterCount * 5);
}
}
private sealed class ReadWriteHelper
{
ReflectionProjectContent pc;
readonly BinaryWriter writer;
readonly Dictionary<string, int> classIndices = new Dictionary<string, int>(StringComparer.InvariantCultureIgnoreCase);
readonly Dictionary<ClassNameTypeCountPair, int> classIndices = new Dictionary<ClassNameTypeCountPair, int>();
readonly BinaryReader reader;
IReturnType[] types;
@ -236,11 +263,11 @@ namespace ICSharpCode.SharpDevelop.Dom @@ -236,11 +263,11 @@ namespace ICSharpCode.SharpDevelop.Dom
classIndices.Clear();
int i = 0;
foreach (IClass c in classes) {
classIndices[c.FullyQualifiedName] = i;
classIndices[new ClassNameTypeCountPair(c)] = i;
i += 1;
}
List<string> externalTypes = new List<string>();
List<ClassNameTypeCountPair> externalTypes = new List<ClassNameTypeCountPair>();
CreateExternalTypeList(externalTypes, classes.Count, classes);
writer.Write(classes.Count);
@ -248,8 +275,9 @@ namespace ICSharpCode.SharpDevelop.Dom @@ -248,8 +275,9 @@ namespace ICSharpCode.SharpDevelop.Dom
foreach (IClass c in classes) {
writer.Write(c.FullyQualifiedName);
}
foreach (string type in externalTypes) {
writer.Write(type);
foreach (ClassNameTypeCountPair type in externalTypes) {
writer.Write(type.ClassName);
writer.Write(type.TypeParameterCount);
}
foreach (IClass c in classes) {
WriteClass(c);
@ -268,7 +296,8 @@ namespace ICSharpCode.SharpDevelop.Dom @@ -268,7 +296,8 @@ namespace ICSharpCode.SharpDevelop.Dom
types[i] = c.DefaultReturnType;
}
for (int i = classCount; i < types.Length; i++) {
types[i] = new GetClassReturnType(pc, reader.ReadString());
string name = reader.ReadString();
types[i] = new GetClassReturnType(pc, name, reader.ReadByte());
}
for (int i = 0; i < classes.Length; i++) {
ReadClass(classes[i]);
@ -385,7 +414,7 @@ namespace ICSharpCode.SharpDevelop.Dom @@ -385,7 +414,7 @@ namespace ICSharpCode.SharpDevelop.Dom
/// Finds all return types used in the class collection and adds the unknown ones
/// to the externalTypeIndices and externalTypes collections.
/// </summary>
void CreateExternalTypeList(List<string> externalTypes,
void CreateExternalTypeList(List<ClassNameTypeCountPair> externalTypes,
int classCount, ICollection<IClass> classes)
{
foreach (IClass c in classes) {
@ -424,13 +453,13 @@ namespace ICSharpCode.SharpDevelop.Dom @@ -424,13 +453,13 @@ namespace ICSharpCode.SharpDevelop.Dom
}
}
void AddExternalType(IReturnType rt, List<string> externalTypes, int classCount)
void AddExternalType(IReturnType rt, List<ClassNameTypeCountPair> externalTypes, int classCount)
{
if (rt.IsDefaultReturnType) {
string name = rt.FullyQualifiedName;
if (!classIndices.ContainsKey(name)) {
classIndices.Add(name, externalTypes.Count + classCount);
externalTypes.Add(name);
ClassNameTypeCountPair pair = new ClassNameTypeCountPair(rt);
if (!classIndices.ContainsKey(pair)) {
classIndices.Add(pair, externalTypes.Count + classCount);
externalTypes.Add(pair);
}
} else if (rt is ArrayReturnType) {
AddExternalType(((ArrayReturnType)rt).ElementType, externalTypes, classCount);
@ -465,7 +494,7 @@ namespace ICSharpCode.SharpDevelop.Dom @@ -465,7 +494,7 @@ namespace ICSharpCode.SharpDevelop.Dom
if (name == "System.Void") {
writer.Write(VoidRTCode);
} else {
writer.Write(classIndices[rt.FullyQualifiedName]);
writer.Write(classIndices[new ClassNameTypeCountPair(rt)]);
}
} else if (rt is ArrayReturnType) {
ArrayReturnType art = (ArrayReturnType)rt;

6
src/Main/Base/Project/Src/Dom/ReflectionLayer/ReflectionReturnType.cs

@ -152,8 +152,10 @@ namespace ICSharpCode.SharpDevelop.Dom @@ -152,8 +152,10 @@ namespace ICSharpCode.SharpDevelop.Dom
name = name.Substring(0, name.Length - 1);
}
}
int typeParameterCount = 0;
if (name.Length > 2) {
if (name[name.Length - 2] == '`') {
typeParameterCount = int.Parse(name[name.Length - 1].ToString());
name = name.Substring(0, name.Length - 2);
}
}
@ -161,13 +163,13 @@ namespace ICSharpCode.SharpDevelop.Dom @@ -161,13 +163,13 @@ namespace ICSharpCode.SharpDevelop.Dom
name = name.Replace('+', '.');
}
if (!createLazyReturnType) {
IClass c = content.GetClass(name);
IClass c = content.GetClass(name, typeParameterCount);
if (c != null)
return c.DefaultReturnType;
// example where name is not found: pointers like System.Char*
// or when the class is in a assembly that is not referenced
}
return new GetClassReturnType(content, name);
return new GetClassReturnType(content, name, typeParameterCount);
}
}

285
src/Main/Base/Project/Src/Services/ParserService/DefaultProjectContent.cs

@ -147,7 +147,18 @@ namespace ICSharpCode.Core @@ -147,7 +147,18 @@ namespace ICSharpCode.Core
public ICollection<IClass> Classes {
get {
return ClassLists[0].Values;
lock (namespaces) {
List<IClass> list = new List<IClass>(ClassLists[0].Count + 10);
foreach (IClass c in ClassLists[0].Values) {
if (c is GenericClassContainer) {
GenericClassContainer gcc = (GenericClassContainer)c;
list.AddRange(gcc.RealClasses);
} else {
list.Add(c);
}
}
return list;
}
}
}
@ -212,14 +223,80 @@ namespace ICSharpCode.Core @@ -212,14 +223,80 @@ namespace ICSharpCode.Core
}
}
/// <summary>
/// Container class that is used when multiple classes with different type parameter
/// count have the same class name.
/// </summary>
private class GenericClassContainer : DefaultClass
{
public GenericClassContainer(string fullyQualifiedName) : base(null, fullyQualifiedName) {}
IClass[] realClasses = new IClass[4];
public IEnumerable<IClass> RealClasses {
get {
foreach (IClass c in realClasses) {
if (c != null) yield return c;
}
}
}
public int RealClassCount {
get {
int count = 0;
foreach (IClass c in realClasses) {
if (c != null) count += 1;
}
return count;
}
}
public IClass Get(int typeParameterCount)
{
if (realClasses.Length > typeParameterCount)
return realClasses[typeParameterCount];
else
return null;
}
public IClass GetBest(int typeParameterCount)
{
IClass c;
for (int i = typeParameterCount; i < realClasses.Length; i++) {
c = Get(i);
if (c != null) return c;
}
for (int i = typeParameterCount - 1; i >= 0; i--) {
c = Get(i);
if (c != null) return c;
}
return null;
}
public void Set(IClass c)
{
int typeParameterCount = c.TypeParameters.Count;
if (realClasses.Length <= typeParameterCount) {
IClass[] newArray = new IClass[typeParameterCount + 2];
realClasses.CopyTo(newArray, 0);
realClasses = newArray;
}
realClasses[typeParameterCount] = c;
}
public void Remove(int typeParameterCount)
{
if (realClasses.Length > typeParameterCount)
realClasses[typeParameterCount] = null;
}
}
protected void AddClassToNamespaceListInternal(IClass addClass)
{
string fullyQualifiedName = addClass.FullyQualifiedName;
if (addClass.IsPartial) {
LoggingService.Debug("Adding partial class " + addClass.Name + " from " + Path.GetFileName(addClass.CompilationUnit.FileName));
Dictionary<string, IClass> classes = GetClasses(language);
CompoundClass compound = null;
if (classes.ContainsKey(addClass.FullyQualifiedName))
compound = classes[addClass.FullyQualifiedName] as CompoundClass;
CompoundClass compound = GetClassInternal(fullyQualifiedName, addClass.TypeParameters.Count, language) as CompoundClass;
if (compound != null) {
// possibly replace existing class (look for CU with same filename)
for (int i = 0; i < compound.Parts.Count; i++) {
@ -240,6 +317,20 @@ namespace ICSharpCode.Core @@ -240,6 +317,20 @@ namespace ICSharpCode.Core
}
}
IClass oldDictionaryClass;
if (GetClasses(language).TryGetValue(fullyQualifiedName, out oldDictionaryClass)) {
GenericClassContainer gcc = oldDictionaryClass as GenericClassContainer;
if (gcc != null) {
gcc.Set(addClass);
return;
} else if (oldDictionaryClass.TypeParameters.Count != addClass.TypeParameters.Count) {
gcc = new GenericClassContainer(fullyQualifiedName);
gcc.Set(addClass);
gcc.Set(oldDictionaryClass);
addClass = gcc;
}
}
foreach (Dictionary<string, IClass> classes in ClassLists) {
classes[addClass.FullyQualifiedName] = addClass;
}
@ -355,13 +446,11 @@ namespace ICSharpCode.Core @@ -355,13 +446,11 @@ namespace ICSharpCode.Core
void RemoveClass(IClass @class)
{
string fullClassName = @class.FullyQualifiedName;
if (!GetClasses(language).ContainsKey(fullClassName)) {
return;
}
string fullyQualifiedName = @class.FullyQualifiedName;
if (@class.IsPartial) {
// remove a part of a partial class
CompoundClass compound = (CompoundClass)GetClasses(language)[fullClassName];
CompoundClass compound = (CompoundClass)GetClassInternal(fullyQualifiedName, @class.TypeParameters.Count, language);
if (compound == null) return;
compound.Parts.Remove(@class);
if (compound.Parts.Count > 0) {
compound.UpdateInformationFromParts();
@ -370,23 +459,33 @@ namespace ICSharpCode.Core @@ -370,23 +459,33 @@ namespace ICSharpCode.Core
@class = compound; // all parts removed, remove compound class
}
}
string nSpace = @class.Namespace;
if (nSpace == null) {
nSpace = String.Empty;
IClass classInDictionary;
if (!GetClasses(language).TryGetValue(fullyQualifiedName, out classInDictionary)) {
return;
}
RemoveClass(fullClassName, nSpace);
}
void RemoveClass(string fullyQualifiedName, string nSpace)
{
GenericClassContainer gcc = classInDictionary as GenericClassContainer;
if (gcc != null) {
gcc.Remove(@class.TypeParameters.Count);
if (gcc.RealClassCount > 0) {
return;
}
}
foreach (Dictionary<string, IClass> classes in ClassLists) {
classes.Remove(fullyQualifiedName);
}
string nSpace = @class.Namespace;
if (nSpace == null) {
nSpace = String.Empty;
}
// Remove class from namespace lists
List<IClass> classList = GetNamespaces(this.language)[nSpace].Classes;
for (int i = 0; i < classList.Count; i++) {
if (classList[i].FullyQualifiedName == fullyQualifiedName) {
if (language.NameComparer.Equals(classList[i].FullyQualifiedName, fullyQualifiedName)) {
classList.RemoveAt(i);
break;
}
@ -399,38 +498,64 @@ namespace ICSharpCode.Core @@ -399,38 +498,64 @@ namespace ICSharpCode.Core
#region Default Parser Layer dependent functions
public IClass GetClass(string typeName)
{
return GetClass(typeName, language, true);
return GetClass(typeName, 0);
}
public IClass GetClass(string typeName, int typeParameterCount)
{
return GetClass(typeName, typeParameterCount, language, true);
}
protected IClass GetClassInternal(string typeName, int typeParameterCount, LanguageProperties language)
{
IClass c;
if (GetClasses(language).TryGetValue(typeName, out c)) {
GenericClassContainer gcc = c as GenericClassContainer;
if (gcc != null) {
return gcc.GetBest(typeParameterCount);
}
return c;
}
return null;
}
public IClass GetClass(string typeName, LanguageProperties language, bool lookInReferences)
public IClass GetClass(string typeName, int typeParameterCount, LanguageProperties language, bool lookInReferences)
{
Dictionary<string, IClass> classes = GetClasses(language);
if (classes.ContainsKey(typeName)) {
return classes[typeName];
IClass c = GetClassInternal(typeName, typeParameterCount, language);
if (c != null && c.TypeParameters.Count == typeParameterCount) {
return c;
}
// Search in references:
if (lookInReferences) {
foreach (IProjectContent content in referencedContents) {
IClass classFromContent = content.GetClass(typeName, language, false);
if (classFromContent != null) {
return classFromContent;
IClass contentClass = content.GetClass(typeName, typeParameterCount, language, false);
if (contentClass != null) {
if (contentClass.TypeParameters.Count == typeParameterCount) {
return contentClass;
} else {
c = contentClass;
}
}
}
}
if (c != null) {
return c;
}
// not found -> maybe nested type -> trying to find class that contains this one.
int lastIndex = typeName.LastIndexOf('.');
if (lastIndex > 0) {
string outerName = typeName.Substring(0, lastIndex);
if (classes.ContainsKey(outerName)) {
IClass upperClass = classes[outerName];
IClass upperClass = GetClassInternal(outerName, typeParameterCount, language);
if (upperClass != null) {
List<IClass> innerClasses = upperClass.InnerClasses;
if (innerClasses != null) {
string innerName = typeName.Substring(lastIndex + 1);
foreach (IClass c in innerClasses) {
if (language.NameComparer.Equals(c.Name, innerName)) {
return c;
foreach (IClass innerClass in innerClasses) {
if (language.NameComparer.Equals(innerClass.Name, innerName)) {
return innerClass;
}
}
}
@ -468,29 +593,12 @@ namespace ICSharpCode.Core @@ -468,29 +593,12 @@ namespace ICSharpCode.Core
if (list.Capacity < newCapacity)
list.Capacity = newCapacity;
foreach (IClass c in ns.Classes) {
if (c.IsInternal && !lookInReferences) {
// internal class and we are looking at it from another project content
continue;
}
if (language.ShowInNamespaceCompletion(c))
list.Add(c);
if (language.ImportModules && c.ClassType == ClassType.Module) {
foreach (IMember m in c.Methods) {
if (m.IsAccessible(null, false))
list.Add(m);
}
foreach (IMember m in c.Events) {
if (m.IsAccessible(null, false))
list.Add(m);
}
foreach (IMember m in c.Fields) {
if (m.IsAccessible(null, false))
list.Add(m);
}
foreach (IMember m in c.Properties) {
if (m.IsAccessible(null, false))
list.Add(m);
if (c is GenericClassContainer) {
foreach (IClass realClass in ((GenericClassContainer)c).RealClasses) {
AddNamespaceContentsClass(list, realClass, language, lookInReferences);
}
} else {
AddNamespaceContentsClass(list, c, language, lookInReferences);
}
}
foreach (string subns in ns.SubNamespaces) {
@ -500,6 +608,34 @@ namespace ICSharpCode.Core @@ -500,6 +608,34 @@ namespace ICSharpCode.Core
}
}
void AddNamespaceContentsClass(ArrayList list, IClass c, LanguageProperties language, bool lookInReferences)
{
if (c.IsInternal && !lookInReferences) {
// internal class and we are looking at it from another project content
return;
}
if (language.ShowInNamespaceCompletion(c))
list.Add(c);
if (language.ImportModules && c.ClassType == ClassType.Module) {
foreach (IMember m in c.Methods) {
if (m.IsAccessible(null, false))
list.Add(m);
}
foreach (IMember m in c.Events) {
if (m.IsAccessible(null, false))
list.Add(m);
}
foreach (IMember m in c.Fields) {
if (m.IsAccessible(null, false))
list.Add(m);
}
foreach (IMember m in c.Properties) {
if (m.IsAccessible(null, false))
list.Add(m);
}
}
}
public bool NamespaceExists(string name)
{
return NamespaceExists(name, language, true);
@ -570,25 +706,27 @@ namespace ICSharpCode.Core @@ -570,25 +706,27 @@ namespace ICSharpCode.Core
return null;
}
public IReturnType SearchType(string name, IClass curType, int caretLine, int caretColumn)
public IReturnType SearchType(string name, int typeParameterCount, IClass curType, int caretLine, int caretColumn)
{
if (curType == null) {
return SearchType(name, null, null, caretLine, caretColumn);
return SearchType(name, typeParameterCount, null, null, caretLine, caretColumn);
}
return SearchType(name, curType, curType.CompilationUnit, caretLine, caretColumn);
return SearchType(name, typeParameterCount, curType, curType.CompilationUnit, caretLine, caretColumn);
}
public IReturnType SearchType(string name, IClass curType, ICompilationUnit unit, int caretLine, int caretColumn)
public IReturnType SearchType(string name, int typeParameterCount, IClass curType, ICompilationUnit unit, int caretLine, int caretColumn)
{
if (name == null || name.Length == 0) {
return null;
}
// Try if name is already the full type name
IClass c = GetClass(name);
IClass c = GetClass(name, typeParameterCount);
if (c != null) {
return c.DefaultReturnType;
}
// fallback-class if the one with the right type parameter count is not found.
IReturnType fallbackClass = null;
if (curType != null) {
// Try parent namespaces of the current class
string fullname = curType.FullyQualifiedName;
@ -599,9 +737,12 @@ namespace ICSharpCode.Core @@ -599,9 +737,12 @@ namespace ICSharpCode.Core
curnamespace.Append('.');
curnamespace.Append(name);
c = GetClass(curnamespace.ToString());
c = GetClass(curnamespace.ToString(), typeParameterCount);
if (c != null) {
return c.DefaultReturnType;
if (c.TypeParameters.Count == typeParameterCount)
return c.DefaultReturnType;
else
fallbackClass = c.DefaultReturnType;
}
// remove class name again to try next namespace
curnamespace.Length -= name.Length;
@ -621,20 +762,28 @@ namespace ICSharpCode.Core @@ -621,20 +762,28 @@ namespace ICSharpCode.Core
// Combine name with usings
foreach (IUsing u in unit.Usings) {
if (u != null) {
IReturnType r = u.SearchType(name);
IReturnType r = u.SearchType(name, typeParameterCount);
if (r != null) {
return r;
if (r.TypeParameterCount == typeParameterCount) {
return r;
} else {
fallbackClass = r;
}
}
}
}
}
if (defaultImports != null) {
IReturnType r = defaultImports.SearchType(name);
IReturnType r = defaultImports.SearchType(name, typeParameterCount);
if (r != null) {
return r;
if (r.TypeParameterCount == typeParameterCount) {
return r;
} else {
fallbackClass = r;
}
}
}
return null;
return fallbackClass;
}
/// <summary>
@ -643,7 +792,7 @@ namespace ICSharpCode.Core @@ -643,7 +792,7 @@ namespace ICSharpCode.Core
/// <param name="fullMemberName">Fully qualified member name (always case sensitive).</param>
public Position GetPosition(string fullMemberName)
{
IClass curClass = GetClass(fullMemberName, LanguageProperties.CSharp, false);
IClass curClass = GetClass(fullMemberName, 0, LanguageProperties.CSharp, false);
if (curClass != null) {
return new Position(curClass.CompilationUnit, curClass.Region.BeginLine, curClass.Region.BeginColumn);
}
@ -651,7 +800,7 @@ namespace ICSharpCode.Core @@ -651,7 +800,7 @@ namespace ICSharpCode.Core
if (pos > 0) {
string className = fullMemberName.Substring(0, pos);
string memberName = fullMemberName.Substring(pos + 1);
curClass = GetClass(className, LanguageProperties.CSharp, false);
curClass = GetClass(className, 0, LanguageProperties.CSharp, false);
if (curClass != null) {
IMember member = curClass.SearchMember(memberName, LanguageProperties.CSharp);
if (member != null) {

7
src/Main/Base/Project/Src/Services/ParserService/IProjectContent.cs

@ -74,10 +74,11 @@ namespace ICSharpCode.Core @@ -74,10 +74,11 @@ namespace ICSharpCode.Core
void UpdateCompilationUnit(ICompilationUnit oldUnit, ICompilationUnit parserOutput, string fileName, bool updateCommentTags);
IClass GetClass(string typeName);
IClass GetClass(string typeName, int typeParameterCount);
bool NamespaceExists(string name);
ArrayList GetNamespaceContents(string nameSpace);
IClass GetClass(string typeName, LanguageProperties language, bool lookInReferences);
IClass GetClass(string typeName, int typeParameterCount, LanguageProperties language, bool lookInReferences);
bool NamespaceExists(string name, LanguageProperties language, bool lookInReferences);
/// <summary>
/// Adds the contents of the specified <paramref name="subNameSpace"/> to the <paramref name="list"/>.
@ -85,8 +86,8 @@ namespace ICSharpCode.Core @@ -85,8 +86,8 @@ namespace ICSharpCode.Core
void AddNamespaceContents(ArrayList list, string subNameSpace, LanguageProperties language, bool lookInReferences);
string SearchNamespace(string name, IClass curType, ICompilationUnit unit, int caretLine, int caretColumn);
IReturnType SearchType(string name, IClass curType, int caretLine, int caretColumn);
IReturnType SearchType(string name, IClass curType, ICompilationUnit unit, int caretLine, int caretColumn);
IReturnType SearchType(string name, int typeParameterCount, IClass curType, int caretLine, int caretColumn);
IReturnType SearchType(string name, int typeParameterCount, IClass curType, ICompilationUnit unit, int caretLine, int caretColumn);
Position GetPosition(string fullMemberName);
}

2
src/Main/Base/Project/Src/Services/ParserService/ReflectionProjectContent.cs

@ -91,7 +91,7 @@ namespace ICSharpCode.SharpDevelop.Dom @@ -91,7 +91,7 @@ namespace ICSharpCode.SharpDevelop.Dom
public void InitializeSpecialClasses()
{
if (ClassLists[0].ContainsKey(VoidClass.VoidName)) {
if (GetClassInternal(VoidClass.VoidName, 0, Language) != null) {
AddClassToNamespaceList(new VoidClass(assemblyCompilationUnit));
}
}

4
src/Main/Base/Project/Src/TextEditor/Commands/CodeGenerators/EqualsCodeGenerator.cs

@ -69,7 +69,7 @@ namespace ICSharpCode.SharpDevelop.DefaultEditor.Commands @@ -69,7 +69,7 @@ namespace ICSharpCode.SharpDevelop.DefaultEditor.Commands
foreach (IField field in currentClass.Fields) {
Indent();
IClass cName = ParserService.CurrentProjectContent.GetClass(field.ReturnType.FullyQualifiedName);
IClass cName = field.ReturnType.GetUnderlyingClass();
if (cName == null || cName.ClassType == ClassType.Struct || cName.ClassType == ClassType.Enum) {
editActionHandler.InsertString("if (" + field.Name + " != " + className + "." + field.Name + ") return false;");++numOps;
} else {
@ -97,7 +97,7 @@ namespace ICSharpCode.SharpDevelop.DefaultEditor.Commands @@ -97,7 +97,7 @@ namespace ICSharpCode.SharpDevelop.DefaultEditor.Commands
editActionHandler.InsertString("return ");++numOps;
for (int i = 0; i < currentClass.Fields.Count; ++i) {
IField field = currentClass.Fields[i];
IClass cName = ParserService.CurrentProjectContent.GetClass(field.ReturnType.FullyQualifiedName);
IClass cName = field.ReturnType.GetUnderlyingClass();
if (cName == null || cName.ClassType == ClassType.Struct || cName.ClassType == ClassType.Enum) {
editActionHandler.InsertString(field.Name + ".GetHashCode()");++numOps;
} else {

2
src/Main/Base/Project/Src/TextEditor/Gui/Editor/QuickClassBrowserPanel.cs

@ -336,7 +336,7 @@ namespace ICSharpCode.SharpDevelop.DefaultEditor.Gui.Editor @@ -336,7 +336,7 @@ namespace ICSharpCode.SharpDevelop.DefaultEditor.Gui.Editor
bool partialMode = false;
IClass currentPart = c;
if (c.IsPartial) {
CompoundClass cc = c.ProjectContent.GetClass(c.FullyQualifiedName) as CompoundClass;
CompoundClass cc = c.DefaultReturnType.GetUnderlyingClass() as CompoundClass;
if (cc != null && cc.Parts.Count > 0) {
partialMode = true;
c = cc;

1
src/Main/Base/Test/ICSharpCode.SharpDevelop.Tests.csproj

@ -50,6 +50,7 @@ @@ -50,6 +50,7 @@
<Compile Include="RefactoringTests.cs" />
<Compile Include="SearchClassTests.cs" />
<Compile Include="OverloadFinding.cs" />
<Compile Include="SearchGenericClassTests.cs" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Project\ICSharpCode.SharpDevelop.csproj">

4
src/Main/Base/Test/ICSharpCode.SharpDevelop.Tests.csproj.user

@ -1,3 +1 @@ @@ -1,3 +1 @@
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' " />
</Project>
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003" />

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

@ -45,7 +45,7 @@ namespace ICSharpCode.SharpDevelop.Tests @@ -45,7 +45,7 @@ namespace ICSharpCode.SharpDevelop.Tests
public void ParameterComparisonTest()
{
DefaultParameter p1 = new DefaultParameter("a", pc.GetClass("System.String").DefaultReturnType, DomRegion.Empty);
DefaultParameter p2 = new DefaultParameter("b", new GetClassReturnType(pc, "System.String"), DomRegion.Empty);
DefaultParameter p2 = new DefaultParameter("b", new GetClassReturnType(pc, "System.String", 0), DomRegion.Empty);
List<IParameter> a1 = new List<IParameter>();
List<IParameter> a2 = new List<IParameter>();
a1.Add(p1);

6
src/Main/Base/Test/SearchClassTests.cs

@ -40,7 +40,7 @@ namespace ICSharpCode.SharpDevelop.Tests @@ -40,7 +40,7 @@ namespace ICSharpCode.SharpDevelop.Tests
IReturnType SearchType(string type)
{
ICompilationUnit cu = Prepare(LanguageProperties.CSharp);
IReturnType c = cu.ProjectContent.SearchType(type, null, cu, 1, 1);
IReturnType c = cu.ProjectContent.SearchType(type, 0, null, cu, 1, 1);
Assert.IsNotNull(c, type + "not found");
return c;
}
@ -48,7 +48,7 @@ namespace ICSharpCode.SharpDevelop.Tests @@ -48,7 +48,7 @@ namespace ICSharpCode.SharpDevelop.Tests
IReturnType SearchTypeVB(string type)
{
ICompilationUnit cu = Prepare(LanguageProperties.VBNet);
IReturnType c = cu.ProjectContent.SearchType(type, null, cu, 1, 1);
IReturnType c = cu.ProjectContent.SearchType(type, 0, null, cu, 1, 1);
Assert.IsNotNull(c, type + "not found");
return c;
}
@ -116,7 +116,7 @@ namespace ICSharpCode.SharpDevelop.Tests @@ -116,7 +116,7 @@ namespace ICSharpCode.SharpDevelop.Tests
public void SearchArrayList()
{
ICompilationUnit cu = Prepare(LanguageProperties.CSharp);
IReturnType c = cu.ProjectContent.SearchType("Collections.ArrayList", null, cu, 1, 1);
IReturnType c = cu.ProjectContent.SearchType("Collections.ArrayList", 0, null, cu, 1, 1);
Assert.IsNull(c, "Namespaces should not be imported in C#");
}

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

@ -0,0 +1,99 @@ @@ -0,0 +1,99 @@
// <file>
// <copyright see="prj:///doc/copyright.txt">2002-2005 AlphaSierraPapa</copyright>
// <license see="prj:///doc/license.txt">GNU General Public License</license>
// <owner name="Daniel Grunwald" email="daniel@danielgrunwald.de"/>
// <version>$Revision$</version>
// </file>
using System;
using System.Collections.Generic;
using NUnit.Framework;
using ICSharpCode.Core;
using ICSharpCode.SharpDevelop.Dom;
namespace ICSharpCode.SharpDevelop.Tests
{
[TestFixture]
public class SearchGenericClassTests
{
#region Helper methods
ICompilationUnit Prepare(LanguageProperties language)
{
DefaultProjectContent pc = new DefaultProjectContent();
pc.ReferencedContents.Add(ProjectContentRegistry.Mscorlib);
pc.Language = language;
DefaultCompilationUnit cu = new DefaultCompilationUnit(pc);
if (language == LanguageProperties.VBNet) {
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 {
cu.Usings.Add(CreateUsing(pc, "System"));
cu.Usings.Add(CreateUsing(pc, "System.Collections"));
cu.Usings.Add(CreateUsing(pc, "System.Collections.Generic"));
}
return cu;
}
IUsing CreateUsing(IProjectContent pc, string @namespace)
{
DefaultUsing @using = new DefaultUsing(pc);
@using.Usings.Add(@namespace);
return @using;
}
IReturnType SearchType(string type, int typeParameterCount)
{
ICompilationUnit cu = Prepare(LanguageProperties.CSharp);
IReturnType c = cu.ProjectContent.SearchType(type, typeParameterCount, null, cu, 1, 1);
Assert.IsNotNull(c, type + "not found");
return c;
}
IReturnType SearchTypeVB(string type, int typeParameterCount)
{
ICompilationUnit cu = Prepare(LanguageProperties.VBNet);
IReturnType c = cu.ProjectContent.SearchType(type, typeParameterCount, null, cu, 1, 1);
Assert.IsNotNull(c, type + "not found");
return c;
}
void CheckType(string shortName, string vbShortName, string fullType, int typeParameterCount)
{
IReturnType type = SearchType(shortName, typeParameterCount);
Assert.AreEqual(fullType, type.FullyQualifiedName);
Assert.AreEqual(typeParameterCount, type.TypeParameterCount);
type = SearchTypeVB(vbShortName, typeParameterCount);
Assert.AreEqual(fullType, type.FullyQualifiedName);
Assert.AreEqual(typeParameterCount, type.TypeParameterCount);
}
#endregion
// EventHandler vs. EventHandler<TEventArgs>
// both mscorlib, both namespace System
[Test] public void FindEventHandler() {
CheckType("EventHandler", "EvEnThAndler", "System.EventHandler", 0);
}
[Test] public void FindGenericEventHandler() {
CheckType("EventHandler", "EvEnThAndler", "System.EventHandler", 1);
}
[Test] public void FindNullableClass() {
CheckType("Nullable", "NuLLable", "System.Nullable", 0);
}
[Test] public void FindNullableStruct() {
CheckType("Nullable", "NuLLable", "System.Nullable", 1);
}
// ICollection vs. ICollection<T>
// both mscorlib, different namespaces
[Test] public void FindCollection() {
CheckType("ICollection", "IColLEction", "System.Collections.ICollection", 0);
}
[Test] public void FindGenericCollection() {
CheckType("ICollection", "IColLEction", "System.Collections.Generic.ICollection", 1);
}
}
}
Loading…
Cancel
Save