Browse Source

Fixed SD2-1397 - Code completion does not work for nested classes inside generic classes.

git-svn-id: svn://svn.sharpdevelop.net/sharpdevelop/branches/3.0@4010 1ccf3a8d-04fe-1044-b7c0-cef0b8235c61
shortcuts
Daniel Grunwald 16 years ago
parent
commit
5df6bd39e8
  1. 14
      src/Main/Base/Test/ReflectionLayerTests.cs
  2. 28
      src/Main/ICSharpCode.SharpDevelop.Dom/Project/Src/CecilReader.cs
  3. 13
      src/Main/ICSharpCode.SharpDevelop.Dom/Project/Src/Implementations/GetClassReturnType.cs
  4. 4
      src/Main/ICSharpCode.SharpDevelop.Dom/Project/Src/ProjectContent/DefaultProjectContent.cs
  5. 3
      src/Main/ICSharpCode.SharpDevelop.Dom/Project/Src/ReflectionLayer/DomPersistence.cs
  6. 30
      src/Main/ICSharpCode.SharpDevelop.Dom/Project/Src/ReflectionLayer/ReflectionClass.cs
  7. 22
      src/Main/ICSharpCode.SharpDevelop.Dom/Project/Src/ReflectionLayer/ReflectionReturnType.cs

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

@ -67,7 +67,7 @@ namespace ICSharpCode.SharpDevelop.Tests @@ -67,7 +67,7 @@ namespace ICSharpCode.SharpDevelop.Tests
{
public CecilLayerTests()
{
pc = CecilReader.LoadAssembly(typeof(object).Assembly.Location, ParserService.DefaultProjectContentRegistry);;
pc = CecilReader.LoadAssembly(typeof(object).Assembly.Location, ParserService.DefaultProjectContentRegistry);
}
protected override IClass GetClass(Type type)
@ -194,6 +194,18 @@ namespace ICSharpCode.SharpDevelop.Tests @@ -194,6 +194,18 @@ namespace ICSharpCode.SharpDevelop.Tests
Assert.AreSame(c.DefaultReturnType, pc.SystemTypes.Void, "pc.SystemTypes.Void is c.DefaultReturnType");
}
[Test]
public void NestedClassInGenericClassTest()
{
IClass dictionary = pc.GetClass("System.Collections.Generic.Dictionary", 2);
Assert.IsNotNull(dictionary);
IClass valueCollection = pc.GetClass("System.Collections.Generic.Dictionary.ValueCollection", 2);
Assert.IsNotNull(valueCollection);
var dictionaryRT = new ConstructedReturnType(dictionary.DefaultReturnType, new[] { pc.SystemTypes.String, pc.SystemTypes.Int32 });
IProperty valueProperty = dictionaryRT.GetProperties().Find(p => p.Name == "Values");
Assert.AreSame(valueCollection, valueProperty.ReturnType.GetUnderlyingClass());
}
public class TestClass<A, B> where A : B {
public void TestMethod<K, V>(string param) where V: K where K: IComparable {}

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

@ -8,10 +8,10 @@ @@ -8,10 +8,10 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Text;
using ICSharpCode.SharpDevelop.Dom.ReflectionLayer;
using Mono.Cecil;
using AssemblyName = System.Reflection.AssemblyName;
namespace ICSharpCode.SharpDevelop.Dom
{
@ -109,13 +109,20 @@ namespace ICSharpCode.SharpDevelop.Dom @@ -109,13 +109,20 @@ namespace ICSharpCode.SharpDevelop.Dom
if (name == null)
throw new ApplicationException("type.FullName returned null. Type: " + type.ToString());
int typeParameterCount;
if (name.IndexOf('/') > 0) {
name = name.Replace('/', '.');
}
int typeParameterCount = 0;
if (name.Length > 2 && name[name.Length - 2] == '`') {
typeParameterCount = name[name.Length - 1] - '0';
name = name.Substring(0, name.Length - 2);
typeParameterCount = 0;
StringBuilder newName = new StringBuilder();
foreach (string namepart in name.Split('/')) {
if (newName.Length > 0)
newName.Append('.');
int partTypeParameterCount;
newName.Append(ReflectionClass.SplitTypeParameterCountFromReflectionName(namepart, out partTypeParameterCount));
typeParameterCount += partTypeParameterCount;
}
name = newName.ToString();
} else {
name = ReflectionClass.SplitTypeParameterCountFromReflectionName(name, out typeParameterCount);
}
IClass c = pc.GetClass(name, typeParameterCount);
@ -238,7 +245,7 @@ namespace ICSharpCode.SharpDevelop.Dom @@ -238,7 +245,7 @@ namespace ICSharpCode.SharpDevelop.Dom
BaseTypes.Add(CreateType(this.ProjectContent, this, iface));
}
ReflectionLayer.ReflectionClass.ApplySpecialsFromAttributes(this);
ReflectionClass.ApplySpecialsFromAttributes(this);
InitMembers(td);
}
@ -265,8 +272,7 @@ namespace ICSharpCode.SharpDevelop.Dom @@ -265,8 +272,7 @@ namespace ICSharpCode.SharpDevelop.Dom
name = name.Substring(pos + 1);
if (name.Length == 0 || name[0] == '<')
continue;
if (name.Length > 2 && name[name.Length - 2] == '`')
name = name.Substring(0, name.Length - 2);
name = ReflectionClass.SplitTypeParameterCountFromReflectionName(name);
name = this.FullyQualifiedName + "." + name;
InnerClasses.Add(new CecilClass(this.CompilationUnit, this, nestedType, name));
}

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

