Browse Source

Fixed code-completion resolving the wrong class when two imported namespaces contain a class with the same name but only one of the classes is accessible.

git-svn-id: svn://svn.sharpdevelop.net/sharpdevelop/branches/3.0@3560 1ccf3a8d-04fe-1044-b7c0-cef0b8235c61
shortcuts
Daniel Grunwald 18 years ago
parent
commit
75ba08f309
  1. 33
      src/Main/Base/Test/SearchClassTests.cs
  2. 42
      src/Main/ICSharpCode.SharpDevelop.Dom/Project/Src/ProjectContent/DefaultProjectContent.cs

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

@ -140,5 +140,38 @@ namespace ICSharpCode.SharpDevelop.Tests @@ -140,5 +140,38 @@ namespace ICSharpCode.SharpDevelop.Tests
{
CheckNamespaceVB("COllEctions.GeNEric", "KeyNotFoundException");
}
[Test]
public void SearchClassPreferVisible()
{
ICompilationUnit ref1 = Prepare(LanguageProperties.CSharp);
ref1.ProjectContent.AddClassToNamespaceList(new DefaultClass(ref1, "ClassName") { Modifiers = ModifierEnum.Internal });
ICompilationUnit ref2 = Prepare(LanguageProperties.CSharp);
ref2.ProjectContent.AddClassToNamespaceList(new DefaultClass(ref2, "ClassName") { Modifiers = ModifierEnum.Public });
ICompilationUnit cu = Prepare(LanguageProperties.CSharp);
cu.ProjectContent.ReferencedContents.Add(ref1.ProjectContent);
cu.ProjectContent.ReferencedContents.Add(ref2.ProjectContent);
SearchTypeResult r = cu.ProjectContent.SearchType(new SearchTypeRequest("ClassName", 0, null, cu, 1, 1));
Assert.AreEqual(ModifierEnum.Public, r.Result.GetUnderlyingClass().Modifiers);
}
[Test]
public void SearchClassDifferentNamespacePreferVisible()
{
ICompilationUnit ref1 = Prepare(LanguageProperties.CSharp);
ref1.ProjectContent.AddClassToNamespaceList(new DefaultClass(ref1, "NS1.ClassName") { Modifiers = ModifierEnum.Internal });
ICompilationUnit ref2 = Prepare(LanguageProperties.CSharp);
ref2.ProjectContent.AddClassToNamespaceList(new DefaultClass(ref2, "NS2.ClassName") { Modifiers = ModifierEnum.Public });
ICompilationUnit cu = Prepare(LanguageProperties.CSharp);
cu.ProjectContent.ReferencedContents.Add(ref1.ProjectContent);
cu.ProjectContent.ReferencedContents.Add(ref2.ProjectContent);
cu.Usings.Add(new DefaultUsing(cu.ProjectContent) { Usings = { "NS1", "NS2" } });
SearchTypeResult r = cu.ProjectContent.SearchType(new SearchTypeRequest("ClassName", 0, null, cu, 1, 1));
Assert.AreEqual(ModifierEnum.Public, r.Result.GetUnderlyingClass().Modifiers);
}
}
}

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

@ -579,6 +579,14 @@ namespace ICSharpCode.SharpDevelop.Dom @@ -579,6 +579,14 @@ namespace ICSharpCode.SharpDevelop.Dom
}
}
bool IsAccessibleClass(IClass c)
{
// check the outermost class (which is either public or internal)
while (c.DeclaringType != null)
c = c.DeclaringType;
return c.IsPublic || c.ProjectContent == this;
}
public IClass GetClass(string typeName, int typeParameterCount, LanguageProperties language, bool lookInReferences)
{
IClass c = GetClassInternal(typeName, typeParameterCount, language);
@ -592,7 +600,9 @@ namespace ICSharpCode.SharpDevelop.Dom @@ -592,7 +600,9 @@ namespace ICSharpCode.SharpDevelop.Dom
foreach (IProjectContent content in referencedContents) {
IClass contentClass = content.GetClass(typeName, typeParameterCount, language, false);
if (contentClass != null) {
if (contentClass.TypeParameters.Count == typeParameterCount) {
if (contentClass.TypeParameters.Count == typeParameterCount
&& IsAccessibleClass(contentClass))
{
return contentClass;
} else {
c = contentClass;
@ -771,6 +781,26 @@ namespace ICSharpCode.SharpDevelop.Dom @@ -771,6 +781,26 @@ namespace ICSharpCode.SharpDevelop.Dom
return null;
}
bool MatchesRequest(ref SearchTypeRequest request, IClass c)
{
return c != null
&& c.TypeParameters.Count == request.TypeParameterCount
&& IsAccessibleClass(c);
}
bool MatchesRequest(ref SearchTypeRequest request, IReturnType rt)
{
if (rt == null)
return false;
if (rt.TypeArgumentCount != request.TypeParameterCount)
return false;
IClass c = rt.GetUnderlyingClass();
if (c != null)
return IsAccessibleClass(c);
else
return true;
}
public SearchTypeResult SearchType(SearchTypeRequest request)
{
string name = request.Name;
@ -780,7 +810,7 @@ namespace ICSharpCode.SharpDevelop.Dom @@ -780,7 +810,7 @@ namespace ICSharpCode.SharpDevelop.Dom
// Try if name is already the full type name
IClass c = GetClass(name, request.TypeParameterCount);
if (c != null) {
if (MatchesRequest(ref request, c)) {
return new SearchTypeResult(c);
}
// fallback-class if the one with the right type parameter count is not found.
@ -793,7 +823,7 @@ namespace ICSharpCode.SharpDevelop.Dom @@ -793,7 +823,7 @@ namespace ICSharpCode.SharpDevelop.Dom
c = GetClass(nameSpace, request.TypeParameterCount);
if (c != null) {
if (c.TypeParameters.Count == request.TypeParameterCount)
if (MatchesRequest(ref request, c))
return new SearchTypeResult(c);
else
fallbackResult = new SearchTypeResult(c);
@ -814,7 +844,7 @@ namespace ICSharpCode.SharpDevelop.Dom @@ -814,7 +844,7 @@ namespace ICSharpCode.SharpDevelop.Dom
if (baseClass.ClassType == ClassType.Class) {
foreach (IClass innerClass in baseClass.InnerClasses) {
if (language.NameComparer.Equals(innerClass.Name, name)) {
if (innerClass.TypeParameters.Count == request.TypeParameterCount) {
if (MatchesRequest(ref request, innerClass)) {
return new SearchTypeResult(innerClass);
} else {
fallbackResult = new SearchTypeResult(innerClass);
@ -830,7 +860,7 @@ namespace ICSharpCode.SharpDevelop.Dom @@ -830,7 +860,7 @@ namespace ICSharpCode.SharpDevelop.Dom
foreach (IUsing u in request.CurrentCompilationUnit.Usings) {
if (u != null) {
foreach (IReturnType r in u.SearchType(name, request.TypeParameterCount)) {
if (r.TypeArgumentCount == request.TypeParameterCount) {
if (MatchesRequest(ref request, r)) {
return new SearchTypeResult(r, u);
} else {
fallbackResult = new SearchTypeResult(r, u);
@ -841,7 +871,7 @@ namespace ICSharpCode.SharpDevelop.Dom @@ -841,7 +871,7 @@ namespace ICSharpCode.SharpDevelop.Dom
}
if (defaultImports != null) {
foreach (IReturnType r in defaultImports.SearchType(name, request.TypeParameterCount)) {
if (r.TypeArgumentCount == request.TypeParameterCount) {
if (MatchesRequest(ref request, r)) {
return new SearchTypeResult(r, defaultImports);
} else {
fallbackResult = new SearchTypeResult(r, defaultImports);

Loading…
Cancel
Save