@ -19,12 +19,19 @@ namespace ICSharpCode.SharpDevelop.Dom @@ -19,12 +19,19 @@ namespace ICSharpCode.SharpDevelop.Dom
string fullName;
string shortName;
int typeArgumentCount;
GetClassOptions options;
public GetClassReturnType(IProjectContent content, string fullName, int typeParameterCount)
public GetClassReturnType(IProjectContent content, string fullName, int typeArgumentCount)
: this(content, fullName, typeArgumentCount, GetClassOptions.Default)
{
}
public GetClassReturnType(IProjectContent content, string fullName, int typeArgumentCount, GetClassOptions options)
{
this.content = content;
this.typeArgumentCount = typeParameterCount;
this.typeArgumentCount = typeArgumentCount;
SetFullyQualifiedName(fullName);
this.options = options;
}
public override bool IsDefaultReturnType {
@ -41,7 +48,7 @@ namespace ICSharpCode.SharpDevelop.Dom @@ -41,7 +48,7 @@ namespace ICSharpCode.SharpDevelop.Dom
public override IReturnType BaseType {
get {
IClass c = content.GetClass(fullName, typeArgumentCount);
IClass c = content.GetClass(fullName, typeArgumentCount, content.Language, options);
return (c != null) ? c.DefaultReturnType : null;
}
}

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

@ -561,6 +561,10 @@ namespace ICSharpCode.SharpDevelop.Dom @@ -561,6 +561,10 @@ namespace ICSharpCode.SharpDevelop.Dom
protected IClass GetClassInternal(string typeName, int typeParameterCount, LanguageProperties language)
{
#if DEBUG
if (System.Text.RegularExpressions.Regex.IsMatch (typeName, "`[0-9]+$"))
Debug.Assert(false, "how did a Reflection type name get here?");
#endif
lock (namespaces) {
IClass c;
if (GetClasses(language).TryGetValue(typeName, out c)) {

3
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 = 18;
public const short FileVersion = 19;
ProjectContentRegistry registry;
string cacheDirectory;
@ -46,7 +46,6 @@ namespace ICSharpCode.SharpDevelop.Dom @@ -46,7 +46,6 @@ namespace ICSharpCode.SharpDevelop.Dom
int pos = assemblyFullName.IndexOf(',');
string fileName = Path.Combine(cacheDirectory,
assemblyFullName.Substring(0, pos)
+ "." + assemblyFullName.GetHashCode().ToString("x", CultureInfo.InvariantCulture)
+ "." + pc.AssemblyLocation.GetHashCode().ToString("x", CultureInfo.InvariantCulture)
+ ".dat");
AddFileNameToCacheIndex(Path.GetFileName(fileName), pc);

30
src/Main/ICSharpCode.SharpDevelop.Dom/Project/Src/ReflectionLayer/ReflectionClass.cs

@ -25,7 +25,7 @@ namespace ICSharpCode.SharpDevelop.Dom.ReflectionLayer @@ -25,7 +25,7 @@ namespace ICSharpCode.SharpDevelop.Dom.ReflectionLayer
// We cannot use nestedType.IsVisible - that only checks for public types,
// but we also need to load protected types.
if (nestedType.IsNestedPublic || nestedType.IsNestedFamily || nestedType.IsNestedFamORAssem) {
string name = nestedType.FullName.Replace('+', '.');
string name = this.FullyQualifiedName + "." + nestedType.Name;
InnerClasses.Add(new ReflectionClass(CompilationUnit, nestedType, name, this));
}
}
@ -100,13 +100,33 @@ namespace ICSharpCode.SharpDevelop.Dom.ReflectionLayer @@ -100,13 +100,33 @@ namespace ICSharpCode.SharpDevelop.Dom.ReflectionLayer
}
}
public ReflectionClass(ICompilationUnit compilationUnit, Type type, string fullName, IClass declaringType) : base(compilationUnit, declaringType)
public static string SplitTypeParameterCountFromReflectionName(string reflectionName)
{
int lastBackTick = reflectionName.LastIndexOf('`');
if (lastBackTick < 0)
return reflectionName;
else
return reflectionName.Substring(0, lastBackTick);
}
public static string SplitTypeParameterCountFromReflectionName(string reflectionName, out int typeParameterCount)
{
if (fullName.Length > 2 && fullName[fullName.Length - 2] == '`') {
FullyQualifiedName = fullName.Substring(0, fullName.Length - 2);
int pos = reflectionName.LastIndexOf('`');
if (pos < 0) {
typeParameterCount = 0;
return reflectionName;
} else {
FullyQualifiedName = fullName;
string typeCount = reflectionName.Substring(pos + 1);
if (int.TryParse(typeCount, out typeParameterCount))
return reflectionName.Substring(0, pos);
else
return reflectionName;
}
}
public ReflectionClass(ICompilationUnit compilationUnit, Type type, string fullName, IClass declaringType) : base(compilationUnit, declaringType)
{
FullyQualifiedName = SplitTypeParameterCountFromReflectionName(fullName);
try {
AddAttributes(compilationUnit.ProjectContent, this.Attributes, CustomAttributeData.GetCustomAttributes(type));

22
src/Main/ICSharpCode.SharpDevelop.Dom/Project/Src/ReflectionLayer/ReflectionReturnType.cs

@ -7,6 +7,7 @@ @@ -7,6 +7,7 @@
using System;
using System.Collections.Generic;
using System.Text;
namespace ICSharpCode.SharpDevelop.Dom.ReflectionLayer
{
@ -69,15 +70,20 @@ namespace ICSharpCode.SharpDevelop.Dom.ReflectionLayer @@ -69,15 +70,20 @@ namespace ICSharpCode.SharpDevelop.Dom.ReflectionLayer
string name = type.FullName;
if (name == null)
throw new ApplicationException("type.FullName returned null. Type: " + type.ToString());
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);
}
}
int typeParameterCount;
if (name.IndexOf('+') > 0) {
name = name.Replace('+', '.');
typeParameterCount = 0;
StringBuilder newName = new StringBuilder();
foreach (string namepart in name.Split('+')) {
if (newName.Length > 0)
newName.Append('.');
int partTypeParameterCount;
newName.Append(ReflectionClass.SplitTypeParameterCountFromReflectionName(namepart, out partTypeParameterCount));
typeParameterCount += partTypeParameterCount;
}
name = newName.ToString();
} else {
name = ReflectionClass.SplitTypeParameterCountFromReflectionName(name, out typeParameterCount);
}
if (!createLazyReturnType) {
IClass c = pc.GetClass(name, typeParameterCount);

Loading…
Cancel
Save